Contract 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c

 

Contract Overview

Balance:
0 BNB

BNB Value:
$0.00

Token:
Ad
Ad
Txn Hash
Block
From
To
Value [Txn Fee]
0x8957295e3d6d8d692d86f7404cbdbc1fb055a39e7b08c37fcf63c517e9d590f1(pending)2021-03-07 0:03:401 sec ago0x9186eb0108a37b1982a8a1ad1bc64b8d9060be07 IN 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB(Pending)
0xfd3f27a0d72211a802dd7967357b32c92ef206124a5eff13eb1a6d8b8d54aa7054570172021-03-07 0:03:365 secs ago0x425ae4bce06d48c598f718e4aded421a077939cc IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00157401
0x73ff3eab87b411ace69a74258ca0ab56aac9121f87e82cefd6e05bfd2e9f9d1754570172021-03-07 0:03:365 secs ago0x4e3deb840f7268862ca6bdda1ee47996dfc4693a IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00298587
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago0x77e4745801be4fba1dc2004551e56f79e3f024ad IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00430403
0x5594dbf6e2630ee411428baddf3b496f40760d311df75a710b6559f17d2b28b454570122021-03-07 0:03:2120 secs ago0x581a4484fb319b05347a85587d8764c29c802f84 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.0044749
0x19b150d283ed243cee955832e5578c18963fd9514c505998ccb083bb0e5bb5b454570112021-03-07 0:03:1823 secs ago0x53e213da8c28d85dc6663c3b5e35bb0ffbb05752 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c26.4 BNB0.00217554
0x93ccc4fc8e3d97e5b707ed9ad8d09ff8bb2e954fb06b85c47550bd44fdd931c154570112021-03-07 0:03:1823 secs ago0xa37f39c248d65f5f07a0b65550faf63c267fbe0d IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.006211439
0x7431b6ef0f00493b82efaf8dda3d8045d18652204fcc723785981bc265c9904154570102021-03-07 0:03:1526 secs ago0x23cefde48cd5eb3ccdf4cf7ee2fc691370e40790 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.083756156041334 BNB0.00179166
0x777b01877b8afce85ee7f4d41eeb74309d5d212ce8837f0a147d426e5e065fab54570102021-03-07 0:03:1526 secs ago0x69655181a55755adc854cd35c15995393f63e9e5 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00217493
0x68590dc4f34bd49b4cdd3f985813708b1a4612fcf6059959886c9a423f8dbc6a54570092021-03-07 0:03:1229 secs ago0x68d6e1b3eb71c8cdd9cba94bd7a63b7c3e488eb2 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00211512
0x5c3aca044794df47f74723a0000fb2f2652a05131e82b908a33d9317402be4e354570092021-03-07 0:03:1229 secs ago0xf397d3a604e178a059f6f77f0de5ed13121a8dff IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00191242
0xc7150e7b7a36333102b1ed50785fde642a6d0496eda71ca253b116f866bd3cc654570092021-03-07 0:03:1229 secs ago0xf0fe77fa815d964cd5a67a25eb61496530830d3b IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00054582
0x873e5c41b56e7f5ca38007cd1d71e8e5a6ec4a88eed2b7b05a7c333f2377579254570082021-03-07 0:03:0932 secs ago0xde739696b4569268ab1f01bf408e656a6f792576 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00206242
0x613579bbc96e78653afe680a6a3c2f43f3d815ad2eca2f62ad6ea3fdd3351c2f54570062021-03-07 0:03:0338 secs ago0x0fb63a1a62e9ca8caf729fa4f12680dd9b55e9a5 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00195235
0xf2594ecf4f0360e9e6ce5be8a8999c26ed97e83808e193218a740a1df9b50c5d54570032021-03-07 0:02:5447 secs ago0x95d66bcb1ed7687140014d0b16e5a645a66fb32b IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00143733
0x737f889da7362f1b4372d7fbb154e04c89e874faae7fd7c611f48590f12bb6d954570032021-03-07 0:02:5447 secs ago0x662edf47a7e6e261b13718dd1616e874f75fa008 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00146843
0x110bbaa39d9e3247ed6dccad79a5d369a1bc1b5fa0c079afd69e2c70914e61fb54570022021-03-07 0:02:5150 secs ago0x44adcd0cb3a2f1df487fba5c0f6878fe7f887ded IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.0019842
0x5f38cb243156b7aea830c93f4a158b2ee6ef6118ba99da809beee2b8bb192b0e54570022021-03-07 0:02:5150 secs ago0x54ea316c0fa3834e5ebc7db09809ea3beabac3df IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c2.131709694255205 BNB0.00178615
0x5f38e2db5b5ba891e100d7f72cccb7aebb302db6147434fd6da02bc5e8f146e154570022021-03-07 0:02:5150 secs ago0xc5e114e271c0fd3b731614694babee826fa90c4e IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00357431
0x5f7de2d0ea62faf467dbe124007bb0d9d8b7867d32e57a76a592bee2005d2ca354570012021-03-07 0:02:4853 secs ago0xa01d590200946d92ee84364624ba459e8b75ffc1 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c1.434185057238029 BNB0.001608
0xea594884284ac701a9cc7bef73fd127bce1dd99f069a7e2180480758ac9b01d954570012021-03-07 0:02:4853 secs ago0xf397d3a604e178a059f6f77f0de5ed13121a8dff IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00199106
0xf4df08f8292eebab574176345e25fc645cc63e475a73b6f6545e0d4c886d228854570012021-03-07 0:02:4853 secs ago0x931335b54d426ccc92aa5894e93049408c34a2a1 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00463664
0xe0a3fd8b0211ac52f4502c280c12d718ed1aa2d0291089000b03256a6b88ec8d54570002021-03-07 0:02:4556 secs ago0xddb30eb43115e0f8ed1d3b578ce08408ab60ca3e IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c231.134840003473154 BNB0.00160398
0xce42bbab8900ce848c89f8435dc4fa5ddea12a0d1038c18e5444f5b11d23614854570002021-03-07 0:02:4556 secs ago0xf4acc1ed6e32e3b043295ca16003e2f64f50d117 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c6.476764771367375 BNB0.00188792
0x5a5bd7bfc7cd4f67879d45e489cf42d4b87c07f07efbf4906e858c234d6fb5f054570002021-03-07 0:02:4556 secs ago0x60c7a104286480ecbb2f46ab74e39ea6fbc3cdb3 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00161647
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c 0xc66e4de0d9b4f3cb3f271c37991fe62f154471eb0 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0x77e4745801be4fba1dc2004551e56f79e3f024ad0.32562188216758013 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago Binance: WBNB Token 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.32562188216758013 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c PancakeSwap: BUSD0 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c PancakeSwap: BUSD0 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c 0x45f24baeef268bb6d63aee5129015d69702bcdfa0 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: BUSD Stablecoin0 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c 0x45f24baeef268bb6d63aee5129015d69702bcdfa0 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: BUSD Stablecoin0 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: BUSD Stablecoin0 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c 0x58bcb3d7bc69b4f3d0d1eca1c7dcf7b4b2f1ebd40 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c 0x58bcb3d7bc69b4f3d0d1eca1c7dcf7b4b2f1ebd40 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: BUSD Stablecoin0 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c 0x45f24baeef268bb6d63aee5129015d69702bcdfa0 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c 0xc66e4de0d9b4f3cb3f271c37991fe62f154471eb0 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c 0x45f24baeef268bb6d63aee5129015d69702bcdfa0 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c 0xc66e4de0d9b4f3cb3f271c37991fe62f154471eb0 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c 0x51509ef5ed3fa020b6011ab10e0383e089fd48230 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c 0x51509ef5ed3fa020b6011ab10e0383e089fd48230 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0 BNB
0x1236124d373704cb50f4fdeb083be4ec1d553874815d78293fc949eff6d1f01654570142021-03-07 0:03:2714 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c 0x45f24baeef268bb6d63aee5129015d69702bcdfa0 BNB
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ValueLiquidRouter

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 999999 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at BscScan.com on 2021-02-23
*/

// SPDX-License-Identifier: SEE LICENSE IN LICENSE

pragma solidity >=0.7.6;
pragma abicoder v2;

interface IValueLiquidFactory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint32 tokenWeight0, uint32 swapFee, uint256);

    function feeTo() external view returns (address);

    function formula() external view returns (address);

    function protocolFee() external view returns (uint256);

    function feeToSetter() external view returns (address);

    function getPair(
        address tokenA,
        address tokenB,
        uint32 tokenWeightA,
        uint32 swapFee
    ) external view returns (address pair);

    function allPairs(uint256) external view returns (address pair);

    function isPair(address) external view returns (bool);

    function allPairsLength() external view returns (uint256);

    function createPair(
        address tokenA,
        address tokenB,
        uint32 tokenWeightA,
        uint32 swapFee
    ) external returns (address pair);

    function getWeightsAndSwapFee(address pair)
        external
        view
        returns (
            uint32 tokenWeight0,
            uint32 tokenWeight1,
            uint32 swapFee
        );

    function setFeeTo(address) external;

    function setFeeToSetter(address) external;

    function setProtocolFee(uint256) external;
}

/*
    Bancor Formula interface
*/
interface IValueLiquidFormula {
    function getReserveAndWeights(address pair, address tokenA)
        external
        view
        returns (
            address tokenB,
            uint256 reserveA,
            uint256 reserveB,
            uint32 tokenWeightA,
            uint32 tokenWeightB,
            uint32 swapFee
        );

    function getFactoryReserveAndWeights(
        address factory,
        address pair,
        address tokenA
    )
        external
        view
        returns (
            address tokenB,
            uint256 reserveA,
            uint256 reserveB,
            uint32 tokenWeightA,
            uint32 tokenWeightB,
            uint32 swapFee
        );

    function getAmountIn(
        uint256 amountOut,
        uint256 reserveIn,
        uint256 reserveOut,
        uint32 tokenWeightIn,
        uint32 tokenWeightOut,
        uint32 swapFee
    ) external view returns (uint256 amountIn);

    function getPairAmountIn(
        address pair,
        address tokenIn,
        uint256 amountOut
    ) external view returns (uint256 amountIn);

    function getAmountOut(
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut,
        uint32 tokenWeightIn,
        uint32 tokenWeightOut,
        uint32 swapFee
    ) external view returns (uint256 amountOut);

    function getPairAmountOut(
        address pair,
        address tokenIn,
        uint256 amountIn
    ) external view returns (uint256 amountOut);

    function getAmountsIn(
        address tokenIn,
        address tokenOut,
        uint256 amountOut,
        address[] calldata path
    ) external view returns (uint256[] memory amounts);

    function getFactoryAmountsIn(
        address factory,
        address tokenIn,
        address tokenOut,
        uint256 amountOut,
        address[] calldata path
    ) external view returns (uint256[] memory amounts);

    function getAmountsOut(
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        address[] calldata path
    ) external view returns (uint256[] memory amounts);

    function getFactoryAmountsOut(
        address factory,
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        address[] calldata path
    ) external view returns (uint256[] memory amounts);

    function ensureConstantValue(
        uint256 reserve0,
        uint256 reserve1,
        uint256 balance0Adjusted,
        uint256 balance1Adjusted,
        uint32 tokenWeight0
    ) external view returns (bool);

    function getReserves(
        address pair,
        address tokenA,
        address tokenB
    ) external view returns (uint256 reserveA, uint256 reserveB);

    function getOtherToken(address pair, address tokenA) external view returns (address tokenB);

    function quote(
        uint256 amountA,
        uint256 reserveA,
        uint256 reserveB
    ) external pure returns (uint256 amountB);

    function sortTokens(address tokenA, address tokenB) external pure returns (address token0, address token1);

    function mintLiquidityFee(
        uint256 totalLiquidity,
        uint112 reserve0,
        uint112 reserve1,
        uint32 tokenWeight0,
        uint32 tokenWeight1,
        uint112 collectedFee0,
        uint112 collectedFee1
    ) external view returns (uint256 amount);
}

interface IValueLiquidPair {
    event Approval(address indexed owner, address indexed spender, uint256 value);
    event Transfer(address indexed from, address indexed to, uint256 value);

    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external pure returns (uint8);

    function totalSupply() external view returns (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender) external view returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);

    function PERMIT_TYPEHASH() external pure returns (bytes32);

    function nonces(address owner) external view returns (uint256);

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    event PaidProtocolFee(uint112 collectedFee0, uint112 collectedFee1);
    event Mint(address indexed sender, uint256 amount0, uint256 amount1);
    event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to);
    event Swap(address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to);
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint256);

    function factory() external view returns (address);

    function token0() external view returns (address);

    function token1() external view returns (address);

    function getReserves()
        external
        view
        returns (
            uint112 reserve0,
            uint112 reserve1,
            uint32 blockTimestampLast
        );

    function getCollectedFees() external view returns (uint112 _collectedFee0, uint112 _collectedFee1);

    function getTokenWeights() external view returns (uint32 tokenWeight0, uint32 tokenWeight1);

    function getSwapFee() external view returns (uint32);

    function price0CumulativeLast() external view returns (uint256);

    function price1CumulativeLast() external view returns (uint256);

    function mint(address to) external returns (uint256 liquidity);

    function burn(address to) external returns (uint256 amount0, uint256 amount1);

    function swap(
        uint256 amount0Out,
        uint256 amount1Out,
        address to,
        bytes calldata data
    ) external;

    function skim(address to) external;

    function sync() external;

    function initialize(
        address,
        address,
        uint32,
        uint32
    ) external;
}

// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library TransferHelper {
    function safeApprove(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('approve(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper: APPROVE_FAILED");
    }

    function safeTransfer(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper: TRANSFER_FAILED");
    }

    function safeTransferFrom(
        address token,
        address from,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper: TRANSFER_FROM_FAILED");
    }

    function safeTransferETH(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, "TransferHelper: ETH_TRANSFER_FAILED");
    }
}

interface IValueLiquidRouter {
    event Exchange(address pair, uint256 amountOut, address output);
    struct Swap {
        address pool;
        address tokenIn;
        address tokenOut;
        uint256 swapAmount; // tokenInAmount / tokenOutAmount
        uint256 limitReturnAmount; // minAmountOut / maxAmountIn
        uint256 maxPrice;
    }

    function factory() external view returns (address);

    function controller() external view returns (address);

    function formula() external view returns (address);

    function WETH() external view returns (address);

    function addLiquidity(
        address pair,
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    )
        external
        returns (
            uint256 amountA,
            uint256 amountB,
            uint256 liquidity
        );

    function addLiquidityETH(
        address pair,
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        );

    function swapExactTokensForTokens(
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapTokensForExactTokens(
        address tokenIn,
        address tokenOut,
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactETHForTokens(
        address tokenOut,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function swapTokensForExactETH(
        address tokenIn,
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactTokensForETH(
        address tokenIn,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapETHForExactTokens(
        address tokenOut,
        uint256 amountOut,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        address tokenOut,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable;

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        address tokenIn,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    function multihopBatchSwapExactIn(
        Swap[][] memory swapSequences,
        address tokenIn,
        address tokenOut,
        uint256 totalAmountIn,
        uint256 minTotalAmountOut,
        uint256 deadline
    ) external payable returns (uint256 totalAmountOut);

    function multihopBatchSwapExactOut(
        Swap[][] memory swapSequences,
        address tokenIn,
        address tokenOut,
        uint256 maxTotalAmountIn,
        uint256 deadline
    ) external payable returns (uint256 totalAmountIn);

    function createPair(
        address tokenA,
        address tokenB,
        uint256 amountA,
        uint256 amountB,
        uint32 tokenWeightA,
        uint32 swapFee,
        address to
    ) external returns (uint256 liquidity);

    function createPairETH(
        address token,
        uint256 amountToken,
        uint32 tokenWeight,
        uint32 swapFee,
        address to
    ) external payable returns (uint256 liquidity);

    function removeLiquidity(
        address pair,
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETH(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountToken, uint256 amountETH);

    function removeLiquidityWithPermit(
        address pair,
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETHWithPermit(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountToken, uint256 amountETH);

    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountETH);

    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountETH);
}

// a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)
library SafeMath {
    function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x + y) >= x, "ds-math-add-overflow");
    }

    function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x - y) <= x, "ds-math-sub-underflow");
    }

    function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow");
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256 c) {
        require(b > 0, "ds-math-division-by-zero");
        c = a / b;
    }
}

interface IWETH {
    function deposit() external payable;

    function transfer(address to, uint256 value) external returns (bool);

    function withdraw(uint256) external;

    function balanceOf(address account) external view returns (uint256);
}

interface IERC20 {
    event Approval(address indexed owner, address indexed spender, uint256 value);
    event Transfer(address indexed from, address indexed to, uint256 value);

    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external view returns (uint8);

    function totalSupply() external view returns (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender) external view returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);
}

interface IBPool is IERC20 {
    function version() external view returns (uint256);

    function swapExactAmountIn(
        address,
        uint256,
        address,
        uint256,
        uint256
    ) external returns (uint256, uint256);

