Contract 0xc1b6296e55b6ca1882a9cefd72ac246acde91414

 
Txn Hash
Block
From
To
Value
0x49e89e781cc02c0c35a299cedce708a983950a3c90ac15911352fcb86c5020a3119743892021-03-04 22:03:481 day 19 hrs ago0x4ec87da8a9eb1179b90d17bee3ace9fdf05030da IN  Value Defi: BSD/DAI Pool 50/500 Ether0.0031209381
0xab8975359fa278a5bbd2e2eb2aa4eca112943b67e333cc9816c04a7375f8c5e9119743892021-03-04 22:03:481 day 19 hrs ago0x4ec87da8a9eb1179b90d17bee3ace9fdf05030da IN  Value Defi: BSD/DAI Pool 50/500 Ether0.01394568981
0x77c20cf56bd9d202e7a66e26a45fb0bf2c91509150aab3535da6cf13f3f8fce9119492982021-03-01 1:12:265 days 16 hrs ago0xffedb92f8b8c7b620ea6b722ef146f28c1b6e665 IN  Value Defi: BSD/DAI Pool 50/500 Ether0.01704759771
0xc16b6f2ab4a4d0e961a374abd7510f9e6c039a2741f8e48bc675a3a6c5547d90119473232021-02-28 18:06:275 days 23 hrs ago0x097790d228a564cbc7012f082cbcbc28288397bd IN  Value Defi: BSD/DAI Pool 50/500 Ether0.01239625125
0x7b0b8ed62fbb2e34668a7eae7a5c4abefd1b37409cacfd7526bd1b220d99af6e119394812021-02-27 12:54:377 days 4 hrs ago0xa0d1f848d57d3263058fca4dd6830821e7f790f0 IN  Value Defi: BSD/DAI Pool 50/500 Ether0.009926917100.1
0xfe4fca158d88580b7c22ebfee4a0c1c49e5082ac91b0e249487fdfbdf2df4f8c119370672021-02-27 3:58:037 days 13 hrs ago0x2e973bc711e1d50508938c8b66d5ac4398dbf29c IN  Value Defi: BSD/DAI Pool 50/500 Ether0.0092228193
0xcfc2f6198e8debb4460a7f43b9a1d64acb29252446214e9c3c2447a737038786119271772021-02-25 15:34:199 days 2 hrs ago0x097790d228a564cbc7012f082cbcbc28288397bd IN  Value Defi: BSD/DAI Pool 50/500 Ether0.02157813189
0x18813e9e31865a7170d4b212e5c910119b60878dc3cce70ad6eaa9f5739e720f119239082021-02-25 3:36:049 days 14 hrs ago0xe1da6acf304460cd1007566549adc012ecb97b6b IN  Value Defi: BSD/DAI Pool 50/500 Ether0.02123562186
0x1f2ff1ee5933532b2384e31493380981c82234a685673d12de0e30bb0532ef91119231322021-02-25 0:38:039 days 17 hrs ago0xa9536b31e9369deaf6d0a086413c818cc9bfe15d IN  Value Defi: BSD/DAI Pool 50/500 Ether0.0233442209111.1
0x73a64af8c4a5e4e4f921374ba70c91883c63bd8e4ba5b9a08499fc9d94b40a9c119229092021-02-24 23:53:379 days 17 hrs ago0x9bba6257036c367e76baa8916725913a1ad60912 IN  Value Defi: BSD/DAI Pool 50/500 Ether0.023952198114
0x2a334c04a370bc57fcb8a7ca90342472151f239367237fde261393076fc6e0ee119040472021-02-22 2:07:4812 days 15 hrs ago0x22f33fbf08d264697a4f54e50f152a16bff5711d IN  Value Defi: BSD/DAI Pool 50/500 Ether0.01071036108
0xdc105d06291abb7fd04a6fcefb4d51353fa8b9f6c7bc27d05c3c7f7d39e31c4f119015862021-02-21 17:17:3513 days 34 mins ago0xb01d8124071c6c0ca2d8a135f2e706ae81cb43ac IN  Value Defi: BSD/DAI Pool 50/500 Ether0.01849554162
0x150dc087d2f065bba952179e1ddb814cfded25bf6593367621e4716ce158724d119007242021-02-21 14:11:3113 days 3 hrs ago0xa0d1f848d57d3263058fca4dd6830821e7f790f0 IN  Value Defi: BSD/DAI Pool 50/500 Ether0.0119004120
0xc736a035743faa10474d465799a3b7adb09df464a56b88ddd42e1964cfb693c4118990502021-02-21 7:53:5513 days 9 hrs ago0xb7d4b6676dd564420f3d64360b9c5bde4961bd02 IN  Value Defi: BSD/DAI Pool 50/500 Ether0.01187368104
0x822d2efc79eef01174420d17d6904a8bb0e82ad29caeacc17071b95c53994f0c118974882021-02-21 1:55:4513 days 15 hrs ago0x4315ed306e03192867b1799e4c0895a4cd9d82d4 IN  Value Defi: BSD/DAI Pool 50/500 Ether0.01356285105
0x21f3740b85977650302d79f7116b297f64a197423c085c0b57d3011c9a9bf4c9118845142021-02-19 2:05:2715 days 15 hrs ago0x7698f83a181ef3e048720927b0b7847600b4bb54 IN  Value Defi: BSD/DAI Pool 50/500 Ether0.006625096172
0x3d9ab411a5eb0bc898e66d1aafd03bc95b13a409cf6a8487c491fbfa11436355118845142021-02-19 2:05:2715 days 15 hrs ago0x7698f83a181ef3e048720927b0b7847600b4bb54 IN  Value Defi: BSD/DAI Pool 50/500 Ether0.032915468172
0xea79dfb32f511bc56573449cb04d38ddfbd13e2d42df525a9fc22077a7d54bdb118752712021-02-17 15:53:4717 days 1 hr ago0x097790d228a564cbc7012f082cbcbc28288397bd IN  Value Defi: BSD/DAI Pool 50/500 Ether0.021190695185213.6805
0x35ce01f3b81139900cc4f810ed33b782a8cf6bd97bdbafc46c4ae9f5e6aec91c118733562021-02-17 8:53:1717 days 8 hrs ago0x0286d1ac3d202ffddf2b2fc8f2b244f1b572ab0a IN  Value Defi: BSD/DAI Pool 50/500 Ether0.01583901110
0xc92828002eb13aa9476299abc7706b2ddb791a2b76e054f881c4a2789697e07e118659932021-02-16 5:48:1818 days 12 hrs ago0x2e973bc711e1d50508938c8b66d5ac4398dbf29c IN  Value Defi: BSD/DAI Pool 50/500 Ether0.01198785105
0x706d801273205de92b759d805811b383e39be5f3b816b2ed9af18c0eff8f9cc4118595402021-02-15 5:52:4419 days 11 hrs ago0x563df37683ff2513cceac514164285c89c4e2178 IN  Value Defi: BSD/DAI Pool 50/500 Ether0.017088529791.3
0xcbb248ea6c3e72ac6469370c2762f15a6ace95a6eae9318671434e92be117b5b118546522021-02-14 11:52:2820 days 5 hrs ago0x563df37683ff2513cceac514164285c89c4e2178 IN  Value Defi: BSD/DAI Pool 50/500 Ether0.0158464746108.9
0x05a8e6937c0c2867b2de65d374aa9b95882f2e118c2c6822ec9fef73aa861372118473882021-02-13 9:08:5621 days 8 hrs ago0xa5f9ca08ddc231be6e2fb0013564e278010e6d95 IN  Value Defi: BSD/DAI Pool 50/500 Ether0.016990938118
0x14567fa4ed5f0626db374391b095eb1f8630b16f65ac5fc67cf4aaaa44da08a4118255962021-02-10 0:43:1424 days 17 hrs ago0xc2c148b176728dac837859f943ff1ceabf17ab9e IN  Value Defi: BSD/DAI Pool 50/500 Ether0.0298720323108.9
0xf9ebe96a81e7722f7c908ad06ab07b3f9996afc2a30a2a8794d045f28b355752118231702021-02-09 15:45:5825 days 2 hrs ago0x0700d5329642fea897b4b09ce3675ba131de154d IN  Value Defi: BSD/DAI Pool 50/500 Ether0.037623381201
[ Download CSV Export 

OVERVIEW

Farms-as-a-Service (FaaS) is a project that allow users to create own FaaS pool and let the community stake to it. This is BSD/DAI Pool with pool weight of 50-50%.

Latest 1 internal transaction
Parent Txn Hash Block From To Value
0x49916f51b614bef28fc4d81683487d4fa9e14a8f5d646d48d473f7e3144523b9114628082020-12-16 7:39:5880 days 10 hrs ago 0x89822f305922c187d42db1017f9b61135be1c1e8  Contract Creation0 Ether
[ Download CSV Export 
Loading

Contract Source Code Verified (Similar Match)
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0x635e4a8d23d9add975e931113ddd2ac3663a7325

Contract Name:
FaaSPoolLite

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 700 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-11-28
*/

// SPDX-License-Identifier: MIT

pragma solidity 0.6.12;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
library BConst {
    uint public constant BONE                     = 10**18;

    uint public constant MIN_BOUND_TOKENS         = 2;
    uint public constant MAX_BOUND_TOKENS         = 8;

    uint public constant DEFAULT_FEE              = BONE * 3 / 1000; // 0.3%
    uint public constant MIN_FEE                  = BONE / 1000; // 0.1%
    uint public constant MAX_FEE                  = BONE / 10; // 10%

    uint public constant DEFAULT_COLLECTED_FEE    = BONE * 33 / 10000; // 0.33%
    uint public constant MAX_COLLECTED_FEE        = BONE * 334 / 10000; // 3.34%

    uint public constant DEFAULT_EXIT_FEE         = 0;
    uint public constant MAX_EXIT_FEE             = BONE / 1000; // 0.1%

    uint public constant MIN_WEIGHT               = BONE;
    uint public constant MAX_WEIGHT               = BONE * 50;
    uint public constant MAX_TOTAL_WEIGHT         = BONE * 50;
    uint public constant MIN_BALANCE              = BONE / 10**12;

    uint public constant DEFAULT_INIT_POOL_SUPPLY = BONE * 100;
    uint public constant MIN_INIT_POOL_SUPPLY     = BONE / 1000;
    uint public constant MAX_INIT_POOL_SUPPLY     = BONE * 10**18;

    uint public constant MIN_BPOW_BASE            = 1 wei;
    uint public constant MAX_BPOW_BASE            = (2 * BONE) - 1 wei;
    uint public constant BPOW_PRECISION           = BONE / 10**10;

    uint public constant MAX_IN_RATIO             = BONE / 2;
    uint public constant MAX_OUT_RATIO            = (BONE / 3) + 1 wei;
}

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
contract BNum {

    function btoi(uint a)
        internal pure 
        returns (uint)
    {
        return a / BConst.BONE;
    }

    function bfloor(uint a)
        internal pure
        returns (uint)
    {
        return btoi(a) * BConst.BONE;
    }

    function badd(uint a, uint b)
        internal pure
        returns (uint)
    {
        uint c = a + b;
        require(c >= a, "add overflow");
        return c;
    }

    function bsub(uint a, uint b)
        internal pure
        returns (uint)
    {
        (uint c, bool flag) = bsubSign(a, b);
        require(!flag, "sub underflow");
        return c;
    }

    function bsubSign(uint a, uint b)
        internal pure
        returns (uint, bool)
    {
        if (a >= b) {
            return (a - b, false);
        } else {
            return (b - a, true);
        }
    }

    function bmul(uint a, uint b)
        internal pure
        returns (uint)
    {
        uint c0 = a * b;
        require(a == 0 || c0 / a == b, "mul overflow");
        uint c1 = c0 + (BConst.BONE / 2);
        require(c1 >= c0, "mul overflow");
        uint c2 = c1 / BConst.BONE;
        return c2;
    }

    function bdiv(uint a, uint b)
        internal pure
        returns (uint)
    {
        require(b != 0, "div by 0");
        uint c0 = a * BConst.BONE;
        require(a == 0 || c0 / a == BConst.BONE, "div internal"); // bmul overflow
        uint c1 = c0 + (b / 2);
        require(c1 >= c0, "div internal"); //  badd require
        uint c2 = c1 / b;
        return c2;
    }

    // DSMath.wpow
    function bpowi(uint a, uint n)
        internal pure
        returns (uint)
    {
        uint z = n % 2 != 0 ? a : BConst.BONE;

        for (n /= 2; n != 0; n /= 2) {
            a = bmul(a, a);

            if (n % 2 != 0) {
                z = bmul(z, a);
            }
        }
        return z;
    }

    // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).
    // Use `bpowi` for `b^e` and `bpowK` for k iterations
    // of approximation of b^0.w
    function bpow(uint base, uint exp)
        internal pure
        returns (uint)
    {
        require(base >= BConst.MIN_BPOW_BASE, "base too low");
        require(base <= BConst.MAX_BPOW_BASE, "base too high");

        uint whole  = bfloor(exp);   
        uint remain = bsub(exp, whole);

        uint wholePow = bpowi(base, btoi(whole));

        if (remain == 0) {
            return wholePow;
        }

        uint partialResult = bpowApprox(base, remain, BConst.BPOW_PRECISION);
        return bmul(wholePow, partialResult);
    }

    function bpowApprox(uint base, uint exp, uint precision)
        internal pure
        returns (uint)
    {
        // term 0:
        uint a     = exp;
        (uint x, bool xneg)  = bsubSign(base, BConst.BONE);
        uint term = BConst.BONE;
        uint sum   = term;
        bool negative = false;


        // term(k) = numer / denom 
        //         = (product(a - i - 1, i=1-->k) * x^k) / (k!)
        // each iteration, multiply previous term by (a-(k-1)) * x / k
        // continue until term is less than precision
        for (uint i = 1; term >= precision; i++) {
            uint bigK = i * BConst.BONE;
            (uint c, bool cneg) = bsubSign(a, bsub(bigK, BConst.BONE));
            term = bmul(term, bmul(c, x));
            term = bdiv(term, bigK);
            if (term == 0) break;

            if (xneg) negative = !negative;
            if (cneg) negative = !negative;
            if (negative) {
                sum = bsub(sum, term);
            } else {
                sum = badd(sum, term);
            }
        }

        return sum;
    }

}

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
// Highly opinionated token implementation
interface IERC20 {
    event Approval(address indexed src, address indexed dst, uint amt);
    event Transfer(address indexed src, address indexed dst, uint amt);

    function totalSupply() external view returns (uint);
    function balanceOf(address whom) external view returns (uint);
    function allowance(address src, address dst) external view returns (uint);

    function approve(address dst, uint amt) external returns (bool);
    function transfer(address dst, uint amt) external returns (bool);
    function transferFrom(
        address src, address dst, uint amt
    ) external returns (bool);
}

contract BTokenBase is BNum {

    mapping(address => uint)                   internal _balance;
    mapping(address => mapping(address=>uint)) internal _allowance;
    uint internal _totalSupply;

    event Approval(address indexed src, address indexed dst, uint amt);
    event Transfer(address indexed src, address indexed dst, uint amt);

    function _mint(uint amt) internal {
        _balance[address(this)] = badd(_balance[address(this)], amt);
        _totalSupply = badd(_totalSupply, amt);
        emit Transfer(address(0), address(this), amt);
    }

    function _burn(uint amt) internal {
        require(_balance[address(this)] >= amt, "!bal");
        _balance[address(this)] = bsub(_balance[address(this)], amt);
        _totalSupply = bsub(_totalSupply, amt);
        emit Transfer(address(this), address(0), amt);
    }

    function _move(address src, address dst, uint amt) internal {
        require(_balance[src] >= amt, "!bal");
        _balance[src] = bsub(_balance[src], amt);
        _balance[dst] = badd(_balance[dst], amt);
        emit Transfer(src, dst, amt);
    }

    function _push(address to, uint amt) internal {
        _move(address(this), to, amt);
    }

    function _pull(address from, uint amt) internal {
        _move(from, address(this), amt);
    }
}

contract BToken is BTokenBase, IERC20 {
    string  private _name     = "Value Liquidity Provider";
    string  private _symbol   = "VLP";
    uint8   private _decimals = 18;

    function name() public view returns (string memory) {
        return _name;
    }

    function symbol() public view returns (string memory) {
        return _symbol;
    }

    function decimals() public view returns(uint8) {
        return _decimals;
    }

    function allowance(address src, address dst) external override view returns (uint) {
        return _allowance[src][dst];
    }

    function balanceOf(address whom) public override view returns (uint) {
        return _balance[whom];
    }

    function totalSupply() public override view returns (uint) {
        return _totalSupply;
    }

    function approve(address dst, uint amt) external override returns (bool) {
        _allowance[msg.sender][dst] = amt;
        emit Approval(msg.sender, dst, amt);
        return true;
    }

    function increaseApproval(address dst, uint amt) external returns (bool) {
        _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);
        emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);
        return true;
    }

    function decreaseApproval(address dst, uint amt) external returns (bool) {
        uint oldValue = _allowance[msg.sender][dst];
        if (amt > oldValue) {
            _allowance[msg.sender][dst] = 0;
        } else {
            _allowance[msg.sender][dst] = bsub(oldValue, amt);
        }
        emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);
        return true;
    }

    function transfer(address dst, uint amt) external override returns (bool) {
        _move(msg.sender, dst, amt);
        return true;
    }

    function transferFrom(address src, address dst, uint amt) external override returns (bool) {
        require(msg.sender == src || amt <= _allowance[src][msg.sender], "!spender");
        _move(src, dst, amt);
        if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) {
            _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);
            emit Approval(msg.sender, dst, _allowance[src][msg.sender]);
        }
        return true;
    }
}

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
contract BMathLite is BNum {
    /**********************************************************************************************
    // calcSpotPrice                                                                             //
    // sP = spotPrice                                                                            //
    // bI = tokenBalanceIn                ( bI / wI )         1                                  //
    // bO = tokenBalanceOut         sP =  -----------  *  ----------                             //
    // wI = tokenWeightIn                 ( bO / wO )     ( 1 - sF )                             //
    // wO = tokenWeightOut                                                                       //
    // sF = swapFee (+ collectedFee)                                                             //
    **********************************************************************************************/
    function calcSpotPrice(
        uint tokenBalanceIn,
        uint tokenWeightIn,
        uint tokenBalanceOut,
        uint tokenWeightOut,
        uint swapFee
    )
        public pure
        returns (uint spotPrice)
    {
        uint numer = bdiv(tokenBalanceIn, tokenWeightIn);
        uint denom = bdiv(tokenBalanceOut, tokenWeightOut);
        uint ratio = bdiv(numer, denom);
        uint scale = bdiv(BConst.BONE, bsub(BConst.BONE, swapFee));
        return  (spotPrice = bmul(ratio, scale));
    }

    /**********************************************************************************************
    // calcOutGivenIn                                                                            //
    // aO = tokenAmountOut                                                                       //
    // bO = tokenBalanceOut                                                                      //
    // bI = tokenBalanceIn              /      /            bI             \    (wI / wO) \      //
    // aI = tokenAmountIn    aO = bO * |  1 - | --------------------------  | ^            |     //
    // wI = tokenWeightIn               \      \ ( bI + ( aI * ( 1 - sF )) /              /      //
    // wO = tokenWeightOut                                                                       //
    // sF = swapFee (+ collectedFee)                                                             //
    **********************************************************************************************/
    function calcOutGivenIn(
        uint tokenBalanceIn,
        uint tokenWeightIn,
        uint tokenBalanceOut,
        uint tokenWeightOut,
        uint tokenAmountIn,
        uint swapFee
    )
        public pure
        returns (uint tokenAmountOut)
    {
        uint weightRatio = bdiv(tokenWeightIn, tokenWeightOut);
        uint adjustedIn = bsub(BConst.BONE, swapFee);
        adjustedIn = bmul(tokenAmountIn, adjustedIn);
        uint y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));
        uint foo = bpow(y, weightRatio);
        uint bar = bsub(BConst.BONE, foo);
        tokenAmountOut = bmul(tokenBalanceOut, bar);
        return tokenAmountOut;
    }

    /**********************************************************************************************
    // calcInGivenOut                                                                            //
    // aI = tokenAmountIn                                                                        //
    // bO = tokenBalanceOut               /  /     bO      \    (wO / wI)      \                 //
    // bI = tokenBalanceIn          bI * |  | ------------  | ^            - 1  |                //
    // aO = tokenAmountOut    aI =        \  \ ( bO - aO ) /                   /                 //
    // wI = tokenWeightIn           --------------------------------------------                 //
    // wO = tokenWeightOut                          ( 1 - sF )                                   //
    // sF = swapFee (+ collectedFee)                                                             //
    **********************************************************************************************/
    function calcInGivenOut(
        uint tokenBalanceIn,
        uint tokenWeightIn,
        uint tokenBalanceOut,
        uint tokenWeightOut,
        uint tokenAmountOut,
        uint swapFee
    )
        public pure
        returns (uint tokenAmountIn)
    {
        uint weightRatio = bdiv(tokenWeightOut, tokenWeightIn);
        uint diff = bsub(tokenBalanceOut, tokenAmountOut);
        uint y = bdiv(tokenBalanceOut, diff);
        uint foo = bpow(y, weightRatio);
        foo = bsub(foo, BConst.BONE);
        tokenAmountIn = bsub(BConst.BONE, swapFee);
        tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);
        return tokenAmountIn;
    }

    /**********************************************************************************************
    // calcPoolOutGivenSingleIn                                                                  //
    // pAo = poolAmountOut         /                                              \              //
    // tAi = tokenAmountIn        ///      /     //    wI \      \\       \     wI \             //
    // wI = tokenWeightIn        //| tAi *| 1 - || 1 - --  | * sF || + tBi \    --  \            //
    // tW = totalWeight     pAo=||  \      \     \\    tW /      //         | ^ tW   | * pS - pS //
    // tBi = tokenBalanceIn      \\  ------------------------------------- /        /            //
    // pS = poolSupply            \\                    tBi               /        /             //
    // sF = swapFee (+ collectedFee)\                                              /              //
    **********************************************************************************************/
    function calcPoolOutGivenSingleIn(
        uint tokenBalanceIn,
        uint tokenWeightIn,
        uint poolSupply,
        uint totalWeight,
        uint tokenAmountIn,
        uint swapFee
    )
        public pure
        returns (uint poolAmountOut)
    {
        // @dev Charge the trading fee for the proportion of tokenAi
        // which is implicitly traded to the other pool tokens.
        // That proportion is (1- weightTokenIn)
        // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);
        uint normalizedWeight = bdiv(tokenWeightIn, totalWeight);
        uint zaz = bmul(bsub(BConst.BONE, normalizedWeight), swapFee);
        uint tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BConst.BONE, zaz));

        uint newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);
        uint tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);

        // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;
        uint poolRatio = bpow(tokenInRatio, normalizedWeight);
        uint newPoolSupply = bmul(poolRatio, poolSupply);
        poolAmountOut = bsub(newPoolSupply, poolSupply);
        return poolAmountOut;
    }

    /**********************************************************************************************
    // calcSingleOutGivenPoolIn                                                                  //
    // tAo = tokenAmountOut            /      /                                             \\   //
    // bO = tokenBalanceOut           /      // pS - (pAi * (1 - eF)) \     /    1    \      \\  //
    // pAi = poolAmountIn            | bO - || ----------------------- | ^ | --------- | * b0 || //
    // ps = poolSupply                \      \\          pS           /     \(wO / tW)/      //  //
    // wI = tokenWeightIn      tAo =   \      \                                             //   //
    // tW = totalWeight                    /     /      wO \       \                             //
    // sF = swapFee (+ collectedFee)   *  | 1 - |  1 - ---- | * sF  |                            //
    // eF = exitFee                        \     \      tW /       /                             //
    **********************************************************************************************/
    function calcSingleOutGivenPoolIn(
        uint tokenBalanceOut,
        uint tokenWeightOut,
        uint poolSupply,
        uint totalWeight,
        uint poolAmountIn,
        uint swapFee,
        uint exitFee
    )
        public pure
        returns (uint tokenAmountOut)
    {
        uint normalizedWeight = bdiv(tokenWeightOut, totalWeight);
        // charge exit fee on the pool token side
        // pAiAfterExitFee = pAi*(1-exitFee)
        uint poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BConst.BONE, exitFee));
        uint newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);
        uint poolRatio = bdiv(newPoolSupply, poolSupply);
     
        // newBalTo = poolRatio^(1/weightTo) * balTo;
        uint tokenOutRatio = bpow(poolRatio, bdiv(BConst.BONE, normalizedWeight));
        uint newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);

        uint tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);

        // charge swap fee on the output token side 
        //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)
        uint zaz = bmul(bsub(BConst.BONE, normalizedWeight), swapFee);
        tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BConst.BONE, zaz));
        return tokenAmountOut;
    }


}