    function swapExactAmountOut(
        address,
        uint256,
        address,
        uint256,
        uint256
    ) external returns (uint256, uint256);

    function calcInGivenOut(
        uint256,
        uint256,
        uint256,
        uint256,
        uint256,
        uint256
    ) external pure returns (uint256);

    function calcOutGivenIn(
        uint256,
        uint256,
        uint256,
        uint256,
        uint256,
        uint256
    ) external pure returns (uint256);

    function getDenormalizedWeight(address) external view returns (uint256);

    function swapFee() external view returns (uint256);

    function setSwapFee(uint256 _swapFee) external;

    function bind(
        address token,
        uint256 balance,
        uint256 denorm
    ) external;

    function rebind(
        address token,
        uint256 balance,
        uint256 denorm
    ) external;

    function finalize(
        uint256 _swapFee,
        uint256 _initPoolSupply,
        address[] calldata _bindTokens,
        uint256[] calldata _bindDenorms
    ) external;

    function setPublicSwap(bool _publicSwap) external;

    function setController(address _controller) external;

    function setExchangeProxy(address _exchangeProxy) external;

    function getFinalTokens() external view returns (address[] memory tokens);

    function getTotalDenormalizedWeight() external view returns (uint256);

    function getBalance(address token) external view returns (uint256);

    function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external;

    function joinPoolFor(
        address account,
        uint256 rewardAmountOut,
        uint256[] calldata maxAmountsIn
    ) external;

    function joinswapPoolAmountOut(
        address tokenIn,
        uint256 poolAmountOut,
        uint256 maxAmountIn
    ) external returns (uint256 tokenAmountIn);

    function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external;

    function exitswapPoolAmountIn(
        address tokenOut,
        uint256 poolAmountIn,
        uint256 minAmountOut
    ) external returns (uint256 tokenAmountOut);

    function exitswapExternAmountOut(
        address tokenOut,
        uint256 tokenAmountOut,
        uint256 maxPoolAmountIn
    ) external returns (uint256 poolAmountIn);

    function joinswapExternAmountIn(
        address tokenIn,
        uint256 tokenAmountIn,
        uint256 minPoolAmountOut
    ) external returns (uint256 poolAmountOut);

    function finalizeRewardFundInfo(address _rewardFund, uint256 _unstakingFrozenTime) external;

    function addRewardPool(
        IERC20 _rewardToken,
        uint256 _startBlock,
        uint256 _endRewardBlock,
        uint256 _rewardPerBlock,
        uint256 _lockRewardPercent,
        uint256 _startVestingBlock,
        uint256 _endVestingBlock
    ) external;

    function isBound(address t) external view returns (bool);

    function getSpotPrice(address tokenIn, address tokenOut) external view returns (uint256 spotPrice);
}