interface IBFactory {
    function collectedToken() external view returns (address);
}

contract BPoolLite is BToken, BMathLite {
    struct Record {
        bool bound;   // is token bound to pool
        uint index;   // private
        uint denorm;  // denormalized weight
        uint balance;
    }

    event LOG_SWAP(
        address indexed caller,
        address indexed tokenIn,
        address indexed tokenOut,
        uint256 tokenAmountIn,
        uint256 tokenAmountOut
    );

    event LOG_JOIN(
        address indexed caller,
        address indexed tokenIn,
        uint256 tokenAmountIn
    );

    event LOG_EXIT(
        address indexed caller,
        address indexed tokenOut,
        uint256 tokenAmountOut
    );

    event LOG_COLLECTED_FUND(
        address indexed collectedToken,
        uint256 collectedAmount
    );

    event LOG_FINALIZE(
        uint swapFee,
        uint initPoolSupply,
        uint version,
        address[] bindTokens,
        uint[] bindDenorms,
        uint[] balances
    );

    modifier _lock_() {
        require(!_mutex, "reentry");
        _mutex = true;
        _;
        _mutex = false;
    }

    modifier _viewlock_() {
        require(!_mutex, "reentry");
        _;
    }

    bool private _mutex;

    uint public version = 2001;
    address public factory;    // BFactory address to push token exitFee to
    address public controller; // has CONTROL role

    // `setSwapFee` and `finalize` require CONTROL
    // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`
    uint public swapFee;
    uint public collectedFee; // 0.05% | https://yfv.finance/vip-vote/vip_5
    uint public exitFee;
    bool public finalized;

    address[] internal _tokens;
    mapping(address => Record) internal _records;
    uint private _totalWeight;

    constructor(address _factory) public {
        controller = _factory;
        factory = _factory;
        swapFee = BConst.DEFAULT_FEE;
        collectedFee = BConst.DEFAULT_COLLECTED_FEE;
        exitFee = BConst.DEFAULT_EXIT_FEE;
        finalized = false;
    }

    function setCollectedFee(uint _collectedFee) public {
        require(msg.sender == factory, "!fctr");
        require(_collectedFee <= BConst.MAX_COLLECTED_FEE, ">maxCoFee");
        require(bmul(_collectedFee, 2) <= swapFee, ">sFee/2");
        collectedFee = _collectedFee;
    }

    function setExitFee(uint _exitFee) public {
        require(!finalized, "fnl");
        require(msg.sender == factory, "!fctr");
        require(_exitFee <= BConst.MAX_EXIT_FEE, ">maxExitFee");
        exitFee = _exitFee;
    }

    function isBound(address t)
    external view
    returns (bool)
    {
        return _records[t].bound;
    }

    function getNumTokens()
    external view
    returns (uint)
    {
        return _tokens.length;
    }

    function getCurrentTokens()
    external view _viewlock_
    returns (address[] memory tokens)
    {
        return _tokens;
    }

    function getFinalTokens()
    external view
    _viewlock_
    returns (address[] memory tokens)
    {
        require(finalized, "!fnl");
        return _tokens;
    }

    function getDenormalizedWeight(address token)
    external view
    _viewlock_
    returns (uint)
    {

        require(_records[token].bound, "!bound");
        return _records[token].denorm;
    }

    function getTotalDenormalizedWeight()
    external view
    _viewlock_
    returns (uint)
    {
        return _totalWeight;
    }

    function getNormalizedWeight(address token)
    external view
    _viewlock_
    returns (uint)
    {

        require(_records[token].bound, "!bound");
        uint denorm = _records[token].denorm;
        return bdiv(denorm, _totalWeight);
    }

    function getBalance(address token)
    external view
    _viewlock_
    returns (uint)
    {

        require(_records[token].bound, "!bound");
        return _records[token].balance;
    }

    function setController(address _controller)
    external
    _lock_
    {
        require(msg.sender == controller, "!cntler");
        controller = _controller;
    }

    function finalize(
        uint _swapFee,
        uint _initPoolSupply,
        address[] calldata _bindTokens,
        uint[] calldata _bindDenorms
    ) external _lock_ {
        require(msg.sender == controller, "!cntler");
        require(!finalized, "fnl");

        require(_swapFee >= BConst.MIN_FEE, "<minFee");
        require(_swapFee <= BConst.MAX_FEE, ">maxFee");
        swapFee = _swapFee;
        collectedFee = _swapFee / 3;

        require(_initPoolSupply >= BConst.MIN_INIT_POOL_SUPPLY, "<minInitPSup");
        require(_initPoolSupply <= BConst.MAX_INIT_POOL_SUPPLY, ">maxInitPSup");

        require(_bindTokens.length >= BConst.MIN_BOUND_TOKENS, "<minTokens");
        require(_bindTokens.length < BConst.MAX_BOUND_TOKENS, ">maxTokens");
        require(_bindTokens.length == _bindDenorms.length, "erLengMism");

        uint totalWeight = 0;
        uint256[] memory balances = new uint[](_bindTokens.length);
        for (uint i = 0; i < _bindTokens.length; i++) {
            address token = _bindTokens[i];
            uint denorm = _bindDenorms[i];
            uint balance = BToken(token).balanceOf(address(this));
            balances[i] = balance;
            require(!_records[token].bound, "bound");
            require(denorm >= BConst.MIN_WEIGHT, "<minWeight");
            require(denorm <= BConst.MAX_WEIGHT, ">maxWeight");
            require(balance >= BConst.MIN_BALANCE, "<minBal");
            _records[token] = Record({
                bound : true,
                index : i,
                denorm : denorm,
                balance : balance
                });
            totalWeight = badd(totalWeight, denorm);
        }
        require(totalWeight <= BConst.MAX_TOTAL_WEIGHT, ">maxTWeight");
        _totalWeight = totalWeight;
        _tokens = _bindTokens;
        finalized = true;
        _mintPoolShare(_initPoolSupply);
        _pushPoolShare(msg.sender, _initPoolSupply);
        emit LOG_FINALIZE(swapFee, _initPoolSupply, version, _bindTokens, _bindDenorms, balances);
    }

    // Absorb any tokens that have been sent to this contract into the pool
    function gulp(address token)
    external
    _lock_
    {
        require(_records[token].bound, "!bound");
        _records[token].balance = IERC20(token).balanceOf(address(this));
    }

    function getSpotPrice(address tokenIn, address tokenOut)
    external view
    _viewlock_
    returns (uint spotPrice)
    {
        require(_records[tokenIn].bound, "!bound");
        require(_records[tokenOut].bound, "!bound");
        Record storage inRecord = _records[tokenIn];
        Record storage outRecord = _records[tokenOut];
        return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, swapFee);
    }

    function getSpotPriceSansFee(address tokenIn, address tokenOut)
    external view
    _viewlock_
    returns (uint spotPrice)
    {
        require(_records[tokenIn].bound, "!bound");
        require(_records[tokenOut].bound, "!bound");
        Record storage inRecord = _records[tokenIn];
        Record storage outRecord = _records[tokenOut];
        return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, 0);
    }

    function joinPool(uint poolAmountOut, uint[] calldata maxAmountsIn)
    external virtual
    _lock_
    {
        require(finalized, "!fnl");

        uint poolTotal = totalSupply();
        uint ratio = bdiv(poolAmountOut, poolTotal);
        require(ratio != 0, "erMApr");

        for (uint i = 0; i < _tokens.length; i++) {
            address t = _tokens[i];
            uint bal = _records[t].balance;
            uint tokenAmountIn = bmul(ratio, bal);
            require(tokenAmountIn != 0, "erMApr");
            require(tokenAmountIn <= maxAmountsIn[i], "<limIn");
            _records[t].balance = badd(_records[t].balance, tokenAmountIn);
            emit LOG_JOIN(msg.sender, t, tokenAmountIn);
            _pullUnderlying(t, msg.sender, tokenAmountIn);
        }
        _mintPoolShare(poolAmountOut);
        _pushPoolShare(msg.sender, poolAmountOut);
    }

    function exitPool(uint poolAmountIn, uint[] calldata minAmountsOut)
    external virtual
    _lock_
    {
        require(finalized, "!fnl");

        uint poolTotal = totalSupply();
        uint _exitFee = bmul(poolAmountIn, exitFee);
        uint pAiAfterExitFee = bsub(poolAmountIn, _exitFee);
        uint ratio = bdiv(pAiAfterExitFee, poolTotal);
        require(ratio != 0, "erMApr");

        _pullPoolShare(msg.sender, poolAmountIn);
        if (_exitFee > 0) {
            _pushPoolShare(factory, _exitFee);
        }
        _burnPoolShare(pAiAfterExitFee);

        for (uint i = 0; i < _tokens.length; i++) {
            address t = _tokens[i];
            uint bal = _records[t].balance;
            uint tokenAmountOut = bmul(ratio, bal);
            require(tokenAmountOut != 0, "erMApr");
            require(tokenAmountOut >= minAmountsOut[i], "<limO");
            _records[t].balance = bsub(_records[t].balance, tokenAmountOut);
            emit LOG_EXIT(msg.sender, t, tokenAmountOut);
            _pushUnderlying(t, msg.sender, tokenAmountOut);
        }
    }

    function swapExactAmountIn(
        address tokenIn,
        uint tokenAmountIn,
        address tokenOut,
        uint minAmountOut,
        uint maxPrice
    )
    external
    _lock_
    returns (uint tokenAmountOut, uint spotPriceAfter)
    {

        require(_records[tokenIn].bound, "!bound");
        require(_records[tokenOut].bound, "!bound");

        Record storage inRecord = _records[address(tokenIn)];
        Record storage outRecord = _records[address(tokenOut)];

        require(tokenAmountIn <= bmul(inRecord.balance, BConst.MAX_IN_RATIO), ">maxIRat");

        uint spotPriceBefore = calcSpotPrice(
            inRecord.balance,
            inRecord.denorm,
            outRecord.balance,
            outRecord.denorm,
            swapFee
        );
        require(spotPriceBefore <= maxPrice, "badLimPrice");

        tokenAmountOut = calcOutGivenIn(
            inRecord.balance,
            inRecord.denorm,
            outRecord.balance,
            outRecord.denorm,
            tokenAmountIn,
            swapFee
        );
        require(tokenAmountOut >= minAmountOut, "<limO");

        inRecord.balance = badd(inRecord.balance, tokenAmountIn);
        outRecord.balance = bsub(outRecord.balance, tokenAmountOut);

        spotPriceAfter = calcSpotPrice(
            inRecord.balance,
            inRecord.denorm,
            outRecord.balance,
            outRecord.denorm,
            swapFee
        );
        require(spotPriceAfter >= spotPriceBefore, "erMApr");
        require(spotPriceAfter <= maxPrice, ">limPrice");
        require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), "erMApr");

        emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);

        _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);
        uint _subTokenAmountIn;
        (_subTokenAmountIn, tokenAmountOut) = _pushCollectedFundGivenOut(tokenIn, tokenAmountIn, tokenOut, tokenAmountOut);
        if (_subTokenAmountIn > 0) inRecord.balance = bsub(inRecord.balance, _subTokenAmountIn);
        _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);

        return (tokenAmountOut, spotPriceAfter);
    }

    function swapExactAmountOut(
        address tokenIn,
        uint maxAmountIn,
        address tokenOut,
        uint tokenAmountOut,
        uint maxPrice
    )
    external
    _lock_
    returns (uint tokenAmountIn, uint spotPriceAfter)
    {
        require(_records[tokenIn].bound, "!bound");
        require(_records[tokenOut].bound, "!bound");

        Record storage inRecord = _records[address(tokenIn)];
        Record storage outRecord = _records[address(tokenOut)];

        require(tokenAmountOut <= bmul(outRecord.balance, BConst.MAX_OUT_RATIO), ">maxORat");

        uint spotPriceBefore = calcSpotPrice(
            inRecord.balance,
            inRecord.denorm,
            outRecord.balance,
            outRecord.denorm,
            swapFee
        );
        require(spotPriceBefore <= maxPrice, "badLimPrice");

        tokenAmountIn = calcInGivenOut(
            inRecord.balance,
            inRecord.denorm,
            outRecord.balance,
            outRecord.denorm,
            tokenAmountOut,
            swapFee
        );
        require(tokenAmountIn <= maxAmountIn, "<limIn");

        inRecord.balance = badd(inRecord.balance, tokenAmountIn);
        outRecord.balance = bsub(outRecord.balance, tokenAmountOut);

        spotPriceAfter = calcSpotPrice(
            inRecord.balance,
            inRecord.denorm,
            outRecord.balance,
            outRecord.denorm,
            swapFee
        );
        require(spotPriceAfter >= spotPriceBefore, "erMApr");
        require(spotPriceAfter <= maxPrice, ">limPrice");
        require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), "erMApr");

        emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);

        _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);
        _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);
        uint _collectedFeeAmount = _pushCollectedFundGivenIn(tokenIn, tokenAmountIn);
        if (_collectedFeeAmount > 0) inRecord.balance = bsub(inRecord.balance, _collectedFeeAmount);

        return (tokenAmountIn, spotPriceAfter);
    }

    function joinswapExternAmountIn(address tokenIn, uint tokenAmountIn, uint minPoolAmountOut)
    external
    _lock_
    returns (uint poolAmountOut)

    {
        require(finalized, "!fnl");
        require(_records[tokenIn].bound, "!bound");
        require(tokenAmountIn <= bmul(_records[tokenIn].balance, BConst.MAX_IN_RATIO), ">maxIRat");

        Record storage inRecord = _records[tokenIn];

        poolAmountOut = calcPoolOutGivenSingleIn(
            inRecord.balance,
            inRecord.denorm,
            _totalSupply,
            _totalWeight,
            tokenAmountIn,
            swapFee
        );

        require(poolAmountOut >= minPoolAmountOut, "<limO");

        inRecord.balance = badd(inRecord.balance, tokenAmountIn);

        emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);

        _mintPoolShare(poolAmountOut);
        _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);
        uint _subTokenAmountIn;
        (_subTokenAmountIn, poolAmountOut) = _pushCollectedFundGivenOut(tokenIn, tokenAmountIn, address(this), poolAmountOut);
        if (_subTokenAmountIn > 0) inRecord.balance = bsub(inRecord.balance, _subTokenAmountIn);
        _pushPoolShare(msg.sender, poolAmountOut);

        return poolAmountOut;
    }

    function exitswapPoolAmountIn(address tokenOut, uint poolAmountIn, uint minAmountOut)
    external
    _lock_
    returns (uint tokenAmountOut)
    {
        require(finalized, "!fnl");
        require(_records[tokenOut].bound, "!bound");

        Record storage outRecord = _records[tokenOut];

        tokenAmountOut = calcSingleOutGivenPoolIn(
            outRecord.balance,
            outRecord.denorm,
            _totalSupply,
            _totalWeight,
            poolAmountIn,
            swapFee,
            exitFee
        );

        require(tokenAmountOut >= minAmountOut, "<limO");

        require(tokenAmountOut <= bmul(_records[tokenOut].balance, BConst.MAX_OUT_RATIO), ">maxORat");

        outRecord.balance = bsub(outRecord.balance, tokenAmountOut);

        uint _exitFee = bmul(poolAmountIn, exitFee);

        emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);

        _pullPoolShare(msg.sender, poolAmountIn);
        _burnPoolShare(bsub(poolAmountIn, _exitFee));
        if (_exitFee > 0) {
            _pushPoolShare(factory, _exitFee);
        }
        (, tokenAmountOut) = _pushCollectedFundGivenOut(address(this), poolAmountIn, tokenOut, tokenAmountOut);
        _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);

        return tokenAmountOut;
    }

    // ==
    // 'Underlying' token-manipulation functions make external calls but are NOT locked
    // You must `_lock_` or otherwise ensure reentry-safety
    //
    // Fixed ERC-20 transfer revert for some special token such as USDT
    function _pullUnderlying(address erc20, address from, uint amount) internal {
        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
        (bool success, bytes memory data) = erc20.call(abi.encodeWithSelector(0x23b872dd, from, address(this), amount));
        require(success && (data.length == 0 || abi.decode(data, (bool))), '!_pullU');
    }

    function _pushUnderlying(address erc20, address to, uint amount) internal
    {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = erc20.call(abi.encodeWithSelector(0xa9059cbb, to, amount));
        require(success && (data.length == 0 || abi.decode(data, (bool))), '!_pushU');
    }

    function _pullPoolShare(address from, uint amount)
    internal
    {
        _pull(from, amount);
    }

    function _pushPoolShare(address to, uint amount)
    internal
    {
        _push(to, amount);
    }

    function _mintPoolShare(uint amount)
    internal
    {
        _mint(amount);
    }

    function _burnPoolShare(uint amount)
    internal
    {
        _burn(amount);
    }

    function _pushCollectedFundGivenOut(address _tokenIn, uint _tokenAmountIn, address _tokenOut, uint _tokenAmountOut) internal returns (uint subTokenAmountIn, uint tokenAmountOut) {
        subTokenAmountIn = 0;
        tokenAmountOut = _tokenAmountOut;
        if (collectedFee > 0) {
            address _collectedToken = IBFactory(factory).collectedToken();
            if (_collectedToken == _tokenIn) {
                subTokenAmountIn = bdiv(bmul(_tokenAmountIn, collectedFee), BConst.BONE);
                _pushUnderlying(_tokenIn, factory, subTokenAmountIn);
                emit LOG_COLLECTED_FUND(_tokenIn, subTokenAmountIn);
            } else {
                uint _collectedFeeAmount = bdiv(bmul(_tokenAmountOut, collectedFee), BConst.BONE);
                _pushUnderlying(_tokenOut, factory, _collectedFeeAmount);
                tokenAmountOut = bsub(_tokenAmountOut, _collectedFeeAmount);
                emit LOG_COLLECTED_FUND(_tokenOut, _collectedFeeAmount);
            }
        }
    }

    // always push out _tokenIn (already have)
    function _pushCollectedFundGivenIn(address _tokenIn, uint _tokenAmountIn) internal returns (uint collectedFeeAmount) {
        collectedFeeAmount = 0;
        if (collectedFee > 0) {
            address _collectedToken = IBFactory(factory).collectedToken();
            if (_collectedToken != address(0)) {
                collectedFeeAmount = bdiv(bmul(_tokenAmountIn, collectedFee), BConst.BONE);
                _pushUnderlying(_tokenIn, factory, collectedFeeAmount);
                emit LOG_COLLECTED_FUND(_tokenIn, collectedFeeAmount);
            }
        }
    }
}

interface IFaaSPool {
    function stake(uint) external;
    function withdraw(uint) external;
    function getReward(uint8 _pid, address _account) external;
    function getAllRewards(address _account) external;
    function pendingReward(uint8 _pid, address _account) external view returns (uint);
    function emergencyWithdraw() external;
}

interface IFaaSRewardFund {
    function balance(IERC20 _token) external view returns (uint);
    function safeTransfer(IERC20 _token, address _to, uint _value) external;
}