contract ValueLiquidRouter is IValueLiquidRouter {
    using SafeMath for uint256;
    address public immutable override factory;
    address public immutable override controller;
    address public immutable override formula;
    address public immutable override WETH;
    address private constant ETH_ADDRESS = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);

    modifier ensure(uint256 deadline) {
        require(deadline >= block.timestamp, "Router: EXPIRED");
        _;
    }

    constructor(
        address _factory,
        address _controller,
        address _WETH
    ) {
        factory = _factory;
        controller = _controller;
        formula = IValueLiquidFactory(_factory).formula();
        WETH = _WETH;
    }

    receive() external payable {
        assert(msg.sender == WETH);
        // only accept ETH via fallback from the WETH contract
    }

    // **** ADD LIQUIDITY ****
    function _addLiquidity(
        address pair,
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin
    ) internal virtual returns (uint256 amountA, uint256 amountB) {
        require(IValueLiquidFactory(factory).isPair(pair), "Router: Invalid pair");
        (uint256 reserveA, uint256 reserveB) = IValueLiquidFormula(formula).getReserves(pair, tokenA, tokenB);
        if (reserveA == 0 && reserveB == 0) {
            (amountA, amountB) = (amountADesired, amountBDesired);
        } else {
            uint256 amountBOptimal = IValueLiquidFormula(formula).quote(amountADesired, reserveA, reserveB);
            if (amountBOptimal <= amountBDesired) {
                require(amountBOptimal >= amountBMin, "Router: INSUFFICIENT_B_AMOUNT");
                (amountA, amountB) = (amountADesired, amountBOptimal);
            } else {
                uint256 amountAOptimal = IValueLiquidFormula(formula).quote(amountBDesired, reserveB, reserveA);
                assert(amountAOptimal <= amountADesired);
                require(amountAOptimal >= amountAMin, "Router: INSUFFICIENT_A_AMOUNT");
                (amountA, amountB) = (amountAOptimal, amountBDesired);
            }
        }
    }

    function _addLiquidityToken(
        address pair,
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin
    ) internal returns (uint256 amountA, uint256 amountB) {
        (amountA, amountB) = _addLiquidity(pair, tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);
        TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA);
        TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB);
    }

    function createPair(
        address tokenA,
        address tokenB,
        uint256 amountA,
        uint256 amountB,
        uint32 tokenWeightA,
        uint32 swapFee,
        address to
    ) public virtual override returns (uint256 liquidity) {
        address pair = IValueLiquidFactory(factory).createPair(tokenA, tokenB, tokenWeightA, swapFee);
        _addLiquidityToken(pair, tokenA, tokenB, amountA, amountB, 0, 0);
        liquidity = IValueLiquidPair(pair).mint(to);
    }

    function addLiquidity(
        address pair,
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    )
        external
        virtual
        override
        ensure(deadline)
        returns (
            uint256 amountA,
            uint256 amountB,
            uint256 liquidity
        )
    {
        (amountA, amountB) = _addLiquidityToken(pair, tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);
        liquidity = IValueLiquidPair(pair).mint(to);
    }

    function _addLiquidityETH(
        address pair,
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to
    )
        internal
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        )
    {
        (amountToken, amountETH) = _addLiquidity(pair, token, WETH, amountTokenDesired, msg.value, amountTokenMin, amountETHMin);
        TransferHelper.safeTransferFrom(token, msg.sender, pair, amountToken);
        transferETHTo(amountETH, pair);
        liquidity = IValueLiquidPair(pair).mint(to);
        // refund dust eth, if any
        if (msg.value > amountETH) TransferHelper.safeTransferETH(msg.sender, msg.value - amountETH);
    }

    function createPairETH(
        address token,
        uint256 amountToken,
        uint32 tokenWeight,
        uint32 swapFee,
        address to
    ) public payable virtual override returns (uint256 liquidity) {
        address pair = IValueLiquidFactory(factory).createPair(token, WETH, tokenWeight, swapFee);
        (, , liquidity) = _addLiquidityETH(pair, token, amountToken, 0, 0, to);
    }

    function addLiquidityETH(
        address pair,
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        public
        payable
        virtual
        override
        ensure(deadline)
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        )
    {
        (amountToken, amountETH, liquidity) = _addLiquidityETH(pair, token, amountTokenDesired, amountTokenMin, amountETHMin, to);
    }

    // **** SWAP ****
    // requires the initial amount to have already been sent to the first pair
    function _swap(
        address tokenIn,
        uint256[] memory amounts,
        address[] memory path,
        address _to
    ) internal virtual {
        address input = tokenIn;
        for (uint256 i = 0; i < path.length; i++) {
            IValueLiquidPair pairV2 = IValueLiquidPair(path[i]);
            address token0 = pairV2.token0();
            uint256 amountOut = amounts[i + 1];
            (uint256 amount0Out, uint256 amount1Out, address output) = input == token0 ? (uint256(0), amountOut, pairV2.token1()) : (amountOut, uint256(0), token0);
            address to = i < path.length - 1 ? path[i + 1] : _to;
            pairV2.swap(amount0Out, amount1Out, to, new bytes(0));
            emit Exchange(address(pairV2), amountOut, output);
            input = output;
        }
    }

    function swapExactTokensForTokens(
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] memory path,
        address to,
        uint256 deadline
    ) public virtual override ensure(deadline) returns (uint256[] memory amounts) {
        amounts = _validateAmountOut(tokenIn, tokenOut, amountIn, amountOutMin, path);

        TransferHelper.safeTransferFrom(tokenIn, msg.sender, path[0], amounts[0]);
        _swap(tokenIn, amounts, path, to);
    }

    function swapTokensForExactTokens(
        address tokenIn,
        address tokenOut,
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external virtual override ensure(deadline) returns (uint256[] memory amounts) {
        amounts = _validateAmountIn(tokenIn, tokenOut, amountOut, amountInMax, path);

        TransferHelper.safeTransferFrom(tokenIn, msg.sender, path[0], amounts[0]);
        _swap(tokenIn, amounts, path, to);
    }

    function swapExactETHForTokens(
        address tokenOut,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable virtual override ensure(deadline) returns (uint256[] memory amounts) {
        amounts = _validateAmountOut(WETH, tokenOut, msg.value, amountOutMin, path);

        transferETHTo(amounts[0], path[0]);
        _swap(WETH, amounts, path, to);
    }

    function swapTokensForExactETH(
        address tokenIn,
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external virtual override ensure(deadline) returns (uint256[] memory amounts) {
        amounts = _validateAmountIn(tokenIn, WETH, amountOut, amountInMax, path);

        TransferHelper.safeTransferFrom(tokenIn, msg.sender, path[0], amounts[0]);
        _swap(tokenIn, amounts, path, address(this));
        transferAll(ETH_ADDRESS, to, amounts[amounts.length - 1]);
    }

    function swapExactTokensForETH(
        address tokenIn,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external virtual override ensure(deadline) returns (uint256[] memory amounts) {
        amounts = _validateAmountOut(tokenIn, WETH, amountIn, amountOutMin, path);

        TransferHelper.safeTransferFrom(tokenIn, msg.sender, path[0], amounts[0]);
        _swap(tokenIn, amounts, path, address(this));
        transferAll(ETH_ADDRESS, to, amounts[amounts.length - 1]);
    }

    function swapETHForExactTokens(
        address tokenOut,
        uint256 amountOut,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable virtual override ensure(deadline) returns (uint256[] memory amounts) {
        amounts = _validateAmountIn(WETH, tokenOut, amountOut, msg.value, path);

        transferETHTo(amounts[0], path[0]);
        _swap(WETH, amounts, path, to);
        // refund dust eth, if any
        if (msg.value > amounts[0]) TransferHelper.safeTransferETH(msg.sender, msg.value - amounts[0]);
    }

    // **** SWAP (supporting fee-on-transfer tokens) ****
    // requires the initial amount to have already been sent to the first pair
    function _swapSupportingFeeOnTransferTokens(
        address tokenIn,
        address[] memory path,
        address _to
    ) internal virtual {
        address input = tokenIn;
        for (uint256 i; i < path.length; i++) {
            IValueLiquidPair pair = IValueLiquidPair(path[i]);

            uint256 amountInput;
            uint256 amountOutput;
            address currentOutput;
            {
                (address output, uint256 reserveInput, uint256 reserveOutput, uint32 tokenWeightInput, uint32 tokenWeightOutput, uint32 swapFee) =
                    IValueLiquidFormula(formula).getFactoryReserveAndWeights(factory, address(pair), input);
                amountInput = IERC20(input).balanceOf(address(pair)).sub(reserveInput);
                amountOutput = IValueLiquidFormula(formula).getAmountOut(amountInput, reserveInput, reserveOutput, tokenWeightInput, tokenWeightOutput, swapFee);
                currentOutput = output;
            }
            (uint256 amount0Out, uint256 amount1Out) = input == pair.token0() ? (uint256(0), amountOutput) : (amountOutput, uint256(0));
            address to = i < path.length - 1 ? path[i + 1] : _to;
            pair.swap(amount0Out, amount1Out, to, new bytes(0));
            emit Exchange(address(pair), amountOutput, currentOutput);
            input = currentOutput;
        }
    }

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external virtual override ensure(deadline) {
        TransferHelper.safeTransferFrom(tokenIn, msg.sender, path[0], amountIn);
        uint256 balanceBefore = IERC20(tokenOut).balanceOf(to);
        _swapSupportingFeeOnTransferTokens(tokenIn, path, to);
        require(IERC20(tokenOut).balanceOf(to).sub(balanceBefore) >= amountOutMin, "Router: INSUFFICIENT_OUTPUT_AMOUNT");
    }

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        address tokenOut,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable virtual override ensure(deadline) {
        //            require(path[0] == WETH, 'Router: INVALID_PATH');
        uint256 amountIn = msg.value;
        transferETHTo(amountIn, path[0]);
        uint256 balanceBefore = IERC20(tokenOut).balanceOf(to);
        _swapSupportingFeeOnTransferTokens(WETH, path, to);
        require(IERC20(tokenOut).balanceOf(to).sub(balanceBefore) >= amountOutMin, "Router: INSUFFICIENT_OUTPUT_AMOUNT");
    }

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        address tokenIn,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external virtual override ensure(deadline) {
        TransferHelper.safeTransferFrom(tokenIn, msg.sender, path[0], amountIn);
        _swapSupportingFeeOnTransferTokens(tokenIn, path, address(this));
        uint256 amountOut = IERC20(WETH).balanceOf(address(this));
        require(amountOut >= amountOutMin, "Router: INSUFFICIENT_OUTPUT_AMOUNT");
        transferAll(ETH_ADDRESS, to, amountOut);
    }

    function multihopBatchSwapExactIn(
        Swap[][] memory swapSequences,
        address tokenIn,
        address tokenOut,
        uint256 totalAmountIn,
        uint256 minTotalAmountOut,
        uint256 deadline
    ) public payable virtual override ensure(deadline) returns (uint256 totalAmountOut) {
        transferFromAll(tokenIn, totalAmountIn);
        uint256 balanceBefore;
        if (!isETH(tokenOut)) {
            balanceBefore = IERC20(tokenOut).balanceOf(msg.sender);
        }

        for (uint256 i = 0; i < swapSequences.length; i++) {
            uint256 tokenAmountOut;
            for (uint256 k = 0; k < swapSequences[i].length; k++) {
                Swap memory swap = swapSequences[i][k];
                if (k == 1) {
                    // Makes sure that on the second swap the output of the first was used
                    // so there is not intermediate token leftover
                    swap.swapAmount = tokenAmountOut;
                }
                tokenAmountOut = _swapSingleSupportFeeOnTransferTokens(swap.tokenIn, swap.tokenOut, swap.pool, swap.swapAmount, swap.limitReturnAmount);
            }

            // This takes the amountOut of the last swap
            totalAmountOut = tokenAmountOut.add(totalAmountOut);
        }

        transferAll(tokenOut, msg.sender, totalAmountOut);
        transferAll(tokenIn, msg.sender, getBalance(tokenIn));

        if (isETH(tokenOut)) {
            require(totalAmountOut >= minTotalAmountOut, "ERR_LIMIT_OUT");
        } else {
            require(IERC20(tokenOut).balanceOf(msg.sender).sub(balanceBefore) >= minTotalAmountOut, "<minTotalAmountOut");
        }
    }

    function multihopBatchSwapExactOut(
        Swap[][] memory swapSequences,
        address tokenIn,
        address tokenOut,
        uint256 maxTotalAmountIn,
        uint256 deadline
    ) public payable virtual override ensure(deadline) returns (uint256 totalAmountIn) {
        transferFromAll(tokenIn, maxTotalAmountIn);

        for (uint256 i = 0; i < swapSequences.length; i++) {
            uint256 tokenAmountInFirstSwap;
            // Specific code for a simple swap and a multihop (2 swaps in sequence)
            if (swapSequences[i].length == 1) {
                Swap memory swap = swapSequences[i][0];
                tokenAmountInFirstSwap = _swapSingleMixOut(swap.tokenIn, swap.tokenOut, swap.pool, swap.swapAmount, swap.limitReturnAmount, swap.maxPrice);
            } else {
                // Consider we are swapping A -> B and B -> C. The goal is to buy a given amount
                // of token C. But first we need to buy B with A so we can then buy C with B
                // To get the exact amount of C we then first need to calculate how much B we'll need:
                uint256 intermediateTokenAmount;
                // This would be token B as described above
                Swap memory secondSwap = swapSequences[i][1];
                {
                    address[] memory paths = new address[](1);
                    paths[0] = secondSwap.pool;
                    uint256[] memory amounts = IValueLiquidFormula(formula).getFactoryAmountsIn(factory, secondSwap.tokenIn, secondSwap.tokenOut, secondSwap.swapAmount, paths);
                    intermediateTokenAmount = amounts[0];
                    require(intermediateTokenAmount <= secondSwap.limitReturnAmount, "Router: EXCESSIVE_INPUT_AMOUNT");
                }

                //// Buy intermediateTokenAmount of token B with A in the first pool
                Swap memory firstSwap = swapSequences[i][0];
                tokenAmountInFirstSwap = _swapSingleMixOut(firstSwap.tokenIn, firstSwap.tokenOut, firstSwap.pool, intermediateTokenAmount, firstSwap.limitReturnAmount, firstSwap.maxPrice);

                //// Buy the final amount of token C desired
                _swapSingle(secondSwap.tokenIn, secondSwap.pool, intermediateTokenAmount, secondSwap.swapAmount);
            }

            totalAmountIn = tokenAmountInFirstSwap.add(totalAmountIn);
        }

        require(totalAmountIn <= maxTotalAmountIn, "ERR_LIMIT_IN");

        transferAll(tokenOut, msg.sender, getBalance(tokenOut));
        transferAll(tokenIn, msg.sender, getBalance(tokenIn));
    }

    function transferFromAll(address token, uint256 amount) internal returns (bool) {
        if (isETH(token)) {
            IWETH(WETH).deposit{value: msg.value}();
        } else {
            TransferHelper.safeTransferFrom(token, msg.sender, address(this), amount);
        }
        return true;
    }

    function getBalance(address token) internal view returns (uint256) {
        if (isETH(token)) {
            return IWETH(WETH).balanceOf(address(this));
        } else {
            return IERC20(token).balanceOf(address(this));
        }
    }

    function _swapSingleMixOut(
        address tokenIn,
        address tokenOut,
        address pool,
        uint256 swapAmount,
        uint256 limitReturnAmount,
        uint256
    ) internal returns (uint256 tokenAmountIn) {
        address[] memory paths = new address[](1);
        paths[0] = pool;
        uint256[] memory amounts = IValueLiquidFormula(formula).getFactoryAmountsIn(factory, tokenIn, tokenOut, swapAmount, paths);
        tokenAmountIn = amounts[0];
        require(tokenAmountIn <= limitReturnAmount, "Router: EXCESSIVE_INPUT_AMOUNT");
        _swapSingle(tokenIn, pool, tokenAmountIn, amounts[1]);
    }

    function _swapSingle(
        address tokenIn,
        address pair,
        uint256 targetSwapAmount,
        uint256 targetOutAmount
    ) internal {
        TransferHelper.safeTransfer(tokenIn, pair, targetSwapAmount);
        IValueLiquidPair pairV2 = IValueLiquidPair(pair);
        address token0 = pairV2.token0();

        (uint256 amount0Out, uint256 amount1Out, address output) = tokenIn == token0 ? (uint256(0), targetOutAmount, pairV2.token1()) : (targetOutAmount, uint256(0), token0);
        pairV2.swap(amount0Out, amount1Out, address(this), new bytes(0));

        emit Exchange(pair, targetOutAmount, output);
    }

    function _swapSingleSupportFeeOnTransferTokens(
        address tokenIn,
        address tokenOut,
        address pool,
        uint256 swapAmount,
        uint256 limitReturnAmount
    ) internal returns (uint256 tokenAmountOut) {
        TransferHelper.safeTransfer(tokenIn, pool, swapAmount);

        uint256 amountOutput;
        {
            (, uint256 reserveInput, uint256 reserveOutput, uint32 tokenWeightInput, uint32 tokenWeightOutput, uint32 swapFee) =
                IValueLiquidFormula(formula).getFactoryReserveAndWeights(factory, pool, tokenIn);
            uint256 amountInput = IERC20(tokenIn).balanceOf(pool).sub(reserveInput);
            amountOutput = IValueLiquidFormula(formula).getAmountOut(amountInput, reserveInput, reserveOutput, tokenWeightInput, tokenWeightOutput, swapFee);
        }
        uint256 balanceBefore = IERC20(tokenOut).balanceOf(address(this));
        (uint256 amount0Out, uint256 amount1Out) = tokenIn == IValueLiquidPair(pool).token0() ? (uint256(0), amountOutput) : (amountOutput, uint256(0));
        IValueLiquidPair(pool).swap(amount0Out, amount1Out, address(this), new bytes(0));
        emit Exchange(pool, amountOutput, tokenOut);

        tokenAmountOut = IERC20(tokenOut).balanceOf(address(this)).sub(balanceBefore);
        require(tokenAmountOut >= limitReturnAmount, "Router: INSUFFICIENT_OUTPUT_AMOUNT");
    }

    function _validateAmountOut(
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] memory path
    ) internal view returns (uint256[] memory amounts) {
        amounts = IValueLiquidFormula(formula).getFactoryAmountsOut(factory, tokenIn, tokenOut, amountIn, path);
        require(amounts[amounts.length - 1] >= amountOutMin, "Router: INSUFFICIENT_OUTPUT_AMOUNT");
    }

    function _validateAmountIn(
        address tokenIn,
        address tokenOut,
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path
    ) internal view returns (uint256[] memory amounts) {
        amounts = IValueLiquidFormula(formula).getFactoryAmountsIn(factory, tokenIn, tokenOut, amountOut, path);
        require(amounts[0] <= amountInMax, "Router: EXCESSIVE_INPUT_AMOUNT");
    }

    function transferETHTo(uint256 amount, address to) internal {
        IWETH(WETH).deposit{value: amount}();
        assert(IWETH(WETH).transfer(to, amount));
    }

    function transferAll(
        address token,
        address to,
        uint256 amount
    ) internal returns (bool) {
        if (amount == 0) {
            return true;
        }

        if (isETH(token)) {
            IWETH(WETH).withdraw(amount);
            TransferHelper.safeTransferETH(to, amount);
        } else {
            TransferHelper.safeTransfer(token, to, amount);
        }
        return true;
    }

    function isETH(address token) internal pure returns (bool) {
        return (token == ETH_ADDRESS);
    }

    // **** REMOVE LIQUIDITY ****
    function _removeLiquidity(
        address pair,
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to
    ) internal returns (uint256 amountA, uint256 amountB) {
        require(IValueLiquidFactory(factory).isPair(pair), "Router: Invalid pair");
        IValueLiquidPair(pair).transferFrom(msg.sender, pair, liquidity);
        // send liquidity to pair
        (uint256 amount0, uint256 amount1) = IValueLiquidPair(pair).burn(to);
        (address token0, ) = IValueLiquidFormula(formula).sortTokens(tokenA, tokenB);
        (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0);
        require(amountA >= amountAMin, "Router: INSUFFICIENT_A_AMOUNT");
        require(amountB >= amountBMin, "Router: INSUFFICIENT_B_AMOUNT");
    }

    function removeLiquidity(
        address pair,
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) public virtual override ensure(deadline) returns (uint256 amountA, uint256 amountB) {
        (amountA, amountB) = _removeLiquidity(pair, tokenA, tokenB, liquidity, amountAMin, amountBMin, to);
    }

    function removeLiquidityETH(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) public virtual override ensure(deadline) returns (uint256 amountToken, uint256 amountETH) {
        (amountToken, amountETH) = _removeLiquidity(pair, token, WETH, liquidity, amountTokenMin, amountETHMin, address(this));
        TransferHelper.safeTransfer(token, to, amountToken);
        transferAll(ETH_ADDRESS, to, amountETH);
    }

    function removeLiquidityWithPermit(
        address pair,
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external virtual override ensure(deadline) returns (uint256 amountA, uint256 amountB) {
        {
            uint256 value = approveMax ? uint256(-1) : liquidity;
            IValueLiquidPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s);
        }
        (amountA, amountB) = _removeLiquidity(pair, tokenA, tokenB, liquidity, amountAMin, amountBMin, to);
    }

    function removeLiquidityETHWithPermit(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external virtual override returns (uint256 amountToken, uint256 amountETH) {
        uint256 value = approveMax ? uint256(-1) : liquidity;
        IValueLiquidPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s);
        (amountToken, amountETH) = removeLiquidityETH(pair, token, liquidity, amountTokenMin, amountETHMin, to, deadline);
    }

    // **** REMOVE LIQUIDITY (supporting fee-on-transfer tokens) ****
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) public virtual override ensure(deadline) returns (uint256 amountETH) {
        (, amountETH) = removeLiquidity(pair, token, WETH, liquidity, amountTokenMin, amountETHMin, address(this), deadline);
        TransferHelper.safeTransfer(token, to, IERC20(token).balanceOf(address(this)));
        transferAll(ETH_ADDRESS, to, amountETH);
    }

    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external virtual override returns (uint256 amountETH) {
        uint256 value = approveMax ? uint256(-1) : liquidity;
        IValueLiquidPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s);
        amountETH = removeLiquidityETHSupportingFeeOnTransferTokens(pair, token, liquidity, amountTokenMin, amountETHMin, to, deadline);
    }
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_controller","type":"address"},{"internalType":"address","name":"_WETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"},{"indexed":false,"internalType":"address","name":"output","type":"address"}],"name":"Exchange","type":"event"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountTokenDesired","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint32","name":"tokenWeightA","type":"uint32"},{"internalType":"uint32","name":"swapFee","type":"uint32"},{"internalType":"address","name":"to","type":"address"}],"name":"createPair","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint32","name":"tokenWeight","type":"uint32"},{"internalType":"uint32","name":"swapFee","type":"uint32"},{"internalType":"address","name":"to","type":"address"}],"name":"createPairETH","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"formula","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"swapAmount","type":"uint256"},{"internalType":"uint256","name":"limitReturnAmount","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"}],"internalType":"struct IValueLiquidRouter.Swap[][]","name":"swapSequences","type":"tuple[][]"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"totalAmountIn","type":"uint256"},{"internalType":"uint256","name":"minTotalAmountOut","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"multihopBatchSwapExactIn","outputs":[{"internalType":"uint256","name":"totalAmountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"swapAmount","type":"uint256"},{"internalType":"uint256","name":"limitReturnAmount","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"}],"internalType":"struct IValueLiquidRouter.Swap[][]","name":"swapSequences","type":"tuple[][]"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"maxTotalAmountIn","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"multihopBatchSwapExactOut","outputs":[{"internalType":"uint256","name":"totalAmountIn","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermit","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityWithPermit","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapETHForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6101006040523480156200001257600080fd5b50604051620057c8380380620057c883398101604081905262000035916200012f565b6001600160601b0319606084811b821660805283901b1660a05260408051634b75f54f60e01b815290516001600160a01b03851691634b75f54f916004808301926020929190829003018186803b1580156200009057600080fd5b505afa158015620000a5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000cb91906200010b565b6001600160601b0319606091821b811660c05291901b1660e05250620001789050565b80516001600160a01b03811681146200010657600080fd5b919050565b6000602082840312156200011d578081fd5b6200012882620000ee565b9392505050565b60008060006060848603121562000144578182fd5b6200014f84620000ee565b92506200015f60208501620000ee565b91506200016f60408501620000ee565b90509250925092565b60805160601c60a05160601c60c05160601c60e05160601c61554662000282600039806101b752806108345280610a315280610ba45280611067528061141b528061147f52806114d452806115bb5280611c1b5280611d7d5280611ef15280611f635280611fca52806129eb5280612a795280612b325280612c1d528061313852508061061b5280610de552806122f352806125c452806127185280612d37528061325b528061366452806139b45280613b095280613f6b5280614077528061418e525080611d18525080610b675280610e2152806116ad528061196552806120d852806126005280612d645280613288528061369152806139f05280613e8952506155466000f3fe60806040526004361061019a5760003560e01c8063b05f579e116100e1578063d59e44ee1161008a578063f77c479111610064578063f77c479114610463578063fa3219d514610478578063fbf4513514610498578063fde1adda146104b8576101e0565b8063d59e44ee14610403578063e1f4a78414610423578063ebb5d2e914610443576101e0565b8063c45a0155116100bb578063c45a0155146103bb578063ce819632146103d0578063d0f2c82a146103e3576101e0565b8063b05f579e14610368578063b56b681d1461037b578063bff51d711461039b576101e0565b80636cb4942811610143578063a4aabb081161011d578063a4aabb0814610313578063a67d0e3c14610333578063ad5c464814610353576101e0565b80636cb49428146102c0578063840c34d0146102d35780639c91fcb5146102e6576101e0565b80634c17fd7c116101745780634c17fd7c1461025f5780635cae03101461028d578063674ee80b146102ad576101e0565b80630e2f024c146101e55780633990ba541461021b5780634b75f54f1461023d576101e0565b366101e0573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146101de57fe5b005b600080fd5b3480156101f157600080fd5b50610205610200366004614842565b6104cb565b60405161021291906153bd565b60405180910390f35b61022e6102293660046147d1565b6105ae565b6040516102129392919061540f565b34801561024957600080fd5b50610252610619565b6040516102129190614d76565b34801561026b57600080fd5b5061027f61027a366004614503565b61063d565b6040516102129291906153c6565b34801561029957600080fd5b506101de6102a83660046149e8565b61074d565b6101de6102bb36600461496e565b610920565b6102056102ce366004614ae0565b610b62565b6102056102e1366004614b47565b610c54565b3480156102f257600080fd5b506103066103013660046149e8565b611024565b6040516102129190615005565b34801561031f57600080fd5b5061027f61032e366004614842565b611187565b34801561033f57600080fd5b506101de61034e36600461464c565b611270565b34801561035f57600080fd5b50610252611419565b61030661037636600461496e565b61143d565b34801561038757600080fd5b5061027f6103963660046147d1565b611576565b3480156103a757600080fd5b506103066103b63660046146e3565b611620565b3480156103c757600080fd5b506102526116ab565b6102056103de366004614bb9565b6116cf565b3480156103ef57600080fd5b506102056103fe3660046148eb565b611960565b34801561040f57600080fd5b5061030661041e36600461464c565b611acc565b34801561042f57600080fd5b5061027f61043e36600461447f565b611b78565b34801561044f57600080fd5b5061020561045e3660046147d1565b611bd7565b34801561046f57600080fd5b50610252611d16565b34801561048457600080fd5b506103066104933660046149e8565b611d3a565b3480156104a457600080fd5b5061022e6104b33660046145be565b611da5565b6103066104c636600461496e565b611eaf565b600080856104d9578a6104fb565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff8e169063d505accf9061055c903390309086908d908c908c908c90600401614d97565b600060405180830381600087803b15801561057657600080fd5b505af115801561058a573d6000803e3d6000fd5b5050505061059d8d8d8d8d8d8d8d611bd7565b9d9c50505050505050505050505050565b600080600083428110156105f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b60405180910390fd5b6106058b8b8b8b8b8b611fbe565b919d909c50909a5098505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600080864281101561067b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b600087610688578c6106aa565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b90508f73ffffffffffffffffffffffffffffffffffffffff1663d505accf3330848d8c8c8c6040518863ffffffff1660e01b81526004016106f19796959493929190614d97565b600060405180830381600087803b15801561070b57600080fd5b505af115801561071f573d6000803e3d6000fd5b50505050506107338f8f8f8f8f8f8f6120d3565b8093508194505050509c509c9a5050505050505050505050565b8042811015610788576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b6107b588338787600081811061079a57fe5b90506020020160208101906107af919061440e565b8a612463565b6107f48886868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525030925061258f915050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a0823190610869903090600401614d76565b60206040518083038186803b15801561088157600080fd5b505afa158015610895573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b99190614cd5565b9050868110156108f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee9061526f565b61091473eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8583612991565b50505050505050505050565b804281101561095b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b3461098581878760008161096b57fe5b9050602002016020810190610980919061440e565b612a77565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff8a16906370a08231906109da908890600401614d76565b60206040518083038186803b1580156109f257600080fd5b505afa158015610a06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2a9190614cd5565b9050610a8b7f00000000000000000000000000000000000000000000000000000000000000008888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508a925061258f915050565b87610b1f828b73ffffffffffffffffffffffffffffffffffffffff166370a08231896040518263ffffffff1660e01b8152600401610ac99190614d76565b60206040518083038186803b158015610ae157600080fd5b505afa158015610af5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b199190614cd5565b90612bc8565b1015610b57576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee9061526f565b505050505050505050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166314572adb887f000000000000000000000000000000000000000000000000000000000000000088886040518563ffffffff1660e01b8152600401610be49493929190614f71565b602060405180830381600087803b158015610bfe57600080fd5b505af1158015610c12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c36919061442a565b9050610c4781888860008088611fbe565b9998505050505050505050565b60008142811015610c91576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b610c9b8685612c0b565b5060005b8751811015610fbc576000888281518110610cb657fe5b60200260200101515160011415610d21576000898381518110610cd557fe5b6020026020010151600081518110610ce957fe5b60200260200101519050610d19816020015182604001518360000151846060015185608001518660a00151612cb6565b915050610fa7565b6000808a8481518110610d3057fe5b6020026020010151600181518110610d4457fe5b602002602001015190506000600167ffffffffffffffff81118015610d6857600080fd5b50604051908082528060200260200182016040528015610d92578160200160208202803683370190505b509050816000015181600081518110610da757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166367f84adc7f0000000000000000000000000000000000000000000000000000000000000000856020015186604001518760600151876040518663ffffffff1660e01b8152600401610e70959493929190614ef1565b60006040518083038186803b158015610e8857600080fd5b505afa158015610e9c573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610ee29190810190614c35565b905080600081518110610ef157fe5b602002602001015193508260800151841115610f39576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee906150ee565b505060008b8581518110610f4957fe5b6020026020010151600081518110610f5d57fe5b60200260200101519050610f898160200151826040015183600001518685608001518660a00151612cb6565b9350610fa382602001518360000151858560600151612e75565b5050505b610fb181856130ae565b935050600101610c9f565b5083821115610ff7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615201565b61100a8533611005886130eb565b612991565b506110198633611005896130eb565b505095945050505050565b60608142811015611061576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b6110c1897f00000000000000000000000000000000000000000000000000000000000000008a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061321b92505050565b91506111048933888860008181106110d557fe5b90506020020160208101906110ea919061440e565b856000815181106110f757fe5b6020026020010151612463565b6111448983888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250613386915050565b61117a73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee858460018651038151811061116d57fe5b6020026020010151612991565b5050979650505050505050565b600080600086611197578b6111b9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff8f169063d505accf9061121a903390309086908e908d908d908d90600401614d97565b600060405180830381600087803b15801561123457600080fd5b505af1158015611248573d6000803e3d6000fd5b5050505061125b8e8e8e8e8e8e8e611576565b909f909e509c50505050505050505050505050565b80428110156112ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b6112bd89338787600081811061079a57fe5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff8a16906370a0823190611312908790600401614d76565b60206040518083038186803b15801561132a57600080fd5b505afa15801561133e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113629190614cd5565b90506113a38a87878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525089925061258f915050565b866113e1828b73ffffffffffffffffffffffffffffffffffffffff166370a08231886040518263ffffffff1660e01b8152600401610ac99190614d76565b1015610914576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee9061526f565b7f000000000000000000000000000000000000000000000000000000000000000081565b6060814281101561147a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b6114a87f00000000000000000000000000000000000000000000000000000000000000008989348a8a613624565b91506114cf826000815181106114ba57fe5b60200260200101518787600081811061096b57fe5b61152f7f0000000000000000000000000000000000000000000000000000000000000000838888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508a9250613386915050565b8160008151811061153c57fe5b602002602001015134111561156b5761156b338360008151811061155c57fe5b6020026020010151340361378f565b509695505050505050565b60008082428110156115b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b6115e38a8a7f00000000000000000000000000000000000000000000000000000000000000008b8b8b306120d3565b90935091506115f3898685613848565b61161273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8684612991565b505097509795505050505050565b6060814281101561165d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b61166a898989898961321b565b915061169389338760008151811061167e57fe5b6020026020010151856000815181106110f757fe5b61169f89838787613386565b50979650505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000814281101561170c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b6117168786612c0b565b5060006117228761396a565b6117cb576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8816906370a0823190611778903390600401614d76565b60206040518083038186803b15801561179057600080fd5b505afa1580156117a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c89190614cd5565b90505b60005b8951811015611875576000805b8b83815181106117e757fe5b60200260200101515181101561185f5760008c848151811061180557fe5b6020026020010151828151811061181857fe5b60200260200101519050816001141561183357606081018390525b6118548160200151826040015183600001518460600151856080015161399c565b9250506001016117db565b5061186a81866130ae565b9450506001016117ce565b50611881873385612991565b5061189088336110058b6130eb565b5061189a8761396a565b156118de57848310156118d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee906151ca565b611954565b8461191c828973ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401610ac99190614d76565b1015611954576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee906150b7565b50509695505050505050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166314572adb8a8a88886040518563ffffffff1660e01b81526004016119c29493929190614f71565b602060405180830381600087803b1580156119dc57600080fd5b505af11580156119f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a14919061442a565b9050611a26818a8a8a8a600080613e49565b50506040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636a62784290611a7a908690600401614d76565b602060405180830381600087803b158015611a9457600080fd5b505af1158015611aa8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c479190614cd5565b60608142811015611b09576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b611b178a8a8a8a8a8a613624565b9150611b2b8a33888860008181106110d557fe5b611b6b8a838888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508a9250613386915050565b5098975050505050505050565b6000808242811015611bb6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b611bc58b8b8b8b8b8b8b6120d3565b909c909b509950505050505050505050565b60008142811015611c14576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b611c4489897f00000000000000000000000000000000000000000000000000000000000000008a8a8a308a611b78565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152909350611cf791508990869073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190611ca2903090600401614d76565b60206040518083038186803b158015611cba57600080fd5b505afa158015611cce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cf29190614cd5565b613848565b61117a73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8584612991565b7f000000000000000000000000000000000000000000000000000000000000000081565b60608142811015611d77576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b6110c1897f00000000000000000000000000000000000000000000000000000000000000008a8a8a8a613624565b60008060008342811015611de5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b611df48d8d8d8d8d8d8d613e49565b6040517f6a627842000000000000000000000000000000000000000000000000000000008152919550935073ffffffffffffffffffffffffffffffffffffffff8e1690636a62784290611e4b908990600401614d76565b602060405180830381600087803b158015611e6557600080fd5b505af1158015611e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e9d9190614cd5565b91505099509950999650505050505050565b60608142811015611eec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b611f4c7f000000000000000000000000000000000000000000000000000000000000000089348a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061321b92505050565b9150611f5e826000815181106114ba57fe5b61156b7f0000000000000000000000000000000000000000000000000000000000000000838888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508a9250613386915050565b6000806000611ff289897f00000000000000000000000000000000000000000000000000000000000000008a348b8b613e84565b909350915061200388338b86612463565b61200d828a612a77565b6040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a1690636a6278429061205f908790600401614d76565b602060405180830381600087803b15801561207957600080fd5b505af115801561208d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120b19190614cd5565b9050813411156120c7576120c73383340361378f565b96509650969350505050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e5e31b138a6040518263ffffffff1660e01b815260040161212f9190614d76565b60206040518083038186803b15801561214757600080fd5b505afa15801561215b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217f9190614cb9565b6121b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615386565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16906323b872dd9061220b9033908d908b90600401614de5565b602060405180830381600087803b15801561222557600080fd5b505af1158015612239573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225d9190614cb9565b506000808a73ffffffffffffffffffffffffffffffffffffffff166389afcb44866040518263ffffffff1660e01b815260040161229a9190614d76565b6040805180830381600087803b1580156122b357600080fd5b505af11580156122c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122eb9190614ced565b9150915060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663544caa568c8c6040518363ffffffff1660e01b815260040161234c929190614e16565b604080518083038186803b15801561236357600080fd5b505afa158015612377573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239b9190614446565b5090508073ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff16146123d85781836123db565b82825b90955093508785101561241a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615193565b86841015612454576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615125565b50505097509795505050505050565b6000808573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161249793929190614de5565b6040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516124e59190614d5a565b6000604051808303816000865af19150503d8060008114612522576040519150601f19603f3d011682016040523d82523d6000602084013e612527565b606091505b50915091508180156125515750805115806125515750808060200190518101906125519190614cb9565b612587576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615329565b505050505050565b8260005b835181101561298a5760008482815181106125aa57fe5b6020026020010151905060008060008060008060008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b33d96b07f00000000000000000000000000000000000000000000000000000000000000008c8f6040518463ffffffff1660e01b815260040161263f93929190614e3d565b60c06040518083038186803b15801561265757600080fd5b505afa15801561266b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268f9190614a6d565b9550955095509550955095506126d8858d73ffffffffffffffffffffffffffffffffffffffff166370a082318d6040518263ffffffff1660e01b8152600401610ac99190614d76565b6040517f671a11b500000000000000000000000000000000000000000000000000000000815290995073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063671a11b590612757908c9089908990899089908990600401615425565b60206040518083038186803b15801561276f57600080fd5b505afa158015612783573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a79190614cd5565b97508596505050505050506000808573ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156127fb57600080fd5b505afa15801561280f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612833919061442a565b73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161461286d57836000612871565b6000845b91509150600060018b5103881061288857896128a0565b8a886001018151811061289757fe5b60200260200101515b604080516000815260208101918290527f022c0d9f0000000000000000000000000000000000000000000000000000000090915290915073ffffffffffffffffffffffffffffffffffffffff88169063022c0d9f9061290890869086908690602481016153d4565b600060405180830381600087803b15801561292257600080fd5b505af1158015612936573d6000803e3d6000fd5b505050507fddac40937f35385a34f721af292e5a83fc5b840f722bff57c2fc71adba708c4887868660405161296d93929190614fd5565b60405180910390a150919650506001909401935061259392505050565b5050505050565b6000816129a057506001612a70565b6129a98461396a565b15612a61576040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632e1a7d4d90612a209085906004016153bd565b600060405180830381600087803b158015612a3a57600080fd5b505af1158015612a4e573d6000803e3d6000fd5b50505050612a5c838361378f565b612a6c565b612a6c848484613848565b5060015b9392505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b158015612adf57600080fd5b505af1158015612af3573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016935063a9059cbb9250612b6c915084908690600401614faf565b602060405180830381600087803b158015612b8657600080fd5b505af1158015612b9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bbe9190614cb9565b612bc457fe5b5050565b80820382811115612c05576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615049565b92915050565b6000612c168361396a565b15612ca1577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015612c8357600080fd5b505af1158015612c97573d6000803e3d6000fd5b5050505050612cad565b612cad83333085612463565b50600192915050565b604080516001808252818301909252600091829190602080830190803683370190505090508581600081518110612ce957fe5b73ffffffffffffffffffffffffffffffffffffffff92831660209182029290920101526040517f67f84adc0000000000000000000000000000000000000000000000000000000081526000917f000000000000000000000000000000000000000000000000000000000000000016906367f84adc90612d94907f0000000000000000000000000000000000000000000000000000000000000000908d908d908c908990600401614ef1565b60006040518083038186803b158015612dac57600080fd5b505afa158015612dc0573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612e069190810190614c35565b905080600081518110612e1557fe5b6020026020010151925084831115612e59576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee906150ee565b61195489888584600181518110612e6c57fe5b60200260200101515b612e80848484613848565b600083905060008173ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015612ecd57600080fd5b505afa158015612ee1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f05919061442a565b905060008060008373ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614612f485785600085612fc9565b6000868673ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015612f9157600080fd5b505afa158015612fa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fc9919061442a565b604080516000815260208101918290527f022c0d9f00000000000000000000000000000000000000000000000000000000909152929550909350915073ffffffffffffffffffffffffffffffffffffffff86169063022c0d9f9061303690869086903090602481016153d4565b600060405180830381600087803b15801561305057600080fd5b505af1158015613064573d6000803e3d6000fd5b505050507fddac40937f35385a34f721af292e5a83fc5b840f722bff57c2fc71adba708c4888878360405161309b93929190614fd5565b60405180910390a1505050505050505050565b80820182811015612c05576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee9061515c565b60006130f68261396a565b156131c4576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a082319061316d903090600401614d76565b60206040518083038186803b15801561318557600080fd5b505afa158015613199573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131bd9190614cd5565b9050613216565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906370a082319061316d903090600401614d76565b919050565b6040517f119220a500000000000000000000000000000000000000000000000000000000815260609073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063119220a5906132b8907f0000000000000000000000000000000000000000000000000000000000000000908a908a908a908990600401614ef1565b60006040518083038186803b1580156132d057600080fd5b505afa1580156132e4573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261332a9190810190614c35565b9050828160018351038151811061333d57fe5b6020026020010151101561337d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee9061526f565b95945050505050565b8360005b83518110156125875760008482815181106133a157fe5b6020026020010151905060008173ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156133f357600080fd5b505afa158015613407573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061342b919061442a565b9050600087846001018151811061343e57fe5b6020026020010151905060008060008473ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614613489578360008661350a565b6000848773ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156134d257600080fd5b505afa1580156134e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061350a919061442a565b925092509250600060018b51038810613523578961353b565b8a886001018151811061353257fe5b60200260200101515b604080516000815260208101918290527f022c0d9f0000000000000000000000000000000000000000000000000000000090915290915073ffffffffffffffffffffffffffffffffffffffff88169063022c0d9f906135a390879087908690602481016153d4565b600060405180830381600087803b1580156135bd57600080fd5b505af11580156135d1573d6000803e3d6000fd5b505050507fddac40937f35385a34f721af292e5a83fc5b840f722bff57c2fc71adba708c4887868460405161360893929190614fd5565b60405180910390a1509650506001909401935061338a92505050565b6040517f67f84adc00000000000000000000000000000000000000000000000000000000815260609073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906367f84adc906136c3907f0000000000000000000000000000000000000000000000000000000000000000908b908b908b908a908a90600401614e6d565b60006040518083038186803b1580156136db57600080fd5b505afa1580156136ef573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526137359190810190614c35565b9050838160008151811061374557fe5b60200260200101511115613785576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee906150ee565b9695505050505050565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff84169083906040516137c69190614d5a565b60006040518083038185875af1925050503d8060008114613803576040519150601f19603f3d011682016040523d82523d6000602084013e613808565b606091505b5050905080613843576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee906152cc565b505050565b6000808473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb858560405160240161387a929190614faf565b6040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516138c89190614d5a565b6000604051808303816000865af19150503d8060008114613905576040519150601f19603f3d011682016040523d82523d6000602084013e61390a565b606091505b50915091508180156139345750805115806139345750808060200190518101906139349190614cb9565b61298a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615080565b73ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14919050565b60006139a9868585613848565b6000806000806000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b33d96b07f00000000000000000000000000000000000000000000000000000000000000008c8f6040518463ffffffff1660e01b8152600401613a2f93929190614e3d565b60c06040518083038186803b158015613a4757600080fd5b505afa158015613a5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a7f9190614a6d565b95509550955095509550506000613ac9868e73ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401610ac99190614d76565b6040517f671a11b500000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063671a11b590613b489084908a908a908a908a908a90600401615425565b60206040518083038186803b158015613b6057600080fd5b505afa158015613b74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b989190614cd5565b965050505050505060008673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401613bdb9190614d76565b60206040518083038186803b158015613bf357600080fd5b505afa158015613c07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c2b9190614cd5565b90506000808773ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015613c7657600080fd5b505afa158015613c8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cae919061442a565b73ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff1614613ce857836000613cec565b6000845b604080516000815260208101918290527f022c0d9f00000000000000000000000000000000000000000000000000000000909152919350915073ffffffffffffffffffffffffffffffffffffffff89169063022c0d9f90613d5690859085903090602481016153d4565b600060405180830381600087803b158015613d7057600080fd5b505af1158015613d84573d6000803e3d6000fd5b505050507fddac40937f35385a34f721af292e5a83fc5b840f722bff57c2fc71adba708c4888858b604051613dbb93929190614fd5565b60405180910390a1613e00838a73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610ac99190614d76565b945085851015613e3c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee9061526f565b5050505095945050505050565b600080613e5b89898989898989613e84565b9092509050613e6c88338b85612463565b613e7887338b84612463565b97509795505050505050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e5e31b138a6040518263ffffffff1660e01b8152600401613ee09190614d76565b60206040518083038186803b158015613ef857600080fd5b505afa158015613f0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f309190614cb9565b613f66576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615386565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663327494618c8c8c6040518463ffffffff1660e01b8152600401613fc693929190614e3d565b604080518083038186803b158015613fdd57600080fd5b505afa158015613ff1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140159190614ced565b91509150816000148015614027575080155b1561403757879350869250611612565b6040517fad615dec00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063ad615dec906140b0908c908790879060040161540f565b60206040518083038186803b1580156140c857600080fd5b505afa1580156140dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141009190614cd5565b905087811161414e5785811015614143576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615125565b889450925082612454565b6040517fad615dec00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063ad615dec906141c7908c908790899060040161540f565b60206040518083038186803b1580156141df57600080fd5b505afa1580156141f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142179190614cd5565b90508981111561422357fe5b8781101561425d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615193565b9c979b50969950505050505050505050565b8035613216816154cb565b60008083601f84011261428b578182fd5b50813567ffffffffffffffff8111156142a2578182fd5b60208301915083602080830285010111156142bc57600080fd5b9250929050565b600082601f8301126142d3578081fd5b813560206142e86142e38361547d565b615459565b82815281810190858301855b858110156143f0578135880189603f82011261430e578788fd5b8581013561431e6142e38261547d565b808282528882019150604084018d604060c08602870101111561433f578b8cfd5b8b94505b838510156143da5760c0818f03121561435a578b8cfd5b60405160c0810181811067ffffffffffffffff8211171561437757fe5b6040528135614385816154cb565b8152614392828c0161426f565b8b8201526143a26040830161426f565b6040820152606082810135908201526080808301359082015260a080830135908201528352600194909401939189019160c001614343565b50875250505092840192908401906001016142f4565b5090979650505050505050565b803560ff8116811461321657600080fd5b60006020828403121561441f578081fd5b8135612a70816154cb565b60006020828403121561443b578081fd5b8151612a70816154cb565b60008060408385031215614458578081fd5b8251614463816154cb565b6020840151909250614474816154cb565b809150509250929050565b600080600080600080600080610100898b03121561449b578384fd5b88356144a6816154cb565b975060208901356144b6816154cb565b965060408901356144c6816154cb565b9550606089013594506080890135935060a0890135925060c08901356144eb816154cb565b8092505060e089013590509295985092959890939650565b6000806000806000806000806000806000806101808d8f031215614525578586fd5b8c35614530816154cb565b9b5060208d0135614540816154cb565b9a5060408d0135614550816154cb565b995060608d0135985060808d0135975060a08d0135965060c08d0135614575816154cb565b955060e08d013594506101008d013561458d816154f0565b935061459c6101208e016143fd565b92506101408d013591506101608d013590509295989b509295989b509295989b565b60008060008060008060008060006101208a8c0312156145dc578283fd5b89356145e7816154cb565b985060208a01356145f7816154cb565b975060408a0135614607816154cb565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a0135614633816154cb565b809250506101008a013590509295985092959850929598565b60008060008060008060008060e0898b031215614667578182fd5b8835614672816154cb565b97506020890135614682816154cb565b96506040890135955060608901359450608089013567ffffffffffffffff8111156146ab578283fd5b6146b78b828c0161427a565b90955093505060a08901356146cb816154cb565b8092505060c089013590509295985092959890939650565b600080600080600080600060e0888a0312156146fd578081fd5b8735614708816154cb565b9650602088810135614719816154cb565b96506040890135955060608901359450608089013567ffffffffffffffff811115614742578283fd5b8901601f81018b13614752578283fd5b80356147606142e38261547d565b81815283810190838501858402850186018f101561477c578687fd5b8694505b838510156147a7578035614793816154cb565b835260019490940193918501918501614780565b5080975050505050506147bc60a0890161426f565b915060c0880135905092959891949750929550565b600080600080600080600060e0888a0312156147eb578081fd5b87356147f6816154cb565b96506020880135614806816154cb565b955060408801359450606088013593506080880135925060a088013561482b816154cb565b8092505060c0880135905092959891949750929550565b60008060008060008060008060008060006101608c8e031215614863578485fd5b8b3561486e816154cb565b9a5060208c013561487e816154cb565b995060408c0135985060608c0135975060808c0135965060a08c01356148a3816154cb565b955060c08c0135945060e08c01356148ba816154f0565b93506148c96101008d016143fd565b92506101208c013591506101408c013590509295989b509295989b9093969950565b600080600080600080600060e0888a031215614905578081fd5b8735614910816154cb565b96506020880135614920816154cb565b95506040880135945060608801359350608088013561493e816154fe565b925060a088013561494e816154fe565b915060c088013561495e816154cb565b8091505092959891949750929550565b60008060008060008060a08789031215614986578384fd5b8635614991816154cb565b955060208701359450604087013567ffffffffffffffff8111156149b3578485fd5b6149bf89828a0161427a565b90955093505060608701356149d3816154cb565b80925050608087013590509295509295509295565b600080600080600080600060c0888a031215614a02578081fd5b8735614a0d816154cb565b96506020880135955060408801359450606088013567ffffffffffffffff811115614a36578182fd5b614a428a828b0161427a565b9095509350506080880135614a56816154cb565b8092505060a0880135905092959891949750929550565b60008060008060008060c08789031215614a85578384fd5b8651614a90816154cb565b8096505060208701519450604087015193506060870151614ab0816154fe565b6080880151909350614ac1816154fe565b60a0880151909250614ad2816154fe565b809150509295509295509295565b600080600080600060a08688031215614af7578283fd5b8535614b02816154cb565b9450602086013593506040860135614b19816154fe565b92506060860135614b29816154fe565b91506080860135614b39816154cb565b809150509295509295909350565b600080600080600060a08688031215614b5e578283fd5b853567ffffffffffffffff811115614b74578384fd5b614b80888289016142c3565b9550506020860135614b91816154cb565b93506040860135614ba1816154cb565b94979396509394606081013594506080013592915050565b60008060008060008060c08789031215614bd1578384fd5b863567ffffffffffffffff811115614be7578485fd5b614bf389828a016142c3565b9650506020870135614c04816154cb565b94506040870135614c14816154cb565b959894975094956060810135955060808101359460a0909101359350915050565b60006020808385031215614c47578182fd5b825167ffffffffffffffff811115614c5d578283fd5b8301601f81018513614c6d578283fd5b8051614c7b6142e38261547d565b8181528381019083850185840285018601891015614c97578687fd5b8694505b8385101561169f578051835260019490940193918501918501614c9b565b600060208284031215614cca578081fd5b8151612a70816154f0565b600060208284031215614ce6578081fd5b5051919050565b60008060408385031215614cff578182fd5b505080516020909101519092909150565b60008151808452614d2881602086016020860161549b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008251614d6c81846020870161549b565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff97881681529590961660208601526040850193909352606084019190915260ff16608083015260a082015260c081019190915260e00190565b73ffffffffffffffffffffffffffffffffffffffff9384168152919092166020820152604081019190915260600190565b73ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff93841681529183166020830152909116604082015260600190565b600060a0820173ffffffffffffffffffffffffffffffffffffffff808a1684526020818a1681860152818916604086015287606086015260a060808601528286845260c086019050879350845b87811015614ee1578435614ecd816154cb565b841682529382019390820190600101614eba565b509b9a5050505050505050505050565b600060a0820173ffffffffffffffffffffffffffffffffffffffff8089168452602081891681860152818816604086015286606086015260a0608086015282865180855260c0870191508288019450855b81811015614f60578551851683529483019491830191600101614f42565b50909b9a5050505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff948516815292909316602083015263ffffffff9081166040830152909116606082015260800190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff93841681526020810192909252909116604082015260600190565b6020808252825182820181905260009190848201906040850190845b8181101561503d57835183529284019291840191600101615021565b50909695505050505050565b60208082526015908201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604082015260600190565b6020808252601f908201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604082015260600190565b60208082526012908201527f3c6d696e546f74616c416d6f756e744f75740000000000000000000000000000604082015260600190565b6020808252601e908201527f526f757465723a204558434553534956455f494e5055545f414d4f554e540000604082015260600190565b6020808252601d908201527f526f757465723a20494e53554646494349454e545f425f414d4f554e54000000604082015260600190565b60208082526014908201527f64732d6d6174682d6164642d6f766572666c6f77000000000000000000000000604082015260600190565b6020808252601d908201527f526f757465723a20494e53554646494349454e545f415f414d4f554e54000000604082015260600190565b6020808252600d908201527f4552525f4c494d49545f4f555400000000000000000000000000000000000000604082015260600190565b6020808252600c908201527f4552525f4c494d49545f494e0000000000000000000000000000000000000000604082015260600190565b6020808252600f908201527f526f757465723a20455850495245440000000000000000000000000000000000604082015260600190565b60208082526022908201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f5560408201527f4e54000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526023908201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960408201527f4c45440000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f464160408201527f494c454400000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526014908201527f526f757465723a20496e76616c69642070616972000000000000000000000000604082015260600190565b90815260200190565b918252602082015260400190565b600085825284602083015273ffffffffffffffffffffffffffffffffffffffff84166040830152608060608301526137856080830184614d10565b9283526020830191909152604082015260600190565b9586526020860194909452604085019290925263ffffffff908116606085015290811660808401521660a082015260c00190565b60405181810167ffffffffffffffff8111828210171561547557fe5b604052919050565b600067ffffffffffffffff82111561549157fe5b5060209081020190565b60005b838110156154b657818101518382015260200161549e565b838111156154c5576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff811681146154ed57600080fd5b50565b80151581146154ed57600080fd5b63ffffffff811681146154ed57600080fdfea26469706673582212200b64ee0912afd1d68a01be202a9ae707748fbd13a053643a727a00d5ba47782964736f6c634300070600330000000000000000000000001b8e12f839bd4e73a47addf76cf7f0097d74c14c000000000000000000000000be879a1a360e5beeb6abdae6b3d4cda300756a8b000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000001b8e12f839bd4e73a47addf76cf7f0097d74c14c000000000000000000000000be879a1a360e5beeb6abdae6b3d4cda300756a8b000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000001b8e12f839bd4e73a47addf76cf7f0097d74c14c
Arg [1] : 000000000000000000000000be879a1a360e5beeb6abdae6b3d4cda300756a8b
Arg [2] : 000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c