// This implements BPool contract, and allows for generalized staking, yield farming, and token distribution.
contract FaaSPoolLite is BPoolLite, IFaaSPool {
    using SafeMath for uint;

    // Info of each user.
    struct UserInfo {
        uint amount;
        mapping(uint8 => uint) rewardDebt;
        mapping(uint8 => uint) accumulatedEarned; // will accumulate every time user harvest
        mapping(uint8 => uint) lockReward;
        mapping(uint8 => uint) lockRewardReleased;
        uint lastStakeTime;
    }

    // Info of each rewardPool funding.
    struct RewardPoolInfo {
        IERC20 rewardToken;     // Address of rewardPool token contract.
        uint lastRewardBlock;   // Last block number that rewardPool distribution occurs.
        uint endRewardBlock;    // Block number which rewardPool distribution ends.
        uint rewardPerBlock;    // Reward token amount to distribute per block.
        uint accRewardPerShare; // Accumulated rewardPool per share, times 1e18.

        uint lockRewardPercent; // Lock reward percent - 0 to disable lock & vesting
        uint startVestingBlock; // Block number which vesting starts.
        uint endVestingBlock;   // Block number which vesting ends.
        uint numOfVestingBlocks;

        uint totalPaidRewards;
    }

    mapping(address => UserInfo) private userInfo;
    RewardPoolInfo[] public rewardPoolInfo;

    IFaaSRewardFund public rewardFund;
    address public exchangeProxy;
    uint public unstakingFrozenTime = 0 days;

    event Deposit(address indexed account, uint256 amount);
    event Withdraw(address indexed account, uint256 amount);
    event RewardPaid(uint8 pid, address indexed account, uint256 amount);

    constructor(address _factory) public BPoolLite(_factory) {
    }

    modifier onlyController() {
        require(msg.sender == controller, "!cntler");
        _;
    }

    function finalizeRewardFundInfo(IFaaSRewardFund _rewardFund, uint _unstakingFrozenTime) external onlyController {
        require(address(rewardFund) == address(0), "rewardFund!=null");
        assert(unstakingFrozenTime <= 30 days);
        // do not lock fund for too long, please!
        unstakingFrozenTime = _unstakingFrozenTime;
        rewardFund = _rewardFund;
    }

    function setExchangeProxy(address _exchangeProxy) public onlyController {
        exchangeProxy = _exchangeProxy;
    }

    function addRewardPool(IERC20 _rewardToken, uint256 _startBlock, uint256 _endRewardBlock, uint256 _rewardPerBlock,
        uint256 _lockRewardPercent, uint256 _startVestingBlock, uint256 _endVestingBlock) external onlyController {
        require(rewardPoolInfo.length < 8, "exceed rwdPoolLim");
        require(_startVestingBlock <= _endVestingBlock, "sVB>eVB");
        _startBlock = (block.number > _startBlock) ? block.number : _startBlock;
        require(_startBlock < _endRewardBlock, "sB>=eB");
        updateReward();
        rewardPoolInfo.push(RewardPoolInfo({
            rewardToken : _rewardToken,
            lastRewardBlock : _startBlock,
            endRewardBlock : _endRewardBlock,
            rewardPerBlock : _rewardPerBlock,
            accRewardPerShare : 0,
            lockRewardPercent : _lockRewardPercent,
            startVestingBlock : _startVestingBlock,
            endVestingBlock : _endVestingBlock,
            numOfVestingBlocks: _endVestingBlock - _startVestingBlock,
            totalPaidRewards: 0
            }));
    }

    function updateRewardPool(uint8 _pid, uint256 _endRewardBlock, uint256 _rewardPerBlock) public onlyController {
        updateReward(_pid);
        RewardPoolInfo storage rewardPool = rewardPoolInfo[_pid];
        require(block.number <= rewardPool.endRewardBlock, "late");
        rewardPool.endRewardBlock = _endRewardBlock;
        rewardPool.rewardPerBlock = _rewardPerBlock;
    }

    function joinPool(uint poolAmountOut, uint[] calldata maxAmountsIn) external override {
        joinPoolFor(msg.sender, poolAmountOut, maxAmountsIn);
    }

    function joinPoolFor(address account, uint poolAmountOut, uint[] calldata maxAmountsIn) public _lock_ {
        require(msg.sender == account || msg.sender == exchangeProxy, "!(prx||own)");
        _joinPool(account, poolAmountOut, maxAmountsIn);
        _stakePoolShare(account, poolAmountOut);
    }

    function joinPoolNotStake(uint poolAmountOut, uint[] calldata maxAmountsIn) external _lock_ {
        _joinPool(msg.sender, poolAmountOut, maxAmountsIn);
        _pushPoolShare(msg.sender, poolAmountOut);
    }

    function _joinPool(address account, uint poolAmountOut, uint[] calldata maxAmountsIn) internal {
        require(finalized, "!fnl");

        uint rewardTotal = totalSupply();
        uint ratio = bdiv(poolAmountOut, rewardTotal);
        require(ratio != 0, "erMApr");

        for (uint i = 0; i < _tokens.length; i++) {
            address t = _tokens[i];
            uint bal = _records[t].balance;
            uint tokenAmountIn = bmul(ratio, bal);
            require(tokenAmountIn != 0 && tokenAmountIn <= maxAmountsIn[i], "erMApr||<limIn");
            _records[t].balance = badd(_records[t].balance, tokenAmountIn);
            emit LOG_JOIN(account, t, tokenAmountIn);
            _pullUnderlying(t, msg.sender, tokenAmountIn);
        }
        _mintPoolShare(poolAmountOut);
    }

    function stake(uint _shares) external override {
        uint _before = balanceOf(address(this));
        _pullPoolShare(msg.sender, _shares);
        uint _after = balanceOf(address(this));
        _shares = bsub(_after, _before); // Additional check for deflationary tokens
        _stakePoolShare(msg.sender, _shares);
    }

    function _stakePoolShare(address _account, uint _shares) internal {
        UserInfo storage user = userInfo[_account];
        getAllRewards(_account);
        user.amount = user.amount.add(_shares);
        uint8 rewardPoolLength = uint8(rewardPoolInfo.length);
        for (uint8 _pid = 0; _pid < rewardPoolLength; ++_pid) {
            user.rewardDebt[_pid] = user.amount.mul(rewardPoolInfo[_pid].accRewardPerShare).div(1e18);
        }
        user.lastStakeTime = block.timestamp;
        emit Deposit(_account, _shares);
    }

    function unfrozenStakeTime(address _account) public view returns (uint) {
        return userInfo[_account].lastStakeTime + unstakingFrozenTime;
    }

    function withdraw(uint _amount) public override {
        UserInfo storage user = userInfo[msg.sender];
        require(user.amount >= _amount, "am>us.am");
        require(block.timestamp >= user.lastStakeTime.add(unstakingFrozenTime), "frozen");
        getAllRewards(msg.sender);
        user.amount = bsub(user.amount, _amount);
        uint8 rewardPoolLength = uint8(rewardPoolInfo.length);
        for (uint8 _pid = 0; _pid < rewardPoolLength; ++_pid) {
            user.rewardDebt[_pid] = user.amount.mul(rewardPoolInfo[_pid].accRewardPerShare).div(1e18);
        }
        _pushPoolShare(msg.sender, _amount);
        emit Withdraw(msg.sender, _amount);
    }

    // using PUSH pattern for using by Proxy if needed
    function getAllRewards(address _account) public override {
        uint8 rewardPoolLength = uint8(rewardPoolInfo.length);
        for (uint8 _pid = 0; _pid < rewardPoolLength; ++_pid) {
            getReward(_pid, _account);
        }
    }

    function getReward(uint8 _pid, address _account) public override {
        updateReward(_pid);
        UserInfo storage user = userInfo[_account];
        RewardPoolInfo storage rewardPool = rewardPoolInfo[_pid];
        uint _pendingReward = user.amount.mul(rewardPool.accRewardPerShare).div(1e18).sub(user.rewardDebt[_pid]);
        uint _lockRewardPercent = rewardPool.lockRewardPercent;
        if (_lockRewardPercent > 0) {
            if (block.number > rewardPool.endVestingBlock) {
                uint _unlockReward = user.lockReward[_pid].sub(user.lockRewardReleased[_pid]);
                if (_unlockReward > 0) {
                    _pendingReward = _pendingReward.add(_unlockReward);
                    user.lockRewardReleased[_pid] = user.lockRewardReleased[_pid].add(_unlockReward);
                }
            } else {
                if (_pendingReward > 0) {
                    uint _toLocked = _pendingReward.mul(_lockRewardPercent).div(100);
                    _pendingReward = _pendingReward.sub(_toLocked);
                    user.lockReward[_pid] = user.lockReward[_pid].add(_toLocked);
                }
                if (block.number > rewardPool.startVestingBlock) {
                    uint _toReleased = user.lockReward[_pid].mul(block.number.sub(rewardPool.startVestingBlock)).div(rewardPool.numOfVestingBlocks);
                    uint _lockRewardReleased = user.lockRewardReleased[_pid];
                    if (_toReleased > _lockRewardReleased) {
                        uint _unlockReward = _toReleased.sub(_lockRewardReleased);
                        user.lockRewardReleased[_pid] = _lockRewardReleased.add(_unlockReward);
                        _pendingReward = _pendingReward.add(_unlockReward);
                    }
                }
            }
        }
        if (_pendingReward > 0) {
            user.accumulatedEarned[_pid] = user.accumulatedEarned[_pid].add(_pendingReward);
            rewardPool.totalPaidRewards = rewardPool.totalPaidRewards.add(_pendingReward);
            rewardFund.safeTransfer(rewardPool.rewardToken, _account, _pendingReward);
            emit RewardPaid(_pid, _account, _pendingReward);
            user.rewardDebt[_pid] = user.amount.mul(rewardPoolInfo[_pid].accRewardPerShare).div(1e18);
        }
    }

    function pendingReward(uint8 _pid, address _account) public override view returns (uint _pending) {
        UserInfo storage user = userInfo[_account];
        RewardPoolInfo storage rewardPool = rewardPoolInfo[_pid];
        uint _accRewardPerShare = rewardPool.accRewardPerShare;
        uint lpSupply = balanceOf(address(this));
        uint _endRewardBlockApplicable = block.number > rewardPool.endRewardBlock ? rewardPool.endRewardBlock : block.number;
        if (_endRewardBlockApplicable > rewardPool.lastRewardBlock && lpSupply != 0) {
            uint _numBlocks = _endRewardBlockApplicable.sub(rewardPool.lastRewardBlock);
            uint _incRewardPerShare = _numBlocks.mul(rewardPool.rewardPerBlock).mul(1e18).div(lpSupply);
            _accRewardPerShare = _accRewardPerShare.add(_incRewardPerShare);
        }
        _pending = user.amount.mul(_accRewardPerShare).div(1e18).sub(user.rewardDebt[_pid]);
    }

    // Withdraw without caring about rewards. EMERGENCY ONLY.
    function emergencyWithdraw() external override {
        UserInfo storage user = userInfo[msg.sender];
        uint _amount = user.amount;
        _pushPoolShare(msg.sender, _amount);
        user.amount = 0;
        uint8 rewardPoolLength = uint8(rewardPoolInfo.length);
        for (uint8 _pid = 0; _pid < rewardPoolLength; ++_pid) {
            user.rewardDebt[_pid] = 0;
        }
        emit Withdraw(msg.sender, _amount);
    }

    function getUserInfo(uint8 _pid, address _account) public view returns (uint amount, uint rewardDebt, uint accumulatedEarned, uint lockReward, uint lockRewardReleased) {
        UserInfo storage user = userInfo[_account];
        amount = user.amount;
        rewardDebt = user.rewardDebt[_pid];
        accumulatedEarned = user.accumulatedEarned[_pid];
        lockReward = user.lockReward[_pid];
        lockRewardReleased = user.lockRewardReleased[_pid];
    }

    function exitPool(uint poolAmountIn, uint[] calldata minAmountsOut) external override _lock_ {
        require(finalized, "!fnl");

        uint rewardTotal = totalSupply();
        uint _exitFee = bmul(poolAmountIn, exitFee);
        uint pAiAfterExitFee = bsub(poolAmountIn, _exitFee);
        uint ratio = bdiv(pAiAfterExitFee, rewardTotal);
        require(ratio != 0, "erMApr");

        uint _externalShares = balanceOf(msg.sender);
        if (_externalShares < poolAmountIn) {
            uint _withdrawShares = bsub(poolAmountIn, _externalShares);
            uint _stakedShares = userInfo[msg.sender].amount;
            require(_stakedShares >= _withdrawShares, "stk<wdr");
            withdraw(_withdrawShares);
        }

        _pullPoolShare(msg.sender, poolAmountIn);
        if (_exitFee > 0) {
            _pushPoolShare(factory, _exitFee);
        }
        _burnPoolShare(pAiAfterExitFee);

        for (uint i = 0; i < _tokens.length; i++) {
            address t = _tokens[i];
            uint bal = _records[t].balance;
            uint tokenAmountOut = bmul(ratio, bal);
            require(tokenAmountOut != 0, "erMApr");
            require(tokenAmountOut >= minAmountsOut[i], "<limO");
            _records[t].balance = bsub(_records[t].balance, tokenAmountOut);
            emit LOG_EXIT(msg.sender, t, tokenAmountOut);
            _pushUnderlying(t, msg.sender, tokenAmountOut);
        }
    }

    function updateReward() public {
        uint8 rewardPoolLength = uint8(rewardPoolInfo.length);
        for (uint8 _pid = 0; _pid < rewardPoolLength; ++_pid) {
            updateReward(_pid);
        }
    }

    function updateReward(uint8 _pid) public {
        RewardPoolInfo storage rewardPool = rewardPoolInfo[_pid];
        uint _endRewardBlockApplicable = block.number > rewardPool.endRewardBlock ? rewardPool.endRewardBlock : block.number;
        if (_endRewardBlockApplicable > rewardPool.lastRewardBlock) {
            uint lpSupply = balanceOf(address(this));
            if (lpSupply > 0) {
                uint _numBlocks = _endRewardBlockApplicable.sub(rewardPool.lastRewardBlock);
                uint _incRewardPerShare = _numBlocks.mul(rewardPool.rewardPerBlock).mul(1e18).div(lpSupply);
                rewardPool.accRewardPerShare = rewardPool.accRewardPerShare.add(_incRewardPerShare);
            }
            rewardPool.lastRewardBlock = _endRewardBlockApplicable;
        }
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_factory","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":true,"internalType":"address","name":"dst","type":"address"},{"indexed":false,"internalType":"uint256","name":"amt","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collectedToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"collectedAmount","type":"uint256"}],"name":"LOG_COLLECTED_FUND","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmountOut","type":"uint256"}],"name":"LOG_EXIT","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"swapFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"initPoolSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"version","type":"uint256"},{"indexed":false,"internalType":"address[]","name":"bindTokens","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"bindDenorms","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"name":"LOG_FINALIZE","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmountIn","type":"uint256"}],"name":"LOG_JOIN","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":true,"internalType":"address","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenAmountOut","type":"uint256"}],"name":"LOG_SWAP","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"pid","type":"uint8"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":true,"internalType":"address","name":"dst","type":"address"},{"indexed":false,"internalType":"uint256","name":"amt","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"contract IERC20","name":"_rewardToken","type":"address"},{"internalType":"uint256","name":"_startBlock","type":"uint256"},{"internalType":"uint256","name":"_endRewardBlock","type":"uint256"},{"internalType":"uint256","name":"_rewardPerBlock","type":"uint256"},{"internalType":"uint256","name":"_lockRewardPercent","type":"uint256"},{"internalType":"uint256","name":"_startVestingBlock","type":"uint256"},{"internalType":"uint256","name":"_endVestingBlock","type":"uint256"}],"name":"addRewardPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"whom","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenBalanceIn","type":"uint256"},{"internalType":"uint256","name":"tokenWeightIn","type":"uint256"},{"internalType":"uint256","name":"tokenBalanceOut","type":"uint256"},{"internalType":"uint256","name":"tokenWeightOut","type":"uint256"},{"internalType":"uint256","name":"tokenAmountOut","type":"uint256"},{"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"calcInGivenOut","outputs":[{"internalType":"uint256","name":"tokenAmountIn","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenBalanceIn","type":"uint256"},{"internalType":"uint256","name":"tokenWeightIn","type":"uint256"},{"internalType":"uint256","name":"tokenBalanceOut","type":"uint256"},{"internalType":"uint256","name":"tokenWeightOut","type":"uint256"},{"internalType":"uint256","name":"tokenAmountIn","type":"uint256"},{"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"calcOutGivenIn","outputs":[{"internalType":"uint256","name":"tokenAmountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenBalanceIn","type":"uint256"},{"internalType":"uint256","name":"tokenWeightIn","type":"uint256"},{"internalType":"uint256","name":"poolSupply","type":"uint256"},{"internalType":"uint256","name":"totalWeight","type":"uint256"},{"internalType":"uint256","name":"tokenAmountIn","type":"uint256"},{"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"calcPoolOutGivenSingleIn","outputs":[{"internalType":"uint256","name":"poolAmountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenBalanceOut","type":"uint256"},{"internalType":"uint256","name":"tokenWeightOut","type":"uint256"},{"internalType":"uint256","name":"poolSupply","type":"uint256"},{"internalType":"uint256","name":"totalWeight","type":"uint256"},{"internalType":"uint256","name":"poolAmountIn","type":"uint256"},{"internalType":"uint256","name":"swapFee","type":"uint256"},{"internalType":"uint256","name":"exitFee","type":"uint256"}],"name":"calcSingleOutGivenPoolIn","outputs":[{"internalType":"uint256","name":"tokenAmountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenBalanceIn","type":"uint256"},{"internalType":"uint256","name":"tokenWeightIn","type":"uint256"},{"internalType":"uint256","name":"tokenBalanceOut","type":"uint256"},{"internalType":"uint256","name":"tokenWeightOut","type":"uint256"},{"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"calcSpotPrice","outputs":[{"internalType":"uint256","name":"spotPrice","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"collectedFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"decreaseApproval","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"exchangeProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exitFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"poolAmountIn","type":"uint256"},{"internalType":"uint256[]","name":"minAmountsOut","type":"uint256[]"}],"name":"exitPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"poolAmountIn","type":"uint256"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"}],"name":"exitswapPoolAmountIn","outputs":[{"internalType":"uint256","name":"tokenAmountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_swapFee","type":"uint256"},{"internalType":"uint256","name":"_initPoolSupply","type":"uint256"},{"internalType":"address[]","name":"_bindTokens","type":"address[]"},{"internalType":"uint256[]","name":"_bindDenorms","type":"uint256[]"}],"name":"finalize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IFaaSRewardFund","name":"_rewardFund","type":"address"},{"internalType":"uint256","name":"_unstakingFrozenTime","type":"uint256"}],"name":"finalizeRewardFundInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finalized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getAllRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentTokens","outputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getDenormalizedWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFinalTokens","outputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getNormalizedWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"},{"internalType":"address","name":"_account","type":"address"}],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"}],"name":"getSpotPrice","outputs":[{"internalType":"uint256","name":"spotPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"}],"name":"getSpotPriceSansFee","outputs":[{"internalType":"uint256","name":"spotPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalDenormalizedWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"},{"internalType":"address","name":"_account","type":"address"}],"name":"getUserInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"},{"internalType":"uint256","name":"accumulatedEarned","type":"uint256"},{"internalType":"uint256","name":"lockReward","type":"uint256"},{"internalType":"uint256","name":"lockRewardReleased","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"gulp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"increaseApproval","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"t","type":"address"}],"name":"isBound","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"poolAmountOut","type":"uint256"},{"internalType":"uint256[]","name":"maxAmountsIn","type":"uint256[]"}],"name":"joinPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"poolAmountOut","type":"uint256"},{"internalType":"uint256[]","name":"maxAmountsIn","type":"uint256[]"}],"name":"joinPoolFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"poolAmountOut","type":"uint256"},{"internalType":"uint256[]","name":"maxAmountsIn","type":"uint256[]"}],"name":"joinPoolNotStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"tokenAmountIn","type":"uint256"},{"internalType":"uint256","name":"minPoolAmountOut","type":"uint256"}],"name":"joinswapExternAmountIn","outputs":[{"internalType":"uint256","name":"poolAmountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"},{"internalType":"address","name":"_account","type":"address"}],"name":"pendingReward","outputs":[{"internalType":"uint256","name":"_pending","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardFund","outputs":[{"internalType":"contract IFaaSRewardFund","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardPoolInfo","outputs":[{"internalType":"contract IERC20","name":"rewardToken","type":"address"},{"internalType":"uint256","name":"lastRewardBlock","type":"uint256"},{"internalType":"uint256","name":"endRewardBlock","type":"uint256"},{"internalType":"uint256","name":"rewardPerBlock","type":"uint256"},{"internalType":"uint256","name":"accRewardPerShare","type":"uint256"},{"internalType":"uint256","name":"lockRewardPercent","type":"uint256"},{"internalType":"uint256","name":"startVestingBlock","type":"uint256"},{"internalType":"uint256","name":"endVestingBlock","type":"uint256"},{"internalType":"uint256","name":"numOfVestingBlocks","type":"uint256"},{"internalType":"uint256","name":"totalPaidRewards","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_collectedFee","type":"uint256"}],"name":"setCollectedFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_exchangeProxy","type":"address"}],"name":"setExchangeProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_exitFee","type":"uint256"}],"name":"setExitFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"tokenAmountIn","type":"uint256"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"}],"name":"swapExactAmountIn","outputs":[{"internalType":"uint256","name":"tokenAmountOut","type":"uint256"},{"internalType":"uint256","name":"spotPriceAfter","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"maxAmountIn","type":"uint256"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"tokenAmountOut","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"}],"name":"swapExactAmountOut","outputs":[{"internalType":"uint256","name":"tokenAmountIn","type":"uint256"},{"internalType":"uint256","name":"spotPriceAfter","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"unfrozenStakeTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unstakingFrozenTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"}],"name":"updateReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_pid","type":"uint8"},{"internalType":"uint256","name":"_endRewardBlock","type":"uint256"},{"internalType":"uint256","name":"_rewardPerBlock","type":"uint256"}],"name":"updateRewardPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c0604052601860808190527f56616c7565204c69717569646974792050726f7669646572000000000000000060a090815262000040916003919062000110565b50604080518082019091526003808252620564c560ec1b60209092019182526200006d9160049162000110565b506005805460ff191660121790556107d160065560006014553480156200009357600080fd5b5060405162005e9338038062005e9383398181016040526020811015620000b957600080fd5b5051600880546001600160a01b039092166001600160a01b0319928316811790915560078054909216179055660aa87bee538000600955660bb9551fc24000600a556000600b55600c805460ff19169055620001ac565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200015357805160ff191683800117855562000183565b8280016001018555821562000183579182015b828111156200018357825182559160200191906001019062000166565b506200019192915062000195565b5090565b5b8082111562000191576000815560010162000196565b615cd780620001bc6000396000f3fe608060405234801561001057600080fd5b50600436106103d05760003560e01c80638656b653116101ff578063c7c30be11161011a578063e811f50a116100ad578063f77c47911161007c578063f77c479114610ee1578063f863b96114610ee9578063f8b2cb4f14610f60578063f8d6aed414610f86576103d0565b8063e811f50a14610ea3578063efe2226614610eab578063f1b8a9b714610eb3578063f36c0a7214610ed9576103d0565b8063db2e21bc116100e9578063db2e21bc14610e2a578063dd62ed3e14610e32578063e5a583a914610e60578063e653bf3a14610e7d576103d0565b8063c7c30be114610de6578063cc77828d14610dee578063cd2ed8fb14610df6578063d73dd62314610dfe576103d0565b8063a9059cbb11610192578063be3bbd2e11610161578063be3bbd2e14610d0f578063be61533514610d67578063c06b6f1d14610d96578063c45a015514610dc2576103d0565b8063a9059cbb14610c29578063b02f0b7314610c55578063b3f05b9714610ccc578063ba9530a614610cd4576103d0565b8063948d8ce6116101ce578063948d8ce614610ba957806395d89b4114610bcf578063a221ee4914610bd7578063a694fc3a14610c0c576103d0565b80638656b65314610b1a5780638c28cbe814610b5557806392eefe9b14610b7b578063936c347714610ba1576103d0565b806354cf2aeb116102ef5780636d3c6d921161028257806379104ea61161025157806379104ea614610a205780637c5e9ea414610a615780638201aa3f14610aba57806385cc179e14610afa576103d0565b80636d3c6d921461092857806370a082311461095757806372aa0a601461097d57806376d743fe146109f4576103d0565b80636284ae41116102be5780636284ae41146107dc578063650e872c146107e457806366188463146108b25780636d142e5b146108de576103d0565b806354cf2aeb1461077457806354fd4d501461077c5780635db342771461078457806360d47088146107b6576103d0565b80632e1a7d4d11610367578063429b4ae611610336578063429b4ae61461062957806346ab38f1146106465780634d950c74146106785780634f69c0d4146106fd576103d0565b80632e1a7d4d146105a05780632f37b624146105bf578063313ce567146105e5578063362a3fad14610603576103d0565b806317837baa116103a357806317837baa1461050057806318160ddd1461050857806323b872dd1461051057806329d7958814610546576103d0565b806306fdde03146103d5578063095ea7b3146104525780631446a7ff1461049257806315e84af9146104d2575b600080fd5b6103dd610fc1565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104175781810151838201526020016103ff565b50505050905090810190601f1680156104445780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61047e6004803603604081101561046857600080fd5b506001600160a01b038135169060200135611057565b604080519115158252519081900360200190f35b6104c0600480360360408110156104a857600080fd5b506001600160a01b03813581169160200135166110be565b60408051918252519081900360200190f35b6104c0600480360360408110156104e857600080fd5b506001600160a01b0381358116916020013516611201565b6104c061133b565b6104c0611341565b61047e6004803603606081101561052657600080fd5b506001600160a01b03813581169160208101359091169060400135611347565b6105756004803603604081101561055c57600080fd5b50803560ff1690602001356001600160a01b03166114bb565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b6105bd600480360360208110156105b657600080fd5b5035611513565b005b61047e600480360360208110156105d557600080fd5b50356001600160a01b0316611698565b6105ed6116b6565b6040805160ff9092168252519081900360200190f35b6105bd6004803603602081101561061957600080fd5b50356001600160a01b03166116bf565b6105bd6004803603602081101561063f57600080fd5b50356116ea565b6104c06004803603606081101561065c57600080fd5b506001600160a01b0381351690602081013590604001356117dd565b6105bd6004803603606081101561068e57600080fd5b6001600160a01b03823516916020810135918101906060810160408201356401000000008111156106be57600080fd5b8201836020820111156106d057600080fd5b803590602001918460208302840111640100000000831117156106f257600080fd5b509092509050611a8b565b6105bd6004803603604081101561071357600080fd5b8135919081019060408101602082013564010000000081111561073557600080fd5b82018360208201111561074757600080fd5b8035906020019184602083028401116401000000008311171561076957600080fd5b509092509050611b7a565b6104c0611b86565b6104c0611b8c565b6104c06004803603606081101561079a57600080fd5b506001600160a01b038135169060208101359060400135611b92565b6104c0600480360360208110156107cc57600080fd5b50356001600160a01b0316611e08565b6104c0611e2d565b6105bd600480360360808110156107fa57600080fd5b81359160208101359181019060608101604082013564010000000081111561082157600080fd5b82018360208201111561083357600080fd5b8035906020019184602083028401116401000000008311171561085557600080fd5b91939092909160208101903564010000000081111561087357600080fd5b82018360208201111561088557600080fd5b803590602001918460208302840111640100000000831117156108a757600080fd5b509092509050611e33565b61047e600480360360408110156108c857600080fd5b506001600160a01b0381351690602001356125fa565b6105bd600480360360e08110156108f457600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060a08101359060c001356126e4565b6105bd6004803603604081101561093e57600080fd5b50803560ff1690602001356001600160a01b0316612a1a565b6104c06004803603602081101561096d57600080fd5b50356001600160a01b0316612d9f565b61099a6004803603602081101561099357600080fd5b5035612dba565b604080516001600160a01b03909b168b5260208b0199909952898901979097526060890195909552608088019390935260a087019190915260c086015260e085015261010084015261012083015251908190036101400190f35b6105bd60048036036060811015610a0a57600080fd5b5060ff8135169060208101359060400135612e25565b6104c0600480360360e0811015610a3657600080fd5b5080359060208101359060408101359060608101359060808101359060a08101359060c00135612eec565b610aa1600480360360a0811015610a7757600080fd5b506001600160a01b0381358116916020810135916040820135169060608101359060800135612fbb565b6040805192835260208301919091528051918290030190f35b610aa1600480360360a0811015610ad057600080fd5b506001600160a01b03813581169160208101359160408201351690606081013590608001356133c5565b6105bd60048036036020811015610b1057600080fd5b503560ff166137b8565b6104c0600480360360c0811015610b3057600080fd5b5080359060208101359060408101359060608101359060808101359060a00135613883565b6105bd60048036036020811015610b6b57600080fd5b50356001600160a01b031661391f565b6105bd60048036036020811015610b9157600080fd5b50356001600160a01b0316613a67565b6104c0613b35565b6104c060048036036020811015610bbf57600080fd5b50356001600160a01b0316613b86565b6103dd613c45565b6104c0600480360360a0811015610bed57600080fd5b5080359060208101359060408101359060608101359060800135613ca6565b6105bd60048036036020811015610c2257600080fd5b5035613d10565b61047e60048036036040811015610c3f57600080fd5b506001600160a01b038135169060200135613d4a565b6105bd60048036036040811015610c6b57600080fd5b81359190810190604081016020820135640100000000811115610c8d57600080fd5b820183602082011115610c9f57600080fd5b80359060200191846020830284011164010000000083111715610cc157600080fd5b509092509050613d60565b61047e61409e565b6104c0600480360360c0811015610cea57600080fd5b5080359060208101359060408101359060608101359060808101359060a001356140a7565b610d17614128565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610d53578181015183820152602001610d3b565b505050509050019250505060405180910390f35b6104c060048036036040811015610d7d57600080fd5b50803560ff1690602001356001600160a01b0316614211565b6105bd60048036036040811015610dac57600080fd5b506001600160a01b03813516906020013561432a565b610dca614405565b604080516001600160a01b039092168252519081900360200190f35b610dca614414565b610d17614423565b6104c061446d565b61047e60048036036040811015610e1457600080fd5b506001600160a01b038135169060200135614473565b6105bd614506565b6104c060048036036040811015610e4857600080fd5b506001600160a01b0381358116916020013516614596565b6105bd60048036036020811015610e7657600080fd5b50356145c1565b6105bd60048036036020811015610e9357600080fd5b50356001600160a01b03166146a7565b6104c0614712565b610dca614718565b6104c060048036036020811015610ec957600080fd5b50356001600160a01b0316614727565b6105bd6147f8565b610dca614821565b6105bd60048036036040811015610eff57600080fd5b81359190810190604081016020820135640100000000811115610f2157600080fd5b820183602082011115610f3357600080fd5b80359060200191846020830284011164010000000083111715610f5557600080fd5b509092509050614830565b6104c060048036036020811015610f7657600080fd5b50356001600160a01b03166148ac565b6104c0600480360360c0811015610f9c57600080fd5b5080359060208101359060408101359060608101359060808101359060a0013561496b565b60038054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561104d5780601f106110225761010080835404028352916020019161104d565b820191906000526020600020905b81548152906001019060200180831161103057829003601f168201915b5050505050905090565b3360008181526001602090815260408083206001600160a01b038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a35060015b92915050565b600554600090610100900460ff1615611108576040805162461bcd60e51b81526020600482015260076024820152667265656e74727960c81b604482015290519081900360640190fd5b6001600160a01b0383166000908152600e602052604090205460ff1661115e576040805162461bcd60e51b815260206004820152600660248201526508589bdd5b9960d21b604482015290519081900360640190fd5b6001600160a01b0382166000908152600e602052604090205460ff166111b4576040805162461bcd60e51b815260206004820152600660248201526508589bdd5b9960d21b604482015290519081900360640190fd5b6001600160a01b038084166000908152600e602052604080822092851682528120600380840154600280860154928401549084015493946111f89492939290613ca6565b95945050505050565b600554600090610100900460ff161561124b576040805162461bcd60e51b81526020600482015260076024820152667265656e74727960c81b604482015290519081900360640190fd5b6001600160a01b0383166000908152600e602052604090205460ff166112a1576040805162461bcd60e51b815260206004820152600660248201526508589bdd5b9960d21b604482015290519081900360640190fd5b6001600160a01b0382166000908152600e602052604090205460ff166112f7576040805162461bcd60e51b815260206004820152600660248201526508589bdd5b9960d21b604482015290519081900360640190fd5b6001600160a01b038084166000908152600e60205260408082209285168252902060038083015460028085015492840154908401546009546111f894929190613ca6565b60145481565b60025490565b6000336001600160a01b038516148061138357506001600160a01b03841660009081526001602090815260408083203384529091529020548211155b6113d4576040805162461bcd60e51b815260206004820152600860248201527f217370656e646572000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6113df8484846149ee565b336001600160a01b0385161480159061141d57506001600160a01b038416600090815260016020908152604080832033845290915290205460001914155b156114b1576001600160a01b03841660009081526001602090815260408083203384529091529020546114509083614af0565b6001600160a01b03858116600090815260016020908152604080832033808552908352928190208590558051948552519287169391927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a35b5060019392505050565b6001600160a01b03166000908152601060209081526040808320805460ff9095168452600181018352818420546002820184528285205460038301855283862054600490930190945291909320549394909391929190565b3360009081526010602052604090208054821115611578576040805162461bcd60e51b815260206004820152600860248201527f616d3e75732e616d000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b601454600582015461158991614b5e565b4210156115c6576040805162461bcd60e51b8152602060048201526006602482015265333937bd32b760d11b604482015290519081900360640190fd5b6115cf336116bf565b80546115db9083614af0565b815560115460005b8160ff168160ff16101561165257611632670de0b6b3a764000061162c60118460ff168154811061161057fe5b600091825260209091206004600a909202010154865490614bb8565b90614c11565b60ff821660009081526001808601602052604090912091909155016115e3565b5061165d3384614c53565b60408051848152905133917f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364919081900360200190a2505050565b6001600160a01b03166000908152600e602052604090205460ff1690565b60055460ff1690565b60115460005b8160ff168160ff1610156116e5576116dd8184612a1a565b6001016116c5565b505050565b6007546001600160a01b03163314611731576040805162461bcd60e51b815260206004820152600560248201526410b331ba3960d91b604482015290519081900360640190fd5b6676a91f7f7f800081111561178d576040805162461bcd60e51b815260206004820152600960248201527f3e6d6178436f4665650000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60095461179b826002614c5d565b11156117d8576040805162461bcd60e51b81526020600482015260076024820152661f39a332b2979960c91b604482015290519081900360640190fd5b600a55565b600554600090610100900460ff1615611827576040805162461bcd60e51b81526020600482015260076024820152667265656e74727960c81b604482015290519081900360640190fd5b6005805461ff001916610100179055600c5460ff16611876576040805162461bcd60e51b8152602060048083019190915260248201526308599b9b60e21b604482015290519081900360640190fd5b6001600160a01b0384166000908152600e602052604090205460ff166118cc576040805162461bcd60e51b815260206004820152600660248201526508589bdd5b9960d21b604482015290519081900360640190fd5b6001600160a01b0384166000908152600e6020526040902060038101546002808301549054600f54600954600b5461190995949392918a91612eec565b915082821015611948576040805162461bcd60e51b81526020600482015260056024820152643c6c696d4f60d81b604482015290519081900360640190fd5b6001600160a01b0385166000908152600e6020526040902060039081015461197d91670de0b6b3a76400005b04600101614c5d565b8211156119bc576040805162461bcd60e51b81526020600482015260086024820152670f9b585e13d4985d60c21b604482015290519081900360640190fd5b6119ca816003015483614af0565b816003018190555060006119e085600b54614c5d565b6040805185815290519192506001600160a01b0388169133917fe74c91552b64c2e2e7bd255639e004e693bd3e1d01cc33e65610b86afcc1ffed919081900360200190a3611a2e3386614d1e565b611a40611a3b8683614af0565b614d28565b8015611a5c57600754611a5c906001600160a01b031682614c53565b611a6830868886614d34565b9350611a779050863385614ec8565b50506005805461ff00191690559392505050565b600554610100900460ff1615611ad2576040805162461bcd60e51b81526020600482015260076024820152667265656e74727960c81b604482015290519081900360640190fd5b6005805461ff001916610100179055336001600160a01b0385161480611b0257506013546001600160a01b031633145b611b53576040805162461bcd60e51b815260206004820152600b60248201527f21287072787c7c6f776e29000000000000000000000000000000000000000000604482015290519081900360640190fd5b611b5f84848484615031565b611b69848461522b565b50506005805461ff00191690555050565b6116e533848484611a8b565b60095481565b60065481565b600554600090610100900460ff1615611bdc576040805162461bcd60e51b81526020600482015260076024820152667265656e74727960c81b604482015290519081900360640190fd5b6005805461ff001916610100179055600c5460ff16611c2b576040805162461bcd60e51b8152602060048083019190915260248201526308599b9b60e21b604482015290519081900360640190fd5b6001600160a01b0384166000908152600e602052604090205460ff16611c81576040805162461bcd60e51b815260206004820152600660248201526508589bdd5b9960d21b604482015290519081900360640190fd5b6001600160a01b0384166000908152600e6020526040902060030154611cb3906002670de0b6b3a76400005b04614c5d565b831115611cf2576040805162461bcd60e51b81526020600482015260086024820152670f9b585e1254985d60c21b604482015290519081900360640190fd5b6001600160a01b0384166000908152600e6020526040902060038101546002808301549054600f54600954611d2c94939291908990613883565b915082821015611d6b576040805162461bcd60e51b81526020600482015260056024820152643c6c696d4f60d81b604482015290519081900360640190fd5b611d798160030154856152f9565b60038201556040805185815290516001600160a01b0387169133917f63982df10efd8dfaaaa0fcc7f50b2d93b7cba26ccc48adee2873220d485dc39a9181900360200190a3611dc782615353565b611dd285338661535c565b6000611de086863086614d34565b935090508015611dfe57611df8826003015482614af0565b60038301555b611a773384614c53565b6014546001600160a01b03821660009081526010602052604090206005015401919050565b600b5481565b600554610100900460ff1615611e7a576040805162461bcd60e51b81526020600482015260076024820152667265656e74727960c81b604482015290519081900360640190fd5b6005805461ff001916610100179055600854336001600160a01b0390911614611ed4576040805162461bcd60e51b815260206004820152600760248201526610b1b73a3632b960c91b604482015290519081900360640190fd5b600c5460ff1615611f12576040805162461bcd60e51b8152602060048201526003602482015262199b9b60ea1b604482015290519081900360640190fd5b66038d7ea4c68000861015611f58576040805162461bcd60e51b81526020600482015260076024820152663c6d696e46656560c81b604482015290519081900360640190fd5b67016345785d8a0000861115611f9f576040805162461bcd60e51b81526020600482015260076024820152663e6d617846656560c81b604482015290519081900360640190fd5b600986905560038604600a5566038d7ea4c68000851015612007576040805162461bcd60e51b815260206004820152600c60248201527f3c6d696e496e6974505375700000000000000000000000000000000000000000604482015290519081900360640190fd5b6ec097ce7bc90715b34b9f100000000085111561206b576040805162461bcd60e51b815260206004820152600c60248201527f3e6d6178496e6974505375700000000000000000000000000000000000000000604482015290519081900360640190fd5b60028310156120c1576040805162461bcd60e51b815260206004820152600a60248201527f3c6d696e546f6b656e7300000000000000000000000000000000000000000000604482015290519081900360640190fd5b60088310612116576040805162461bcd60e51b815260206004820152600a60248201527f3e6d6178546f6b656e7300000000000000000000000000000000000000000000604482015290519081900360640190fd5b82811461216a576040805162461bcd60e51b815260206004820152600a60248201527f65724c656e674d69736d00000000000000000000000000000000000000000000604482015290519081900360640190fd5b600060608467ffffffffffffffff8111801561218557600080fd5b506040519080825280602002602001820160405280156121af578160200160208202803683370190505b50905060005b8581101561245f5760008787838181106121cb57fe5b905060200201356001600160a01b0316905060008686848181106121eb57fe5b9050602002013590506000826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561224357600080fd5b505afa158015612257573d6000803e3d6000fd5b505050506040513d602081101561226d57600080fd5b50518551909150819086908690811061228257fe5b6020908102919091018101919091526001600160a01b0384166000908152600e909152604090205460ff16156122e7576040805162461bcd60e51b8152602060048201526005602482015264189bdd5b9960da1b604482015290519081900360640190fd5b670de0b6b3a7640000821015612344576040805162461bcd60e51b815260206004820152600a60248201527f3c6d696e57656967687400000000000000000000000000000000000000000000604482015290519081900360640190fd5b6802b5e3af16b18800008211156123a2576040805162461bcd60e51b815260206004820152600a60248201527f3e6d617857656967687400000000000000000000000000000000000000000000604482015290519081900360640190fd5b620f42408110156123e4576040805162461bcd60e51b81526020600482015260076024820152660f1b5a5b90985b60ca1b604482015290519081900360640190fd5b6040805160808101825260018082526020808301888152838501878152606085018781526001600160a01b038a166000908152600e909452959092209351845460ff19169015151784555191830191909155516002820155905160039091015561244e86836152f9565b955050600190920191506121b59050565b506802b5e3af16b18800008211156124be576040805162461bcd60e51b815260206004820152600b60248201527f3e6d617854576569676874000000000000000000000000000000000000000000604482015290519081900360640190fd5b600f8290556124cf600d8787615bfe565b50600c805460ff191660011790556124e687615353565b6124f03388614c53565b7f84544fec6632b8b4c691c6d5d5288102f47b6d448e731f535b38767d2bfd2662600954886006548989898988604051808981526020018881526020018781526020018060200180602001806020018481038452898982818152602001925060200280828437600083820152601f01601f191690910185810384528781526020908101915088908802808284376000838201819052601f909101601f19169092018681038452875181528751602091820193828a0193509102908190849084905b838110156125c95781810151838201526020016125b1565b505050509050019b50505050505050505050505060405180910390a150506005805461ff0019169055505050505050565b3360009081526001602090815260408083206001600160a01b03861684529091528120548083111561264f573360009081526001602090815260408083206001600160a01b038816845290915281205561267e565b6126598184614af0565b3360009081526001602090815260408083206001600160a01b03891684529091529020555b3360008181526001602090815260408083206001600160a01b0389168085529083529281902054815190815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060019392505050565b6008546001600160a01b0316331461272d576040805162461bcd60e51b815260206004820152600760248201526610b1b73a3632b960c91b604482015290519081900360640190fd5b601154600811612784576040805162461bcd60e51b815260206004820152601160248201527f65786365656420727764506f6f6c4c696d000000000000000000000000000000604482015290519081900360640190fd5b808211156127c3576040805162461bcd60e51b815260206004820152600760248201526639ab211f32ab2160c91b604482015290519081900360640190fd5b8543116127d057856127d2565b435b9550848610612811576040805162461bcd60e51b815260206004820152600660248201526539a11f1eb2a160d11b604482015290519081900360640190fd5b6128196147f8565b60408051610140810182526001600160a01b039889168152602081019788529081019586526060810194855260006080820181815260a0830195865260c0830185815260e08401858152959094036101008401908152610120840183815260118054600181018255945293517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c68600a90940293840180546001600160a01b03191691909c1617909a5597517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6982015595517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6a87015593517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6b86015594517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6c85015590517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6d84015592517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6e83015591517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6f82015591517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c70830155517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c7190910155565b612a23826137b8565b6001600160a01b03811660009081526010602052604081206011805491929160ff8616908110612a4f57fe5b6000918252602080832060ff88168452600186019091526040832054600a929092020160048101548554919450612a9e9291612a9891670de0b6b3a76400009161162c91614bb8565b906154c4565b60058301549091508015612c38578260070154431115612b335760ff8616600090815260048501602090815260408083205460038801909252822054612ae3916154c4565b90508015612b2d57612af58382614b5e565b60ff88166000908152600487016020526040902054909350612b179082614b5e565b60ff881660009081526004870160205260409020555b50612c38565b8115612b8f576000612b4a606461162c8585614bb8565b9050612b5683826154c4565b60ff88166000908152600387016020526040902054909350612b789082614b5e565b60ff88166000908152600387016020526040902055505b8260060154431115612c38576000612bda846008015461162c612bbf8760060154436154c490919063ffffffff16565b60ff8b16600090815260038a01602052604090205490614bb8565b60ff8816600090815260048701602052604090205490915080821115612c35576000612c0683836154c4565b9050612c128282614b5e565b60ff8a166000908152600489016020526040902055612c318582614b5e565b9450505b50505b8115612d975760ff86166000908152600285016020526040902054612c5d9083614b5e565b60ff871660009081526002860160205260409020556009830154612c819083614b5e565b600984015560125483546040805163d1660f9960e01b81526001600160a01b0392831660048201528883166024820152604481018690529051919092169163d1660f9991606480830192600092919082900301818387803b158015612ce557600080fd5b505af1158015612cf9573d6000803e3d6000fd5b50506040805160ff8a1681526020810186905281516001600160a01b038a1694507f636c8a1a63bdbdbe782bbd46665206ecd64f1d1f745ed547cc9dd708864fd2b093509081900390910190a2612d81670de0b6b3a764000061162c60118960ff1681548110612d6557fe5b600091825260209091206004600a909202010154875490614bb8565b60ff871660009081526001860160205260409020555b505050505050565b6001600160a01b031660009081526020819052604090205490565b60118181548110612dc757fe5b60009182526020909120600a909102018054600182015460028301546003840154600485015460058601546006870154600788015460088901546009909901546001600160a01b03909816995095979496939592949193909291908a565b6008546001600160a01b03163314612e6e576040805162461bcd60e51b815260206004820152600760248201526610b1b73a3632b960c91b604482015290519081900360640190fd5b612e77836137b8565b600060118460ff1681548110612e8957fe5b90600052602060002090600a020190508060020154431115612edb576040805162461bcd60e51b815260206004808301919091526024820152636c61746560e01b604482015290519081900360640190fd5b600281019290925560039091015550565b600080612ef98887615506565b90506000612f1886612f13670de0b6b3a764000087614af0565b614c5d565b90506000612f268983614af0565b90506000612f34828b615506565b90506000612f5382612f4e670de0b6b3a764000088615506565b615617565b90506000612f61828f614c5d565b90506000612f6f8f83614af0565b90506000612f8e612f88670de0b6b3a76400008a614af0565b8c614c5d565b9050612fa682612f13670de0b6b3a764000084614af0565b98505050505050505050979650505050505050565b6005546000908190610100900460ff1615613007576040805162461bcd60e51b81526020600482015260076024820152667265656e74727960c81b604482015290519081900360640190fd5b6005805461ff0019166101001790556001600160a01b0387166000908152600e602052604090205460ff1661306c576040805162461bcd60e51b815260206004820152600660248201526508589bdd5b9960d21b604482015290519081900360640190fd5b6001600160a01b0385166000908152600e602052604090205460ff166130c2576040805162461bcd60e51b815260206004820152600660248201526508589bdd5b9960d21b604482015290519081900360640190fd5b6001600160a01b038088166000908152600e6020526040808220928816825290206003808201546130fb91670de0b6b3a7640000611974565b86111561313a576040805162461bcd60e51b81526020600482015260086024820152670f9b585e13d4985d60c21b604482015290519081900360640190fd5b600061315b8360030154846002015484600301548560020154600954613ca6565b9050858111156131a0576040805162461bcd60e51b815260206004820152600b60248201526a6261644c696d507269636560a81b604482015290519081900360640190fd5b6131c083600301548460020154846003015485600201548b60095461496b565b945088851115613200576040805162461bcd60e51b81526020600482015260066024820152651e3634b6a4b760d11b604482015290519081900360640190fd5b61320e8360030154866152f9565b8360030181905550613224826003015488614af0565b600380840182905584015460028086015490850154600954613247949190613ca6565b935080841015613287576040805162461bcd60e51b815260206004820152600660248201526532b926a0b83960d11b604482015290519081900360640190fd5b858411156132c8576040805162461bcd60e51b81526020600482015260096024820152683e6c696d507269636560b81b604482015290519081900360640190fd5b6132d28588615506565b81111561330f576040805162461bcd60e51b815260206004820152600660248201526532b926a0b83960d11b604482015290519081900360640190fd5b876001600160a01b03168a6001600160a01b0316336001600160a01b03167f908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378888b604051808381526020018281526020019250505060405180910390a46133778a338761535c565b613382883389614ec8565b600061338e8b87615734565b905080156133aa576133a4846003015482614af0565b60038501555b505050506005805461ff001916905590969095509350505050565b6005546000908190610100900460ff1615613411576040805162461bcd60e51b81526020600482015260076024820152667265656e74727960c81b604482015290519081900360640190fd5b6005805461ff0019166101001790556001600160a01b0387166000908152600e602052604090205460ff16613476576040805162461bcd60e51b815260206004820152600660248201526508589bdd5b9960d21b604482015290519081900360640190fd5b6001600160a01b0385166000908152600e602052604090205460ff166134cc576040805162461bcd60e51b815260206004820152600660248201526508589bdd5b9960d21b604482015290519081900360640190fd5b6001600160a01b038088166000908152600e6020526040808220928816825290206003820154613506906002670de0b6b3a7640000611cad565b881115613545576040805162461bcd60e51b81526020600482015260086024820152670f9b585e1254985d60c21b604482015290519081900360640190fd5b60006135668360030154846002015484600301548560020154600954613ca6565b9050858111156135ab576040805162461bcd60e51b815260206004820152600b60248201526a6261644c696d507269636560a81b604482015290519081900360640190fd5b6135cb83600301548460020154846003015485600201548d6009546140a7565b94508685101561360a576040805162461bcd60e51b81526020600482015260056024820152643c6c696d4f60d81b604482015290519081900360640190fd5b61361883600301548a6152f9565b836003018190555061362e826003015486614af0565b600380840182905584015460028086015490850154600954613651949190613ca6565b935080841015613691576040805162461bcd60e51b815260206004820152600660248201526532b926a0b83960d11b604482015290519081900360640190fd5b858411156136d2576040805162461bcd60e51b81526020600482015260096024820152683e6c696d507269636560b81b604482015290519081900360640190fd5b6136dc8986615506565b811115613719576040805162461bcd60e51b815260206004820152600660248201526532b926a0b83960d11b604482015290519081900360640190fd5b876001600160a01b03168a6001600160a01b0316336001600160a01b03167f908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d433788c89604051808381526020018281526020019250505060405180910390a46137818a338b61535c565b600061378f8b8b8b89614d34565b9650905080156137ad576137a7846003015482614af0565b60038501555b6133aa893388614ec8565b600060118260ff16815481106137ca57fe5b90600052602060002090600a020190506000816002015443116137ed57436137f3565b81600201545b905081600101548111156116e557600061380c30612d9f565b9050801561387857600061382d8460010154846154c490919063ffffffff16565b9050600061385e8361162c670de0b6b3a7640000613858896003015487614bb890919063ffffffff16565b90614bb8565b60048601549091506138709082614b5e565b600486015550505b506001919091015550565b6000806138908786615506565b905060006138af6138a9670de0b6b3a764000084614af0565b85614c5d565b905060006138c986612f13670de0b6b3a764000085614af0565b905060006138d78b836152f9565b905060006138e5828d615506565b905060006138f38287615617565b90506000613901828d614c5d565b905061390d818d614af0565b9e9d5050505050505050505050505050565b600554610100900460ff1615613966576040805162461bcd60e51b81526020600482015260076024820152667265656e74727960c81b604482015290519081900360640190fd5b6005805461ff0019166101001790556001600160a01b0381166000908152600e602052604090205460ff166139cb576040805162461bcd60e51b815260206004820152600660248201526508589bdd5b9960d21b604482015290519081900360640190fd5b604080516370a0823160e01b815230600482015290516001600160a01b038316916370a08231916024808301926020929190829003018186803b158015613a1157600080fd5b505afa158015613a25573d6000803e3d6000fd5b505050506040513d6020811015613a3b57600080fd5b50516001600160a01b039091166000908152600e60205260409020600301556005805461ff0019169055565b600554610100900460ff1615613aae576040805162461bcd60e51b81526020600482015260076024820152667265656e74727960c81b604482015290519081900360640190fd5b6005805461ff001916610100179055600854336001600160a01b0390911614613b08576040805162461bcd60e51b815260206004820152600760248201526610b1b73a3632b960c91b604482015290519081900360640190fd5b600880546001600160a01b0319166001600160a01b03929092169190911790556005805461ff0019169055565b600554600090610100900460ff1615613b7f576040805162461bcd60e51b81526020600482015260076024820152667265656e74727960c81b604482015290519081900360640190fd5b50600f5490565b600554600090610100900460ff1615613bd0576040805162461bcd60e51b81526020600482015260076024820152667265656e74727960c81b604482015290519081900360640190fd5b6001600160a01b0382166000908152600e602052604090205460ff16613c26576040805162461bcd60e51b815260206004820152600660248201526508589bdd5b9960d21b604482015290519081900360640190fd5b506001600160a01b03166000908152600e602052604090206002015490565b60048054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561104d5780601f106110225761010080835404028352916020019161104d565b600080613cb38787615506565b90506000613cc18686615506565b90506000613ccf8383615506565b90506000613cf6670de0b6b3a7640000613cf1670de0b6b3a764000089614af0565b615506565b9050613d028282614c5d565b9a9950505050505050505050565b6000613d1b30612d9f565b9050613d273383614d1e565b6000613d3230612d9f565b9050613d3e8183614af0565b92506116e5338461522b565b6000613d573384846149ee565b50600192915050565b600554610100900460ff1615613da7576040805162461bcd60e51b81526020600482015260076024820152667265656e74727960c81b604482015290519081900360640190fd5b6005805461ff001916610100179055600c5460ff16613df6576040805162461bcd60e51b8152602060048083019190915260248201526308599b9b60e21b604482015290519081900360640190fd5b6000613e00611341565b90506000613e1085600b54614c5d565b90506000613e1e8683614af0565b90506000613e2c8285615506565b905080613e69576040805162461bcd60e51b815260206004820152600660248201526532b926a0b83960d11b604482015290519081900360640190fd5b6000613e7433612d9f565b905087811015613ee8576000613e8a8983614af0565b3360009081526010602052604090205490915081811015613edc576040805162461bcd60e51b815260206004820152600760248201526639ba359e3bb23960c91b604482015290519081900360640190fd5b613ee582611513565b50505b613ef23389614d1e565b8315613f0e57600754613f0e906001600160a01b031685614c53565b613f1783614d28565b60005b600d54811015614088576000600d8281548110613f3357fe5b60009182526020808320909101546001600160a01b0316808352600e909152604082206003015490925090613f688683614c5d565b905080613fa5576040805162461bcd60e51b815260206004820152600660248201526532b926a0b83960d11b604482015290519081900360640190fd5b8a8a85818110613fb157fe5b90506020020135811015613ff4576040805162461bcd60e51b81526020600482015260056024820152643c6c696d4f60d81b604482015290519081900360640190fd5b6001600160a01b0383166000908152600e602052604090206003015461401a9082614af0565b6001600160a01b0384166000818152600e60209081526040918290206003019390935580518481529051919233927fe74c91552b64c2e2e7bd255639e004e693bd3e1d01cc33e65610b86afcc1ffed9281900390910190a361407d833383614ec8565b505050600101613f1a565b50506005805461ff001916905550505050505050565b600c5460ff1681565b6000806140b48786615506565b905060006140ca670de0b6b3a764000085614af0565b90506140d68582614c5d565b905060006140e88a613cf18c856152f9565b905060006140f68285615617565b9050600061410c670de0b6b3a764000083614af0565b90506141188a82614c5d565b9c9b505050505050505050505050565b600554606090610100900460ff1615614172576040805162461bcd60e51b81526020600482015260076024820152667265656e74727960c81b604482015290519081900360640190fd5b600c5460ff166141b2576040805162461bcd60e51b8152602060048083019190915260248201526308599b9b60e21b604482015290519081900360640190fd5b600d80548060200260200160405190810160405280929190818152602001828054801561104d57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116141ea575050505050905090565b6001600160a01b03811660009081526010602052604081206011805483919060ff871690811061423d57fe5b90600052602060002090600a02019050600081600401549050600061426130612d9f565b9050600083600201544311614276574361427c565b83600201545b905083600101548111801561429057508115155b156142ea5760006142ae8560010154836154c490919063ffffffff16565b905060006142d98461162c670de0b6b3a76400006138588a6003015487614bb890919063ffffffff16565b90506142e58582614b5e565b945050505b60ff88166000908152600186016020526040902054855461431e9190612a9890670de0b6b3a76400009061162c9088614bb8565b98975050505050505050565b6008546001600160a01b03163314614373576040805162461bcd60e51b815260206004820152600760248201526610b1b73a3632b960c91b604482015290519081900360640190fd5b6012546001600160a01b0316156143d1576040805162461bcd60e51b815260206004820152601060248201527f72657761726446756e64213d6e756c6c00000000000000000000000000000000604482015290519081900360640190fd5b62278d0060145411156143e057fe5b601455601280546001600160a01b0319166001600160a01b0392909216919091179055565b6007546001600160a01b031681565b6013546001600160a01b031681565b600554606090610100900460ff16156141b2576040805162461bcd60e51b81526020600482015260076024820152667265656e74727960c81b604482015290519081900360640190fd5b600d5490565b3360009081526001602090815260408083206001600160a01b03861684529091528120546144a190836152f9565b3360008181526001602090815260408083206001600160a01b0389168085529083529281902085905580519485525191937f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a350600192915050565b336000818152601060205260409020805490916145239082614c53565b6000808355601154905b8160ff168160ff16101561455a5760ff81166000908152600180860160205260408220919091550161452d565b5060408051838152905133917f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364919081900360200190a2505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600c5460ff16156145ff576040805162461bcd60e51b8152602060048201526003602482015262199b9b60ea1b604482015290519081900360640190fd5b6007546001600160a01b03163314614646576040805162461bcd60e51b815260206004820152600560248201526410b331ba3960d91b604482015290519081900360640190fd5b66038d7ea4c680008111156146a2576040805162461bcd60e51b815260206004820152600b60248201527f3e6d617845786974466565000000000000000000000000000000000000000000604482015290519081900360640190fd5b600b55565b6008546001600160a01b031633146146f0576040805162461bcd60e51b815260206004820152600760248201526610b1b73a3632b960c91b604482015290519081900360640190fd5b601380546001600160a01b0319166001600160a01b0392909216919091179055565b600a5481565b6012546001600160a01b031681565b600554600090610100900460ff1615614771576040805162461bcd60e51b81526020600482015260076024820152667265656e74727960c81b604482015290519081900360640190fd5b6001600160a01b0382166000908152600e602052604090205460ff166147c7576040805162461bcd60e51b815260206004820152600660248201526508589bdd5b9960d21b604482015290519081900360640190fd5b6001600160a01b0382166000908152600e6020526040902060020154600f546147f1908290615506565b9392505050565b60115460005b8160ff168160ff16101561481d57614815816137b8565b6001016147fe565b5050565b6008546001600160a01b031681565b600554610100900460ff1615614877576040805162461bcd60e51b81526020600482015260076024820152667265656e74727960c81b604482015290519081900360640190fd5b6005805461ff00191661010017905561489233848484615031565b61489c3384614c53565b50506005805461ff001916905550565b600554600090610100900460ff16156148f6576040805162461bcd60e51b81526020600482015260076024820152667265656e74727960c81b604482015290519081900360640190fd5b6001600160a01b0382166000908152600e602052604090205460ff1661494c576040805162461bcd60e51b815260206004820152600660248201526508589bdd5b9960d21b604482015290519081900360640190fd5b506001600160a01b03166000908152600e602052604090206003015490565b6000806149788588615506565b905060006149868786614af0565b905060006149948883615506565b905060006149a28285615617565b90506149b681670de0b6b3a7640000614af0565b90506149ca670de0b6b3a764000087614af0565b94506149df6149d98c83614c5d565b86615506565b9b9a5050505050505050505050565b6001600160a01b038316600090815260208190526040902054811115614a44576040805162461bcd60e51b815260206004808301919091526024820152630858985b60e21b604482015290519081900360640190fd5b6001600160a01b038316600090815260208190526040902054614a679082614af0565b6001600160a01b038085166000908152602081905260408082209390935590841681522054614a9690826152f9565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b6000806000614aff8585615832565b915091508015614b56576040805162461bcd60e51b815260206004820152600d60248201527f73756220756e646572666c6f7700000000000000000000000000000000000000604482015290519081900360640190fd5b509392505050565b6000828201838110156147f1576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082614bc7575060006110b8565b82820282848281614bd457fe5b04146147f15760405162461bcd60e51b8152600401808060200182810382526021815260200180615c816021913960400191505060405180910390fd5b60006147f183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250615857565b61481d82826158f9565b6000828202831580614c77575082848281614c7457fe5b04145b614cb7576040805162461bcd60e51b815260206004820152600c60248201526b6d756c206f766572666c6f7760a01b604482015290519081900360640190fd5b6706f05b59d3b20000810181811015614d06576040805162461bcd60e51b815260206004820152600c60248201526b6d756c206f766572666c6f7760a01b604482015290519081900360640190fd5b6000670de0b6b3a7640000825b049695505050505050565b61481d8282615904565b614d318161590f565b50565b600a54600090829015614ebf57600754604080516374b1330b60e11b815290516000926001600160a01b03169163e9626616916004808301926020929190829003018186803b158015614d8657600080fd5b505afa158015614d9a573d6000803e3d6000fd5b505050506040513d6020811015614db057600080fd5b505190506001600160a01b038082169088161415614e4457614de5614dd787600a54614c5d565b670de0b6b3a7640000615506565b600754909350614e009088906001600160a01b031685614ec8565b6040805184815290516001600160a01b038916917faa299fc96f84481838321cf4ac49861748dc206dd9101e1b8ed3f34bb88cadbd919081900360200190a2614ebd565b6000614e55614dd786600a54614c5d565b600754909150614e709087906001600160a01b031683614ec8565b614e7a8582614af0565b6040805183815290519194506001600160a01b038816917faa299fc96f84481838321cf4ac49861748dc206dd9101e1b8ed3f34bb88cadbd9181900360200190a2505b505b94509492505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1663a9059cbb60e01b178152925182516000946060949389169392918291908083835b60208310614f5a5780518252601f199092019160209182019101614f3b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114614fbc576040519150601f19603f3d011682016040523d82523d6000602084013e614fc1565b606091505b5091509150818015614fef575080511580614fef5750808060200190516020811015614fec57600080fd5b50515b61502a576040805162461bcd60e51b8152602060048201526007602482015266215f707573685560c81b604482015290519081900360640190fd5b5050505050565b600c5460ff16615071576040805162461bcd60e51b8152602060048083019190915260248201526308599b9b60e21b604482015290519081900360640190fd5b600061507b611341565b905060006150898583615506565b9050806150c6576040805162461bcd60e51b815260206004820152600660248201526532b926a0b83960d11b604482015290519081900360640190fd5b60005b600d54811015615221576000600d82815481106150e257fe5b60009182526020808320909101546001600160a01b0316808352600e9091526040822060030154909250906151178583614c5d565b9050801580159061513a575087878581811061512f57fe5b905060200201358111155b61518b576040805162461bcd60e51b815260206004820152600e60248201527f65724d4170727c7c3c6c696d496e000000000000000000000000000000000000604482015290519081900360640190fd5b6001600160a01b0383166000908152600e60205260409020600301546151b190826152f9565b6001600160a01b038085166000818152600e602090815260409182902060030194909455805185815290519193928e16927f63982df10efd8dfaaaa0fcc7f50b2d93b7cba26ccc48adee2873220d485dc39a92918290030190a361521683338361535c565b5050506001016150c9565b50612d9785615353565b6001600160a01b038216600090815260106020526040902061524c836116bf565b80546152589083614b5e565b815560115460005b8160ff168160ff1610156152ad5761528d670de0b6b3a764000061162c60118460ff168154811061161057fe5b60ff82166000908152600180860160205260409091209190915501615260565b504260058301556040805184815290516001600160a01b038616917fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c919081900360200190a250505050565b6000828201838110156147f1576040805162461bcd60e51b815260206004820152600c60248201527f616464206f766572666c6f770000000000000000000000000000000000000000604482015290519081900360640190fd5b614d31816159d1565b604080516001600160a01b038481166024830152306044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166323b872dd60e01b178152925182516000946060949389169392918291908083835b602083106153f45780518252601f1990920191602091820191016153d5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114615456576040519150601f19603f3d011682016040523d82523d6000602084013e61545b565b606091505b5091509150818015615489575080511580615489575080806020019051602081101561548657600080fd5b50515b61502a576040805162461bcd60e51b8152602060048201526007602482015266215f70756c6c5560c81b604482015290519081900360640190fd5b60006147f183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615a46565b60008161555a576040805162461bcd60e51b815260206004820152600860248201527f6469762062792030000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b670de0b6b3a764000083028315806155825750670de0b6b3a764000084828161557f57fe5b04145b6155c2576040805162461bcd60e51b815260206004820152600c60248201526b191a5d881a5b9d195c9b985b60a21b604482015290519081900360640190fd5b6002830481018181101561560c576040805162461bcd60e51b815260206004820152600c60248201526b191a5d881a5b9d195c9b985b60a21b604482015290519081900360640190fd5b6000848281614d1357fe5b6000600183101561566f576040805162461bcd60e51b815260206004820152600c60248201527f6261736520746f6f206c6f770000000000000000000000000000000000000000604482015290519081900360640190fd5b671bc16d674ec7ffff8311156156cc576040805162461bcd60e51b815260206004820152600d60248201527f6261736520746f6f206869676800000000000000000000000000000000000000604482015290519081900360640190fd5b60006156d783615aa0565b905060006156e58483614af0565b905060006156fb866156f685615abb565b615ac9565b90508161570c5792506110b8915050565b600061571d87846305f5e100615b20565b90506157298282614c5d565b979650505050505050565b600a54600090156110b857600754604080516374b1330b60e11b815290516000926001600160a01b03169163e9626616916004808301926020929190829003018186803b15801561578457600080fd5b505afa158015615798573d6000803e3d6000fd5b505050506040513d60208110156157ae57600080fd5b505190506001600160a01b0381161561582b576157d0614dd784600a54614c5d565b6007549092506157eb9085906001600160a01b031684614ec8565b6040805183815290516001600160a01b038616917faa299fc96f84481838321cf4ac49861748dc206dd9101e1b8ed3f34bb88cadbd919081900360200190a25b5092915050565b6000808284106158485750508082036000615850565b505081810360015b9250929050565b600081836158e35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156158a8578181015183820152602001615890565b50505050905090810190601f1680156158d55780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816158ef57fe5b0495945050505050565b61481d3083836149ee565b61481d8230836149ee565b3060009081526020819052604090205481111561595c576040805162461bcd60e51b815260206004808301919091526024820152630858985b60e21b604482015290519081900360640190fd5b306000908152602081905260409020546159769082614af0565b306000908152602081905260409020556002546159939082614af0565b60025560408051828152905160009130917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a350565b306000908152602081905260409020546159eb90826152f9565b30600090815260208190526040902055600254615a0890826152f9565b60025560408051828152905130916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a350565b60008184841115615a985760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156158a8578181015183820152602001615890565b505050900390565b6000670de0b6b3a7640000615ab483615abb565b0292915050565b670de0b6b3a7640000900490565b60008060028306615ae257670de0b6b3a7640000615ae4565b835b90506002830492505b82156147f157615afd8485614c5d565b93506002830615615b1557615b128185614c5d565b90505b600283049250615aed565b6000828180615b3787670de0b6b3a7640000615832565b9092509050670de0b6b3a764000080600060015b888410615bef576000670de0b6b3a764000082029050600080615b7f8a615b7a85670de0b6b3a7640000614af0565b615832565b91509150615b9187612f13848c614c5d565b9650615b9d8784615506565b965086615bac57505050615bef565b8715615bb6579315935b8015615bc0579315935b8415615bd757615bd08688614af0565b9550615be4565b615be186886152f9565b95505b505050600101615b4b565b50909998505050505050505050565b828054828255906000526020600020908101928215615c51579160200282015b82811115615c515781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190615c1e565b50615c5d929150615c61565b5090565b5b80821115615c5d5780546001600160a01b0319168155600101615c6256fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220ed25ab735b494d192255c92c5c826f77a35050dad2cc13156cffa6332de25c3264736f6c634300060c0033000000000000000000000000ebc44681c125d63210a33d30c55fd3d37762675b

Deployed ByteCode Sourcemap

47495:14155:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14830:83;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15465:193;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;15465:193:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;34272:465;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;34272:465:0;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;33800:464;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;33800:464:0;;;;;;;;;;:::i;48886:40::-;;;:::i;15360:97::-;;;:::i;16481:487::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;16481:487:0;;;;;;;;;;;;;;;;;:::i;58681:470::-;;;;;;;;;;;;;;;;-1:-1:-1;58681:470:0;;;;;;;;-1:-1:-1;;;;;58681:470:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53888:679;;;;;;;;;;;;;;;;-1:-1:-1;53888:679:0;;:::i;:::-;;29860:115;;;;;;;;;;;;;;;;-1:-1:-1;29860:115:0;-1:-1:-1;;;;;29860:115:0;;:::i;15016:82::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;54631:245;;;;;;;;;;;;;;;;-1:-1:-1;54631:245:0;-1:-1:-1;;;;;54631:245:0;;:::i;29325:287::-;;;;;;;;;;;;;;;;-1:-1:-1;29325:287:0;;:::i;42448:1328::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;42448:1328:0;;;;;;;;;;;;;:::i;51485:305::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51485:305:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51485:305:0;;-1:-1:-1;51485:305:0;-1:-1:-1;51485:305:0;:::i;51320:157::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51320:157:0;;-1:-1:-1;51320:157:0;-1:-1:-1;51320:157:0;:::i;28769:19::-;;;:::i;28492:26::-;;;:::i;41154:1286::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;41154:1286:0;;;;;;;;;;;;;:::i;53728:152::-;;;;;;;;;;;;;;;;-1:-1:-1;53728:152:0;-1:-1:-1;;;;;53728:152:0;;:::i;28872:19::-;;;:::i;31434:2079::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31434:2079:0;;-1:-1:-1;31434:2079:0;-1:-1:-1;31434:2079:0;:::i;15926:397::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;15926:397:0;;;;;;;;:::i;49835:1078::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;49835:1078:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;54884:2330::-;;;;;;;;;;;;;;;;-1:-1:-1;54884:2330:0;;;;;;;;-1:-1:-1;;;;;54884:2330:0;;:::i;15243:109::-;;;;;;;;;;;;;;;;-1:-1:-1;15243:109:0;-1:-1:-1;;;;;15243:109:0;;:::i;48764:38::-;;;;;;;;;;;;;;;;-1:-1:-1;48764:38:0;;:::i;:::-;;;;-1:-1:-1;;;;;48764:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50921:391;;;;;;;;;;;;;;;;-1:-1:-1;50921:391:0;;;;;;;;;;;;;;:::i;25831:1312::-;;;;;;;;;;;;;;;;-1:-1:-1;25831:1312:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;38993:2153::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;38993:2153:0;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;36764:2221;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;36764:2221:0;;;;;;;;;;;;;;;;;;;;;;;;;:::i;60844:803::-;;;;;;;;;;;;;;;;-1:-1:-1;60844:803:0;;;;:::i;23529:1183::-;;;;;;;;;;;;;;;;-1:-1:-1;23529:1183:0;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;33598:194::-;;;;;;;;;;;;;;;;-1:-1:-1;33598:194:0;-1:-1:-1;;;;;33598:194:0;;:::i;31253:173::-;;;;;;;;;;;;;;;;-1:-1:-1;31253:173:0;-1:-1:-1;;;;;31253:173:0;;:::i;30640:136::-;;;:::i;30425:207::-;;;;;;;;;;;;;;;;-1:-1:-1;30425:207:0;-1:-1:-1;;;;;30425:207:0;;:::i;14921:87::-;;;:::i;18568:523::-;;;;;;;;;;;;;;;;-1:-1:-1;18568:523:0;;;;;;;;;;;;;;;;;;;;;;:::i;52836:333::-;;;;;;;;;;;;;;;;-1:-1:-1;52836:333:0;;:::i;16331:142::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;16331:142:0;;;;;;;;:::i;59159:1457::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59159:1457:0;;-1:-1:-1;59159:1457:0;-1:-1:-1;59159:1457:0;:::i;28898:21::-;;;:::i;20109:697::-;;;;;;;;;;;;;;;;-1:-1:-1;20109:697:0;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;30242:175::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57222:936;;;;;;;;;;;;;;;;-1:-1:-1;57222:936:0;;;;;;;;-1:-1:-1;;;;;57222:936:0;;:::i;49317:381::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;49317:381:0;;;;;;;;:::i;28525:22::-;;;:::i;:::-;;;;-1:-1:-1;;;;;28525:22:0;;;;;;;;;;;;;;48851:28;;;:::i;30099:135::-;;;:::i;29983:108::-;;;:::i;15666:252::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;15666:252:0;;;;;;;;:::i;58229:444::-;;;:::i;15106:129::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;15106:129:0;;;;;;;;;;:::i;29620:232::-;;;;;;;;;;;;;;;;-1:-1:-1;29620:232:0;;:::i;49706:121::-;;;;;;;;;;;;;;;;-1:-1:-1;49706:121:0;-1:-1:-1;;;;;49706:121:0;;:::i;28795:24::-;;;:::i;48811:33::-;;;:::i;30784:256::-;;;;;;;;;;;;;;;;-1:-1:-1;30784:256:0;-1:-1:-1;;;;;30784:256:0;;:::i;60624:212::-;;;:::i;28602:25::-;;;:::i;51798:213::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51798:213:0;;-1:-1:-1;51798:213:0;-1:-1:-1;51798:213:0;:::i;31048:197::-;;;;;;;;;;;;;;;;-1:-1:-1;31048:197:0;-1:-1:-1;;;;;31048:197:0;;:::i;21824:686::-;;;;;;;;;;;;;;;;-1:-1:-1;21824:686:0;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;14830:83::-;14900:5;14893:12;;;;;;;;-1:-1:-1;;14893:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14867:13;;14893:12;;14900:5;;14893:12;;14900:5;14893:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14830:83;:::o;15465:193::-;15560:10;15532:4;15549:22;;;:10;:22;;;;;;;;-1:-1:-1;;;;;15549:27:0;;;;;;;;;;;:33;;;15598:30;;;;;;;15532:4;;15549:27;;15560:10;;15598:30;;;;;;;;-1:-1:-1;15646:4:0;15465:193;;;;;:::o;34272:465::-;28418:6;;34385:14;;28418:6;;;;;28417:7;28409:27;;;;;-1:-1:-1;;;28409:27:0;;;;;;;;;;;;-1:-1:-1;;;28409:27:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;34425:17:0;::::1;;::::0;;;:8:::1;:17;::::0;;;;:23;::::1;;34417:42;;;::::0;;-1:-1:-1;;;34417:42:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;34417:42:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;34478:18:0;::::1;;::::0;;;:8:::1;:18;::::0;;;;:24;::::1;;34470:43;;;::::0;;-1:-1:-1;;;34470:43:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;34470:43:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;34550:17:0;;::::1;34524:23;34550:17:::0;;;:8:::1;:17;::::0;;;;;34605:18;;::::1;::::0;;;;34655:16:::1;::::0;;::::1;::::0;34673:15:::1;::::0;;::::1;::::0;34690:17;;::::1;::::0;34709:16;;::::1;::::0;34605:18;;34641:88:::1;::::0;34655:16;;34673:15;34709:16;34641:13:::1;:88::i;:::-;34634:95:::0;34272:465;-1:-1:-1;;;;;34272:465:0:o;33800:464::-;28418:6;;33906:14;;28418:6;;;;;28417:7;28409:27;;;;;-1:-1:-1;;;28409:27:0;;;;;;;;;;;;-1:-1:-1;;;28409:27:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;33946:17:0;::::1;;::::0;;;:8:::1;:17;::::0;;;;:23;::::1;;33938:42;;;::::0;;-1:-1:-1;;;33938:42:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;33938:42:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;33999:18:0;::::1;;::::0;;;:8:::1;:18;::::0;;;;:24;::::1;;33991:43;;;::::0;;-1:-1:-1;;;33991:43:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;33991:43:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;34071:17:0;;::::1;34045:23;34071:17:::0;;;:8:::1;:17;::::0;;;;;34126:18;;::::1;::::0;;;;34176:16:::1;::::0;;::::1;::::0;34194:15:::1;::::0;;::::1;::::0;34211:17;;::::1;::::0;34230:16;;::::1;::::0;34248:7:::1;::::0;34162:94:::1;::::0;34194:15;34211:17;34230:16;34162:13:::1;:94::i;48886:40::-:0;;;;:::o;15360:97::-;15437:12;;15360:97;:::o;16481:487::-;16566:4;16591:10;-1:-1:-1;;;;;16591:17:0;;;;:55;;-1:-1:-1;;;;;;16619:15:0;;;;;;:10;:15;;;;;;;;16635:10;16619:27;;;;;;;;16612:34;;;16591:55;16583:76;;;;;-1:-1:-1;;;16583:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;16670:20;16676:3;16681;16686;16670:5;:20::i;:::-;16705:10;-1:-1:-1;;;;;16705:17:0;;;;;;:63;;-1:-1:-1;;;;;;16726:15:0;;;;;;:10;:15;;;;;;;;16742:10;16726:27;;;;;;;;-1:-1:-1;;16726:42:0;;16705:63;16701:238;;;-1:-1:-1;;;;;16820:15:0;;;;;;:10;:15;;;;;;;;16836:10;16820:27;;;;;;;;16815:38;;16849:3;16815:4;:38::i;:::-;-1:-1:-1;;;;;16785:15:0;;;;;;;:10;:15;;;;;;;;16801:10;16785:27;;;;;;;;;;:68;;;16873:54;;;;;;;;;;16801:10;;16873:54;;;;;;;;;;16701:238;-1:-1:-1;16956:4:0;16481:487;;;;;:::o;58681:470::-;-1:-1:-1;;;;;58884:18:0;58753:11;58884:18;;;:8;:18;;;;;;;;58922:11;;58957:21;;;;;;:15;;;:21;;;;;;59009:22;;;:28;;;;;;59061:15;;;:21;;;;;;59114:23;;;;:29;;;;;;;;58922:11;;58957:21;;59009:28;;59061:21;59114:29;58681:470::o;53888:679::-;53980:10;53947:21;53971:20;;;:8;:20;;;;;54010:11;;:22;-1:-1:-1;54010:22:0;54002:43;;;;;-1:-1:-1;;;54002:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;54106:19;;54083:18;;;;:43;;:22;:43::i;:::-;54064:15;:62;;54056:81;;;;;-1:-1:-1;;;54056:81:0;;;;;;;;;;;;-1:-1:-1;;;54056:81:0;;;;;;;;;;;;;;;54148:25;54162:10;54148:13;:25::i;:::-;54203:11;;54198:26;;54216:7;54198:4;:26::i;:::-;54184:40;;54266:14;:21;54184:11;54299:170;54327:16;54320:23;;:4;:23;;;54299:170;;;54392:65;54452:4;54392:55;54408:14;54423:4;54408:20;;;;;;;;;;;;;;;;;;:38;:20;;;;;:38;;54392:11;;;:15;:55::i;:::-;:59;;:65::i;:::-;54368:21;;;;;;;:15;;;;:21;;;;;;:89;;;;54345:6;54299:170;;;;54479:35;54494:10;54506:7;54479:14;:35::i;:::-;54530:29;;;;;;;;54539:10;;54530:29;;;;;;;;;;53888:679;;;:::o;29860:115::-;-1:-1:-1;;;;;29950:11:0;29921:4;29950:11;;;:8;:11;;;;;:17;;;;29860:115::o;15016:82::-;15081:9;;;;15016:82;:::o;54631:245::-;54730:14;:21;54699:22;54763:106;54791:16;54784:23;;:4;:23;;;54763:106;;;54832:25;54842:4;54848:8;54832:9;:25::i;:::-;54809:6;;54763:106;;;;54631:245;;:::o;29325:287::-;29410:7;;-1:-1:-1;;;;;29410:7:0;29396:10;:21;29388:39;;;;;-1:-1:-1;;;29388:39:0;;;;;;;;;;;;-1:-1:-1;;;29388:39:0;;;;;;;;;;;;;;;6565:18;29446:41;;;29438:63;;;;;-1:-1:-1;;;29438:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;29546:7;;29520:22;29525:13;29540:1;29520:4;:22::i;:::-;:33;;29512:53;;;;;-1:-1:-1;;;29512:53:0;;;;;;;;;;;;-1:-1:-1;;;29512:53:0;;;;;;;;;;;;;;;29576:12;:28;29325:287::o;42448:1328::-;28281:6;;42574:19;;28281:6;;;;;28280:7;28272:27;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;;;;28310:6;:13;;-1:-1:-1;;28310:13:0;;;;;42619:9:::1;::::0;28310:13;42619:9:::1;42611:26;;;::::0;;-1:-1:-1;;;42611:26:0;;::::1;;::::0;;::::1;::::0;;;;;;;;-1:-1:-1;;;42611:26:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;42656:18:0;::::1;;::::0;;;:8:::1;:18;::::0;;;;:24;::::1;;42648:43;;;::::0;;-1:-1:-1;;;42648:43:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;42648:43:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;42731:18:0;::::1;42704:24;42731:18:::0;;;:8:::1;:18;::::0;;;;42818:17:::1;::::0;::::1;::::0;42850:16:::1;::::0;;::::1;::::0;42881:12;;42908::::1;::::0;42962:7:::1;::::0;42984::::1;::::0;42779:223:::1;::::0;42818:17;42850:16;42881:12;42908;42935;;42779:24:::1;:223::i;:::-;42762:240;;43041:12;43023:14;:30;;43015:48;;;::::0;;-1:-1:-1;;;43015:48:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;43015:48:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;43107:18:0;::::1;;::::0;;;:8:::1;:18;::::0;;;;:26:::1;::::0;;::::1;::::0;43102:54:::1;::::0;6082:6:::1;7506:8;;7518:5;7505:18;43102:4;:54::i;:::-;43084:14;:72;;43076:93;;;::::0;;-1:-1:-1;;;43076:93:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;43076:93:0;;;;;;;;;;;;;::::1;;43202:39;43207:9;:17;;;43226:14;43202:4;:39::i;:::-;43182:9;:17;;:59;;;;43254:13;43270:27;43275:12;43289:7;;43270:4;:27::i;:::-;43315:46;::::0;;;;;;;43254:43;;-1:-1:-1;;;;;;43315:46:0;::::1;::::0;43324:10:::1;::::0;43315:46:::1;::::0;;;;;::::1;::::0;;::::1;43374:40;43389:10;43401:12;43374:14;:40::i;:::-;43425:44;43440:28;43445:12;43459:8;43440:4;:28::i;:::-;43425:14;:44::i;:::-;43484:12:::0;;43480:78:::1;;43528:7;::::0;43513:33:::1;::::0;-1:-1:-1;;;;;43528:7:0::1;43537:8:::0;43513:14:::1;:33::i;:::-;43589:81;43624:4;43631:12;43645:8;43655:14;43589:26;:81::i;:::-;43568:102:::0;-1:-1:-1;43681:53:0::1;::::0;-1:-1:-1;43697:8:0;43707:10:::1;43568:102:::0;43681:15:::1;:53::i;:::-;43747:21;;28346:6:::0;:14;;-1:-1:-1;;28346:14:0;;;42448:1328;;-1:-1:-1;;;42448:1328:0:o;51485:305::-;28281:6;;;;;;;28280:7;28272:27;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;;;;28310:6;:13;;-1:-1:-1;;28310:13:0;;;;;51606:10:::1;-1:-1:-1::0;;;;;51606:21:0;::::1;;::::0;:52:::1;;-1:-1:-1::0;51645:13:0::1;::::0;-1:-1:-1;;;;;51645:13:0::1;51631:10;:27;51606:52;51598:76;;;::::0;;-1:-1:-1;;;51598:76:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;51685:47;51695:7;51704:13;51719:12;;51685:9;:47::i;:::-;51743:39;51759:7;51768:13;51743:15;:39::i;:::-;-1:-1:-1::0;;28346:6:0;:14;;-1:-1:-1;;28346:14:0;;;-1:-1:-1;;51485:305:0:o;51320:157::-;51417:52;51429:10;51441:13;51456:12;;51417:11;:52::i;28769:19::-;;;;:::o;28492:26::-;;;;:::o;41154:1286::-;28281:6;;41286:18;;28281:6;;;;;28280:7;28272:27;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;;;;28310:6;:13;;-1:-1:-1;;28310:13:0;;;;;41332:9:::1;::::0;28310:13;41332:9:::1;41324:26;;;::::0;;-1:-1:-1;;;41324:26:0;;::::1;;::::0;;::::1;::::0;;;;;;;;-1:-1:-1;;;41324:26:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;41369:17:0;::::1;;::::0;;;:8:::1;:17;::::0;;;;:23;::::1;;41361:42;;;::::0;;-1:-1:-1;;;41361:42:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;41361:42:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;41444:17:0;::::1;;::::0;;;:8:::1;:17;::::0;;;;:25:::1;;::::0;41439:52:::1;::::0;7449:1:::1;6082:6;7442:8;;41439:4;:52::i;:::-;41422:13;:69;;41414:90;;;::::0;;-1:-1:-1;;;41414:90:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;41414:90:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;41543:17:0;::::1;41517:23;41543:17:::0;;;:8:::1;:17;::::0;;;;41628:16:::1;::::0;::::1;::::0;41659:15:::1;::::0;;::::1;::::0;41689:12;;41716::::1;::::0;41771:7:::1;::::0;41589:200:::1;::::0;41628:16;41659:15;41689:12;41716;41743:13;;41589:24:::1;:200::i;:::-;41573:216;;41827:16;41810:13;:33;;41802:51;;;::::0;;-1:-1:-1;;;41802:51:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;41802:51:0;;;;;;;;;;;;;::::1;;41885:37;41890:8;:16;;;41908:13;41885:4;:37::i;:::-;41866:16;::::0;::::1;:56:::0;41940:44:::1;::::0;;;;;;;-1:-1:-1;;;;;41940:44:0;::::1;::::0;41949:10:::1;::::0;41940:44:::1;::::0;;;;::::1;::::0;;::::1;41997:29;42012:13;41997:14;:29::i;:::-;42037:51;42053:7;42062:10;42074:13;42037:15;:51::i;:::-;42099:22;42169:80;42196:7;42205:13;42228:4;42235:13;42169:26;:80::i;:::-;42132:117:::0;-1:-1:-1;42132:117:0;-1:-1:-1;42264:21:0;;42260:87:::1;;42306:41;42311:8;:16;;;42329:17;42306:4;:41::i;:::-;42287:16;::::0;::::1;:60:::0;42260:87:::1;42358:41;42373:10;42385:13;42358:14;:41::i;53728:152::-:0;53853:19;;-1:-1:-1;;;;;53818:18:0;;53794:4;53818:18;;;:8;:18;;;;;:32;;;:54;53728:152;;;:::o;28872:19::-;;;;:::o;31434:2079::-;28281:6;;;;;;;28280:7;28272:27;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;;;;28310:6;:13;;-1:-1:-1;;28310:13:0;;;;;31643:10:::1;::::0;31629::::1;-1:-1:-1::0;;;;;31643:10:0;;::::1;31629:24;31621:44;;;::::0;;-1:-1:-1;;;31621:44:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;31621:44:0;;;;;;;;;;;;;::::1;;31685:9;::::0;::::1;;31684:10;31676:26;;;::::0;;-1:-1:-1;;;31676:26:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;31676:26:0;;;;;;;;;;;;;::::1;;6337:11:::0;31723:26;::::1;;31715:46;;;::::0;;-1:-1:-1;;;31715:46:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;31715:46:0;;;;;;;;;;;;;::::1;;6411:9:::0;31780:26;::::1;;31772:46;;;::::0;;-1:-1:-1;;;31772:46:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;31772:46:0;;;;;;;;;;;;;::::1;;31829:7;:18:::0;;;31884:1:::1;31873:12:::0;::::1;31858;:27:::0;7103:11;31906:46;::::1;;31898:71;;;::::0;;-1:-1:-1;;;31898:71:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;7169:13:::0;31988:46;::::1;;31980:71;;;::::0;;-1:-1:-1;;;31980:71:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;6145:1;32072:45:::0;::::1;;32064:68;;;::::0;;-1:-1:-1;;;32064:68:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;6201:1;32151:44:::0;::::1;32143:67;;;::::0;;-1:-1:-1;;;32143:67:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;32229:41:::0;;::::1;32221:64;;;::::0;;-1:-1:-1;;;32221:64:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;32298:16;32329:25;32368:11:::0;32357:30:::1;::::0;::::1;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;32357:30:0::1;;32329:58;;32403:6;32398:743;32415:22:::0;;::::1;32398:743;;;32459:13;32475:11;;32487:1;32475:14;;;;;;;;;;;;;-1:-1:-1::0;;;;;32475:14:0::1;32459:30;;32504:11;32518:12;;32531:1;32518:15;;;;;;;;;;;;;32504:29;;32548:12;32570:5;-1:-1:-1::0;;;;;32563:23:0::1;;32595:4;32563:38;;;;;;;;;;;;;-1:-1:-1::0;;;;;32563:38:0::1;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;32563:38:0;32616:11;;32563:38;;-1:-1:-1;32563:38:0;;32616:8;;32625:1;;32616:11;::::1;;;;;;::::0;;::::1;::::0;;;;;;:21;;;;-1:-1:-1;;;;;32661:15:0;::::1;;::::0;;;:8:::1;:15:::0;;;;;;:21;::::1;;32660:22;32652:40;;;::::0;;-1:-1:-1;;;32652:40:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;32652:40:0;;;;;;;;;;;;;::::1;;6082:6;32715;:27;;32707:50;;;::::0;;-1:-1:-1;;;32707:50:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;6840:9:::0;32780:27;::::1;;32772:50;;;::::0;;-1:-1:-1;;;32772:50:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;6968:13:::0;32845:29;::::1;;32837:49;;;::::0;;-1:-1:-1;;;32837:49:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;32837:49:0;;;;;;;;;;;;;::::1;;32919:156;::::0;;::::1;::::0;::::1;::::0;;32953:4:::1;32919:156:::0;;;::::1;::::0;;::::1;::::0;;;;;;;;;;;;;;;-1:-1:-1;;;;;32901:15:0;::::1;-1:-1:-1::0;32901:15:0;;;:8:::1;:15:::0;;;;;;;:174;;;;-1:-1:-1;;32901:174:0::1;::::0;::::1;;;::::0;;;;;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;;::::1;::::0;33104:25:::1;33109:11:::0;32919:156;33104:4:::1;:25::i;:::-;33090:39:::0;-1:-1:-1;;32439:3:0::1;::::0;;::::1;::::0;-1:-1:-1;32398:743:0::1;::::0;-1:-1:-1;32398:743:0::1;;-1:-1:-1::0;6904:9:0;33159:38;::::1;;33151:62;;;::::0;;-1:-1:-1;;;33151:62:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;33224:12;:26:::0;;;33261:21:::1;:7;33271:11:::0;;33261:21:::1;:::i;:::-;-1:-1:-1::0;33293:9:0::1;:16:::0;;-1:-1:-1;;33293:16:0::1;33305:4;33293:16;::::0;;33320:31:::1;33335:15:::0;33320:14:::1;:31::i;:::-;33362:43;33377:10;33389:15;33362:14;:43::i;:::-;33421:84;33434:7;;33443:15;33460:7;;33469:11;;33482:12;;33496:8;33421:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;;::::1;::::0;::::1;;-1:-1:-1::0;;33421:84:0::1;::::0;;::::1;::::0;;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;-1:-1:-1;33421:84:0;;;::::1;::::0;;;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;::::1;-1:-1:-1::0;;33421:84:0::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;-1:-1:-1;33421:84:0;::::1;::::0;;;;;;;::::1;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;28346:6:0;:14;;-1:-1:-1;;28346:14:0;;;-1:-1:-1;;;;;;31434:2079:0:o;15926:397::-;16037:10;15993:4;16026:22;;;:10;:22;;;;;;;;-1:-1:-1;;;;;16026:27:0;;;;;;;;;;16068:14;;;16064:160;;;16110:10;16129:1;16099:22;;;:10;:22;;;;;;;;-1:-1:-1;;;;;16099:27:0;;;;;;;;;:31;16064:160;;;16193:19;16198:8;16208:3;16193:4;:19::i;:::-;16174:10;16163:22;;;;:10;:22;;;;;;;;-1:-1:-1;;;;;16163:27:0;;;;;;;;;:49;16064:160;16248:10;16265:22;;;;:10;:22;;;;;;;;-1:-1:-1;;;;;16239:54:0;;16265:27;;;;;;;;;;;16239:54;;;;;;;;;16248:10;16239:54;;;;;;;;;;;-1:-1:-1;16311:4:0;;15926:397;-1:-1:-1;;;15926:397:0:o;49835:1078::-;49267:10;;-1:-1:-1;;;;;49267:10:0;49253;:24;49245:44;;;;;-1:-1:-1;;;49245:44:0;;;;;;;;;;;;-1:-1:-1;;;49245:44:0;;;;;;;;;;;;;;;50084:14:::1;:21:::0;50108:1:::1;-1:-1:-1::0;50076:55:0::1;;;::::0;;-1:-1:-1;;;50076:55:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;50172:16;50150:18;:38;;50142:58;;;::::0;;-1:-1:-1;;;50142:58:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;50142:58:0;;;;;;;;;;;;;::::1;;50241:11;50226:12;:26;50225:57;;50271:11;50225:57;;;50256:12;50225:57;50211:71;;50315:15;50301:11;:29;50293:48;;;::::0;;-1:-1:-1;;;50293:48:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;50293:48:0;;;;;;;;;;;;;::::1;;50352:14;:12;:14::i;:::-;50397:507;::::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;;;;;50397:507:0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;;;;;;;;-1:-1:-1;50397:507:0;;;;;;;;;;;;;;;;;;;;;;;;50817:37;;;::::1;50397:507:::0;;;;;;;;;;;;50377:14:::1;:528:::0;;::::1;::::0;::::1;::::0;;;;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;-1:-1:-1;;;;;;50377:528:0::1;::::0;;;::::1;;::::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49835:1078::o;54884:2330::-;54960:18;54973:4;54960:12;:18::i;:::-;-1:-1:-1;;;;;55013:18:0;;54989:21;55013:18;;;:8;:18;;;;;55078:14;:20;;55013:18;;54989:21;55078:20;;;;;;;;;;;;;;;;;;55191:21;;;;;:15;;;:21;;;;;;;55078:20;;;;;;55147:28;;;;55131:11;;55078:20;;-1:-1:-1;55131:82:0;;55191:21;55131:55;;55181:4;;55131:45;;:15;:45::i;:55::-;:59;;:82::i;:::-;55250:28;;;;55109:104;;-1:-1:-1;55293:22:0;;55289:1432;;55351:10;:26;;;55336:12;:41;55332:1378;;;55445:29;;;55398:18;55445:29;;;:23;;;:29;;;;;;;;;55419:15;;;:21;;;;;;:56;;:25;:56::i;:::-;55398:77;-1:-1:-1;55498:17:0;;55494:219;;55557:33;:14;55576:13;55557:18;:33::i;:::-;55645:29;;;;;;;:23;;;:29;;;;;;55540:50;;-1:-1:-1;55645:48:0;;55679:13;55645:33;:48::i;:::-;55613:29;;;;;;;:23;;;:29;;;;;:80;55494:219;55332:1378;;;;55757:18;;55753:283;;55800:14;55817:47;55860:3;55817:38;:14;55836:18;55817;:38::i;:47::-;55800:64;-1:-1:-1;55904:29:0;:14;55800:64;55904:18;:29::i;:::-;55980:21;;;;;;;:15;;;:21;;;;;;55887:46;;-1:-1:-1;55980:36:0;;56006:9;55980:25;:36::i;:::-;55956:21;;;;;;;:15;;;:21;;;;;:60;-1:-1:-1;55753:283:0;56073:10;:28;;;56058:12;:43;56054:641;;;56126:16;56145:108;56223:10;:29;;;56145:73;56171:46;56188:10;:28;;;56171:12;:16;;:46;;;;:::i;:::-;56145:21;;;;;;;:15;;;:21;;;;;;;:25;:73::i;:108::-;56303:29;;;56276:24;56303:29;;;:23;;;:29;;;;;;56126:127;;-1:-1:-1;56359:33:0;;;56355:321;;;56421:18;56442:36;:11;56458:19;56442:15;:36::i;:::-;56421:57;-1:-1:-1;56537:38:0;:19;56421:57;56537:23;:38::i;:::-;56505:29;;;;;;;:23;;;:29;;;;;:70;56619:33;:14;56638:13;56619:18;:33::i;:::-;56602:50;;56355:321;;56054:641;;;56735:18;;56731:476;;56801:28;;;;;;;:22;;;:28;;;;;;:48;;56834:14;56801:32;:48::i;:::-;56770:28;;;;;;;:22;;;:28;;;;;:79;56894:27;;;;:47;;56926:14;56894:31;:47::i;:::-;56864:27;;;:77;56956:10;;56980:22;;56956:73;;;-1:-1:-1;;;56956:73:0;;-1:-1:-1;;;;;56980:22:0;;;56956:73;;;;;;;;;;;;;;;;;;;:10;;;;;:23;;:73;;;;;:10;;:73;;;;;;;:10;;:73;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;57049:42:0;;;;;;;;;;;;;;;;-1:-1:-1;;;;;57049:42:0;;;-1:-1:-1;57049:42:0;;-1:-1:-1;57049:42:0;;;;;;;;;57130:65;57190:4;57130:55;57146:14;57161:4;57146:20;;;;;;;;;;;;;;;;;;:38;:20;;;;;:38;;57130:11;;;:15;:55::i;:65::-;57106:21;;;;;;;:15;;;:21;;;;;:89;56731:476;54884:2330;;;;;;:::o;15243:109::-;-1:-1:-1;;;;;15330:14:0;15306:4;15330:14;;;;;;;;;;;;15243:109::o;48764:38::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;48764:38:0;;;;-1:-1:-1;48764:38:0;;;;;;;;;;;;;;;:::o;50921:391::-;49267:10;;-1:-1:-1;;;;;49267:10:0;49253;:24;49245:44;;;;;-1:-1:-1;;;49245:44:0;;;;;;;;;;;;-1:-1:-1;;;49245:44:0;;;;;;;;;;;;;;;51042:18:::1;51055:4;51042:12;:18::i;:::-;51071:33;51107:14;51122:4;51107:20;;;;;;;;;;;;;;;;;;;;51071:56;;51162:10;:25;;;51146:12;:41;;51138:58;;;::::0;;-1:-1:-1;;;51138:58:0;;::::1;;::::0;;::::1;::::0;;;;;;;;-1:-1:-1;;;51138:58:0;;;;;;;;;;;;;::::1;;51207:25;::::0;::::1;:43:::0;;;;51261:25:::1;::::0;;::::1;:43:::0;-1:-1:-1;50921:391:0:o;25831:1312::-;26099:19;26136:21;26160:33;26165:14;26181:11;26160:4;:33::i;:::-;26136:57;;26301:29;26333:46;26338:12;26352:26;6082:6;26370:7;26352:4;:26::i;:::-;26333:4;:46::i;:::-;26301:78;;26390:18;26411:42;26416:10;26428:24;26411:4;:42::i;:::-;26390:63;;26464:14;26481:31;26486:13;26501:10;26481:4;:31::i;:::-;26464:48;;26585:18;26606:52;26611:9;26622:35;6082:6;26640:16;26622:4;:35::i;:::-;26606:4;:52::i;:::-;26585:73;;26669:23;26695:36;26700:13;26715:15;26695:4;:36::i;:::-;26669:62;;26744:32;26779:41;26784:15;26801:18;26779:4;:41::i;:::-;26744:76;;26957:8;26968:50;26973:35;6082:6;26991:16;26973:4;:35::i;:::-;27010:7;26968:4;:50::i;:::-;26957:61;;27046:57;27051:27;27080:22;6082:6;27098:3;27080:4;:22::i;27046:57::-;27029:74;;27114:21;;;;;;;;25831:1312;;;;;;;;;:::o;38993:2153::-;28281:6;;39202:18;;;;28281:6;;;;;28280:7;28272:27;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;;;;28310:6;:13;;-1:-1:-1;;28310:13:0;;;;;-1:-1:-1;;;;;39267:17:0;::::1;28310:13:::0;39267:17;;;:8:::1;:17;::::0;;;;:23;28310:13;39267:23:::1;39259:42;;;::::0;;-1:-1:-1;;;39259:42:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;39259:42:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;39320:18:0;::::1;;::::0;;;:8:::1;:18;::::0;;;;:24;::::1;;39312:43;;;::::0;;-1:-1:-1;;;39312:43:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;39312:43:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;39394:26:0;;::::1;39368:23;39394:26:::0;;;:8:::1;:26;::::0;;;;;39458:27;;::::1;::::0;;;;39529:17:::1;::::0;;::::1;::::0;39524:45:::1;::::0;6082:6:::1;7506:8;::::0;39524:45:::1;39506:14;:63;;39498:84;;;::::0;;-1:-1:-1;;;39498:84:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;39498:84:0;;;;;;;;;;;;;::::1;;39595:20;39618:170;39646:8;:16;;;39677:8;:15;;;39707:9;:17;;;39739:9;:16;;;39770:7;;39618:13;:170::i;:::-;39595:193;;39826:8;39807:15;:27;;39799:51;;;::::0;;-1:-1:-1;;;39799:51:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;39799:51:0;;;;;;;;;;;;;::::1;;39879:200;39908:8;:16;;;39939:8;:15;;;39969:9;:17;;;40001:9;:16;;;40032:14;40061:7;;39879:14;:200::i;:::-;39863:216;;40115:11;40098:13;:28;;40090:47;;;::::0;;-1:-1:-1;;;40090:47:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;40090:47:0;;;;;;;;;;;;;::::1;;40169:37;40174:8;:16;;;40192:13;40169:4;:37::i;:::-;40150:8;:16;;:56;;;;40237:39;40242:9;:17;;;40261:14;40237:4;:39::i;:::-;40217:17;::::0;;::::1;:59:::0;;;40334:16;::::1;::::0;40365:15:::1;::::0;;::::1;::::0;40427:16;;::::1;::::0;40458:7:::1;::::0;40306:170:::1;::::0;40217:59;40427:16;40306:13:::1;:170::i;:::-;40289:187;;40513:15;40495:14;:33;;40487:52;;;::::0;;-1:-1:-1;;;40487:52:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;40487:52:0;;;;;;;;;;;;;::::1;;40576:8;40558:14;:26;;40550:48;;;::::0;;-1:-1:-1;;;40550:48:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;40550:48:0;;;;;;;;;;;;;::::1;;40636:35;40641:13;40656:14;40636:4;:35::i;:::-;40617:15;:54;;40609:73;;;::::0;;-1:-1:-1;;;40609:73:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;40609:73:0;;;;;;;;;;;;;::::1;;40730:8;-1:-1:-1::0;;;;;40700:70:0::1;40721:7;-1:-1:-1::0;;;;;40700:70:0::1;40709:10;-1:-1:-1::0;;;;;40700:70:0::1;;40740:13;40755:14;40700:70;;;;;;;;;;;;;;;;;;;;;;;;40783:51;40799:7;40808:10;40820:13;40783:15;:51::i;:::-;40845:53;40861:8;40871:10;40883:14;40845:15;:53::i;:::-;40909:24;40936:49;40962:7;40971:13;40936:25;:49::i;:::-;40909:76:::0;-1:-1:-1;41000:23:0;;40996:91:::1;;41044:43;41049:8;:16;;;41067:19;41044:4;:43::i;:::-;41025:16;::::0;::::1;:62:::0;40996:91:::1;41100:38;;;;28346:6:::0;:14;;-1:-1:-1;;28346:14:0;;;38993:2153;;;;-1:-1:-1;38993:2153:0;-1:-1:-1;;;;38993:2153:0:o;36764:2221::-;28281:6;;36972:19;;;;28281:6;;;;;28280:7;28272:27;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;;;;28310:6;:13;;-1:-1:-1;;28310:13:0;;;;;-1:-1:-1;;;;;37040:17:0;::::1;28310:13:::0;37040:17;;;:8:::1;:17;::::0;;;;:23;28310:13;37040:23:::1;37032:42;;;::::0;;-1:-1:-1;;;37032:42:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;37032:42:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;37093:18:0;::::1;;::::0;;;:8:::1;:18;::::0;;;;:24;::::1;;37085:43;;;::::0;;-1:-1:-1;;;37085:43:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;37085:43:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;37167:26:0;;::::1;37141:23;37167:26:::0;;;:8:::1;:26;::::0;;;;;37231:27;;::::1;::::0;;;;37301:16:::1;::::0;::::1;::::0;37296:43:::1;::::0;7449:1:::1;6082:6;7442:8;::::0;37296:43:::1;37279:13;:60;;37271:81;;;::::0;;-1:-1:-1;;;37271:81:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;37271:81:0;;;;;;;;;;;;;::::1;;37365:20;37388:170;37416:8;:16;;;37447:8;:15;;;37477:9;:17;;;37509:9;:16;;;37540:7;;37388:13;:170::i;:::-;37365:193;;37596:8;37577:15;:27;;37569:51;;;::::0;;-1:-1:-1;;;37569:51:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;37569:51:0;;;;;;;;;;;;;::::1;;37650:199;37679:8;:16;;;37710:8;:15;;;37740:9;:17;;;37772:9;:16;;;37803:13;37831:7;;37650:14;:199::i;:::-;37633:216;;37886:12;37868:14;:30;;37860:48;;;::::0;;-1:-1:-1;;;37860:48:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;37860:48:0;;;;;;;;;;;;;::::1;;37940:37;37945:8;:16;;;37963:13;37940:4;:37::i;:::-;37921:8;:16;;:56;;;;38008:39;38013:9;:17;;;38032:14;38008:4;:39::i;:::-;37988:17;::::0;;::::1;:59:::0;;;38105:16;::::1;::::0;38136:15:::1;::::0;;::::1;::::0;38198:16;;::::1;::::0;38229:7:::1;::::0;38077:170:::1;::::0;37988:59;38198:16;38077:13:::1;:170::i;:::-;38060:187;;38284:15;38266:14;:33;;38258:52;;;::::0;;-1:-1:-1;;;38258:52:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;38258:52:0;;;;;;;;;;;;;::::1;;38347:8;38329:14;:26;;38321:48;;;::::0;;-1:-1:-1;;;38321:48:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;38321:48:0;;;;;;;;;;;;;::::1;;38407:35;38412:13;38427:14;38407:4;:35::i;:::-;38388:15;:54;;38380:73;;;::::0;;-1:-1:-1;;;38380:73:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;38380:73:0;;;;;;;;;;;;;::::1;;38501:8;-1:-1:-1::0;;;;;38471:70:0::1;38492:7;-1:-1:-1::0;;;;;38471:70:0::1;38480:10;-1:-1:-1::0;;;;;38471:70:0::1;;38511:13;38526:14;38471:70;;;;;;;;;;;;;;;;;;;;;;;;38554:51;38570:7;38579:10;38591:13;38554:15;:51::i;:::-;38616:22;38687:76;38714:7;38723:13;38738:8;38748:14;38687:26;:76::i;:::-;38649:114:::0;-1:-1:-1;38649:114:0;-1:-1:-1;38778:21:0;;38774:87:::1;;38820:41;38825:8;:16;;;38843:17;38820:4;:41::i;:::-;38801:16;::::0;::::1;:60:::0;38774:87:::1;38872:53;38888:8;38898:10;38910:14;38872:15;:53::i;60844:803::-:0;60896:33;60932:14;60947:4;60932:20;;;;;;;;;;;;;;;;;;;;60896:56;;60963:30;61011:10;:25;;;60996:12;:40;:83;;61067:12;60996:83;;;61039:10;:25;;;60996:83;60963:116;;61122:10;:26;;;61094:25;:54;61090:550;;;61165:13;61181:24;61199:4;61181:9;:24::i;:::-;61165:40;-1:-1:-1;61224:12:0;;61220:340;;61257:15;61275:57;61305:10;:26;;;61275:25;:29;;:57;;;;:::i;:::-;61257:75;;61351:23;61377:65;61433:8;61377:51;61423:4;61377:41;61392:10;:25;;;61377:10;:14;;:41;;;;:::i;:::-;:45;;:51::i;:65::-;61492:28;;;;61351:91;;-1:-1:-1;61492:52:0;;61351:91;61492:32;:52::i;:::-;61461:28;;;:83;-1:-1:-1;;61220:340:0;-1:-1:-1;61574:26:0;;;;;:54;-1:-1:-1;60844:803:0:o;23529:1183::-;23773:18;24060:21;24084:32;24089:13;24104:11;24084:4;:32::i;:::-;24060:56;;24127:8;24138:50;24143:35;6082:6;24161:16;24143:4;:35::i;:::-;24180:7;24138:4;:50::i;:::-;24127:61;;24199:26;24228:43;24233:13;24248:22;6082:6;24266:3;24248:4;:22::i;24228:43::-;24199:72;;24284:22;24309:43;24314:14;24330:21;24309:4;:43::i;:::-;24284:68;;24363:17;24383:39;24388:17;24407:14;24383:4;:39::i;:::-;24363:59;;24503:14;24520:36;24525:12;24539:16;24520:4;:36::i;:::-;24503:53;;24567:18;24588:27;24593:9;24604:10;24588:4;:27::i;:::-;24567:48;;24642:31;24647:13;24662:10;24642:4;:31::i;:::-;24626:47;23529:1183;-1:-1:-1;;;;;;;;;;;;;;23529:1183:0:o;33598:194::-;28281:6;;;;;;;28280:7;28272:27;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;;;;28310:6;:13;;-1:-1:-1;;28310:13:0;;;;;-1:-1:-1;;;;;33677:15:0;::::1;28310:13:::0;33677:15;;;:8:::1;:15;::::0;;;;:21;28310:13;33677:21:::1;33669:40;;;::::0;;-1:-1:-1;;;33669:40:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;33669:40:0;;;;;;;;;;;;;::::1;;33746:38;::::0;;-1:-1:-1;;;33746:38:0;;33778:4:::1;33746:38;::::0;::::1;::::0;;;-1:-1:-1;;;;;33746:23:0;::::1;::::0;::::1;::::0;:38;;;;;::::1;::::0;;;;;;;;:23;:38;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;33746:38:0;-1:-1:-1;;;;;33720:15:0;;::::1;;::::0;;;:8:::1;33746:38;33720:15:::0;;;;:23:::1;;:64:::0;28346:6;:14;;-1:-1:-1;;28346:14:0;;;33598:194::o;31253:173::-;28281:6;;;;;;;28280:7;28272:27;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;;;;28310:6;:13;;-1:-1:-1;;28310:13:0;;;;;31361:10:::1;::::0;31347::::1;-1:-1:-1::0;;;;;31361:10:0;;::::1;31347:24;31339:44;;;::::0;;-1:-1:-1;;;31339:44:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;31339:44:0;;;;;;;;;;;;;::::1;;31394:10;:24:::0;;-1:-1:-1;;;;;;31394:24:0::1;-1:-1:-1::0;;;;;31394:24:0;;;::::1;::::0;;;::::1;::::0;;28346:6;:14;;-1:-1:-1;;28346:14:0;;;31253:173::o;30640:136::-;28418:6;;30727:4;;28418:6;;;;;28417:7;28409:27;;;;;-1:-1:-1;;;28409:27:0;;;;;;;;;;;;-1:-1:-1;;;28409:27:0;;;;;;;;;;;;;;;-1:-1:-1;30756:12:0::1;::::0;30640:136;:::o;30425:207::-;28418:6;;30520:4;;28418:6;;;;;28417:7;28409:27;;;;;-1:-1:-1;;;28409:27:0;;;;;;;;;;;;-1:-1:-1;;;28409:27:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;30552:15:0;::::1;;::::0;;;:8:::1;:15;::::0;;;;:21;::::1;;30544:40;;;::::0;;-1:-1:-1;;;30544:40:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;30544:40:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;;30602:15:0::1;;::::0;;;:8:::1;:15;::::0;;;;:22:::1;;::::0;;30425:207::o;14921:87::-;14993:7;14986:14;;;;;;;;-1:-1:-1;;14986:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14960:13;;14986:14;;14993:7;;14986:14;;14993:7;14986:14;;;;;;;;;;;;;;;;;;;;;;;;18568:523;18780:14;18812:10;18825:35;18830:14;18846:13;18825:4;:35::i;:::-;18812:48;;18871:10;18884:37;18889:15;18906:14;18884:4;:37::i;:::-;18871:50;;18932:10;18945:18;18950:5;18957;18945:4;:18::i;:::-;18932:31;;18974:10;18987:45;6082:6;19005:26;6082:6;19023:7;19005:4;:26::i;:::-;18987:4;:45::i;:::-;18974:58;;19064:18;19069:5;19076;19064:4;:18::i;:::-;19052:30;18568:523;-1:-1:-1;;;;;;;;;;18568:523:0:o;52836:333::-;52894:12;52909:24;52927:4;52909:9;:24::i;:::-;52894:39;;52944:35;52959:10;52971:7;52944:14;:35::i;:::-;52990:11;53004:24;53022:4;53004:9;:24::i;:::-;52990:38;;53049:21;53054:6;53062:7;53049:4;:21::i;:::-;53039:31;;53125:36;53141:10;53153:7;53125:15;:36::i;16331:142::-;16399:4;16416:27;16422:10;16434:3;16439;16416:5;:27::i;:::-;-1:-1:-1;16461:4:0;16331:142;;;;:::o;59159:1457::-;28281:6;;;;;;;28280:7;28272:27;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;;;;28310:6;:13;;-1:-1:-1;;28310:13:0;;;;;59271:9:::1;::::0;28310:13;59271:9:::1;59263:26;;;::::0;;-1:-1:-1;;;59263:26:0;;::::1;;::::0;;::::1;::::0;;;;;;;;-1:-1:-1;;;59263:26:0;;;;;;;;;;;;;::::1;;59302:16;59321:13;:11;:13::i;:::-;59302:32;;59345:13;59361:27;59366:12;59380:7;;59361:4;:27::i;:::-;59345:43;;59399:20;59422:28;59427:12;59441:8;59422:4;:28::i;:::-;59399:51;;59461:10;59474:34;59479:15;59496:11;59474:4;:34::i;:::-;59461:47:::0;-1:-1:-1;59527:10:0;59519:29:::1;;;::::0;;-1:-1:-1;;;59519:29:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;59519:29:0;;;;;;;;;;;;;::::1;;59561:20;59584:21;59594:10;59584:9;:21::i;:::-;59561:44;;59638:12;59620:15;:30;59616:291;;;59667:20;59690:35;59695:12;59709:15;59690:4;:35::i;:::-;59770:10;59740:18;59761:20:::0;;;:8:::1;:20;::::0;;;;:27;59667:58;;-1:-1:-1;59811:32:0;;::::1;;59803:52;;;::::0;;-1:-1:-1;;;59803:52:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;59803:52:0;;;;;;;;;;;;;::::1;;59870:25;59879:15;59870:8;:25::i;:::-;59616:291;;;59919:40;59934:10;59946:12;59919:14;:40::i;:::-;59974:12:::0;;59970:78:::1;;60018:7;::::0;60003:33:::1;::::0;-1:-1:-1;;;;;60018:7:0::1;60027:8:::0;60003:14:::1;:33::i;:::-;60058:31;60073:15;60058:14;:31::i;:::-;60107:6;60102:507;60123:7;:14:::0;60119:18;::::1;60102:507;;;60159:9;60171:7;60179:1;60171:10;;;;;;;;;::::0;;;::::1;::::0;;;;;::::1;::::0;-1:-1:-1;;;;;60171:10:0::1;60207:11:::0;;;:8:::1;:11:::0;;;;;;:19:::1;;::::0;60171:10;;-1:-1:-1;60207:19:0;60263:16:::1;60268:5:::0;60207:19;60263:4:::1;:16::i;:::-;60241:38:::0;-1:-1:-1;60302:19:0;60294:38:::1;;;::::0;;-1:-1:-1;;;60294:38:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;60294:38:0;;;;;;;;;;;;;::::1;;60373:13;;60387:1;60373:16;;;;;;;;;;;;;60355:14;:34;;60347:52;;;::::0;;-1:-1:-1;;;60347:52:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;60347:52:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;60441:11:0;::::1;;::::0;;;:8:::1;:11;::::0;;;;:19:::1;;::::0;60436:41:::1;::::0;60462:14;60436:4:::1;:41::i;:::-;-1:-1:-1::0;;;;;60414:11:0;::::1;;::::0;;;:8:::1;:11;::::0;;;;;;;;:19:::1;;:63:::0;;;;60497:39;;;;;;;60414:11;;60506:10:::1;::::0;60497:39:::1;::::0;;;;;;;;::::1;60551:46;60567:1;60570:10;60582:14;60551:15;:46::i;:::-;-1:-1:-1::0;;;60139:3:0::1;;60102:507;;;-1:-1:-1::0;;28346:6:0;:14;;-1:-1:-1;;28346:14:0;;;-1:-1:-1;;;;;;;59159:1457:0:o;28898:21::-;;;;;;:::o;20109:697::-;20351:19;20388:16;20407:35;20412:13;20427:14;20407:4;:35::i;:::-;20388:54;;20453:15;20471:26;6082:6;20489:7;20471:4;:26::i;:::-;20453:44;;20521:31;20526:13;20541:10;20521:4;:31::i;:::-;20508:44;;20563:6;20572:54;20577:14;20593:32;20598:14;20614:10;20593:4;:32::i;20572:54::-;20563:63;;20637:8;20648:20;20653:1;20656:11;20648:4;:20::i;:::-;20637:31;;20679:8;20690:22;6082:6;20708:3;20690:4;:22::i;:::-;20679:33;;20740:26;20745:15;20762:3;20740:4;:26::i;:::-;20723:43;20109:697;-1:-1:-1;;;;;;;;;;;;20109:697:0:o;30242:175::-;28418:6;;30317:23;;28418:6;;;;;28417:7;28409:27;;;;;-1:-1:-1;;;28409:27:0;;;;;;;;;;;;-1:-1:-1;;;28409:27:0;;;;;;;;;;;;;;;30366:9:::1;::::0;::::1;;30358:26;;;::::0;;-1:-1:-1;;;30358:26:0;;::::1;;::::0;;::::1;::::0;;;;;;;;-1:-1:-1;;;30358:26:0;;;;;;;;;;;;;::::1;;30402:7;30395:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;;-1:-1:-1;;;;;30395:14:0::1;::::0;;;;;::::1;::::0;::::1;;::::0;;::::1;;;;;;;;;;30242:175:::0;:::o;57222:936::-;-1:-1:-1;;;;;57355:18:0;;57305:13;57355:18;;;:8;:18;;;;;57420:14;:20;;57305:13;;57420:14;:20;;;;;;;;;;;;;;;;;;;;57384:56;;57451:23;57477:10;:28;;;57451:54;;57516:13;57532:24;57550:4;57532:9;:24::i;:::-;57516:40;;57567:30;57615:10;:25;;;57600:12;:40;:83;;57671:12;57600:83;;;57643:10;:25;;;57600:83;57567:116;;57726:10;:26;;;57698:25;:54;:71;;;;-1:-1:-1;57756:13:0;;;57698:71;57694:363;;;57786:15;57804:57;57834:10;:26;;;57804:25;:29;;:57;;;;:::i;:::-;57786:75;;57876:23;57902:65;57958:8;57902:51;57948:4;57902:41;57917:10;:25;;;57902:10;:14;;:41;;;;:::i;:65::-;57876:91;-1:-1:-1;58003:42:0;:18;57876:91;58003:22;:42::i;:::-;57982:63;;57694:363;;;58128:21;;;;;;;:15;;;:21;;;;;;58078:11;;:72;;58128:21;58078:45;;58118:4;;58078:35;;58094:18;58078:15;:35::i;:72::-;58067:83;57222:936;-1:-1:-1;;;;;;;;57222:936:0:o;49317:381::-;49267:10;;-1:-1:-1;;;;;49267:10:0;49253;:24;49245:44;;;;;-1:-1:-1;;;49245:44:0;;;;;;;;;;;;-1:-1:-1;;;49245:44:0;;;;;;;;;;;;;;;49456:10:::1;::::0;-1:-1:-1;;;;;49456:10:0::1;49448:33:::0;49440:62:::1;;;::::0;;-1:-1:-1;;;49440:62:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;49543:7;49520:19;;:30;;49513:38;;;;49613:19;:42:::0;49666:10:::1;:24:::0;;-1:-1:-1;;;;;;49666:24:0::1;-1:-1:-1::0;;;;;49666:24:0;;;::::1;::::0;;;::::1;::::0;;49317:381::o;28525:22::-;;;-1:-1:-1;;;;;28525:22:0;;:::o;48851:28::-;;;-1:-1:-1;;;;;48851:28:0;;:::o;30099:135::-;28418:6;;30171:23;;28418:6;;;;;28417:7;28409:27;;;;;-1:-1:-1;;;28409:27:0;;;;;;;;;;;;-1:-1:-1;;;28409:27:0;;;;;;;;;;;;;;29983:108;30069:7;:14;29983:108;:::o;15666:252::-;15796:10;15733:4;15785:22;;;:10;:22;;;;;;;;-1:-1:-1;;;;;15785:27:0;;;;;;;;;;15780:38;;15814:3;15780:4;:38::i;:::-;15761:10;15750:22;;;;:10;:22;;;;;;;;-1:-1:-1;;;;;15750:27:0;;;;;;;;;;;;:68;;;15834:54;;;;;;15750:27;;15834:54;;;;;;;;;;;-1:-1:-1;15906:4:0;15666:252;;;;:::o;58229:444::-;58320:10;58287:21;58311:20;;;:8;:20;;;;;58357:11;;58311:20;;58379:35;;58357:11;58379:14;:35::i;:::-;58439:1;58425:15;;;58482:14;:21;;58515:106;58543:16;58536:23;;:4;:23;;;58515:106;;;58584:21;;;58608:1;58584:21;;;:15;;;;:21;;;;;:25;;;;58561:6;58515:106;;;-1:-1:-1;58636:29:0;;;;;;;;58645:10;;58636:29;;;;;;;;;;58229:444;;;:::o;15106:129::-;-1:-1:-1;;;;;15207:15:0;;;15183:4;15207:15;;;:10;:15;;;;;;;;:20;;;;;;;;;;;;;15106:129::o;29620:232::-;29682:9;;;;29681:10;29673:26;;;;;-1:-1:-1;;;29673:26:0;;;;;;;;;;;;-1:-1:-1;;;29673:26:0;;;;;;;;;;;;;;;29732:7;;-1:-1:-1;;;;;29732:7:0;29718:10;:21;29710:39;;;;;-1:-1:-1;;;29710:39:0;;;;;;;;;;;;-1:-1:-1;;;29710:39:0;;;;;;;;;;;;;;;6705:11;29768:31;;;29760:55;;;;;-1:-1:-1;;;29760:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;29826:7;:18;29620:232::o;49706:121::-;49267:10;;-1:-1:-1;;;;;49267:10:0;49253;:24;49245:44;;;;;-1:-1:-1;;;49245:44:0;;;;;;;;;;;;-1:-1:-1;;;49245:44:0;;;;;;;;;;;;;;;49789:13:::1;:30:::0;;-1:-1:-1;;;;;;49789:30:0::1;-1:-1:-1::0;;;;;49789:30:0;;;::::1;::::0;;;::::1;::::0;;49706:121::o;28795:24::-;;;;:::o;48811:33::-;;;-1:-1:-1;;;;;48811:33:0;;:::o;30784:256::-;28418:6;;30877:4;;28418:6;;;;;28417:7;28409:27;;;;;-1:-1:-1;;;28409:27:0;;;;;;;;;;;;-1:-1:-1;;;28409:27:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;30909:15:0;::::1;;::::0;;;:8:::1;:15;::::0;;;;:21;::::1;;30901:40;;;::::0;;-1:-1:-1;;;30901:40:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;30901:40:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;30966:15:0;::::1;30952:11;30966:15:::0;;;:8:::1;:15;::::0;;;;:22:::1;;::::0;31019:12:::1;::::0;31006:26:::1;::::0;30966:22;;31006:4:::1;:26::i;:::-;30999:33:::0;30784:256;-1:-1:-1;;;30784:256:0:o;60624:212::-;60697:14;:21;60666:22;60730:99;60758:16;60751:23;;:4;:23;;;60730:99;;;60799:18;60812:4;60799:12;:18::i;:::-;60776:6;;60730:99;;;;60624:212;:::o;28602:25::-;;;-1:-1:-1;;;;;28602:25:0;;:::o;51798:213::-;28281:6;;;;;;;28280:7;28272:27;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;-1:-1:-1;;;28272:27:0;;;;;;;;;;;;;;;28310:6;:13;;-1:-1:-1;;28310:13:0;;;;;51901:50:::1;51911:10;51923:13:::0;51938:12;;51901:9:::1;:50::i;:::-;51962:41;51977:10;51989:13;51962:14;:41::i;:::-;-1:-1:-1::0;;28346:6:0;:14;;-1:-1:-1;;28346:14:0;;;-1:-1:-1;51798:213:0:o;31048:197::-;28418:6;;31132:4;;28418:6;;;;;28417:7;28409:27;;;;;-1:-1:-1;;;28409:27:0;;;;;;;;;;;;-1:-1:-1;;;28409:27:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;31164:15:0;::::1;;::::0;;;:8:::1;:15;::::0;;;;:21;::::1;;31156:40;;;::::0;;-1:-1:-1;;;31156:40:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;31156:40:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;;31214:15:0::1;;::::0;;;:8:::1;:15;::::0;;;;:23:::1;;::::0;;31048:197::o;21824:686::-;22067:18;22103:16;22122:35;22127:14;22143:13;22122:4;:35::i;:::-;22103:54;;22168:9;22180:37;22185:15;22202:14;22180:4;:37::i;:::-;22168:49;;22228:6;22237:27;22242:15;22259:4;22237;:27::i;:::-;22228:36;;22275:8;22286:20;22291:1;22294:11;22286:4;:20::i;:::-;22275:31;;22323:22;22328:3;6082:6;22323:4;:22::i;:::-;22317:28;;22372:26;6082:6;22390:7;22372:4;:26::i;:::-;22356:42;;22425:46;22430:25;22435:14;22451:3;22430:4;:25::i;:::-;22457:13;22425:4;:46::i;:::-;22409:62;21824:686;-1:-1:-1;;;;;;;;;;;21824:686:0:o;14173:257::-;-1:-1:-1;;;;;14252:13:0;;:8;:13;;;;;;;;;;;:20;-1:-1:-1;14252:20:0;14244:37;;;;;-1:-1:-1;;;14244:37:0;;;;;;;;;;;;;;;-1:-1:-1;;;14244:37:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;14313:13:0;;:8;:13;;;;;;;;;;;14308:24;;14328:3;14308:4;:24::i;:::-;-1:-1:-1;;;;;14292:13:0;;;:8;:13;;;;;;;;;;;:40;;;;14364:13;;;;;;;14359:24;;14379:3;14359:4;:24::i;:::-;-1:-1:-1;;;;;14343:13:0;;;:8;:13;;;;;;;;;;;;:40;;;;14399:23;;;;;;;14343:13;;14399:23;;;;;;;;;;;;;14173:257;;;:::o;8643:198::-;8714:4;8737:6;8745:9;8758:14;8767:1;8770;8758:8;:14::i;:::-;8736:36;;;;8792:4;8791:5;8783:31;;;;;-1:-1:-1;;;8783:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8832:1:0;8643:198;-1:-1:-1;;;8643:198:0:o;902:181::-;960:7;992:5;;;1016:6;;;;1008:46;;;;;-1:-1:-1;;;1008:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;2256:471;2314:7;2559:6;2555:47;;-1:-1:-1;2589:1:0;2582:8;;2555:47;2626:5;;;2630:1;2626;:5;:1;2650:5;;;;;:10;2642:56;;;;-1:-1:-1;;;2642:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3203:132;3261:7;3288:39;3292:1;3295;3288:39;;;;;;;;;;;;;;;;;:3;:39::i;44878:104::-;44957:17;44963:2;44967:6;44957:5;:17::i;9080:317::-;9151:4;9183:5;;;9207:6;;;:21;;;9227:1;9222;9217:2;:6;;;;;;:11;9207:21;9199:46;;;;;-1:-1:-1;;;9199:46:0;;;;;;;;;;;;-1:-1:-1;;;9199:46:0;;;;;;;;;;;;;;;9272:15;9266:22;;9307:8;;;;9299:33;;;;;-1:-1:-1;;;9299:33:0;;;;;;;;;;;;-1:-1:-1;;;9299:33:0;;;;;;;;;;;;;;;9343:7;6082:6;9353:2;:16;;;9080:317;-1:-1:-1;;;;;;9080:317:0:o;44762:108::-;44843:19;44849:4;44855:6;44843:5;:19::i;45086:88::-;45153:13;45159:6;45153:5;:13::i;:::-;45086:88;:::o;45182:1024::-;45449:12;;45316:21;;45419:15;;45449:16;45445:754;;45518:7;;45508:35;;;-1:-1:-1;;;45508:35:0;;;;45482:23;;-1:-1:-1;;;;;45518:7:0;;45508:33;;:35;;;;;;;;;;;;;;45518:7;45508:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45508:35:0;;-1:-1:-1;;;;;;45562:27:0;;;;;;;45558:630;;;45629:53;45634:34;45639:14;45655:12;;45634:4;:34::i;:::-;6082:6;45629:4;:53::i;:::-;45727:7;;45610:72;;-1:-1:-1;45701:52:0;;45717:8;;-1:-1:-1;;;;;45727:7:0;45610:72;45701:15;:52::i;:::-;45777:46;;;;;;;;-1:-1:-1;;;;;45777:46:0;;;;;;;;;;;;;45558:630;;;45864:24;45891:54;45896:35;45901:15;45918:12;;45896:4;:35::i;45891:54::-;45991:7;;45864:81;;-1:-1:-1;45964:56:0;;45980:9;;-1:-1:-1;;;;;45991:7:0;45864:81;45964:15;:56::i;:::-;46056:42;46061:15;46078:19;46056:4;:42::i;:::-;46122:50;;;;;;;;46039:59;;-1:-1:-1;;;;;;46122:50:0;;;;;;;;;;;;45558:630;;45445:754;;45182:1024;;;;;;;:::o;44407:347::-;44611:46;;;-1:-1:-1;;;;;44611:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;44611:46:0;;;44600:58;;;;44565:12;;44579:17;;44600:10;;;;44611:46;44600:58;;;44611:46;44600:58;;44611:46;44600:58;;;;;;;;;;-1:-1:-1;;44600:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44564:94;;;;44677:7;:57;;;;-1:-1:-1;44689:11:0;;:16;;:44;;;44720:4;44709:24;;;;;;;;;;;;;;;-1:-1:-1;44709:24:0;44689:44;44669:77;;;;;-1:-1:-1;;;44669:77:0;;;;;;;;;;;;-1:-1:-1;;;44669:77:0;;;;;;;;;;;;;;;44407:347;;;;;:::o;52019:809::-;52133:9;;;;52125:26;;;;;-1:-1:-1;;;52125:26:0;;;;;;;;;;;;;;;-1:-1:-1;;;52125:26:0;;;;;;;;;;;;;;;52164:16;52183:13;:11;:13::i;:::-;52164:32;;52207:10;52220:32;52225:13;52240:11;52220:4;:32::i;:::-;52207:45;-1:-1:-1;52271:10:0;52263:29;;;;;-1:-1:-1;;;52263:29:0;;;;;;;;;;;;-1:-1:-1;;;52263:29:0;;;;;;;;;;;;;;;52310:6;52305:476;52326:7;:14;52322:18;;52305:476;;;52362:9;52374:7;52382:1;52374:10;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52374:10:0;52410:11;;;:8;:11;;;;;;:19;;;52374:10;;-1:-1:-1;52410:19:0;52465:16;52470:5;52410:19;52465:4;:16::i;:::-;52444:37;-1:-1:-1;52504:18:0;;;;;:54;;;52543:12;;52556:1;52543:15;;;;;;;;;;;;;52526:13;:32;;52504:54;52496:81;;;;;-1:-1:-1;;;52496:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52619:11:0;;;;;;:8;:11;;;;;:19;;;52614:40;;52640:13;52614:4;:40::i;:::-;-1:-1:-1;;;;;52592:11:0;;;;;;;:8;:11;;;;;;;;;:19;;:62;;;;52674:35;;;;;;;52592:11;;52674:35;;;;;;;;;;;;;52724:45;52740:1;52743:10;52755:13;52724:15;:45::i;:::-;-1:-1:-1;;;52342:3:0;;52305:476;;;;52791:29;52806:13;52791:14;:29::i;53177:543::-;-1:-1:-1;;;;;53278:18:0;;53254:21;53278:18;;;:8;:18;;;;;53307:23;53287:8;53307:13;:23::i;:::-;53355:11;;:24;;53371:7;53355:15;:24::i;:::-;53341:38;;53421:14;:21;53341:11;53454:170;53482:16;53475:23;;:4;:23;;;53454:170;;;53547:65;53607:4;53547:55;53563:14;53578:4;53563:20;;;;;;;;;53547:65;53523:21;;;;;;;:15;;;;:21;;;;;;:89;;;;53500:6;53454:170;;;-1:-1:-1;53655:15:0;53634:18;;;:36;53686:26;;;;;;;;-1:-1:-1;;;;;53686:26:0;;;;;;;;;;;;;53177:543;;;;:::o;8459:176::-;8530:4;8561:5;;;8585:6;;;;8577:31;;;;;-1:-1:-1;;;8577:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;44990:88;45057:13;45063:6;45057:5;:13::i;44026:373::-;44239:63;;;-1:-1:-1;;;;;44239:63:0;;;;;;;44288:4;44239:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;44239:63:0;;;44228:75;;;;44193:12;;44207:17;;44228:10;;;;44239:63;44228:75;;;44239:63;44228:75;;44239:63;44228:75;;;;;;;;;;-1:-1:-1;;44228:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44192:111;;;;44322:7;:57;;;;-1:-1:-1;44334:11:0;;:16;;:44;;;44365:4;44354:24;;;;;;;;;;;;;;;-1:-1:-1;44354:24:0;44334:44;44314:77;;;;;-1:-1:-1;;;44314:77:0;;;;;;;;;;;;-1:-1:-1;;;44314:77:0;;;;;;;;;;;;;;1366:136;1424:7;1451:43;1455:1;1458;1451:43;;;;;;;;;;;;;;;;;:3;:43::i;9405:389::-;9476:4;9506:6;9498:27;;;;;-1:-1:-1;;;9498:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;6082:6;9546:15;;9580:6;;;:31;;;6082:6;9595:1;9590:2;:6;;;;;;:21;9580:31;9572:56;;;;;-1:-1:-1;;;9572:56:0;;;;;;;;;;;;-1:-1:-1;;;9572:56:0;;;;;;;;;;;;;;;9676:1;9672:5;;9666:12;;9697:8;;;;9689:33;;;;;-1:-1:-1;;;9689:33:0;;;;;;;;;;;;-1:-1:-1;;;9689:33:0;;;;;;;;;;;;;;;9750:7;9765:1;9760:2;:6;;;;10304:558;10380:4;7239:5;10410:4;:28;;10402:53;;;;;-1:-1:-1;;;10402:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;7299:18;10474:28;;;10466:54;;;;;-1:-1:-1;;;10466:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;10533:10;10547:11;10554:3;10547:6;:11::i;:::-;10533:25;;10572:11;10586:16;10591:3;10596:5;10586:4;:16::i;:::-;10572:30;;10615:13;10631:24;10637:4;10643:11;10648:5;10643:4;:11::i;:::-;10631:5;:24::i;:::-;10615:40;-1:-1:-1;10672:11:0;10668:59;;10707:8;-1:-1:-1;10700:15:0;;-1:-1:-1;;10700:15:0;10668:59;10739:18;10760:47;10771:4;10777:6;7372:13;10760:10;:47::i;:::-;10739:68;;10825:29;10830:8;10840:13;10825:4;:29::i;:::-;10818:36;10304:558;-1:-1:-1;;;;;;;10304:558:0:o;46262:581::-;46427:12;;46354:23;;46427:16;46423:413;;46496:7;;46486:35;;;-1:-1:-1;;;46486:35:0;;;;46460:23;;-1:-1:-1;;;;;46496:7:0;;46486:33;;:35;;;;;;;;;;;;;;46496:7;46486:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;46486:35:0;;-1:-1:-1;;;;;;46540:29:0;;;46536:289;;46611:53;46616:34;46621:14;46637:12;;46616:4;:34::i;46611:53::-;46709:7;;46590:74;;-1:-1:-1;46683:54:0;;46699:8;;-1:-1:-1;;;;;46709:7:0;46590:74;46683:15;:54::i;:::-;46761:48;;;;;;;;-1:-1:-1;;;;;46761:48:0;;;;;;;;;;;;;46536:289;46423:413;46262:581;;;;:::o;8849:223::-;8924:4;8930;8961:1;8956;:6;8952:113;;-1:-1:-1;;8987:5:0;;;8994;8979:21;;8952:113;-1:-1:-1;;9041:5:0;;;9048:4;8952:113;8849:223;;;;;:::o;3831:278::-;3917:7;3952:12;3945:5;3937:28;;;;-1:-1:-1;;;3937:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3976:9;3992:1;3988;:5;;;;;;;3831:278;-1:-1:-1;;;;;3831:278:0:o;14438:94::-;14495:29;14509:4;14516:2;14520:3;14495:5;:29::i;14540:98::-;14599:31;14605:4;14619;14626:3;14599:5;:31::i;13889:276::-;13959:4;13942:8;:23;;;;;;;;;;;:30;-1:-1:-1;13942:30:0;13934:47;;;;;-1:-1:-1;;;13934:47:0;;;;;;;;;;;;;;;-1:-1:-1;;;13934:47:0;;;;;;;;;;;;;;;14040:4;14023:8;:23;;;;;;;;;;;14018:34;;14048:3;14018:4;:34::i;:::-;14009:4;13992:8;:23;;;;;;;;;;:60;14083:12;;14078:23;;14097:3;14078:4;:23::i;:::-;14063:12;:38;14117:40;;;;;;;;14149:1;;14134:4;;14117:40;;;;;;;;;13889:276;:::o;13663:218::-;13756:4;13739:8;:23;;;;;;;;;;;13734:34;;13764:3;13734:4;:34::i;:::-;13725:4;13708:8;:23;;;;;;;;;;:60;13799:12;;13794:23;;13813:3;13794:4;:23::i;:::-;13779:12;:38;13833:40;;;;;;;;13862:4;;13850:1;;13833:40;;;;;;;;;13663:218;:::o;1805:192::-;1891:7;1927:12;1919:6;;;;1911:29;;;;-1:-1:-1;;;1911:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1963:5:0;;;1805:192::o;8328:123::-;8393:4;6082:6;8422:7;8427:1;8422:4;:7::i;:::-;:21;;8328:123;-1:-1:-1;;8328:123:0:o;8204:116::-;6082:6;8297:15;;;8204:116::o;9822:321::-;9894:4;;9929:1;9925;:5;:28;;6082:6;9925:28;;;9938:1;9925:28;9916:37;-1:-1:-1;9976:1:0;9971:6;;;;9966:151;9979:6;;9966:151;;10014:10;10019:1;10022;10014:4;:10::i;:::-;10010:14;-1:-1:-1;10049:1:0;10045;:5;:10;10041:65;;10080:10;10085:1;10088;10080:4;:10::i;:::-;10076:14;;10041:65;9992:1;9987:6;;;;9966:151;;10870:1108;10968:4;11023:3;10968:4;;11060:27;11069:4;6082:6;11060:8;:27::i;:::-;11037:50;;-1:-1:-1;11037:50:0;-1:-1:-1;6082:6:0;;11098:9;11439:1;11425:523;11450:9;11442:4;:17;11425:523;;11481:9;6082:6;11493:1;:15;11481:27;;11524:6;11532:9;11545:36;11554:1;11557:23;11562:4;6082:6;11557:4;:23::i;:::-;11545:8;:36::i;:::-;11523:58;;;;11603:22;11608:4;11614:10;11619:1;11622;11614:4;:10::i;11603:22::-;11596:29;;11647:16;11652:4;11658;11647;:16::i;:::-;11640:23;-1:-1:-1;11682:9:0;11678:20;;11693:5;;;;;11678:20;11719:4;11715:30;;;11736:9;;;11715:30;11764:4;11760:30;;;11781:9;;;11760:30;11809:8;11805:132;;;11844:15;11849:3;11854:4;11844;:15::i;:::-;11838:21;;11805:132;;;11906:15;11911:3;11916:4;11906;:15::i;:::-;11900:21;;11805:132;-1:-1:-1;;;11461:3:0;;11425:523;;;-1:-1:-1;11967:3:0;;10870:1108;-1:-1:-1;;;;;;;;;10870:1108:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;

Swarm Source

ipfs://ed25ab735b494d192255c92c5c826f77a35050dad2cc13156cffa6332de25c32
Block Transaction Difficulty Gas Used Reward
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.