Deployed ByteCode Sourcemap

21708:27604:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22524:10;:18;22538:4;22524:18;;22517:26;;;;21708:27604;;;;;48608:701;;;;;;;;;;-1:-1:-1;48608:701:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26983:594;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;21896:41::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;46518:722::-;;;;;;;;;;-1:-1:-1;46518:722:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;34684:642::-;;;;;;;;;;-1:-1:-1;34684:642:0;;;;;:::i;:::-;;:::i;34006:670::-;;;;;;:::i;:::-;;:::i;26567:408::-;;;;;;:::i;:::-;;:::i;37043:2619::-;;;;;;:::i;:::-;;:::i;30643:583::-;;;;;;;;;;-1:-1:-1;30643:583:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;47248:679::-;;;;;;;;;;-1:-1:-1;47248:679:0;;;;;:::i;:::-;;:::i;33350:648::-;;;;;;;;;;-1:-1:-1;33350:648:0;;;;;:::i;:::-;;:::i;21944:38::-;;;;;;;;;;;;;:::i;31234:580::-;;;;;;:::i;:::-;;:::i;45949:561::-;;;;;;;;;;-1:-1:-1;45949:561:0;;;;;:::i;:::-;;:::i;28512:534::-;;;;;;;;;;-1:-1:-1;28512:534:0;;;;;:::i;:::-;;:::i;21797:41::-;;;;;;;;;;;;;:::i;35334:1701::-;;;;;;:::i;:::-;;:::i;24571:498::-;;;;;;;;;;-1:-1:-1;24571:498:0;;;;;:::i;:::-;;:::i;29054:537::-;;;;;;;;;;-1:-1:-1;29054:537:0;;;;;:::i;:::-;;:::i;45501:440::-;;;;;;;;;;-1:-1:-1;45501:440:0;;;;;:::i;:::-;;:::i;48006:594::-;;;;;;;;;;-1:-1:-1;48006:594:0;;;;;:::i;:::-;;:::i;21845:44::-;;;;;;;;;;;;;:::i;30053:582::-;;;;;;;;;;-1:-1:-1;30053:582:0;;;;;:::i;:::-;;:::i;25077:669::-;;;;;;;;;;-1:-1:-1;25077:669:0;;;;;:::i;:::-;;:::i;29599:446::-;;;;;;:::i;:::-;;:::i;48608:701::-;48988:17;49018:13;49034:10;:36;;49061:9;49034:36;;;49055:2;49034:36;49081:82;;;;;49018:52;;-1:-1:-1;49081:29:0;;;;;;:82;;49111:10;;49131:4;;49018:52;;49145:8;;49155:1;;49158;;49161;;49081:82;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49186:115;49234:4;49240:5;49247:9;49258:14;49274:12;49288:2;49292:8;49186:47;:115::i;:::-;49174:127;48608:701;-1:-1:-1;;;;;;;;;;;;;48608:701:0:o;26983:594::-;27337:19;27371:17;27403;27295:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;27486:83:::1;27503:4;27509:5;27516:18;27536:14;27552:12;27566:2;27486:16;:83::i;:::-;27448:121:::0;;;;-1:-1:-1;27448:121:0;;-1:-1:-1;26983:594:0;-1:-1:-1;;;;;;;;;26983:594:0:o;21896:41::-;;;:::o;46518:722::-;46903:15;46920;46884:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;46963:13:::1;46979:10;:36;;47006:9;46979:36;;;47000:2;46979:36;46963:52;;47047:4;47030:29;;;47060:10;47080:4;47087:5;47094:8;47104:1;47107;47110;47030:82;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;22199:1;47155:77;47172:4;47178:6;47186;47194:9;47205:10;47217;47229:2;47155:16;:77::i;:::-;47134:98;;;;;;;;46518:722:::0;;;;;;;;;;;;;;;;:::o;34684:642::-;34950:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;34971:71:::1;35003:7;35012:10;35024:4;;35029:1;35024:7;;;;;;;;;;;;;;;;;;;;:::i;:::-;35033:8;34971:31;:71::i;:::-;35053:64;35088:7;35097:4;;35053:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;35111:4:0::1;::::0;-1:-1:-1;35053:34:0::1;::::0;-1:-1:-1;;35053:64:0:i:1;:::-;35148:37;::::0;;;;35128:17:::1;::::0;35148:22:::1;35155:4;35148:22;::::0;::::1;::::0;:37:::1;::::0;35179:4:::1;::::0;35148:37:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35128:57;;35217:12;35204:9;:25;;35196:72;;;;;;;;;;;;:::i;:::-;35279:39;22036:42;35304:2;35308:9;35279:11;:39::i;:::-;;22199:1;34684:642:::0;;;;;;;;:::o;34006:670::-;34254:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;34367:9:::1;34387:32;34367:9:::0;34411:4;;34348:16:::1;34411:7:::0;::::1;;;;;;;;;;;;;;;;;:::i;:::-;34387:13;:32::i;:::-;34454:30;::::0;;;;34430:21:::1;::::0;34454:26:::1;::::0;::::1;::::0;::::1;::::0;:30:::1;::::0;34481:2;;34454:30:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34430:54;;34495:50;34530:4;34536;;34495:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;34542:2:0;;-1:-1:-1;34495:34:0::1;::::0;-1:-1:-1;;34495:50:0:i:1;:::-;34617:12;34564:49;34599:13;34571:8;34564:26;;;34591:2;34564:30;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:34:::0;::::1;:49::i;:::-;:65;;34556:112;;;;;;;;;;;;:::i;:::-;22199:1;;34006:670:::0;;;;;;;:::o;26567:408::-;26767:17;26797:12;26832:7;26812:39;;;26852:5;26859:4;26865:11;26878:7;26812:74;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;26797:89;;26915:52;26932:4;26938:5;26945:11;26958:1;26961;26964:2;26915:16;:52::i;:::-;26897:70;26567:408;-1:-1:-1;;;;;;;;;26567:408:0:o;37043:2619::-;37298:21;37279:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;37332:42:::1;37348:7;37357:16;37332:15;:42::i;:::-;;37392:9;37387:2065;37411:13;:20;37407:1;:24;37387:2065;;;37453:30;37587:13;37601:1;37587:16;;;;;;;;;;;;;;:23;37614:1;37587:28;37583:1784;;;37636:16;37655:13;37669:1;37655:16;;;;;;;;;;;;;;37672:1;37655:19;;;;;;;;;;;;;;37636:38;;37718:113;37736:4;:12;;;37750:4;:13;;;37765:4;:9;;;37776:4;:15;;;37793:4;:22;;;37817:4;:13;;;37718:17;:113::i;:::-;37693:138;;37583:1784;;;;38168:31;38279:22:::0;38304:13:::1;38318:1;38304:16;;;;;;;;;;;;;;38321:1;38304:19;;;;;;;;;;;;;;38279:44;;38365:22;38404:1;38390:16;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;38390:16:0::1;;38365:41;;38440:10;:15;;;38429:5;38435:1;38429:8;;;;;;;;;;;;;:26;;;;;;;;;::::0;::::1;38478:24;38525:7;38505:48;;;38554:7;38563:10;:18;;;38583:10;:19;;;38604:10;:21;;;38627:5;38505:128;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;::::0;::::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;38478:155;;38682:7;38690:1;38682:10;;;;;;;;;;;;;;38656:36;;38750:10;:28;;;38723:23;:55;;38715:98;;;;;;;;;;;;:::i;:::-;37583:1784;;38939:21;38963:13;38977:1;38963:16;;;;;;;;;;;;;;38980:1;38963:19;;;;;;;;;;;;;;38939:43;;39026:146;39044:9;:17;;;39063:9;:18;;;39083:9;:14;;;39099:23;39124:9;:27;;;39153:9;:18;;;39026:17;:146::i;:::-;39001:171;;39255:96;39267:10;:18;;;39287:10;:15;;;39304:23;39329:10;:21;;;39255:11;:96::i;:::-;37583:1784;;;;39399:41;:22:::0;39426:13;39399:26:::1;:41::i;:::-;39383:57:::0;-1:-1:-1;;37433:3:0::1;;37387:2065;;;;39489:16;39472:13;:33;;39464:58;;;;;;;;;;;;:::i;:::-;39535:55;39547:8;39557:10;39569:20;39580:8;39569:10;:20::i;:::-;39535:11;:55::i;:::-;;39601:53;39613:7;39622:10;39634:19;39645:7;39634:10;:19::i;39601:53::-;;37043:2619:::0;;;;;;;;:::o;30643:583::-;30899:24;30880:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;30946:63:::1;30965:7;30974:4;30980:8;30990:12;31004:4;;30946:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;30946:18:0::1;::::0;-1:-1:-1;;;30946:63:0:i:1;:::-;30936:73;;31022;31054:7;31063:10;31075:4;;31080:1;31075:7;;;;;;;;;;;;;;;;;;;;:::i;:::-;31084;31092:1;31084:10;;;;;;;;;;;;;;31022:31;:73::i;:::-;31106:44;31112:7;31121;31130:4;;31106:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;31144:4:0::1;::::0;-1:-1:-1;31106:5:0::1;::::0;-1:-1:-1;;31106:44:0:i:1;:::-;31161:57;22036:42;31186:2;31190:7;31215:1;31198:7;:14;:18;31190:27;;;;;;;;;;;;;;31161:11;:57::i;:::-;;30643:583:::0;;;;;;;;;;:::o;47248:679::-;47599:19;47620:17;47650:13;47666:10;:36;;47693:9;47666:36;;;47687:2;47666:36;47713:82;;;;;47650:52;;-1:-1:-1;47713:29:0;;;;;;:82;;47743:10;;47763:4;;47650:52;;47777:8;;47787:1;;47790;;47793;;47713:82;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47833:86;47852:4;47858:5;47865:9;47876:14;47892:12;47906:2;47910:8;47833:18;:86::i;:::-;47806:113;;;;-1:-1:-1;47248:679:0;-1:-1:-1;;;;;;;;;;;;;47248:679:0:o;33350:648::-;33646:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;33667:71:::1;33699:7;33708:10;33720:4;;33725:1;33720:7;;;;;;33667:71;33773:30;::::0;;;;33749:21:::1;::::0;33773:26:::1;::::0;::::1;::::0;::::1;::::0;:30:::1;::::0;33800:2;;33773:30:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;33749:54;;33814:53;33849:7;33858:4;;33814:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;33864:2:0;;-1:-1:-1;33814:34:0::1;::::0;-1:-1:-1;;33814:53:0:i:1;:::-;33939:12;33886:49;33921:13;33893:8;33886:26;;;33913:2;33886:30;;;;;;;;;;;;;;;:::i;:49::-;:65;;33878:112;;;;;;;;;;;;:::i;21944:38::-:0;;;:::o;31234:580::-;31469:24;31450:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;31516:61:::1;31534:4;31540:8;31550:9;31561;31572:4;;31516:17;:61::i;:::-;31506:71;;31590:34;31604:7;31612:1;31604:10;;;;;;;;;;;;;;31616:4;;31621:1;31616:7;;;;;;31590:34;31635:30;31641:4;31647:7;31656:4;;31635:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;31662:2:0;;-1:-1:-1;31635:5:0::1;::::0;-1:-1:-1;;31635:30:0:i:1;:::-;31728:7;31736:1;31728:10;;;;;;;;;;;;;;31716:9;:22;31712:94;;;31740:66;31771:10;31795:7;31803:1;31795:10;;;;;;;;;;;;;;31783:9;:22;31740:30;:66::i;:::-;31234:580:::0;;;;;;;;;:::o;45949:561::-;46221:19;46242:17;46202:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;46299:91:::1;46316:4;46322:5;46329:4;46335:9;46346:14;46362:12;46384:4;46299:16;:91::i;:::-;46272:118:::0;;-1:-1:-1;46272:118:0;-1:-1:-1;46401:51:0::1;46429:5:::0;46436:2;46272:118;46401:27:::1;:51::i;:::-;46463:39;22036:42;46488:2;46492:9;46463:11;:39::i;:::-;;45949:561:::0;;;;;;;;;;;:::o;28512:534::-;28794:24;28775:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;28841:67:::1;28860:7;28869:8;28879;28889:12;28903:4;28841:18;:67::i;:::-;28831:77;;28921:73;28953:7;28962:10;28974:4;28979:1;28974:7;;;;;;;;;;;;;;28983;28991:1;28983:10;;;;;;;28921:73;29005:33;29011:7;29020;29029:4;29035:2;29005:5;:33::i;:::-;28512:534:::0;;;;;;;;;;:::o;21797:41::-;;;:::o;35334:1701::-;35621:22;35602:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;35656:39:::1;35672:7;35681:13;35656:15;:39::i;:::-;;35706:21;35743:15;35749:8;35743:5;:15::i;:::-;35738:103;;35791:38;::::0;;;;:26:::1;::::0;::::1;::::0;::::1;::::0;:38:::1;::::0;35818:10:::1;::::0;35791:38:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35775:54;;35738:103;35858:9;35853:786;35877:13;:20;35873:1;:24;35853:786;;;35919:22;::::0;35956:546:::1;35980:13;35994:1;35980:16;;;;;;;;;;;;;;:23;35976:1;:27;35956:546;;;36029:16;36048:13;36062:1;36048:16;;;;;;;;;;;;;;36065:1;36048:19;;;;;;;;;;;;;;36029:38;;36090:1;36095;36090:6;36086:247;;;36281:15;::::0;::::1;:32:::0;;;36086:247:::1;36368:118;36406:4;:12;;;36420:4;:13;;;36435:4;:9;;;36446:4;:15;;;36463:4;:22;;;36368:37;:118::i;:::-;36351:135:::0;-1:-1:-1;;36005:3:0::1;;35956:546;;;-1:-1:-1::0;36593:34:0::1;:14:::0;36612;36593:18:::1;:34::i;:::-;36576:51:::0;-1:-1:-1;;35899:3:0::1;;35853:786;;;;36651:49;36663:8;36673:10;36685:14;36651:11;:49::i;:::-;;36711:53;36723:7;36732:10;36744:19;36755:7;36744:10;:19::i;36711:53::-;;36781:15;36787:8;36781:5;:15::i;:::-;36777:251;;;36839:17;36821:14;:35;;36813:61;;;;;;;;;;;;:::i;:::-;36777:251;;;36976:17;36915:57;36958:13;36922:8;36915:26;;;36942:10;36915:38;;;;;;;;;;;;;;;:::i;:57::-;:78;;36907:109;;;;;;;;;;;;:::i;:::-;22199:1;35334:1701:::0;;;;;;;;;:::o;24571:498::-;24809:17;24839:12;24874:7;24854:39;;;24894:6;24902;24910:12;24924:7;24854:78;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;24839:93;;24943:64;24962:4;24968:6;24976;24984:7;24993;25002:1;25005;24943:18;:64::i;:::-;-1:-1:-1;;25030:31:0;;;;;:27;;;;;;:31;;25058:2;;25030:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;29054:537::-;29340:24;29321:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;29387:66:::1;29405:7;29414:8;29424:9;29435:11;29448:4;;29387:17;:66::i;:::-;29377:76;;29466:73;29498:7;29507:10;29519:4;;29524:1;29519:7;;;;;;29466:73;29550:33;29556:7;29565;29574:4;;29550:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;29580:2:0;;-1:-1:-1;29550:5:0::1;::::0;-1:-1:-1;;29550:33:0:i:1;:::-;29054:537:::0;;;;;;;;;;;:::o;45501:440::-;45790:15;45807;45771:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;45856:77:::1;45873:4;45879:6;45887;45895:9;45906:10;45918;45930:2;45856:16;:77::i;:::-;45835:98:::0;;;;-1:-1:-1;45501:440:0;-1:-1:-1;;;;;;;;;;45501:440:0:o;48006:594::-;48307:17;48288:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;48353:100:::1;48369:4;48375:5;48382:4;48388:9;48399:14;48415:12;48437:4;48444:8;48353:15;:100::i;:::-;48503:38;::::0;;;;48337:116;;-1:-1:-1;48464:78:0::1;::::0;-1:-1:-1;48492:5:0;;48499:2;;48503:23:::1;::::0;::::1;::::0;::::1;::::0;:38:::1;::::0;48535:4:::1;::::0;48503:38:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48464:27;:78::i;:::-;48553:39;22036:42;48578:2;48582:9;48553:11;:39::i;21845:44::-:0;;;:::o;30053:582::-;30309:24;30290:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;30356:62:::1;30374:7;30383:4;30389:9;30400:11;30413:4;;30356:17;:62::i;25077:669::-:0;25462:15;25492;25522:17;25420:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;25588:96:::1;25607:4;25613:6;25621;25629:14;25645;25661:10;25673;25588:18;:96::i;:::-;25707:31;::::0;;;;25567:117;;-1:-1:-1;25567:117:0;-1:-1:-1;25707:27:0::1;::::0;::::1;::::0;::::1;::::0;:31:::1;::::0;25735:2;;25707:31:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;25695:43;;25077:669:::0;;;;;;;;;;;;;;:::o;29599:446::-;29837:24;29818:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;29884:65:::1;29903:4;29909:8;29919:9;29930:12;29944:4;;29884:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;29884:18:0::1;::::0;-1:-1:-1;;;29884:65:0:i:1;:::-;29874:75;;29962:34;29976:7;29984:1;29976:10;;;;;;;29962:34;30007:30;30013:4;30019:7;30028:4;;30007:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;30034:2:0;;-1:-1:-1;30007:5:0::1;::::0;-1:-1:-1;;30007:30:0:i:1;25754:805::-:0;26006:19;26040:17;26072;26144:93;26158:4;26164:5;26171:4;26177:18;26197:9;26208:14;26224:12;26144:13;:93::i;:::-;26117:120;;-1:-1:-1;26117:120:0;-1:-1:-1;26248:69:0;26280:5;26287:10;26299:4;26117:120;26248:31;:69::i;:::-;26328:30;26342:9;26353:4;26328:13;:30::i;:::-;26381:31;;;;;:27;;;;;;:31;;26409:2;;26381:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;26369:43;;26475:9;26463;:21;26459:92;;;26486:65;26517:10;26541:9;26529;:21;26486:30;:65::i;:::-;25754:805;;;;;;;;;;:::o;44621:872::-;44852:15;44869;44925:7;44905:35;;;44941:4;44905:41;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44897:74;;;;;;;;;;;;:::i;:::-;44982:64;;;;;:35;;;;;;:64;;45018:10;;44999:4;;45036:9;;44982:64;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;45093:15;45110;45146:4;45129:27;;;45157:2;45129:31;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45092:68;;;;45172:14;45212:7;45192:39;;;45232:6;45240;45192:55;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45171:76;;;45289:6;45279:16;;:6;:16;;;:58;;45320:7;45329;45279:58;;;45299:7;45308;45279:58;45258:79;;-1:-1:-1;45258:79:0;-1:-1:-1;45356:21:0;;;;45348:63;;;;;;;;;;;;:::i;:::-;45441:10;45430:7;:21;;45422:63;;;;;;;;;;;;:::i;:::-;44621:872;;;;;;;;;;;;;:::o;8954:448::-;9179:12;9193:17;9214:5;:10;;9248;9260:4;9266:2;9270:5;9225:51;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9214:63;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9178:99;;;;9296:7;:57;;;;-1:-1:-1;9308:11:0;;:16;;:44;;;9339:4;9328:24;;;;;;;;;;;;:::i;:::-;9288:106;;;;;;;;;;;;:::i;:::-;8954:448;;;;;;:::o;31961:1381::-;32136:7;32120:13;32154:1181;32174:4;:11;32170:1;:15;32154:1181;;;32207:21;32248:4;32253:1;32248:7;;;;;;;;;;;;;;32207:49;;32273:19;32307:20;32342:21;32398:14;32414:20;32436:21;32459:23;32484:24;32510:14;32569:7;32549:56;;;32606:7;32623:4;32630:5;32549:87;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32397:239;;;;;;;;;;;;32669:56;32712:12;32676:5;32669:23;;;32701:4;32669:38;;;;;;;;;;;;;;;:::i;:56::-;32759:129;;;;;32655:70;;-1:-1:-1;32759:41:0;32779:7;32759:41;;;;:129;;32655:70;;32814:12;;32828:13;;32843:16;;32861:17;;32880:7;;32759:129;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32744:144;;32923:6;32907:22;;32154:1181;;;;;;32960:18;32980;33011:4;:11;;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;33002:22;;:5;:22;;;:80;;33057:12;33079:1;33002:80;;;33036:1;33040:12;33002:80;32959:123;;;;33097:10;33128:1;33114:4;:11;:15;33110:1;:19;:39;;33146:3;33110:39;;;33132:4;33137:1;33141;33137:5;33132:11;;;;;;;;;;;;;;33110:39;33202:12;;;33212:1;33202:12;;;;;;;;;33164:51;;;;33097:52;;-1:-1:-1;33164:9:0;;;;;;:51;;33174:10;;33186;;33097:52;;33164:51;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33235:52;33252:4;33259:12;33273:13;33235:52;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;33310:13:0;;-1:-1:-1;;32187:3:0;;;;;-1:-1:-1;32154:1181:0;;-1:-1:-1;;;32154:1181:0;;;31961:1381;;;;:::o;44025:438::-;44141:4;44162:11;44158:55;;-1:-1:-1;44197:4:0;44190:11;;44158:55;44229:12;44235:5;44229;:12::i;:::-;44225:209;;;44258:28;;;;;:20;44264:4;44258:20;;;;:28;;44279:6;;44258:28;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44301:42;44332:2;44336:6;44301:30;:42::i;:::-;44225:209;;;44376:46;44404:5;44411:2;44415:6;44376:27;:46::i;:::-;-1:-1:-1;44451:4:0;44025:438;;;;;;:::o;43851:166::-;43928:4;43922:19;;;43949:6;43922:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;43976:32:0;;;;;:20;43982:4;43976:20;;-1:-1:-1;43976:20:0;;-1:-1:-1;43976:32:0;;-1:-1:-1;43997:2:0;;44001:6;;43976:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43969:40;;;;43851:166;;:::o;16682:138::-;16775:5;;;16770:16;;;;16762:50;;;;;;;;;;;;:::i;:::-;16682:138;;;;:::o;39670:310::-;39744:4;39765:12;39771:5;39765;:12::i;:::-;39761:190;;;39800:4;39794:19;;;39821:9;39794:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39761:190;;;39866:73;39898:5;39905:10;39925:4;39932:6;39866:31;:73::i;:::-;-1:-1:-1;39968:4:0;39670:310;;;;:::o;40247:642::-;40517:16;;;40531:1;40517:16;;;;;;;;;40458:21;;;;40517:16;;;;;;;;;;;;-1:-1:-1;40517:16:0;40492:41;;40555:4;40544:5;40550:1;40544:8;;;;;;;;:15;;;;:8;;;;;;;;;:15;40597:95;;;;;40570:24;;40617:7;40597:48;;;;:95;;40646:7;;40655;;40664:8;;40674:10;;40686:5;;40597:95;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40570:122;;40719:7;40727:1;40719:10;;;;;;;;;;;;;;40703:26;;40765:17;40748:13;:34;;40740:77;;;;;;;;;;;;:::i;:::-;40828:53;40840:7;40849:4;40855:13;40870:7;40878:1;40870:10;;;;;;;;;;;;;;40897:646;41063:60;41091:7;41100:4;41106:16;41063:27;:60::i;:::-;41134:23;41177:4;41134:48;;41193:14;41210:6;:13;;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41193:32;;41239:18;41259;41279:14;41308:6;41297:17;;:7;:17;;;:106;;41367:15;41392:1;41396:6;41297:106;;;41326:1;41330:15;41347:6;:13;;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41465:12;;;41475:1;41465:12;;;;;;;;;41414:64;;;;41238:165;;-1:-1:-1;41238:165:0;;-1:-1:-1;41238:165:0;-1:-1:-1;41414:11:0;;;;;;:64;;41238:165;;;;41458:4;;41414:64;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41496:39;41505:4;41511:15;41528:6;41496:39;;;;;;;;:::i;:::-;;;;;;;;40897:646;;;;;;;;;:::o;16537:137::-;16630:5;;;16625:16;;;;16617:49;;;;;;;;;;;;:::i;39988:251::-;40046:7;40070:12;40076:5;40070;:12::i;:::-;40066:166;;;40106:36;;;;;:21;40112:4;40106:21;;;;:36;;40136:4;;40106:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40099:43;;;;40066:166;40182:38;;;;;:23;;;;;;:38;;40214:4;;40182:38;;;:::i;40066:166::-;39988:251;;;:::o;42956:450::-;43204:93;;;;;43157:24;;43204:49;43224:7;43204:49;;;;:93;;43254:7;;43263;;43272:8;;43282;;43292:4;;43204:93;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43194:103;;43347:12;43316:7;43341:1;43324:7;:14;:18;43316:27;;;;;;;;;;;;;;:43;;43308:90;;;;;;;;;;;;:::i;:::-;42956:450;;;;;;;:::o;27688:816::-;27869:7;27853:13;27887:610;27911:4;:11;27907:1;:15;27887:610;;;27944:23;27987:4;27992:1;27987:7;;;;;;;;;;;;;;27944:51;;28010:14;28027:6;:13;;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;28010:32;;28057:17;28077:7;28085:1;28089;28085:5;28077:14;;;;;;;;;;;;;;28057:34;;28107:18;28127;28147:14;28174:6;28165:15;;:5;:15;;;:92;;28227:9;28246:1;28250:6;28165:92;;;28192:1;28196:9;28207:6;:13;;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;28106:151;;;;;;28272:10;28303:1;28289:4;:11;:15;28285:1;:19;:39;;28321:3;28285:39;;;28307:4;28312:1;28316;28312:5;28307:11;;;;;;;;;;;;;;28285:39;28379:12;;;28389:1;28379:12;;;;;;;;;28339:53;;;;28272:52;;-1:-1:-1;28339:11:0;;;;;;:53;;28351:10;;28363;;28272:52;;28339:53;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28412:44;28429:6;28438:9;28449:6;28412:44;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;28479:6:0;-1:-1:-1;;27924:3:0;;;;;-1:-1:-1;27887:610:0;;-1:-1:-1;;;27887:610:0;43414:429;43663:93;;;;;43616:24;;43663:48;43683:7;43663:48;;;;:93;;43712:7;;43721;;43730:8;;43740:9;;43751:4;;;;43663:93;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43653:103;;43789:11;43775:7;43783:1;43775:10;;;;;;;;;;;;;;:25;;43767:68;;;;;;;;;;;;:::i;:::-;43414:429;;;;;;;;:::o;9410:200::-;9523:12;;;9483;9523;;;;;;;;;9501:7;;;;9516:5;;9501:35;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9482:54;;;9555:7;9547:55;;;;;;;;;;;;:::i;:::-;9410:200;;;:::o;8548:398::-;8734:12;8748:17;8769:5;:10;;8803;8815:2;8819:5;8780:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8769:57;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8733:93;;;;8845:7;:57;;;;-1:-1:-1;8857:11:0;;:16;;:44;;;8888:4;8877:24;;;;;;;;;;;;:::i;:::-;8837:101;;;;;;;;;;;;:::i;44471:107::-;44549:20;;;22036:42;44549:20;44471:107;;;:::o;41551:1397::-;41764:22;41799:54;41827:7;41836:4;41842:10;41799:27;:54::i;:::-;41866:20;41915;41937:21;41960:23;41985:24;42011:14;42066:7;42046:56;;;42103:7;42112:4;42118:7;42046:80;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41912:214;;;;;;;;;;;42141:19;42163:49;42199:12;42170:7;42163:25;;;42189:4;42163:31;;;;;;;;;;;;;;;:::i;:49::-;42242:129;;;;;42141:71;;-1:-1:-1;42242:41:0;42262:7;42242:41;;;;:129;;42141:71;;42297:12;;42311:13;;42326:16;;42344:17;;42363:7;;42242:129;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42227:144;;41551:1397;;;;;;42393:21;42424:8;42417:26;;;42452:4;42417:41;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42393:65;;42470:18;42490;42540:4;42523:29;;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42512:42;;:7;:42;;;:100;;42587:12;42609:1;42512:100;;;42566:1;42570:12;42512:100;42690:12;;;42700:1;42690:12;;;;;;;;;42623:80;;;;42469:143;;-1:-1:-1;42469:143:0;-1:-1:-1;42623:27:0;;;;;;:80;;42469:143;;;;42683:4;;42623:80;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42719:38;42728:4;42734:12;42748:8;42719:38;;;;;;;;:::i;:::-;;;;;;;;42787:60;42833:13;42794:8;42787:26;;;42822:4;42787:41;;;;;;;;;;;;;;;:::i;:60::-;42770:77;;42884:17;42866:14;:35;;42858:82;;;;;;;;;;;;:::i;:::-;41551:1397;;;;;;;;;;;:::o;23994:569::-;24244:15;24261;24310:91;24324:4;24330:6;24338;24346:14;24362;24378:10;24390;24310:13;:91::i;:::-;24289:112;;-1:-1:-1;24289:112:0;-1:-1:-1;24412:66:0;24444:6;24452:10;24464:4;24289:112;24412:31;:66::i;:::-;24489;24521:6;24529:10;24541:4;24547:7;24489:31;:66::i;:::-;23994:569;;;;;;;;;;:::o;22655:1331::-;22908:15;22925;22981:7;22961:35;;;22997:4;22961:41;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22953:74;;;;;;;;;;;;:::i;:::-;23039:16;23057;23097:7;23077:40;;;23118:4;23124:6;23132;23077:62;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23038:101;;;;23154:8;23166:1;23154:13;:30;;;;-1:-1:-1;23171:13:0;;23154:30;23150:829;;;23223:14;;-1:-1:-1;23239:14:0;;-1:-1:-1;23150:829:0;;;23312:70;;;;;23287:22;;23312:34;23332:7;23312:34;;;;:70;;23347:14;;23363:8;;23373;;23312:70;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23287:95;;23419:14;23401;:32;23397:571;;23480:10;23462:14;:28;;23454:70;;;;;;;;;;;;:::i;:::-;23565:14;;-1:-1:-1;23581:14:0;-1:-1:-1;23581:14:0;23397:571;;;23662:70;;;;;23637:22;;23662:34;23682:7;23662:34;;;;:70;;23697:14;;23713:8;;23723;;23662:70;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23637:95;;23776:14;23758;:32;;23751:40;;;;23836:10;23818:14;:28;;23810:70;;;;;;;;;;;;:::i;:::-;23921:14;23937;;-1:-1:-1;22655:1331:0;;-1:-1:-1;;;;;;;;;;22655:1331:0:o;14:138:1:-;84:20;;113:33;84:20;113:33;:::i;157:404::-;;;290:3;283:4;275:6;271:17;267:27;257:2;;315:8;305;298:26;257:2;-1:-1:-1;345:20:1;;388:18;377:30;;374:2;;;427:8;417;410:26;374:2;471:4;463:6;459:17;447:29;;534:3;527:4;519;511:6;507:17;499:6;495:30;491:41;488:50;485:2;;;551:1;548;541:12;485:2;247:314;;;;;:::o;566:2147::-;;698:3;691:4;683:6;679:17;675:27;665:2;;720:5;713;706:20;665:2;760:6;747:20;786:4;810:65;825:49;871:2;825:49;:::i;:::-;810:65;:::i;:::-;909:15;;;940:12;;;;972:15;;;1005:5;1019:1665;1033:2;1030:1;1027:9;1019:1665;;;1113:3;1100:17;1092:6;1088:30;1158:3;1153:2;1149;1145:11;1141:21;1131:2;;1180:5;1173;1166:20;1131:2;1232;1228;1224:11;1211:25;1262:65;1277:49;1323:2;1277:49;:::i;1262:65::-;1353:5;1385:2;1378:5;1371:17;1421:2;1414:5;1410:14;1401:23;;1458:2;1454;1450:11;1513:3;1508:2;1500:4;1496:2;1492:13;1488:2;1484:22;1480:31;1477:40;1474:2;;;1534:5;1527;1520:20;1474:2;1566:5;1555:16;;1584:995;1600:2;1595:3;1592:11;1584:995;;;1681:4;1673:5;1668:3;1664:15;1660:26;1657:2;;;1703:5;1696;1689:20;1657:2;1748;1742:9;1798:4;1790:6;1786:17;1877:6;1865:10;1862:22;1841:18;1829:10;1826:34;1823:62;1820:2;;;1888:9;1820:2;1923;1916:22;1968:19;;2004:33;1968:19;2004:33;:::i;:::-;2054:21;;2116:36;2137:14;;;2116:36;:::i;:::-;2111:2;2103:6;2099:15;2092:61;2194:36;2226:2;2219:5;2215:14;2194:36;:::i;:::-;2189:2;2177:15;;2170:61;2296:2;2285:14;;;2272:28;2255:15;;;2248:53;2367:3;2356:15;;;2343:29;2325:16;;;2318:55;2439:3;2428:15;;;2415:29;2397:16;;;2390:55;2462:21;;1622:1;1613:11;;;;;2509:14;;;;2560:4;2549:16;1584:995;;;-1:-1:-1;2592:18:1;;-1:-1:-1;;;2630:12:1;;;;2662;;;;1051:1;1044:9;1019:1665;;;-1:-1:-1;2702:5:1;;655:2058;-1:-1:-1;;;;;;;655:2058:1:o;2718:158::-;2786:20;;2846:4;2835:16;;2825:27;;2815:2;;2866:1;2863;2856:12;2881:259;;2993:2;2981:9;2972:7;2968:23;2964:32;2961:2;;;3014:6;3006;2999:22;2961:2;3058:9;3045:23;3077:33;3104:5;3077:33;:::i;3145:263::-;;3268:2;3256:9;3247:7;3243:23;3239:32;3236:2;;;3289:6;3281;3274:22;3236:2;3326:9;3320:16;3345:33;3372:5;3345:33;:::i;3413:399::-;;;3553:2;3541:9;3532:7;3528:23;3524:32;3521:2;;;3574:6;3566;3559:22;3521:2;3611:9;3605:16;3630:33;3657:5;3630:33;:::i;:::-;3732:2;3717:18;;3711:25;3682:5;;-1:-1:-1;3745:35:1;3711:25;3745:35;:::i;:::-;3799:7;3789:17;;;3511:301;;;;;:::o;3817:965::-;;;;;;;;;4048:3;4036:9;4027:7;4023:23;4019:33;4016:2;;;4070:6;4062;4055:22;4016:2;4114:9;4101:23;4133:33;4160:5;4133:33;:::i;:::-;4185:5;-1:-1:-1;4242:2:1;4227:18;;4214:32;4255:35;4214:32;4255:35;:::i;:::-;4309:7;-1:-1:-1;4368:2:1;4353:18;;4340:32;4381:35;4340:32;4381:35;:::i;:::-;4435:7;-1:-1:-1;4489:2:1;4474:18;;4461:32;;-1:-1:-1;4540:3:1;4525:19;;4512:33;;-1:-1:-1;4592:3:1;4577:19;;4564:33;;-1:-1:-1;4649:3:1;4634:19;;4621:33;4663:35;4621:33;4663:35;:::i;:::-;4717:7;4707:17;;;4771:3;4760:9;4756:19;4743:33;4733:43;;4006:776;;;;;;;;;;;:::o;4787:1318::-;;;;;;;;;;;;;5083:3;5071:9;5062:7;5058:23;5054:33;5051:2;;;5105:6;5097;5090:22;5051:2;5149:9;5136:23;5168:33;5195:5;5168:33;:::i;:::-;5220:5;-1:-1:-1;5277:2:1;5262:18;;5249:32;5290:35;5249:32;5290:35;:::i;:::-;5344:7;-1:-1:-1;5403:2:1;5388:18;;5375:32;5416:35;5375:32;5416:35;:::i;:::-;5470:7;-1:-1:-1;5524:2:1;5509:18;;5496:32;;-1:-1:-1;5575:3:1;5560:19;;5547:33;;-1:-1:-1;5627:3:1;5612:19;;5599:33;;-1:-1:-1;5684:3:1;5669:19;;5656:33;5698:35;5656:33;5698:35;:::i;:::-;5752:7;-1:-1:-1;5806:3:1;5791:19;;5778:33;;-1:-1:-1;5863:3:1;5848:19;;5835:33;5877:32;5835:33;5877:32;:::i;:::-;5928:7;-1:-1:-1;5954:39:1;5988:3;5973:19;;5954:39;:::i;:::-;5944:49;;6041:3;6030:9;6026:19;6013:33;6002:44;;6094:3;6083:9;6079:19;6066:33;6055:44;;5041:1064;;;;;;;;;;;;;;:::o;6110:1034::-;;;;;;;;;;6358:3;6346:9;6337:7;6333:23;6329:33;6326:2;;;6380:6;6372;6365:22;6326:2;6424:9;6411:23;6443:33;6470:5;6443:33;:::i;:::-;6495:5;-1:-1:-1;6552:2:1;6537:18;;6524:32;6565:35;6524:32;6565:35;:::i;:::-;6619:7;-1:-1:-1;6678:2:1;6663:18;;6650:32;6691:35;6650:32;6691:35;:::i;:::-;6745:7;-1:-1:-1;6799:2:1;6784:18;;6771:32;;-1:-1:-1;6850:3:1;6835:19;;6822:33;;-1:-1:-1;6902:3:1;6887:19;;6874:33;;-1:-1:-1;6954:3:1;6939:19;;6926:33;;-1:-1:-1;7011:3:1;6996:19;;6983:33;7025:35;6983:33;7025:35;:::i;:::-;7079:7;7069:17;;;7133:3;7122:9;7118:19;7105:33;7095:43;;6316:828;;;;;;;;;;;:::o;7149:1094::-;;;;;;;;;7398:3;7386:9;7377:7;7373:23;7369:33;7366:2;;;7420:6;7412;7405:22;7366:2;7464:9;7451:23;7483:33;7510:5;7483:33;:::i;:::-;7535:5;-1:-1:-1;7592:2:1;7577:18;;7564:32;7605:35;7564:32;7605:35;:::i;:::-;7659:7;-1:-1:-1;7713:2:1;7698:18;;7685:32;;-1:-1:-1;7764:2:1;7749:18;;7736:32;;-1:-1:-1;7819:3:1;7804:19;;7791:33;7847:18;7836:30;;7833:2;;;7884:6;7876;7869:22;7833:2;7928:76;7996:7;7987:6;7976:9;7972:22;7928:76;:::i;:::-;8023:8;;-1:-1:-1;7902:102:1;-1:-1:-1;;8110:3:1;8095:19;;8082:33;8124:35;8082:33;8124:35;:::i;:::-;8178:7;8168:17;;;8232:3;8221:9;8217:19;8204:33;8194:43;;7356:887;;;;;;;;;;;:::o;8248:1600::-;;;;;;;;8487:3;8475:9;8466:7;8462:23;8458:33;8455:2;;;8509:6;8501;8494:22;8455:2;8553:9;8540:23;8572:33;8599:5;8572:33;:::i;:::-;8624:5;-1:-1:-1;8648:2:1;8687:18;;;8674:32;8715:35;8674:32;8715:35;:::i;:::-;8769:7;-1:-1:-1;8823:2:1;8808:18;;8795:32;;-1:-1:-1;8874:2:1;8859:18;;8846:32;;-1:-1:-1;8929:3:1;8914:19;;8901:33;8957:18;8946:30;;8943:2;;;8994:6;8986;8979:22;8943:2;9022:22;;9075:4;9067:13;;9063:27;-1:-1:-1;9053:2:1;;9109:6;9101;9094:22;9053:2;9150;9137:16;9173:65;9188:49;9234:2;9188:49;:::i;9173:65::-;9272:15;;;9303:12;;;;9335:11;;;9373;;;9365:20;;9361:29;;9358:42;-1:-1:-1;9355:2:1;;;9418:6;9410;9403:22;9355:2;9445:6;9436:15;;9460:246;9474:2;9471:1;9468:9;9460:246;;;9547:3;9534:17;9564:35;9591:7;9564:35;:::i;:::-;9612:20;;9492:1;9485:9;;;;;9652:12;;;;9684;;9460:246;;;9464:3;9725:5;9715:15;;;;;;;9749:41;9785:3;9774:9;9770:19;9749:41;:::i;:::-;9739:51;;9837:3;9826:9;9822:19;9809:33;9799:43;;8445:1403;;;;;;;;;;:::o;9853:821::-;;;;;;;;10067:3;10055:9;10046:7;10042:23;10038:33;10035:2;;;10089:6;10081;10074:22;10035:2;10133:9;10120:23;10152:33;10179:5;10152:33;:::i;:::-;10204:5;-1:-1:-1;10261:2:1;10246:18;;10233:32;10274:35;10233:32;10274:35;:::i;:::-;10328:7;-1:-1:-1;10382:2:1;10367:18;;10354:32;;-1:-1:-1;10433:2:1;10418:18;;10405:32;;-1:-1:-1;10484:3:1;10469:19;;10456:33;;-1:-1:-1;10541:3:1;10526:19;;10513:33;10555:35;10513:33;10555:35;:::i;:::-;10609:7;10599:17;;;10663:3;10652:9;10648:19;10635:33;10625:43;;10025:649;;;;;;;;;;:::o;10679:1172::-;;;;;;;;;;;;10957:3;10945:9;10936:7;10932:23;10928:33;10925:2;;;10979:6;10971;10964:22;10925:2;11023:9;11010:23;11042:33;11069:5;11042:33;:::i;:::-;11094:5;-1:-1:-1;11151:2:1;11136:18;;11123:32;11164:35;11123:32;11164:35;:::i;:::-;11218:7;-1:-1:-1;11272:2:1;11257:18;;11244:32;;-1:-1:-1;11323:2:1;11308:18;;11295:32;;-1:-1:-1;11374:3:1;11359:19;;11346:33;;-1:-1:-1;11431:3:1;11416:19;;11403:33;11445:35;11403:33;11445:35;:::i;:::-;11499:7;-1:-1:-1;11553:3:1;11538:19;;11525:33;;-1:-1:-1;11610:3:1;11595:19;;11582:33;11624:32;11582:33;11624:32;:::i;:::-;11675:7;-1:-1:-1;11701:39:1;11735:3;11720:19;;11701:39;:::i;:::-;11691:49;;11787:3;11776:9;11772:19;11759:33;11749:43;;11840:3;11829:9;11825:19;11812:33;11801:44;;10915:936;;;;;;;;;;;;;;:::o;11856:967::-;;;;;;;;12068:3;12056:9;12047:7;12043:23;12039:33;12036:2;;;12090:6;12082;12075:22;12036:2;12134:9;12121:23;12153:33;12180:5;12153:33;:::i;:::-;12205:5;-1:-1:-1;12262:2:1;12247:18;;12234:32;12275:35;12234:32;12275:35;:::i;:::-;12329:7;-1:-1:-1;12383:2:1;12368:18;;12355:32;;-1:-1:-1;12434:2:1;12419:18;;12406:32;;-1:-1:-1;12490:3:1;12475:19;;12462:33;12504:34;12462:33;12504:34;:::i;:::-;12557:7;-1:-1:-1;12616:3:1;12601:19;;12588:33;12630:34;12588:33;12630:34;:::i;:::-;12683:7;-1:-1:-1;12742:3:1;12727:19;;12714:33;12756:35;12714:33;12756:35;:::i;:::-;12810:7;12800:17;;;12026:797;;;;;;;;;;:::o;12828:881::-;;;;;;;13043:3;13031:9;13022:7;13018:23;13014:33;13011:2;;;13065:6;13057;13050:22;13011:2;13109:9;13096:23;13128:33;13155:5;13128:33;:::i;:::-;13180:5;-1:-1:-1;13232:2:1;13217:18;;13204:32;;-1:-1:-1;13287:2:1;13272:18;;13259:32;13314:18;13303:30;;13300:2;;;13351:6;13343;13336:22;13300:2;13395:76;13463:7;13454:6;13443:9;13439:22;13395:76;:::i;:::-;13490:8;;-1:-1:-1;13369:102:1;-1:-1:-1;;13577:2:1;13562:18;;13549:32;13590:35;13549:32;13590:35;:::i;:::-;13644:7;13634:17;;;13698:3;13687:9;13683:19;13670:33;13660:43;;13001:708;;;;;;;;:::o;13714:950::-;;;;;;;;13946:3;13934:9;13925:7;13921:23;13917:33;13914:2;;;13968:6;13960;13953:22;13914:2;14012:9;13999:23;14031:33;14058:5;14031:33;:::i;:::-;14083:5;-1:-1:-1;14135:2:1;14120:18;;14107:32;;-1:-1:-1;14186:2:1;14171:18;;14158:32;;-1:-1:-1;14241:2:1;14226:18;;14213:32;14268:18;14257:30;;14254:2;;;14305:6;14297;14290:22;14254:2;14349:76;14417:7;14408:6;14397:9;14393:22;14349:76;:::i;:::-;14444:8;;-1:-1:-1;14323:102:1;-1:-1:-1;;14531:3:1;14516:19;;14503:33;14545:35;14503:33;14545:35;:::i;:::-;14599:7;14589:17;;;14653:3;14642:9;14638:19;14625:33;14615:43;;13904:760;;;;;;;;;;:::o;14669:790::-;;;;;;;14874:3;14862:9;14853:7;14849:23;14845:33;14842:2;;;14896:6;14888;14881:22;14842:2;14933:9;14927:16;14952:33;14979:5;14952:33;:::i;:::-;15004:5;14994:15;;;15049:2;15038:9;15034:18;15028:25;15018:35;;15093:2;15082:9;15078:18;15072:25;15062:35;;15142:2;15131:9;15127:18;15121:25;15155:34;15181:7;15155:34;:::i;:::-;15260:3;15245:19;;15239:26;15208:7;;-1:-1:-1;15274:34:1;15239:26;15274:34;:::i;:::-;15379:3;15364:19;;15358:26;15327:7;;-1:-1:-1;15393:34:1;15358:26;15393:34;:::i;:::-;15446:7;15436:17;;;14832:627;;;;;;;;:::o;15464:754::-;;;;;;15642:3;15630:9;15621:7;15617:23;15613:33;15610:2;;;15664:6;15656;15649:22;15610:2;15708:9;15695:23;15727:33;15754:5;15727:33;:::i;:::-;15779:5;-1:-1:-1;15831:2:1;15816:18;;15803:32;;-1:-1:-1;15887:2:1;15872:18;;15859:32;15900:34;15859:32;15900:34;:::i;:::-;15953:7;-1:-1:-1;16012:2:1;15997:18;;15984:32;16025:34;15984:32;16025:34;:::i;:::-;16078:7;-1:-1:-1;16137:3:1;16122:19;;16109:33;16151:35;16109:33;16151:35;:::i;:::-;16205:7;16195:17;;;15600:618;;;;;;;;:::o;16223:857::-;;;;;;16474:3;16462:9;16453:7;16449:23;16445:33;16442:2;;;16496:6;16488;16481:22;16442:2;16541:9;16528:23;16574:18;16566:6;16563:30;16560:2;;;16611:6;16603;16596:22;16560:2;16639:86;16717:7;16708:6;16697:9;16693:22;16639:86;:::i;:::-;16629:96;;;16775:2;16764:9;16760:18;16747:32;16788:33;16815:5;16788:33;:::i;:::-;16840:5;-1:-1:-1;16897:2:1;16882:18;;16869:32;16910:35;16869:32;16910:35;:::i;:::-;16432:648;;;;-1:-1:-1;16964:7:1;;17018:2;17003:18;;16990:32;;-1:-1:-1;17069:3:1;17054:19;17041:33;;16432:648;-1:-1:-1;;16432:648:1:o;17085:926::-;;;;;;;17353:3;17341:9;17332:7;17328:23;17324:33;17321:2;;;17375:6;17367;17360:22;17321:2;17420:9;17407:23;17453:18;17445:6;17442:30;17439:2;;;17490:6;17482;17475:22;17439:2;17518:86;17596:7;17587:6;17576:9;17572:22;17518:86;:::i;:::-;17508:96;;;17654:2;17643:9;17639:18;17626:32;17667:33;17694:5;17667:33;:::i;:::-;17719:5;-1:-1:-1;17776:2:1;17761:18;;17748:32;17789:35;17748:32;17789:35;:::i;:::-;17311:700;;;;-1:-1:-1;17843:7:1;;17897:2;17882:18;;17869:32;;-1:-1:-1;17948:3:1;17933:19;;17920:33;;18000:3;17985:19;;;17972:33;;-1:-1:-1;17311:700:1;-1:-1:-1;;17311:700:1:o;18016:943::-;;18142:2;18185;18173:9;18164:7;18160:23;18156:32;18153:2;;;18206:6;18198;18191:22;18153:2;18244:9;18238:16;18277:18;18269:6;18266:30;18263:2;;;18314:6;18306;18299:22;18263:2;18342:22;;18395:4;18387:13;;18383:27;-1:-1:-1;18373:2:1;;18429:6;18421;18414:22;18373:2;18463;18457:9;18486:65;18501:49;18547:2;18501:49;:::i;18486:65::-;18585:15;;;18616:12;;;;18648:11;;;18686;;;18678:20;;18674:29;;18671:42;-1:-1:-1;18668:2:1;;;18731:6;18723;18716:22;18668:2;18758:6;18749:15;;18773:156;18787:2;18784:1;18781:9;18773:156;;;18844:10;;18832:23;;18805:1;18798:9;;;;;18875:12;;;;18907;;18773:156;;18964:257;;19084:2;19072:9;19063:7;19059:23;19055:32;19052:2;;;19105:6;19097;19090:22;19052:2;19142:9;19136:16;19161:30;19185:5;19161:30;:::i;19226:194::-;;19349:2;19337:9;19328:7;19324:23;19320:32;19317:2;;;19370:6;19362;19355:22;19317:2;-1:-1:-1;19398:16:1;;19307:113;-1:-1:-1;19307:113:1:o;19425:255::-;;;19565:2;19553:9;19544:7;19540:23;19536:32;19533:2;;;19586:6;19578;19571:22;19533:2;-1:-1:-1;;19614:16:1;;19670:2;19655:18;;;19649:25;19614:16;;19649:25;;-1:-1:-1;19523:157:1:o;19685:318::-;;19766:5;19760:12;19793:6;19788:3;19781:19;19809:63;19865:6;19858:4;19853:3;19849:14;19842:4;19835:5;19831:16;19809:63;:::i;:::-;19917:2;19905:15;19922:66;19901:88;19892:98;;;;19992:4;19888:109;;19736:267;-1:-1:-1;;19736:267:1:o;20008:274::-;;20175:6;20169:13;20191:53;20237:6;20232:3;20225:4;20217:6;20213:17;20191:53;:::i;:::-;20260:16;;;;;20145:137;-1:-1:-1;;20145:137:1:o;20287:226::-;20463:42;20451:55;;;;20433:74;;20421:2;20406:18;;20388:125::o;20757:709::-;21094:42;21163:15;;;21145:34;;21215:15;;;;21210:2;21195:18;;21188:43;21262:2;21247:18;;21240:34;;;;21305:2;21290:18;;21283:34;;;;21366:4;21354:17;21348:3;21333:19;;21326:46;21403:3;21388:19;;21381:35;21447:3;21432:19;;21425:35;;;;21071:3;21056:19;;21038:428::o;21471:406::-;21691:42;21760:15;;;21742:34;;21812:15;;;;21807:2;21792:18;;21785:43;21859:2;21844:18;;21837:34;;;;21669:2;21654:18;;21636:241::o;21882:327::-;22066:42;22135:15;;;22117:34;;22187:15;;22182:2;22167:18;;22160:43;22044:2;22029:18;;22011:198::o;22214:407::-;22426:42;22495:15;;;22477:34;;22547:15;;;22542:2;22527:18;;22520:43;22599:15;;;22594:2;22579:18;;22572:43;22404:2;22389:18;;22371:250::o;22626:1069::-;;22938:3;22927:9;22923:19;22961:42;23042:2;23034:6;23030:15;23019:9;23012:34;23065:2;23115;23107:6;23103:15;23098:2;23087:9;23083:18;23076:43;23167:2;23159:6;23155:15;23150:2;23139:9;23135:18;23128:43;23207:6;23202:2;23191:9;23187:18;23180:34;23251:3;23245;23234:9;23230:19;23223:32;23275:6;23305;23297;23290:22;23343:3;23332:9;23328:19;23321:26;;23370:6;23356:20;;23394:4;23407:262;23421:6;23418:1;23415:13;23407:262;;;23496:6;23483:20;23516:33;23543:5;23516:33;:::i;:::-;23574:14;;23562:27;;23644:15;;;;23609:12;;;;23443:1;23436:9;23407:262;;;-1:-1:-1;23686:3:1;22899:796;-1:-1:-1;;;;;;;;;;;22899:796:1:o;23700:1020::-;;24002:3;23991:9;23987:19;24025:42;24106:2;24098:6;24094:15;24083:9;24076:34;24129:2;24179;24171:6;24167:15;24162:2;24151:9;24147:18;24140:43;24231:2;24223:6;24219:15;24214:2;24203:9;24199:18;24192:43;24271:6;24266:2;24255:9;24251:18;24244:34;24315:3;24309;24298:9;24294:19;24287:32;24339:6;24374;24368:13;24405:6;24397;24390:22;24443:3;24432:9;24428:19;24421:26;;24482:2;24474:6;24470:15;24456:29;;24503:4;24516:178;24530:6;24527:1;24524:13;24516:178;;;24595:13;;24591:22;;24579:35;;24669:15;;;;24634:12;;;;24552:1;24545:9;24516:178;;;-1:-1:-1;24711:3:1;;23963:757;-1:-1:-1;;;;;;;;;;;23963:757:1:o;25128:513::-;25365:42;25434:15;;;25416:34;;25486:15;;;;25481:2;25466:18;;25459:43;25521:10;25567:15;;;25562:2;25547:18;;25540:43;25619:15;;;25614:2;25599:18;;25592:43;25342:3;25327:19;;25309:332::o;25646:297::-;25850:42;25838:55;;;;25820:74;;25925:2;25910:18;;25903:34;25808:2;25793:18;;25775:168::o;25948:398::-;26160:42;26229:15;;;26211:34;;26276:2;26261:18;;26254:34;;;;26324:15;;;26319:2;26304:18;;26297:43;26138:2;26123:18;;26105:241::o;26351:635::-;26522:2;26574:21;;;26644:13;;26547:18;;;26666:22;;;26351:635;;26522:2;26745:15;;;;26719:2;26704:18;;;26351:635;26791:169;26805:6;26802:1;26799:13;26791:169;;;26866:13;;26854:26;;26935:15;;;;26900:12;;;;26827:1;26820:9;26791:169;;;-1:-1:-1;26977:3:1;;26502:484;-1:-1:-1;;;;;;26502:484:1:o;26991:345::-;27193:2;27175:21;;;27232:2;27212:18;;;27205:30;27271:23;27266:2;27251:18;;27244:51;27327:2;27312:18;;27165:171::o;27341:355::-;27543:2;27525:21;;;27582:2;27562:18;;;27555:30;27621:33;27616:2;27601:18;;27594:61;27687:2;27672:18;;27515:181::o;27701:342::-;27903:2;27885:21;;;27942:2;27922:18;;;27915:30;27981:20;27976:2;27961:18;;27954:48;28034:2;28019:18;;27875:168::o;28048:354::-;28250:2;28232:21;;;28289:2;28269:18;;;28262:30;28328:32;28323:2;28308:18;;28301:60;28393:2;28378:18;;28222:180::o;28407:353::-;28609:2;28591:21;;;28648:2;28628:18;;;28621:30;28687:31;28682:2;28667:18;;28660:59;28751:2;28736:18;;28581:179::o;28765:344::-;28967:2;28949:21;;;29006:2;28986:18;;;28979:30;29045:22;29040:2;29025:18;;29018:50;29100:2;29085:18;;28939:170::o;29114:353::-;29316:2;29298:21;;;29355:2;29335:18;;;29328:30;29394:31;29389:2;29374:18;;29367:59;29458:2;29443:18;;29288:179::o;29472:337::-;29674:2;29656:21;;;29713:2;29693:18;;;29686:30;29752:15;29747:2;29732:18;;29725:43;29800:2;29785:18;;29646:163::o;29814:336::-;30016:2;29998:21;;;30055:2;30035:18;;;30028:30;30094:14;30089:2;30074:18;;30067:42;30141:2;30126:18;;29988:162::o;30155:339::-;30357:2;30339:21;;;30396:2;30376:18;;;30369:30;30435:17;30430:2;30415:18;;30408:45;30485:2;30470:18;;30329:165::o;30499:398::-;30701:2;30683:21;;;30740:2;30720:18;;;30713:30;30779:34;30774:2;30759:18;;30752:62;30850:4;30845:2;30830:18;;30823:32;30887:3;30872:19;;30673:224::o;30902:399::-;31104:2;31086:21;;;31143:2;31123:18;;;31116:30;31182:34;31177:2;31162:18;;31155:62;31253:5;31248:2;31233:18;;31226:33;31291:3;31276:19;;31076:225::o;31306:400::-;31508:2;31490:21;;;31547:2;31527:18;;;31520:30;31586:34;31581:2;31566:18;;31559:62;31657:6;31652:2;31637:18;;31630:34;31696:3;31681:19;;31480:226::o;31711:344::-;31913:2;31895:21;;;31952:2;31932:18;;;31925:30;31991:22;31986:2;31971:18;;31964:50;32046:2;32031:18;;31885:170::o;32060:177::-;32206:25;;;32194:2;32179:18;;32161:76::o;32242:248::-;32416:25;;;32472:2;32457:18;;32450:34;32404:2;32389:18;;32371:119::o;32495:491::-;;32734:6;32723:9;32716:25;32777:6;32772:2;32761:9;32757:18;32750:34;32832:42;32824:6;32820:55;32815:2;32804:9;32800:18;32793:83;32912:3;32907:2;32896:9;32892:18;32885:31;32933:47;32975:3;32964:9;32960:19;32952:6;32933:47;:::i;33479:319::-;33681:25;;;33737:2;33722:18;;33715:34;;;;33780:2;33765:18;;33758:34;33669:2;33654:18;;33636:162::o;33803:585::-;34084:25;;;34140:2;34125:18;;34118:34;;;;34183:2;34168:18;;34161:34;;;;34214:10;34260:15;;;34255:2;34240:18;;34233:43;34313:15;;;34307:3;34292:19;;34285:44;34366:15;34360:3;34345:19;;34338:44;34071:3;34056:19;;34038:350::o;34393:242::-;34463:2;34457:9;34493:17;;;34540:18;34525:34;;34561:22;;;34522:62;34519:2;;;34587:9;34519:2;34614;34607:22;34437:198;;-1:-1:-1;34437:198:1:o;34640:183::-;;34739:18;34731:6;34728:30;34725:2;;;34761:9;34725:2;-1:-1:-1;34812:4:1;34793:17;;;34789:28;;34715:108::o;34828:258::-;34900:1;34910:113;34924:6;34921:1;34918:13;34910:113;;;35000:11;;;34994:18;34981:11;;;34974:39;34946:2;34939:10;34910:113;;;35041:6;35038:1;35035:13;35032:2;;;35076:1;35067:6;35062:3;35058:16;35051:27;35032:2;;34881:205;;;:::o;35091:156::-;35179:42;35172:5;35168:54;35161:5;35158:65;35148:2;;35237:1;35234;35227:12;35148:2;35138:109;:::o;35252:120::-;35340:5;35333:13;35326:21;35319:5;35316:32;35306:2;;35362:1;35359;35352:12;35377:123;35464:10;35457:5;35453:22;35446:5;35443:33;35433:2;;35490:1;35487;35480:12

Swarm Source

ipfs://0b64ee0912afd1d68a01be202a9ae707748fbd13a053643a727a00d5ba477829
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.