ETH Price: $1,827.04 (-2.75%)

Contract

0x88E8a1143e561f5A5ca64e1c843F81912b765F82
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Withdraw All105169112020-07-23 17:00:471714 days ago1595523647IN
0x88E8a114...12b765F82
0 ETH0.00571678113
Close Strategies105166082020-07-23 15:54:071714 days ago1595519647IN
0x88E8a114...12b765F82
0 ETH0.06706222101.25
Close Strategies105166062020-07-23 15:53:201714 days ago1595519600IN
0x88E8a114...12b765F82
0 ETH0.06544496101.25
Collect Usd For ...105165792020-07-23 15:46:271714 days ago1595519187IN
0x88E8a114...12b765F82
0 ETH0.0456941790
Collect Usd For ...105122502020-07-22 23:43:461715 days ago1595461426IN
0x88E8a114...12b765F82
0 ETH0.0176146647
Collect Usd For ...105118812020-07-22 22:27:121715 days ago1595456832IN
0x88E8a114...12b765F82
0 ETH0.0128076544
Withdraw All103170152020-06-22 17:50:151745 days ago1592848215IN
0x88E8a114...12b765F82
0 ETH0.0023271846
Close Strategies103168952020-06-22 17:24:221745 days ago1592846662IN
0x88E8a114...12b765F82
0 ETH0.0300863146.25
Collect Usd For ...103168912020-06-22 17:23:531745 days ago1592846633IN
0x88E8a114...12b765F82
0 ETH0.040703550.6
Collect Usd For ...103168572020-06-22 17:15:111745 days ago1592846111IN
0x88E8a114...12b765F82
0 ETH0.018073350.6
Collect Usd For ...103167822020-06-22 16:57:281745 days ago1592845048IN
0x88E8a114...12b765F82
0 ETH0.0021674849.5198
Set Admin Permis...102761912020-06-16 10:11:061751 days ago1592302266IN
0x88E8a114...12b765F82
0 ETH0.0024368237
Accept Owner102760672020-06-16 9:44:081751 days ago1592300648IN
0x88E8a114...12b765F82
0 ETH0.0010929138
Change Owner102330902020-06-09 18:16:211758 days ago1591726581IN
0x88E8a114...12b765F82
0 ETH0.001301730

Latest 23 internal transactions

Advanced mode:
Parent Transaction Hash Method Block
From
To
-105169112020-07-23 17:00:471714 days ago1595523647
0x88E8a114...12b765F82
0.20350353 ETH
-105166082020-07-23 15:54:071714 days ago1595519647
0x88E8a114...12b765F82
0.14390873 ETH
-105166082020-07-23 15:54:071714 days ago1595519647
0x88E8a114...12b765F82
75.0123207 ETH
-105166082020-07-23 15:54:071714 days ago1595519647
0x88E8a114...12b765F82
75.0123207 ETH
-105166062020-07-23 15:53:201714 days ago1595519600
0x88E8a114...12b765F82
0.15002465 ETH
-105166062020-07-23 15:53:201714 days ago1595519600
0x88E8a114...12b765F82
0.15002465 ETH
-105165792020-07-23 15:46:271714 days ago1595519187
0x88E8a114...12b765F82
0.05947893 ETH
-105165792020-07-23 15:46:271714 days ago1595519187
0x88E8a114...12b765F82
74.448894 ETH
-105165792020-07-23 15:46:271714 days ago1595519187
0x88E8a114...12b765F82
74.448894 ETH
-105122502020-07-22 23:43:461715 days ago1595461426
0x88E8a114...12b765F82
0.00011586 ETH
-105122502020-07-22 23:43:461715 days ago1595461426
0x88E8a114...12b765F82
0.149765 ETH
-105122502020-07-22 23:43:461715 days ago1595461426
0x88E8a114...12b765F82
0.149765 ETH
-105118812020-07-22 22:27:121715 days ago1595456832
0x88E8a114...12b765F82
74.952674 ETH
-105118812020-07-22 22:27:121715 days ago1595456832
0x88E8a114...12b765F82
74.952674 ETH
-103170152020-06-22 17:50:151745 days ago1592848215
0x88E8a114...12b765F82
0.17834041 ETH
-103168952020-06-22 17:24:221745 days ago1592846662
0x88E8a114...12b765F82
0.09567517 ETH
-103168952020-06-22 17:24:221745 days ago1592846662
0x88E8a114...12b765F82
113.75020765 ETH
-103168952020-06-22 17:24:221745 days ago1592846662
0x88E8a114...12b765F82
113.75020765 ETH
-103168912020-06-22 17:23:531745 days ago1592846633
0x88E8a114...12b765F82
0.08266524 ETH
-103168912020-06-22 17:23:531745 days ago1592846633
0x88E8a114...12b765F82
113.444657 ETH
-103168912020-06-22 17:23:531745 days ago1592846633
0x88E8a114...12b765F82
113.444657 ETH
-103168572020-06-22 17:15:111745 days ago1592846111
0x88E8a114...12b765F82
113.465379 ETH
-103168572020-06-22 17:15:111745 days ago1592846111
0x88E8a114...12b765F82
113.465379 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
DfFinanceCloseCompound

Compiler Version
v0.5.17+commit.d19bba13

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-06-09
*/

pragma solidity ^0.5.16;

contract Ownable {
    address payable public owner;
    address payable internal newOwnerCandidate;

    constructor() public {
        owner = msg.sender;
    }

    modifier onlyOwner {
        require(msg.sender == owner, "Permission denied");
        _;
    }

    function changeOwner(address payable newOwner) public onlyOwner {
        newOwnerCandidate = newOwner;
    }

    function acceptOwner() public {
        require(msg.sender == newOwnerCandidate, "Permission denied");
        owner = newOwnerCandidate;
    }
}

// import "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol";
// import "./SafeMath.sol";

// import "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol";

/**
 * @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.
     *
     * _Available since v2.4.0._
     */
    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.
     *
     * _Available since v2.4.0._
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        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.
     *
     * _Available since v2.4.0._
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

// import "@openzeppelin/contracts-ethereum-package/contracts/utils/Address.sol";

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * This test is non-exhaustive, and there may be false-negatives: during the
     * execution of a contract's constructor, its address will be reported as
     * not containing a contract.
     *
     * IMPORTANT: It is unsafe to assume that an address for which this
     * function returns false is an externally-owned account (EOA) and not a
     * contract.
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies in extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != 0x0 && codehash != accountHash);
    }

    /**
     * @dev Converts an `address` into `address payable`. Note that this is
     * simply a type cast: the actual underlying value is not changed.
     *
     * _Available since v2.4.0._
     */
    function toPayable(address account) internal pure returns (address payable) {
        return address(uint160(account));
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     *
     * _Available since v2.4.0._
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-call-value
        (bool success, ) = recipient.call.value(amount)("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }
}

interface IToken {
    function decimals() external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);
    function balanceOf(address account) external view returns (uint);
    function approve(address spender, uint value) external;
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);
    function deposit() external payable;
    function withdraw(uint amount) external;
}

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {

    using SafeMath for uint256;
    using Address for address;

    function safeTransfer(IToken token, address to, uint256 value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IToken token, address from, address to, uint256 value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    function safeApprove(IToken token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IToken token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).add(value);
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IToken token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value);
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function callOptionalReturn(IToken token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves.

        // A Solidity high level call has three parts:
        //  1. The target address is checked to verify it contains contract code
        //  2. The call itself is made, and success asserted
        //  3. The return value is decoded, which in turn checks the size of the returned data.
        // solhint-disable-next-line max-line-length
        require(address(token).isContract(), "SafeERC20: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = address(token).call(data);
        require(success, "SafeERC20: low-level call failed");

        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

library UniversalERC20 {

    using SafeMath for uint256;
    using SafeERC20 for IToken;

    IToken private constant ZERO_ADDRESS = IToken(0x0000000000000000000000000000000000000000);
    IToken private constant ETH_ADDRESS = IToken(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);

    function universalTransfer(IToken token, address to, uint256 amount) internal {
        universalTransfer(token, to, amount, false);
    }

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

        if (token == ZERO_ADDRESS || token == ETH_ADDRESS) {
            if (mayFail) {
                return address(uint160(to)).send(amount);
            } else {
                address(uint160(to)).transfer(amount);
                return true;
            }
        } else {
            token.safeTransfer(to, amount);
            return true;
        }
    }

    function universalApprove(IToken token, address to, uint256 amount) internal {
        if (token != ZERO_ADDRESS && token != ETH_ADDRESS) {
            token.safeApprove(to, amount);
        }
    }

    function universalTransferFrom(IToken token, address from, address to, uint256 amount) internal {
        if (amount == 0) {
            return;
        }

        if (token == ZERO_ADDRESS || token == ETH_ADDRESS) {
            require(from == msg.sender && msg.value >= amount, "msg.value is zero");
            if (to != address(this)) {
                address(uint160(to)).transfer(amount);
            }
            if (msg.value > amount) {
                msg.sender.transfer(uint256(msg.value).sub(amount));
            }
        } else {
            token.safeTransferFrom(from, to, amount);
        }
    }

    function universalBalanceOf(IToken token, address who) internal view returns (uint256) {
        if (token == ZERO_ADDRESS || token == ETH_ADDRESS) {
            return who.balance;
        } else {
            return token.balanceOf(who);
        }
    }
}

contract FundsMgr is Ownable {
    using UniversalERC20 for IToken;

    function withdraw(address token, uint256 amount) public onlyOwner {
        if (token == address(0x0)) {
            owner.transfer(amount);
        } else {
            IToken(token).universalTransfer(owner, amount);
        }
    }

    function withdrawAll(address[] memory tokens) public onlyOwner {
        for(uint256 i = 0; i < tokens.length;i++) {
            withdraw(tokens[i], IToken(tokens[i]).universalBalanceOf(address(this)));
        }
    }
}

interface IGST2 {
	function freeUpTo(uint256 value) external returns(uint256 freed);
	function freeFromUpTo(address from, uint256 value) external returns(uint256 freed);
    function balanceOf(address account) external view returns (uint256);
}

contract GasTokenSpender {

    address public constant GAS_TOKEN = 0x0000000000b3F879cb30FE243b4Dfee438691c04;

    // ** PUBLIC VIEW functions **

    function gasTokenBalance() public view returns(uint256 amount) {
        amount = IGST2(GAS_TOKEN).balanceOf(address(this));
    }

    // ** INTERNAL functions **

    function _burnGasToken(uint256 gasSpent) internal returns(bool) {
        uint maxTokens = gasTokenBalance();
        if (maxTokens == 0) {
            return false;
        }

        uint tokensToBurn = (gasSpent + 14154) / 41130;
        if (tokensToBurn > maxTokens) {
            tokensToBurn = maxTokens;
        }

        IGST2(GAS_TOKEN).freeUpTo(tokensToBurn);

        return true;
    }
}

contract DSMath {
    function add(uint x, uint y) internal pure returns (uint z) {
        require((z = x + y) >= x);
    }
    function sub(uint x, uint y) internal pure returns (uint z) {
        require((z = x - y) <= x);
    }
    function mul(uint x, uint y) internal pure returns (uint z) {
        require(y == 0 || (z = x * y) / y == x);
    }

    function min(uint x, uint y) internal pure returns (uint z) {
        return x <= y ? x : y;
    }
    function max(uint x, uint y) internal pure returns (uint z) {
        return x >= y ? x : y;
    }
    function imin(int x, int y) internal pure returns (int z) {
        return x <= y ? x : y;
    }
    function imax(int x, int y) internal pure returns (int z) {
        return x >= y ? x : y;
    }

    uint constant WAD = 10 ** 18;
    uint constant RAY = 10 ** 27;

    function wmul(uint x, uint y, uint base) internal pure returns (uint z) {
        z = add(mul(x, y), base / 2) / base;
    }

    function wmul(uint x, uint y) internal pure returns (uint z) {
        z = add(mul(x, y), WAD / 2) / WAD;
    }
    function rmul(uint x, uint y) internal pure returns (uint z) {
        z = add(mul(x, y), RAY / 2) / RAY;
    }
    function wdiv(uint x, uint y) internal pure returns (uint z) {
        z = add(mul(x, WAD), y / 2) / y;
    }
    function rdiv(uint x, uint y) internal pure returns (uint z) {
        z = add(mul(x, RAY), y / 2) / y;
    }

    // This famous algorithm is called "exponentiation by squaring"
    // and calculates x^n with x as fixed-point and n as regular unsigned.
    //
    // It's O(log n), instead of O(n) for naive repeated multiplication.
    //
    // These facts are why it works:
    //
    //  If n is even, then x^n = (x^2)^(n/2).
    //  If n is odd,  then x^n = x * x^(n-1),
    //   and applying the equation for even x gives
    //    x^n = x * (x^2)^((n-1) / 2).
    //
    //  Also, EVM division is flooring and
    //    floor[(n-1) / 2] = floor[n / 2].
    //
    /*function rpow(uint x, uint n) internal pure returns (uint z) {
        z = n % 2 != 0 ? x : RAY;

        for (n /= 2; n != 0; n /= 2) {
            x = rmul(x, x);

            if (n % 2 != 0) {
                z = rmul(z, x);
            }
        }
    }*/
}
// import "../utils/UniversalERC20.sol";

contract ConstantAddressesMainnet {
    address public constant COMPTROLLER = 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B;
    address public constant COMPOUND_ORACLE = 0x1D8aEdc9E924730DD3f9641CDb4D1B92B848b4bd;

    address public constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
    address public constant CETH_ADDRESS = 0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5;

    address public constant USDC_ADDRESS = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
    address public constant CUSDC_ADDRESS = 0x39AA39c021dfbaE8faC545936693aC917d5E7563;

    address public constant WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
}

// solhint-disable-next-line no-empty-blocks
contract ConstantAddresses is ConstantAddressesMainnet {}

// ** INTERFACES **

interface IDfWallet {

    function setDfFinanceClose(address _dfFinanceClose) external;

    function deposit(
        address _tokenIn, address _cTokenIn, uint _amountIn, address _tokenOut, address _cTokenOut, uint _amountOut
    ) external payable;

    function withdraw(
        address _tokenIn, address _cTokenIn, address _tokenOut, address _cTokenOut
    ) external payable;

}

interface ICToken {
    function mint(uint256 mintAmount) external returns (uint256);

    function mint() external payable;

    function redeem(uint256 redeemTokens) external returns (uint256);

    function redeemUnderlying(uint256 redeemAmount) external returns (uint256);

    function borrow(uint256 borrowAmount) external returns (uint256);

    function repayBorrow(uint256 repayAmount) external returns (uint256);

    function repayBorrow() external payable;

    function repayBorrowBehalf(address borrower, uint256 repayAmount) external returns (uint256);

    function repayBorrowBehalf(address borrower) external payable;

    function liquidateBorrow(address borrower, uint256 repayAmount, address cTokenCollateral)
        external
        returns (uint256);

    function liquidateBorrow(address borrower, address cTokenCollateral) external payable;

    function exchangeRateCurrent() external returns (uint256);

    function supplyRatePerBlock() external returns (uint256);

    function borrowRatePerBlock() external returns (uint256);

    function totalReserves() external returns (uint256);

    function reserveFactorMantissa() external returns (uint256);

    function borrowBalanceCurrent(address account) external returns (uint256);

    function borrowBalanceStored(address account) external view returns (uint256);

    function totalBorrowsCurrent() external returns (uint256);

    function getCash() external returns (uint256);

    function balanceOfUnderlying(address owner) external returns (uint256);

    function underlying() external returns (address);
}

interface ICompoundOracle {
    function getUnderlyingPrice(address cToken) external view returns (uint);
}

interface IDfFinanceClose {

    // setup with Compound Oracle eth price
    function setupStrategy(
        address _owner, address _dfWallet, uint256 _deposit, uint8 _profitPercent, uint8 _fee
    ) external;

    // setup with special eth price
    function setupStrategy(
        address _owner, address _dfWallet, uint256 _deposit, uint256 _priceEth, uint8 _profitPercent, uint8 _fee
    ) external;

    // setup with special eth price and current extraCoef – for strategy migration
    function setupStrategy(
        address _owner, address _dfWallet, uint256 _deposit, uint256 _priceEth, uint8 _profitPercent, uint8 _fee, uint256 _extraCoef
    ) external;

    function getStrategy(
        address _dfWallet
    ) external view
    returns(
        address strategyOwner,
        uint deposit,
        uint extraCoef,
        uint entryEthPrice,
        uint profitPercent,
        uint fee,
        uint ethForRedeem,
        uint usdToWithdraw,
        bool onlyProfitInUsd);

    function migrateStrategies(address[] calldata _dfWallets) external;

    function collectAndCloseByUser(
        address _dfWallet,
        uint256 _ethForRedeem,
        uint256 _minAmountUsd,
        bool _onlyProfitInUsd,
        bytes calldata _exData
    ) external payable;

    function exitAfterLiquidation(
        address _dfWallet,
        uint256 _ethForRedeem,
        uint256 _minAmountUsd,
        bytes calldata _exData
    ) external payable;

    function depositEth(address _dfWallet) external payable;

}

interface IOneInchExchange {
    function spender() external view returns (address);
}

interface ILoanPool {
    function loan(uint _amount) external;
}

interface IAffiliateProgram {

    function getProfitPercentByReferral(address referral) external view returns (uint8);

    function addReferral(address referral, bytes32 code, uint256 ethValue) external;
    function distributeProfitByReferral(address referral) external payable;

/*
    function getPartnerByReferral(address referral) external view returns (address, uint8, uint256, uint256, uint256);
    function levels(uint8 level) external view returns (uint16, uint256);
*/

    // Old functions for Maker Sai ver.
    function addUserUseCode(address user, string calldata code) external;
    function getPartnerFromUser(address user) external view returns (address, uint8, uint256, uint256);
    function levels(uint8 level) external view returns (uint16, uint256);
    function addPartnerProfitUseAddress(address partner) external payable;

}

contract DfFinanceCloseCompound is DSMath, ConstantAddresses, GasTokenSpender, FundsMgr {
    using UniversalERC20 for IToken;

    struct Strategy {
        // first bytes32 (== uint256) slot
        uint80 deposit;  // in eth – max more 1.2 mln eth
        uint80 entryEthPrice;  // in usd – max more 1.2 mln USD for 1 eth
        uint8 profitPercent;  // % – 0 to 255
        uint8 fee;  // % – 0 to 100 (ex. 30% = 30)
        uint80 ethForRedeem;  // eth for repay loan – max more 1.2 mln eth

        // second bytes32 (== uint256) slot
        uint64 usdToWithdraw;  // in usd
        bool onlyProfitInUsd;  // only profit withdraw in usd (deposit withdraw in eth)
        address owner;  // == uint160
        uint16 extraCoef;  // extra locked coef in % (100 == 1/1) where ethLocked = extraCoef * deposit
    }

    mapping(address => bool) public admins;
    mapping(address => bool) public strategyManagers;

    mapping(address => Strategy) public strategies;  //  dfWallet => Strategy

    ILoanPool public loanPool;
    IAffiliateProgram public aff;

    IDfFinanceClose public upgradedAddress;  // DfFinanceClose contract for migration

    // Fee
    uint256 public earlyCloseFee;  // fee for early close
    uint256 public dateUntilFees;  // date until earlyCloseFee available

    // ** EVENTS **

    event StrategyClosing(address indexed dfWallet, uint ethToWithdraw, uint usdToWithdraw);
    event StrategyClosed(address indexed dfWallet, uint ethToWithdraw, uint usdToWithdraw);
    event SetupStrategy(
        address indexed owner, address indexed dfWallet, uint deposit, uint priceEth, uint8 profitPercent, uint8 fee
    );

    event StrategyMigrated(address indexed dfWallet);

    event SystemProfit(uint profit);

    // ** MODIFIERS **

    modifier hasSetupStrategyPermission {
        require(strategyManagers[msg.sender], "Setup cup permission denied");
        _;
    }

    modifier onlyOwnerOrAdmin {
        require(admins[msg.sender] || msg.sender == owner, "Permission denied");
        _;
    }

    modifier useGasToken {
        uint gasProvided = gasleft();
        _;
        _burnGasToken(sub(gasProvided, gasleft()));
    }

    // ** CONSTRUCTOR **

    constructor() public {
        loanPool = ILoanPool(0x9EdAe6aAb4B0f0f8146051ab353593209982d6B6);
        strategyManagers[address(0xBA3EEeb0cf1584eE565F34fCaBa74d3e73268c0b)] = true;  // TODO: set DfFinanceOpenCompound
        strategyManagers[address(0x7eF7eBf6c5DA51A95109f31063B74ECf269b22bE)] = true;  // TODO: set DfFinanceOpenCompound (v2)
    }

    // ** PUBLIC VIEW function **

    function getStrategy(address _dfWallet) public view returns(
        address strategyOwner,
        uint deposit,
        uint extraCoef,
        uint entryEthPrice,
        uint profitPercent,
        uint fee,
        uint ethForRedeem,
        uint usdToWithdraw,
        bool onlyProfitInUsd)
    {
        strategyOwner = strategies[_dfWallet].owner;
        deposit = strategies[_dfWallet].deposit;
        extraCoef = strategies[_dfWallet].extraCoef;
        entryEthPrice = strategies[_dfWallet].entryEthPrice;
        profitPercent = strategies[_dfWallet].profitPercent;
        fee = strategies[_dfWallet].fee;
        ethForRedeem = strategies[_dfWallet].ethForRedeem;
        usdToWithdraw = strategies[_dfWallet].usdToWithdraw;
        onlyProfitInUsd = strategies[_dfWallet].onlyProfitInUsd;
    }

    function getCurPriceEth() public view returns(uint256) {
        // eth - usdc price call to Compound Oracle contract
        uint price = ICompoundOracle(COMPOUND_ORACLE).getUnderlyingPrice(CUSDC_ADDRESS) / 1e12;   // get 1e18 price * 1e12
        return wdiv(WAD, price);
    }

    // * SETUP_STRATAGY_PERMISSION function **

    // setup with Compound Oracle eth price
    function setupStrategy(
        address _owner, address _dfWallet, uint256 _deposit, uint8 _profitPercent, uint8 _fee
    ) public hasSetupStrategyPermission {
        _setupStrategy(_owner, _dfWallet, _deposit, getCurPriceEth(), _profitPercent, _fee, 0);
    }

    // setup with special eth price
    function setupStrategy(
        address _owner, address _dfWallet, uint256 _deposit, uint256 _priceEth, uint8 _profitPercent, uint8 _fee
    ) public hasSetupStrategyPermission {
        _setupStrategy(_owner, _dfWallet, _deposit, _priceEth, _profitPercent, _fee, 0);
    }

    // setup with special eth price and current extraCoef – for strategy migration
    function setupStrategy(
        address _owner,
        address _dfWallet,
        uint256 _deposit,
        uint256 _priceEth,
        uint8 _profitPercent,
        uint8 _fee,
        uint256 _extraCoef
    ) public hasSetupStrategyPermission {
        _setupStrategy(_owner, _dfWallet, _deposit, _priceEth, _profitPercent, _fee, _extraCoef);
    }

    // ** ONLY_OWNER_OR_ADMIN functions **

    // with GasToken usage
    function collectUsdForStrategies(
        address[] memory _dfWallets,
        uint256 _amountUsdToRedeem,
        uint256 _amountUsdToBuy,
        uint256 _usdPrice,
        bool _onlyProfitInUsd,
        bool _useExchange,
        bytes memory _exData
    ) public
    useGasToken
    onlyOwnerOrAdmin {
        // uint usdDecimals = IToken(USDC_ADDRESS).decimals(); == 1e6
        uint totalLoanEth = wmul(add(_amountUsdToRedeem, _amountUsdToBuy), _usdPrice, 1e6) * 1e12;

        // exchange function result
        /**
            exResult[2] - extra ToTokens after exchange – USDC
            exResult[3] - extra FromTokens after exchange – ETH
         */
        uint[4] memory exResult;

        // Use 1inch exchange (ETH to USDC swap)
        if (_useExchange) {
            loanPool.loan(totalLoanEth);  // take an totalCredit eth loan
            exResult = _exchange(
                IToken(ETH_ADDRESS), totalLoanEth,
                IToken(USDC_ADDRESS), add(_amountUsdToRedeem, _amountUsdToBuy),
                _exData
            );
        }

        uint ethAfterClose = 0; //  count all ETH gets for USDC exchange after closing strategies

        // collect USD for close logic
        for (uint i = 0; i < _dfWallets.length; i++) {
            ethAfterClose += _collectUsdHelper(_dfWallets[i], _amountUsdToBuy, _usdPrice, _onlyProfitInUsd);
        }

        require(ethAfterClose >= totalLoanEth, "EthAfterClose is not enough");

        // distribute extra exchange profit
        if (exResult[2] > 0 || exResult[3] > 0) {
            /**
                exResult[2] - extra ToTokens after exchange – USDC
                exResult[3] - extra FromTokens after exchange – ETH
             */
            _distributeExtraExchangeProfit(_dfWallets, exResult[3], exResult[2]);
        }
    }

    // with GasToken usage
    function collectAndClose(
        address[] memory _dfWallets,
        uint256 _amountUsdToRedeem,
        uint256 _amountUsdToBuy,
        uint256 _usdPrice,
        bool _onlyProfitInUsd,
        bool _useExchange,
        bytes memory _exData
    ) public {  // onlyOwnerOrAdmin & useGasToken in collectUsdForStrategies function

        // step 1: collect usd for closing
        collectUsdForStrategies(
            _dfWallets,
            _amountUsdToRedeem,
            _amountUsdToBuy,
            _usdPrice,
            _onlyProfitInUsd,
            _useExchange,
            _exData
        );

        // step 2: close strategies
        closeStrategies(_dfWallets);
    }

    // ** PUBLIC function **

    // with GasToken usage
    function closeStrategy(address _dfWallet) public useGasToken {
        require(strategies[_dfWallet].ethForRedeem > 0, "Strategy is not exists or ready for close");

        // close strategy internal
        _strategyCloseHelper(_dfWallet);
    }

    // with GasToken usage
    function closeStrategies(address[] memory _dfWallets) public useGasToken {
        for (uint i = 0; i < _dfWallets.length; i++) {
            require(strategies[_dfWallets[i]].ethForRedeem > 0, "Strategy is not exists or ready for close");
            // close strategy internal
            _strategyCloseHelper(_dfWallets[i]);
        }
    }

    function migrateStrategies(address[] memory _dfWallets) public {
        IDfFinanceClose migrationAddress = upgradedAddress;
        require(migrationAddress != IDfFinanceClose(0), "Migration is not available");

        for(uint i = 0; i < _dfWallets.length; i++) {
            Strategy memory strategy = strategies[_dfWallets[i]];
            require(strategy.owner == msg.sender, "Strategy permission denied");
            require(strategy.ethForRedeem == 0, "Strategy is not valid for migrate");

            migrationAddress.setupStrategy(
                strategy.owner,
                _dfWallets[i],
                strategy.deposit,
                strategy.entryEthPrice,
                strategy.profitPercent,
                strategy.fee,
                strategy.extraCoef
            );

            // change dfWallet's DfFinanceClose contract state
            IDfWallet(_dfWallets[i]).setDfFinanceClose(address(migrationAddress));

            // clear _dfWallets[i] strategy struct
            _clearStrategy(_dfWallets[i]);

            emit StrategyMigrated(_dfWallets[i]);
        }
    }

    function depositEth(address _dfWallet) public payable {
        require(strategies[_dfWallet].deposit > 0, "Strategy is not exists");

        uint addedEth = msg.value;

        strategies[_dfWallet].deposit += uint80(addedEth);

        // mint cEther without borrowing
        IDfWallet(_dfWallet).deposit.value(addedEth)(ETH_ADDRESS, CETH_ADDRESS, addedEth, address(0), address(0), 0);
    }

    // with GasToken usage
    function collectAndCloseByUser(
        address _dfWallet,
        uint256 _ethForRedeem,
        uint256 _minAmountUsd,
        bool _onlyProfitInUsd,
        bytes memory _exData
    ) public payable useGasToken {
        require(strategies[_dfWallet].owner == msg.sender, "Strategy permission denied");

        _collectAndCloseHelper(
            _dfWallet, _ethForRedeem, _minAmountUsd, _onlyProfitInUsd, _exData, true
        );
    }

    // with GasToken usage
    function exitAfterLiquidation(
        address _dfWallet,
        uint256 _ethForRedeem,
        uint256 _minAmountUsd,
        bytes memory _exData
    ) public payable useGasToken {
        Strategy memory strategy = strategies[_dfWallet];

        // only strategy owner or onlyOwnerOrAdmin call
        require(
            msg.sender == strategy.owner ||
            msg.sender == owner ||
            admins[msg.sender], "Permission denied");

        uint ethLocked = ICToken(CETH_ADDRESS).balanceOfUnderlying(_dfWallet);
        uint ethInitial = mul(strategy.deposit, strategy.extraCoef) / 100;

        require(ethLocked < ethInitial, "Strategy is active - there was no liquidation");

        _collectAndCloseHelper(
            _dfWallet, _ethForRedeem, _minAmountUsd, false, _exData, false
        );
    }

    // ** ONLY_OWNER functions **

    function setLoanPool(address _loanAddr) public onlyOwner {
        require(_loanAddr != address(0), "Address must not be zero");
        loanPool = ILoanPool(_loanAddr);
    }

    function setAdminPermission(address _admin, bool _status) public onlyOwner {
        admins[_admin] = _status;
    }

    function setAdminPermission(address[] memory _admins, bool _status) public onlyOwner {
        for (uint i = 0; i < _admins.length; i++) {
            admins[_admins[i]] = _status;
        }
    }

    function setSetupStrategyPermission(address _manager, bool _status) public onlyOwner {
        strategyManagers[_manager] = _status;
    }

    function setSetupStrategyPermission(address[] memory _managers, bool _status) public onlyOwner {
        for (uint i = 0; i < _managers.length; i++) {
            strategyManagers[_managers[i]] = _status;
        }
    }

    function setAffProgram(address _aff) public onlyOwner {
        aff = IAffiliateProgram(_aff);
    }

    function upgrade(address _upgradedAddress) public onlyOwner {
        require(_upgradedAddress != address(0), "Address must not be zero");
        upgradedAddress = IDfFinanceClose(_upgradedAddress);
    }

    // ** INTERNAL VIEW functions **

    function _getProfitEth(
        address _dfWallet, uint256 _ethLocked, uint256 _ethForRedeem
    ) internal view returns(uint256 profitEth) {
        uint deposit = strategies[_dfWallet].deposit;  // in eth
        uint fee = strategies[_dfWallet].fee; // in percent (from 0 to 100)
        uint profitPercent = strategies[_dfWallet].profitPercent; // in percent (from 0 to 255)

        // user additional profit in eth
        profitEth = sub(sub(_ethLocked, deposit), _ethForRedeem) * sub(100, fee) / 100;

        require(wdiv(profitEth, deposit) * 100 >= profitPercent * WAD, "Needs more profit in eth");
    }

    function _getUsdToWithdraw(
        address _dfWallet, uint256 _ethLocked, uint256 _ethForRedeem, uint256 _usdPrice
    ) internal view returns(uint256 usdProfit, uint256 usdToWithdraw) {
        uint deposit = strategies[_dfWallet].deposit;  // in eth
        uint fee = strategies[_dfWallet].fee; // in percent (from 0 to 100)
        uint profitPercent = strategies[_dfWallet].profitPercent; // in percent (from 0 to 255)
        uint ethPrice = strategies[_dfWallet].entryEthPrice;

        // user additional profit in eth
        uint profitEth = sub(sub(_ethLocked, deposit), _ethForRedeem) * sub(100, fee) / 100;

        usdToWithdraw = wdiv(add(deposit, profitEth), _usdPrice * 1e12) / 1e12;

        uint usdOriginal = wmul(deposit, ethPrice) / 1e12;
        require(usdOriginal > 0, "Incorrect entry usd amount");

        usdProfit = sub(usdToWithdraw, usdOriginal);

        require(wdiv(usdProfit, usdOriginal) * 100 >= profitPercent * WAD, "Needs more profit in usd");
    }

    function _takeFeeHelper(
        Strategy memory _strategy,
        uint256 _ethToWithdraw,
        uint256 _minAmountUsd,
        bool _onlyProfitInUsd
    ) internal view returns(
        uint256 ethToWithdraw, bool hasProfit, uint256 extraProfitEth
    ) {
        ethToWithdraw = _ethToWithdraw;

        // is profitable
        // ethToWithdraw = ethLocked - ethForReedem
        if (ethToWithdraw > _strategy.deposit) {
            extraProfitEth = sub(ethToWithdraw, _strategy.deposit);

            if (_minAmountUsd > 0) {
                if (_onlyProfitInUsd) {
                    // VIA deposit in ETH and profit in USD
                    hasProfit = (_minAmountUsd * 1e12 * 10000 / wmul(_strategy.deposit, _strategy.entryEthPrice)) >= uint(_strategy.profitPercent) * 100;
                } else {
                    // VIA USD
                    hasProfit = (_minAmountUsd * 1e12 * 10000 / wmul(_strategy.deposit, _strategy.entryEthPrice)) >= (100 + uint(_strategy.profitPercent)) * 100;
                }
            } else {
                // VIA ETH
                hasProfit = ((extraProfitEth * sub(100, _strategy.fee) / 100) * 10000 / _strategy.deposit) >= uint(_strategy.profitPercent) * 100;
            }
        }

        if (hasProfit) {
            uint ethAfterFee = add(_strategy.deposit, extraProfitEth * sub(100, _strategy.fee) / 100);
            require(ethToWithdraw >= ethAfterFee, "ethRest less then ethAfterFee");

            ethToWithdraw = ethAfterFee;
        } else {
            // if not profitable strategy - addition fee
            if (now < dateUntilFees) {
                ethToWithdraw = sub(ethToWithdraw, mul(ethToWithdraw, earlyCloseFee) / 100);
            }
        }
    }

    // ** INTERNAL functions **

    function _setupStrategy(
        address _owner,
        address _dfWallet,
        uint256 _deposit,
        uint256 _priceEth,
        uint8 _profitPercent,
        uint8 _fee,
        uint256 _extraCoef
    ) internal {
        require(strategies[_dfWallet].deposit == 0, "Strategy already set");

        uint extraCoef = _extraCoef;
        if (extraCoef == 0) {
            uint ethLocked = ICToken(CETH_ADDRESS).balanceOfUnderlying(_dfWallet);
            extraCoef = ethLocked / _deposit;
        }

        strategies[_dfWallet] = Strategy(
            uint80(_deposit),
            uint80(_priceEth),
            _profitPercent,
            _fee,
            0,
            0,
            false,
            _owner,
            uint16(extraCoef)
        );

        emit SetupStrategy(_owner, _dfWallet, _deposit, _priceEth, _profitPercent, _fee);
    }

    function _collectUsdHelper(
        address _dfWallet,
        uint256 _amountUsdToBuy,
        uint256 _usdPrice,
        bool _onlyProfitInUsd
    ) internal returns(
        uint256 ethAfterClose
    ) {
        Strategy storage strategy = strategies[_dfWallet];
        require(strategy.ethForRedeem == 0 && strategy.deposit > 0, "Strategy is not exists or valid");

        uint ethLocked = ICToken(CETH_ADDRESS).balanceOfUnderlying(_dfWallet);
        uint ethForRedeem = wmul(ICToken(CUSDC_ADDRESS).borrowBalanceStored(_dfWallet), _usdPrice, 1e6) * 1e12;

        uint usdToWithdraw = 0;
        uint ethToWithdraw = 0;

        if (_amountUsdToBuy > 0) { // in USD
            uint usdProfit;
            (usdProfit, usdToWithdraw) = _getUsdToWithdraw(_dfWallet, ethLocked, ethForRedeem, _usdPrice);

            // return value
            ethAfterClose = ethLocked;

            // deposit in ETH and profit in USD
            if (_onlyProfitInUsd) {
                strategy.onlyProfitInUsd = _onlyProfitInUsd;  // set strategy value

                ethToWithdraw = strategy.deposit;
                usdToWithdraw = usdProfit;

                // return value
                ethAfterClose = sub(ethLocked, ethToWithdraw);
            }

            strategy.usdToWithdraw = uint64(usdToWithdraw);  // set strategy value
        } else { // in ETH
            uint profitEth = _getProfitEth(_dfWallet, ethLocked, ethForRedeem);
            ethToWithdraw = add(strategy.deposit, profitEth);

            // return value
            ethAfterClose = ethForRedeem;
        }

        strategy.ethForRedeem = uint80(ethForRedeem);  // set strategy value

        emit StrategyClosing(_dfWallet, ethToWithdraw, usdToWithdraw);
    }

    function _strategyCloseHelper(address _dfWallet) internal {
        Strategy memory strategy = strategies[_dfWallet];

        uint ethLocked = ICToken(CETH_ADDRESS).balanceOfUnderlying(_dfWallet);
        // uint ethForRedeem = wmul(ICToken(CUSDC_ADDRESS).borrowBalanceStored(_dfWallet), _usdPrice, 1e6) * 1e12;

        // TODO: check usdc balance and ceth transfer to dfWallet
        IToken(USDC_ADDRESS).approve(_dfWallet, uint(-1));
        IDfWallet(_dfWallet).withdraw(ETH_ADDRESS, CETH_ADDRESS, USDC_ADDRESS, CUSDC_ADDRESS);

        // Calculate affiliate process partner profit
        uint systemProfit = sub(sub(ethLocked, strategy.deposit), strategy.ethForRedeem) * strategy.fee / 100;
        uint partnerProfit = _affiliateProcess(strategy.owner, systemProfit);

        uint usdToWithdraw = strategy.usdToWithdraw;
        uint ethToWithdraw = 0;

        if (usdToWithdraw > 0) {
            // transfer USDC to user
            IToken(USDC_ADDRESS).universalTransfer(strategy.owner, usdToWithdraw);

            // close: deposit in ETH + profit in usd
            if (strategy.onlyProfitInUsd) {
                ethToWithdraw = strategy.deposit;
            }
        } else {  // close in ETH
            uint profitEth = _getProfitEth(_dfWallet, ethLocked, strategy.ethForRedeem);
            ethToWithdraw = add(strategy.deposit, profitEth);
        }

        // transfer ETH to user
        if (ethToWithdraw > 0) {
            IToken(ETH_ADDRESS).universalTransfer(strategy.owner, ethToWithdraw);
        }

        // transfer loan and our profit to loanPool
        uint loanAndProfit = sub(sub(ethLocked, ethToWithdraw), partnerProfit);
        _transferEth(address(loanPool), loanAndProfit);

        // call strategy owner's callback function (without revert if callback does not exist)
        _callbackTo(strategy.owner);

        // clear _dfWallet strategy struct
        _clearStrategy(_dfWallet);

        emit StrategyClosed(_dfWallet, ethToWithdraw, usdToWithdraw);
    }

    function _collectAndCloseHelper(
        address _dfWallet,
        uint256 _ethForRedeem,
        uint256 _minAmountUsd,
        bool _onlyProfitInUsd,
        bytes memory _exData,
        bool _withFee
    ) internal returns(bool hasProfit, uint256 extraProfitEth) {
        Strategy memory strategy = strategies[_dfWallet];
        require(strategy.deposit > 0 && strategy.ethForRedeem == 0, "Strategy is not exists or valid for close");

        // ethToWithdraw = ethLocked - _ethForRedeem
        uint ethToWithdraw = sub(ICToken(CETH_ADDRESS).balanceOfUnderlying(_dfWallet), _ethForRedeem);

        // with fee logic
        if (_withFee) {
            (ethToWithdraw, hasProfit, extraProfitEth) = _takeFeeHelper(strategy, ethToWithdraw, _minAmountUsd, _onlyProfitInUsd);
        }

        uint ethForExchange = _ethForRedeem;

        // if close not in eth
        if (_minAmountUsd > 0) {
            // VIA USD
            ethForExchange = add(ethForExchange, ethToWithdraw);

            if (_onlyProfitInUsd) {
                // VIA deposit in ETH and profit in USD
                ethForExchange = sub(ethForExchange, strategy.deposit);
            }
        }

        // calculate and take an extra eth loan from LoanPool
        uint loan = 0;
        if (msg.value < ethForExchange) {
            loan = sub(ethForExchange, msg.value);
            loanPool.loan(loan);
        }

        /**
            exResult[2] - extra ToTokens after exchange – USDC
            exResult[3] - extra FromTokens after exchange – ETH
         */
        uint[4] memory exResult = _exchangeAndRedeemHelper(_dfWallet, ethForExchange, _minAmountUsd, _exData);

        // affiliate pay to referrer
        uint systemProfit = 0;
        if (hasProfit) {
            uint fee = mul(extraProfitEth, strategy.fee) / 100;
            systemProfit = sub(fee, _affiliateProcess(strategy.owner, fee));
        }

        // return loan and system profit to LoanPool
        if (add(loan, systemProfit) > 0) {
            _transferEth(address(loanPool), add(loan, systemProfit));
        }

        if (_minAmountUsd > 0) {
            if (_onlyProfitInUsd) {
                // VIA deposit in ETH and profit in USD
                ethToWithdraw = strategy.deposit;
            } else {
                // VIA USD
                ethToWithdraw = 0;
            }
        }

        /**
            exResult[2] - extra ToTokens after exchange – USDC
            exResult[3] - extra FromTokens after exchange – ETH
         */
        _withdrawProfit(
            strategy.owner,
            (ethToWithdraw + exResult[3]),
            (_minAmountUsd + exResult[2])
        );

        // call strategy owner's callback function (without revert if callback does not exist)
        _callbackTo(strategy.owner);

        // clear _dfWallet strategy struct
        _clearStrategy(_dfWallet);

        // return msg.value to msg.sender
        if (msg.value > 0) {
            address(msg.sender).transfer(msg.value);
        }

        // emit StrategyClosed(_dfWallet, ethToWithdraw, _minAmountUsd);

        // with extra eth and usdc after exchange profit
        emit StrategyClosed(_dfWallet, (ethToWithdraw + exResult[3]), (_minAmountUsd + exResult[2]));
    }

    function _exchangeAndRedeemHelper(
        address _dfWallet,
        uint256 _ethForExchange,
        uint256 _minAmountUsd,
        bytes memory _exData
    ) internal returns(
        uint[4] memory exResult
        /**
            [0] - received ToTokens
            [1] - spent FromTokens
            [2] - extra ToTokens after exchange
            [3] - extra FromTokens after exchange
         */
    ) {
        //  ETH => USDC - 1inch exchange
        uint usdcForRedeem = ICToken(CUSDC_ADDRESS).borrowBalanceStored(_dfWallet);

        exResult = _exchange(
            IToken(ETH_ADDRESS), _ethForExchange,
            IToken(USDC_ADDRESS), add(usdcForRedeem, _minAmountUsd),
            _exData
        );

        // redeem usdc and unlock eth
        IToken(USDC_ADDRESS).approve(_dfWallet, uint(-1));
        IDfWallet(_dfWallet).withdraw(ETH_ADDRESS, CETH_ADDRESS, USDC_ADDRESS, CUSDC_ADDRESS);
    }

    function _withdrawProfit(
        address _strategyOwner, uint256 _ethToWithdraw, uint256 _usdToWithdraw
    ) internal {
        // withdraw ETH to strategy owner
        if (_ethToWithdraw > 0) {
            IToken(ETH_ADDRESS).universalTransfer(_strategyOwner, _ethToWithdraw);
        }

        // withdraw USDC to strategy owner
        if (_usdToWithdraw > 0) {
            IToken(USDC_ADDRESS).universalTransfer(_strategyOwner, _usdToWithdraw);
        }
    }

    function _transferEth(address receiver, uint256 amount) internal {
        address payable receiverPayable = address(uint160(receiver));
        (bool result, ) = receiverPayable.call.value(amount)("");
        require(result, "Transfer of ETH failed");
    }

    function _exchange(
        IToken _fromToken, uint256 _maxFromTokenAmount,
        IToken _toToken, uint256 _minToTokenAmount,
        bytes memory _exData
    ) internal returns(
        uint[4] memory res
        /**
            [0] - received ToTokens
            [1] - spent FromTokens
            [2] - extra ToTokens after exchange
            [3] - extra FromTokens after exchange
         */
    ) {
        IOneInchExchange ex = IOneInchExchange(0x11111254369792b2Ca5d084aB5eEA397cA8fa48B);

        // Approve tokens for 1inch
        uint256 ethAmount = 0;
        if (address(_fromToken) != ETH_ADDRESS) {
            if (_fromToken.allowance(address(this), ex.spender()) != uint(-1)) {
                _fromToken.approve(ex.spender(), uint(-1));
            }
        } else {
            ethAmount = _maxFromTokenAmount;
        }

        uint fromTokenBalanceBefore = _fromToken.universalBalanceOf(address(this));
        uint toTokenBalanceBefore = _toToken.universalBalanceOf(address(this));

        bytes32 response;
        assembly {
            // call(g, a, v, in, insize, out, outsize)
            let succeeded := call(sub(gas, 5000), ex, ethAmount, add(_exData, 0x20), mload(_exData), 0, 32)
            response := mload(0)      // load delegatecall output
            //switch iszero(succeeded)
            //case 1 {
            //    // throw if call failed
            //    revert(0, 0)
            //}
        }

        res[0] = sub(_toToken.universalBalanceOf(address(this)), toTokenBalanceBefore);         //  received ToTokens
        res[1] = sub(fromTokenBalanceBefore, _fromToken.universalBalanceOf(address(this)));     // spent FromTokens
        res[2] = sub(res[0], _minToTokenAmount);    //  extra ToTokens
        res[3] = sub(_maxFromTokenAmount, res[1]);  // extra FromTokens
    }

    function _clearStrategy(address _dfWallet) internal {
        strategies[_dfWallet] = Strategy(0, 0, 0, 0, 0, 0, false, address(0), 0);
    }

    function _affiliateProcess(address _strategyOwner, uint256 _systemProfit) internal returns(uint256 affPayment) {
        if (aff != IAffiliateProgram(0)) {
            affPayment = _systemProfit * aff.getProfitPercentByReferral(_strategyOwner) / 100;
            require(affPayment < _systemProfit, "Incorrect affiliate program payment percent");

            // tranfer eth to AffiliateProgram contract
            aff.distributeProfitByReferral.value(affPayment)(_strategyOwner);

            emit SystemProfit(sub(_systemProfit, affPayment));
        } else {
            emit SystemProfit(_systemProfit);
        }
    }

    function _distributeExtraExchangeProfit(
        address[] memory _dfWallets,
        uint256 _extraEth,
        uint256 _extraUsd
    ) internal {

        // deposits of strategies
        uint[] memory deposits = new uint[](_dfWallets.length);

        uint totalDeposit = 0;  //  total deposit of these strategies

        // deposits of strategies and totalDeposit calculate
        for (uint i = 0; i < _dfWallets.length; i++) {
            deposits[i] = strategies[_dfWallets[i]].deposit;
            totalDeposit += deposits[i];
        }

        // add extra ETH and USDC to strategies profit
        for (uint i = 0; i < _dfWallets.length; i++) {
            uint strategyShare = wdiv(deposits[i], totalDeposit);

            if (_extraEth > 0) {
                uint ethForStrategy = wmul(strategyShare, _extraEth);
                if (strategies[_dfWallets[i]].ethForRedeem > ethForStrategy) {
                    strategies[_dfWallets[i]].ethForRedeem -= uint80(ethForStrategy);
                }
            }

            if (_extraUsd > 0) {
                uint usdForStrategy = wmul(strategyShare, _extraUsd);
                strategies[_dfWallets[i]].usdToWithdraw += uint64(usdForStrategy);
            }
        }
    }

    function _callbackTo(address _to) internal {
        bytes4 sig = bytes4(keccak256("__callback()"));

        // call without revert if function does not exist
        assembly {
            let x := mload(0x40)
            mstore(x, sig)
            let success := call(sub(gas, 5000), _to, 0, x, 0x04, 0, 0)
        }
    }

    // ** FALLBACK functions **
    function() external payable {}

}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"dfWallet","type":"address"},{"indexed":false,"internalType":"uint256","name":"deposit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"priceEth","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"profitPercent","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"fee","type":"uint8"}],"name":"SetupStrategy","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"dfWallet","type":"address"},{"indexed":false,"internalType":"uint256","name":"ethToWithdraw","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"usdToWithdraw","type":"uint256"}],"name":"StrategyClosed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"dfWallet","type":"address"},{"indexed":false,"internalType":"uint256","name":"ethToWithdraw","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"usdToWithdraw","type":"uint256"}],"name":"StrategyClosing","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"dfWallet","type":"address"}],"name":"StrategyMigrated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"profit","type":"uint256"}],"name":"SystemProfit","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":true,"inputs":[],"name":"CETH_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"COMPOUND_ORACLE","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"COMPTROLLER","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CUSDC_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ETH_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"GAS_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"USDC_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"WETH_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"admins","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"aff","outputs":[{"internalType":"contract IAffiliateProgram","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address payable","name":"newOwner","type":"address"}],"name":"changeOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"_dfWallets","type":"address[]"}],"name":"closeStrategies","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_dfWallet","type":"address"}],"name":"closeStrategy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"_dfWallets","type":"address[]"},{"internalType":"uint256","name":"_amountUsdToRedeem","type":"uint256"},{"internalType":"uint256","name":"_amountUsdToBuy","type":"uint256"},{"internalType":"uint256","name":"_usdPrice","type":"uint256"},{"internalType":"bool","name":"_onlyProfitInUsd","type":"bool"},{"internalType":"bool","name":"_useExchange","type":"bool"},{"internalType":"bytes","name":"_exData","type":"bytes"}],"name":"collectAndClose","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_dfWallet","type":"address"},{"internalType":"uint256","name":"_ethForRedeem","type":"uint256"},{"internalType":"uint256","name":"_minAmountUsd","type":"uint256"},{"internalType":"bool","name":"_onlyProfitInUsd","type":"bool"},{"internalType":"bytes","name":"_exData","type":"bytes"}],"name":"collectAndCloseByUser","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"_dfWallets","type":"address[]"},{"internalType":"uint256","name":"_amountUsdToRedeem","type":"uint256"},{"internalType":"uint256","name":"_amountUsdToBuy","type":"uint256"},{"internalType":"uint256","name":"_usdPrice","type":"uint256"},{"internalType":"bool","name":"_onlyProfitInUsd","type":"bool"},{"internalType":"bool","name":"_useExchange","type":"bool"},{"internalType":"bytes","name":"_exData","type":"bytes"}],"name":"collectUsdForStrategies","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"dateUntilFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_dfWallet","type":"address"}],"name":"depositEth","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"earlyCloseFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_dfWallet","type":"address"},{"internalType":"uint256","name":"_ethForRedeem","type":"uint256"},{"internalType":"uint256","name":"_minAmountUsd","type":"uint256"},{"internalType":"bytes","name":"_exData","type":"bytes"}],"name":"exitAfterLiquidation","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"gasTokenBalance","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurPriceEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_dfWallet","type":"address"}],"name":"getStrategy","outputs":[{"internalType":"address","name":"strategyOwner","type":"address"},{"internalType":"uint256","name":"deposit","type":"uint256"},{"internalType":"uint256","name":"extraCoef","type":"uint256"},{"internalType":"uint256","name":"entryEthPrice","type":"uint256"},{"internalType":"uint256","name":"profitPercent","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"ethForRedeem","type":"uint256"},{"internalType":"uint256","name":"usdToWithdraw","type":"uint256"},{"internalType":"bool","name":"onlyProfitInUsd","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"loanPool","outputs":[{"internalType":"contract ILoanPool","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"_dfWallets","type":"address[]"}],"name":"migrateStrategies","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address payable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_admin","type":"address"},{"internalType":"bool","name":"_status","type":"bool"}],"name":"setAdminPermission","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"_admins","type":"address[]"},{"internalType":"bool","name":"_status","type":"bool"}],"name":"setAdminPermission","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_aff","type":"address"}],"name":"setAffProgram","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_loanAddr","type":"address"}],"name":"setLoanPool","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"_managers","type":"address[]"},{"internalType":"bool","name":"_status","type":"bool"}],"name":"setSetupStrategyPermission","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_manager","type":"address"},{"internalType":"bool","name":"_status","type":"bool"}],"name":"setSetupStrategyPermission","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_dfWallet","type":"address"},{"internalType":"uint256","name":"_deposit","type":"uint256"},{"internalType":"uint8","name":"_profitPercent","type":"uint8"},{"internalType":"uint8","name":"_fee","type":"uint8"}],"name":"setupStrategy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_dfWallet","type":"address"},{"internalType":"uint256","name":"_deposit","type":"uint256"},{"internalType":"uint256","name":"_priceEth","type":"uint256"},{"internalType":"uint8","name":"_profitPercent","type":"uint8"},{"internalType":"uint8","name":"_fee","type":"uint8"}],"name":"setupStrategy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_dfWallet","type":"address"},{"internalType":"uint256","name":"_deposit","type":"uint256"},{"internalType":"uint256","name":"_priceEth","type":"uint256"},{"internalType":"uint8","name":"_profitPercent","type":"uint8"},{"internalType":"uint8","name":"_fee","type":"uint8"},{"internalType":"uint256","name":"_extraCoef","type":"uint256"}],"name":"setupStrategy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"strategies","outputs":[{"internalType":"uint80","name":"deposit","type":"uint80"},{"internalType":"uint80","name":"entryEthPrice","type":"uint80"},{"internalType":"uint8","name":"profitPercent","type":"uint8"},{"internalType":"uint8","name":"fee","type":"uint8"},{"internalType":"uint80","name":"ethForRedeem","type":"uint80"},{"internalType":"uint64","name":"usdToWithdraw","type":"uint64"},{"internalType":"bool","name":"onlyProfitInUsd","type":"bool"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint16","name":"extraCoef","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"strategyManagers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_upgradedAddress","type":"address"}],"name":"upgrade","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"upgradedAddress","outputs":[{"internalType":"contract IDfFinanceClose","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"withdrawAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b50600080546001600160a01b03199081163317825560058054909116739edae6aab4b0f0f8146051ab353593209982d6b617905560036020527f8486d6778b4cf7c91764cdba2bdd2b06c6a65fd60a787ffe4d06f2b0f7a00aad805460ff199081166001908117909255737ef7ebf6c5da51a95109f31063b74ecf269b22be9092527f3709e7a0251439b746430fa9d85403aabb68468a0da2b6520aa7663ffabc11488054909216179055614c7e806100ca6000396000f3fe6080604052600436106102515760003560e01c80638af8d4c311610139578063bb09d9b7116100b6578063ebbc49651161007a578063ebbc496514610eca578063ee5f4afd14610edf578063f3fef3a314610ef4578063f8806a1314610f2d578063f93f20d814610fb3578063ffb6c79c14610fc857610251565b8063bb09d9b714610cc0578063c63f0dc114610cd5578063d1e1ecba14610d37578063e1ea330014610d6a578063eb21d9c414610e1a57610251565b8063a6f9dae1116100fd578063a6f9dae114610bc5578063a734f06e14610bf8578063ad9d4ba314610c0d578063ae5f8f7214610c33578063b3c18b1614610c6657610251565b80638af8d4c314610a015780638da5cb5b14610a1657806394771d7614610a2b57806398fb838714610a40578063a46c310314610b9257610251565b8063416d4efb116101d25780635f82c67e116101965780635f82c67e146108855780636568a2791461089a57806366408eb014610948578063672c42911461095d57806375f3974b146109b15780638a5e8cc7146109ec57610251565b8063416d4efb14610562578063429b62e5146106295780634ab45d33146106705780635969490d1461068557806359966b24146107d757610251565b806326976e3f1161021957806326976e3f146103b35780632840e1b3146103c85780632bb083fc146103dd578063331934ec1461041057806339ebf823146104be57610251565b8063040141e5146102535780630900f0101461028457806312defc83146102b75780631d8319e4146102de57806325fda7881461039e575b005b34801561025f57600080fd5b50610268611003565b604080516001600160a01b039092168252519081900360200190f35b34801561029057600080fd5b50610251600480360360208110156102a757600080fd5b50356001600160a01b031661101b565b3480156102c357600080fd5b506102cc6110e0565b60408051918252519081900360200190f35b610251600480360360808110156102f457600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b81111561032a57600080fd5b82018360208201111561033c57600080fd5b803590602001918460018302840111600160201b8311171561035d57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506111a0945050505050565b3480156103aa57600080fd5b506102cc611406565b3480156103bf57600080fd5b5061026861140c565b3480156103d457600080fd5b5061026861141b565b3480156103e957600080fd5b506102516004803603602081101561040057600080fd5b50356001600160a01b031661142a565b34801561041c57600080fd5b506102516004803603602081101561043357600080fd5b810190602081018135600160201b81111561044d57600080fd5b82018360208201111561045f57600080fd5b803590602001918460208302840111600160201b8311171561048057600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506114ef945050505050565b3480156104ca57600080fd5b506104f1600480360360208110156104e157600080fd5b50356001600160a01b03166118a9565b604080516001600160501b039a8b168152988a1660208a015260ff978816898201529590961660608801529290961660808601526001600160401b031660a085015293151560c08401526001600160a01b0390931660e083015261ffff166101008201529051908190036101200190f35b610251600480360360a081101561057857600080fd5b6001600160a01b0382351691602081013591604082013591606081013515159181019060a081016080820135600160201b8111156105b557600080fd5b8201836020820111156105c757600080fd5b803590602001918460018302840111600160201b831117156105e857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611928945050505050565b34801561063557600080fd5b5061065c6004803603602081101561064c57600080fd5b50356001600160a01b03166119ce565b604080519115158252519081900360200190f35b34801561067c57600080fd5b506102686119e3565b34801561069157600080fd5b50610251600480360360e08110156106a857600080fd5b810190602081018135600160201b8111156106c257600080fd5b8201836020820111156106d457600080fd5b803590602001918460208302840111600160201b831117156106f557600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092958435956020860135956040810135955060608101351515945060808101351515935060c081019060a00135600160201b81111561076357600080fd5b82018360208201111561077557600080fd5b803590602001918460018302840111600160201b8311171561079657600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506119fb945050505050565b3480156107e357600080fd5b50610251600480360360208110156107fa57600080fd5b810190602081018135600160201b81111561081457600080fd5b82018360208201111561082657600080fd5b803590602001918460208302840111600160201b8311171561084757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611a0f945050505050565b34801561089157600080fd5b50610268611ad4565b3480156108a657600080fd5b50610251600480360360208110156108bd57600080fd5b810190602081018135600160201b8111156108d757600080fd5b8201836020820111156108e957600080fd5b803590602001918460208302840111600160201b8311171561090a57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611aec945050505050565b34801561095457600080fd5b50610268611b9c565b34801561096957600080fd5b50610251600480360360a081101561098057600080fd5b506001600160a01b03813581169160208101359091169060408101359060ff60608201358116916080013516611bb4565b3480156109bd57600080fd5b50610251600480360360408110156109d457600080fd5b506001600160a01b0381351690602001351515611c36565b3480156109f857600080fd5b50610268611cae565b348015610a0d57600080fd5b50610268611cc6565b348015610a2257600080fd5b50610268611cd9565b348015610a3757600080fd5b50610268611ce8565b348015610a4c57600080fd5b50610251600480360360e0811015610a6357600080fd5b810190602081018135600160201b811115610a7d57600080fd5b820183602082011115610a8f57600080fd5b803590602001918460208302840111600160201b83111715610ab057600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092958435956020860135956040810135955060608101351515945060808101351515935060c081019060a00135600160201b811115610b1e57600080fd5b820183602082011115610b3057600080fd5b803590602001918460018302840111600160201b83111715610b5157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611cf7945050505050565b348015610b9e57600080fd5b5061025160048036036020811015610bb557600080fd5b50356001600160a01b0316611f12565b348015610bd157600080fd5b5061025160048036036020811015610be857600080fd5b50356001600160a01b0316611f92565b348015610c0457600080fd5b50610268612001565b61025160048036036020811015610c2357600080fd5b50356001600160a01b0316612019565b348015610c3f57600080fd5b5061065c60048036036020811015610c5657600080fd5b50356001600160a01b0316612160565b348015610c7257600080fd5b50610251600480360360c0811015610c8957600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff608082013581169160a0013516612175565b348015610ccc57600080fd5b506102686121e9565b348015610ce157600080fd5b50610251600480360360e0811015610cf857600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff608082013581169160a08101359091169060c00135612201565b348015610d4357600080fd5b5061025160048036036020811015610d5a57600080fd5b50356001600160a01b0316612274565b348015610d7657600080fd5b5061025160048036036040811015610d8d57600080fd5b810190602081018135600160201b811115610da757600080fd5b820183602082011115610db957600080fd5b803590602001918460208302840111600160201b83111715610dda57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955050505035151590506122e3565b348015610e2657600080fd5b5061025160048036036040811015610e3d57600080fd5b810190602081018135600160201b811115610e5757600080fd5b820183602082011115610e6957600080fd5b803590602001918460208302840111600160201b83111715610e8a57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505050503515159050612387565b348015610ed657600080fd5b5061025161242b565b348015610eeb57600080fd5b506102cc61249c565b348015610f0057600080fd5b5061025160048036036040811015610f1757600080fd5b506001600160a01b0381351690602001356124a2565b348015610f3957600080fd5b50610f6060048036036020811015610f5057600080fd5b50356001600160a01b031661255c565b604080516001600160a01b03909a168a5260208a0198909852888801969096526060880194909452608087019290925260a086015260c085015260e0840152151561010083015251908190036101200190f35b348015610fbf57600080fd5b506102cc6125e1565b348015610fd457600080fd5b5061025160048036036040811015610feb57600080fd5b506001600160a01b0381351690602001351515612662565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6000546001600160a01b03163314611068576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b6001600160a01b0381166110be576040805162461bcd60e51b815260206004820152601860248201527741646472657373206d757374206e6f74206265207a65726f60401b604482015290519081900360640190fd5b600780546001600160a01b0319166001600160a01b0392909216919091179055565b6040805163fc57d4df60e01b81527339aa39c021dfbae8fac545936693ac917d5e756360048201529051600091829164e8d4a5100091731d8aedc9e924730dd3f9641cdb4d1b92b848b4bd9163fc57d4df91602480820192602092909190829003018186803b15801561115257600080fd5b505afa158015611166573d6000803e3d6000fd5b505050506040513d602081101561117c57600080fd5b50518161118557fe5b04905061119a670de0b6b3a7640000826126da565b91505090565b60005a90506111ad614aca565b506001600160a01b0385811660009081526004602090815260409182902082516101208101845281546001600160501b038082168352600160501b8204811694830194909452600160a01b810460ff90811695830195909552600160a81b810485166060830152600160b01b90049092166080830152600101546001600160401b03811660a0830152600160401b8104909216151560c0820152600160481b820490921660e08301819052600160e81b90910461ffff1661010083015233148061128157506000546001600160a01b031633145b8061129b57503360009081526002602052604090205460ff165b6112da576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b60408051633af9e66960e01b81526001600160a01b03881660048201529051600091734ddc2d193948926d02f9b1fe9e1daa0718270ed591633af9e6699160248082019260209290919082900301818787803b15801561133957600080fd5b505af115801561134d573d6000803e3d6000fd5b505050506040513d602081101561136357600080fd5b5051825161010084015191925060009160649161138f916001600160501b039091169061ffff1661270b565b8161139657fe5b0490508082106113d75760405162461bcd60e51b815260040180806020018281038252602d815260200180614ba1602d913960400191505060405180910390fd5b6113e78888886000896000612735565b50505050506113fe6113f9825a612b31565b612b41565b505050505050565b60095481565b6007546001600160a01b031681565b6006546001600160a01b031681565b6000546001600160a01b03163314611477576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b6001600160a01b0381166114cd576040805162461bcd60e51b815260206004820152601860248201527741646472657373206d757374206e6f74206265207a65726f60401b604482015290519081900360640190fd5b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6007546001600160a01b03168061154d576040805162461bcd60e51b815260206004820152601a60248201527f4d6967726174696f6e206973206e6f7420617661696c61626c65000000000000604482015290519081900360640190fd5b60005b82518110156118a457611561614aca565b6004600085848151811061157157fe5b6020908102919091018101516001600160a01b03908116835282820193909352604091820160002082516101208101845281546001600160501b038082168352600160501b8204811694830194909452600160a01b810460ff90811695830195909552600160a81b810485166060830152600160b01b90049092166080830152600101546001600160401b03811660a0830152600160401b8104909216151560c0820152600160481b820490921660e08301819052600160e81b90910461ffff16610100830152909150331461168e576040805162461bcd60e51b815260206004820152601a60248201527f5374726174656779207065726d697373696f6e2064656e696564000000000000604482015290519081900360640190fd5b60808101516001600160501b0316156116d85760405162461bcd60e51b8152600401808060200182810382526021815260200180614b606021913960400191505060405180910390fd5b826001600160a01b031663c63f0dc18260e001518685815181106116f857fe5b60209081029190910181015185519186015160408088015160608901516101008a015183516001600160e01b031960e08b901b1681526001600160a01b0398891660048201529790951660248801526001600160501b03958616604488015294909216606486015260ff9182166084860152921660a484015261ffff1660c48301525160e480830192600092919082900301818387803b15801561179b57600080fd5b505af11580156117af573d6000803e3d6000fd5b505050508382815181106117bf57fe5b60200260200101516001600160a01b0316635b85a60a846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050600060405180830381600087803b15801561181e57600080fd5b505af1158015611832573d6000803e3d6000fd5b5050505061185284838151811061184557fe5b6020026020010151612bfe565b83828151811061185e57fe5b60200260200101516001600160a01b03167f7c9a2d2ec51230d7dbed27f113a325b7e20aef7b049e68b2339257b5edff5bea60405160405180910390a250600101611550565b505050565b600460205260009081526040902080546001909101546001600160501b0380831692600160501b810482169260ff600160a01b8304811693600160a81b8404821693600160b01b900416916001600160401b03811691600160401b820416906001600160a01b03600160481b8204169061ffff600160e81b9091041689565b60005a6001600160a01b03878116600090815260046020526040902060010154919250600160481b9091041633146119a7576040805162461bcd60e51b815260206004820152601a60248201527f5374726174656779207065726d697373696f6e2064656e696564000000000000604482015290519081900360640190fd5b6119b686868686866001612735565b50506119c56113f9825a612b31565b50505050505050565b60026020526000908152604090205460ff1681565b734ddc2d193948926d02f9b1fe9e1daa0718270ed581565b611a0a87878787878787611cf7565b6119c5875b60005a905060005b8251811015611ac657600060046000858481518110611a3257fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002054600160b01b90046001600160501b031611611aa25760405162461bcd60e51b8152600401808060200182810382526029815260200180614bf76029913960400191505060405180910390fd5b611abe838281518110611ab157fe5b6020026020010151612d78565b600101611a17565b506118a46113f9825a612b31565b733d9819210a31b4961b30ef54be2aed79b9c9cd3b81565b6000546001600160a01b03163314611b39576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b60005b8151811015611b9857611b90828281518110611b5457fe5b6020026020010151611b8b30858581518110611b6c57fe5b60200260200101516001600160a01b031661319d90919063ffffffff16565b6124a2565b600101611b3c565b5050565b7339aa39c021dfbae8fac545936693ac917d5e756381565b3360009081526003602052604090205460ff16611c18576040805162461bcd60e51b815260206004820152601b60248201527f536574757020637570207065726d697373696f6e2064656e6965640000000000604482015290519081900360640190fd5b611c2f858585611c266110e0565b86866000613270565b5050505050565b6000546001600160a01b03163314611c83576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b6001600160a01b03919091166000908152600260205260409020805460ff1916911515919091179055565b731d8aedc9e924730dd3f9641cdb4d1b92b848b4bd81565b6eb3f879cb30fe243b4dfee438691c0481565b6000546001600160a01b031681565b6005546001600160a01b031681565b60005a3360009081526002602052604090205490915060ff1680611d2557506000546001600160a01b031633145b611d64576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b6000611d7d611d738989613600565b87620f4240613610565b64e8d4a51000029050611d8e614b16565b8415611e3a5760055460408051631b2d298360e11b81526004810185905290516001600160a01b039092169163365a53069160248082019260009290919082900301818387803b158015611de157600080fd5b505af1158015611df5573d6000803e3d6000fd5b50505050611e3773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8373a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48611e318d8d613600565b88613630565b90505b6000805b8b51811015611e7257611e668c8281518110611e5657fe5b60200260200101518b8b8b613915565b90910190600101611e3e565b5082811015611ec8576040805162461bcd60e51b815260206004820152601b60248201527f4574684166746572436c6f7365206973206e6f7420656e6f7567680000000000604482015290519081900360640190fd5b6040820151151580611edd5750606082015115155b15611ef75760608201516040830151611ef7918d91613bf0565b505050611f076113f9825a612b31565b505050505050505050565b60005a6001600160a01b038316600090815260046020526040902054909150600160b01b90046001600160501b0316611f7c5760405162461bcd60e51b8152600401808060200182810382526029815260200180614bf76029913960400191505060405180910390fd5b611f8582612d78565b6118a46113f9825a612b31565b6000546001600160a01b03163314611fdf576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b6001600160a01b0381166000908152600460205260409020546001600160501b0316612085576040805162461bcd60e51b81526020600482015260166024820152755374726174656779206973206e6f742065786973747360501b604482015290519081900360640190fd5b6001600160a01b0381166000818152600460208190526040808320805469ffffffffffffffffffff198116346001600160501b0392831681019092161790915581516302d35a5960e01b815273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee93810193909352734ddc2d193948926d02f9b1fe9e1daa0718270ed5602484015260448301819052606483018490526084830184905260a4830184905290519093926302d35a5992859260c4808301939282900301818588803b15801561214c57600080fd5b505af11580156119c5573d6000803e3d6000fd5b60036020526000908152604090205460ff1681565b3360009081526003602052604090205460ff166121d9576040805162461bcd60e51b815260206004820152601b60248201527f536574757020637570207065726d697373696f6e2064656e6965640000000000604482015290519081900360640190fd5b6113fe8686868686866000613270565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b3360009081526003602052604090205460ff16612265576040805162461bcd60e51b815260206004820152601b60248201527f536574757020637570207065726d697373696f6e2064656e6965640000000000604482015290519081900360640190fd5b6119c587878787878787613270565b6000546001600160a01b031633146122c1576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b600680546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314612330576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b60005b82518110156118a457816003600085848151811061234d57fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055600101612333565b6000546001600160a01b031633146123d4576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b60005b82518110156118a45781600260008584815181106123f157fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff19169115159190911790556001016123d7565b6001546001600160a01b03163314612478576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b600154600080546001600160a01b0319166001600160a01b03909216919091179055565b60085481565b6000546001600160a01b031633146124ef576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b6001600160a01b03821661253c57600080546040516001600160a01b039091169183156108fc02918491818181858888f19350505050158015612536573d6000803e3d6000fd5b50611b98565b600054611b98906001600160a01b0384811691168363ffffffff613e1716565b6001600160a01b03908116600090815260046020526040902060018101549054600160481b8204909216926001600160501b038084169361ffff600160e81b85041693600160501b820483169360ff600160a01b8404811694600160a81b8504821694600160b01b900416926001600160401b03811692600160401b90910490911690565b604080516370a0823160e01b815230600482015290516000916eb3f879cb30fe243b4dfee438691c04916370a0823191602480820192602092909190829003018186803b15801561263157600080fd5b505afa158015612645573d6000803e3d6000fd5b505050506040513d602081101561265b57600080fd5b5051919050565b6000546001600160a01b031633146126af576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b6001600160a01b03919091166000908152600360205260409020805460ff1916911515919091179055565b6000816126fc6126f285670de0b6b3a764000061270b565b6002855b04613600565b8161270357fe5b049392505050565b60008115806127265750508082028282828161272357fe5b04145b61272f57600080fd5b92915050565b600080612740614aca565b506001600160a01b0388811660009081526004602090815260409182902082516101208101845281546001600160501b03808216808452600160501b8304821695840195909552600160a01b820460ff90811696840196909652600160a81b820486166060840152600160b01b9091041660808201526001909101546001600160401b03811660a0830152600160401b8104909316151560c0820152600160481b830490931660e0840152600160e81b90910461ffff1661010083015215801590612816575060808101516001600160501b0316155b6128515760405162461bcd60e51b8152600401808060200182810382526029815260200180614bce6029913960400191505060405180910390fd5b60408051633af9e66960e01b81526001600160a01b038b16600482015290516000916128e591734ddc2d193948926d02f9b1fe9e1daa0718270ed591633af9e66991602480830192602092919082900301818887803b1580156128b357600080fd5b505af11580156128c7573d6000803e3d6000fd5b505050506040513d60208110156128dd57600080fd5b50518a612b31565b90508415612901576128f982828a8a613e2a565b909550935090505b888815612934576129128183613600565b90508715612934576129318184600001516001600160501b0316612b31565b90505b6000348211156129b1576129488234612b31565b60055460408051631b2d298360e11b81526004810184905290519293506001600160a01b039091169163365a53069160248082019260009290919082900301818387803b15801561299857600080fd5b505af11580156129ac573d6000803e3d6000fd5b505050505b6129b9614b16565b6129c58d848d8c614012565b905060008715612a0957600060646129e489896060015160ff1661270b565b816129eb57fe5b049050612a0581612a008960e001518461422d565b612b31565b9150505b6000612a158483613600565b1115612a3a57600554612a3a906001600160a01b0316612a358584613600565b6143ef565b8b15612a5d578a15612a585785516001600160501b03169450612a5d565b600094505b60e086015160608301516040840151612a7b92918801908f01614490565b612a888660e001516144e6565b612a918e612bfe565b3415612ac55760405133903480156108fc02916000818181858888f19350505050158015612ac3573d6000803e3d6000fd5b505b6001600160a01b038e167f53bb08c62ecc11fdb8b19d8f885288b800b5b6e28ed23f0587dd199872ae42ef8360036020020151870184600260200201518f01604051808381526020018281526020019250505060405180910390a2505050505050965096945050505050565b8082038281111561272f57600080fd5b600080612b4c6125e1565b905080612b5d576000915050612bf9565b61a0aa61374a84010481811115612b715750805b6eb3f879cb30fe243b4dfee438691c046001600160a01b0316636366b936826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015612bc657600080fd5b505af1158015612bda573d6000803e3d6000fd5b505050506040513d6020811015612bf057600080fd5b50600193505050505b919050565b604080516101208101825260008082526020808301828152838501838152606085018481526080860185815260a0870186815260c0880187815260e089018881526101008a018981526001600160a01b039c8d168a5260049098529990972097518854955194519351925169ffffffffffffffffffff199096166001600160501b039182161769ffffffffffffffffffff60501b1916600160501b958216959095029490941760ff60a01b1916600160a01b60ff948516021760ff60a81b1916600160a81b9390921692909202176001600160b01b0316600160b01b9290931691909102919091178455516001909301805492519451915167ffffffffffffffff199093166001600160401b039094169390931760ff60401b1916600160401b94151594909402939093177fffffff0000000000000000000000000000000000000000ffffffffffffffffff16600160481b93909416929092029290921761ffff60e81b1916600160e81b61ffff90921691909102179055565b612d80614aca565b506001600160a01b03808216600081815260046020818152604080842081516101208101835281546001600160501b038082168352600160501b820481168387015260ff600160a01b8304811684870152600160a81b830481166060850152600160b01b9092041660808301526001909201546001600160401b03811660a0830152600160401b8104909216151560c0820152600160481b820490971660e088015261ffff600160e81b909104166101008701528051633af9e66960e01b81529283019490945292519192734ddc2d193948926d02f9b1fe9e1daa0718270ed592633af9e66992602480820193929182900301818787803b158015612e8457600080fd5b505af1158015612e98573d6000803e3d6000fd5b505050506040513d6020811015612eae57600080fd5b50516040805163095ea7b360e01b81526001600160a01b03861660048201526000196024820152905191925073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489163095ea7b39160448082019260009290919082900301818387803b158015612f1757600080fd5b505af1158015612f2b573d6000803e3d6000fd5b5050604080516335d0353d60e21b815273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6004820152734ddc2d193948926d02f9b1fe9e1daa0718270ed5602482015273a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4860448201527339aa39c021dfbae8fac545936693ac917d5e7563606482015290516001600160a01b038716935063d740d4f49250608480830192600092919082900301818387803b158015612fd857600080fd5b505af1158015612fec573d6000803e3d6000fd5b5050505060006064836060015160ff166130296130168587600001516001600160501b0316612b31565b86608001516001600160501b0316612b31565b028161303157fe5b04905060006130448460e001518361422d565b60a08501519091506001600160401b0316600081156130a45760e08601516130889073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48908463ffffffff613e1716565b8560c001511561309f575084516001600160501b03165b6130db565b60006130be888789608001516001600160501b031661451f565b90506130d787600001516001600160501b031682613600565b9150505b801561310c5760e086015161310c9073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee908363ffffffff613e1716565b600061312161311b8784612b31565b85612b31565b60055490915061313a906001600160a01b0316826143ef565b6131478760e001516144e6565b61315088612bfe565b604080518381526020810185905281516001600160a01b038b16927f53bb08c62ecc11fdb8b19d8f885288b800b5b6e28ed23f0587dd199872ae42ef928290030190a25050505050505050565b60006001600160a01b03831615806131d157506001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b156131e757506001600160a01b0381163161272f565b826001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561323d57600080fd5b505afa158015613251573d6000803e3d6000fd5b505050506040513d602081101561326757600080fd5b5051905061272f565b6001600160a01b0386166000908152600460205260409020546001600160501b0316156132db576040805162461bcd60e51b815260206004820152601460248201527314dd1c985d1959de48185b1c9958591e481cd95d60621b604482015290519081900360640190fd5b808061337c5760408051633af9e66960e01b81526001600160a01b03891660048201529051600091734ddc2d193948926d02f9b1fe9e1daa0718270ed591633af9e6699160248082019260209290919082900301818787803b15801561334057600080fd5b505af1158015613354573d6000803e3d6000fd5b505050506040513d602081101561336a57600080fd5b5051905086818161337757fe5b049150505b604051806101200160405280876001600160501b03168152602001866001600160501b031681526020018560ff1681526020018460ff16815260200160006001600160501b0316815260200160006001600160401b03168152602001600015158152602001896001600160a01b031681526020018261ffff1681525060046000896001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a8154816001600160501b0302191690836001600160501b03160217905550602082015181600001600a6101000a8154816001600160501b0302191690836001600160501b0316021790555060408201518160000160146101000a81548160ff021916908360ff16021790555060608201518160000160156101000a81548160ff021916908360ff16021790555060808201518160000160166101000a8154816001600160501b0302191690836001600160501b0316021790555060a08201518160010160006101000a8154816001600160401b0302191690836001600160401b0316021790555060c08201518160010160086101000a81548160ff02191690831515021790555060e08201518160010160096101000a8154816001600160a01b0302191690836001600160a01b0316021790555061010082015181600101601d6101000a81548161ffff021916908361ffff160217905550905050866001600160a01b0316886001600160a01b03167fc505104967ca2886d648964d4dfffad3cd217df1ce0b3d286cf67543d035187888888888604051808581526020018481526020018360ff1660ff1681526020018260ff1660ff16815260200194505050505060405180910390a35050505050505050565b8082018281101561272f57600080fd5b6000816136206126f2868661270b565b8161362757fe5b04949350505050565b613638614b16565b7311111254369792b2ca5d084ab5eea397ca8fa48b60006001600160a01b03881673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1461384a57600019886001600160a01b031663dd62ed3e30856001600160a01b031663e8edc8166040518163ffffffff1660e01b815260040160206040518083038186803b1580156136bf57600080fd5b505afa1580156136d3573d6000803e3d6000fd5b505050506040513d60208110156136e957600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b039384166004820152929091166024830152516044808301926020929190829003018186803b15801561373957600080fd5b505afa15801561374d573d6000803e3d6000fd5b505050506040513d602081101561376357600080fd5b50511461384557876001600160a01b031663095ea7b3836001600160a01b031663e8edc8166040518163ffffffff1660e01b815260040160206040518083038186803b1580156137b257600080fd5b505afa1580156137c6573d6000803e3d6000fd5b505050506040513d60208110156137dc57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b039092166004830152600019602483015251604480830192600092919082900301818387803b15801561382c57600080fd5b505af1158015613840573d6000803e3d6000fd5b505050505b61384d565b50855b60006138686001600160a01b038a163063ffffffff61319d16565b905060006138856001600160a01b0389163063ffffffff61319d16565b9050600060206000885160208a0187896113885a03f150506000516138c26138bc6001600160a01b038b163063ffffffff61319d16565b83612b31565b86526138db83612a006001600160a01b038e163061319d565b602087015285516138ec9089612b31565b60408701526020860151613901908b90612b31565b606087015250939998505050505050505050565b6001600160a01b03841660009081526004602052604081208054600160b01b90046001600160501b0316158015613955575080546001600160501b031615155b6139a6576040805162461bcd60e51b815260206004820152601f60248201527f5374726174656779206973206e6f7420657869737473206f722076616c696400604482015290519081900360640190fd5b60408051633af9e66960e01b81526001600160a01b03881660048201529051600091734ddc2d193948926d02f9b1fe9e1daa0718270ed591633af9e6699160248082019260209290919082900301818787803b158015613a0557600080fd5b505af1158015613a19573d6000803e3d6000fd5b505050506040513d6020811015613a2f57600080fd5b5051604080516395dd919360e01b81526001600160a01b038a1660048201529051919250600091613acc917339aa39c021dfbae8fac545936693ac917d5e7563916395dd919391602480820192602092909190829003018186803b158015613a9657600080fd5b505afa158015613aaa573d6000803e3d6000fd5b505050506040513d6020811015613ac057600080fd5b505187620f4240613610565b64e8d4a510000290506000808815613b56576000613aec8b86868c6145f6565b9597508795935090508715613b325760018601805460ff60401b1916600160401b8a15150217905585549092506001600160501b0316905081613b2f8583612b31565b96505b5060018501805467ffffffffffffffff19166001600160401b038416179055613b82565b6000613b638b868661451f565b8654909150613b7b906001600160501b031682613600565b9150839650505b84546001600160b01b0316600160b01b6001600160501b03851602178555604080518281526020810184905281516001600160a01b038d16927f253535bb9d23118941521a3ebcf52effeeed74d6716b9a2c2e33fee2329988dd928290030190a25050505050949350505050565b60608351604051908082528060200260200182016040528015613c1d578160200160208202803883390190505b5090506000805b8551811015613cac5760046000878381518110613c3d57fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205483516001600160501b0390911690849083908110613c7b57fe5b602002602001018181525050828181518110613c9357fe5b6020026020010151820191508080600101915050613c24565b5060005b85518110156113fe576000613cd8848381518110613cca57fe5b6020026020010151846126da565b90508515613d9d576000613cec8288614788565b905080600460008a8681518110613cff57fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002054600160b01b90046001600160501b03161115613d9b5780600460008a8681518110613d4a57fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002080546001600160501b03600160b01b808304821694909403169092026001600160b01b039092169190911790555b505b8415613e0e576000613daf8287614788565b905080600460008a8681518110613dc257fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020600101805467ffffffffffffffff1981166001600160401b039182169390930116919091179055505b50600101613cb0565b613e2483838360006147b0565b50505050565b8351839060009081906001600160501b0316831115613f4857613e5a8388600001516001600160501b0316612b31565b90508415613f00578315613eb257866040015160ff16606402613e9788600001516001600160501b031689602001516001600160501b0316614788565b662386f26fc10000870281613ea857fe5b0410159150613efb565b866040015160ff16606401606402613ee488600001516001600160501b031689602001516001600160501b0316614788565b662386f26fc10000870281613ef557fe5b04101591505b613f48565b866040015160ff1660640287600001516001600160501b03166064613f2d60648b6060015160ff16612b31565b840281613f3657fe5b046127100281613f4257fe5b04101591505b8115613fdc576000613f7e88600001516001600160501b03166064613f7560648c6060015160ff16612b31565b8502816126f657fe5b905080841015613fd5576040805162461bcd60e51b815260206004820152601d60248201527f65746852657374206c657373207468656e206574684166746572466565000000604482015290519081900360640190fd5b9250614008565b60095442101561400857614005836064613ff88660085461270b565b81613fff57fe5b04612b31565b92505b9450945094915050565b61401a614b16565b604080516395dd919360e01b81526001600160a01b038716600482015290516000917339aa39c021dfbae8fac545936693ac917d5e7563916395dd919391602480820192602092909190829003018186803b15801561407857600080fd5b505afa15801561408c573d6000803e3d6000fd5b505050506040513d60208110156140a257600080fd5b505190506140e473eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486140de8589613600565b87613630565b6040805163095ea7b360e01b81526001600160a01b03891660048201526000196024820152905191935073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489163095ea7b39160448082019260009290919082900301818387803b15801561414b57600080fd5b505af115801561415f573d6000803e3d6000fd5b5050604080516335d0353d60e21b815273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6004820152734ddc2d193948926d02f9b1fe9e1daa0718270ed5602482015273a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4860448201527339aa39c021dfbae8fac545936693ac917d5e7563606482015290516001600160a01b038a16935063d740d4f49250608480830192600092919082900301818387803b15801561420c57600080fd5b505af1158015614220573d6000803e3d6000fd5b5050505050949350505050565b6006546000906001600160a01b0316156143b6576006546040805163b1a1c1cf60e01b81526001600160a01b0386811660048301529151606493929092169163b1a1c1cf91602480820192602092909190829003018186803b15801561429257600080fd5b505afa1580156142a6573d6000803e3d6000fd5b505050506040513d60208110156142bc57600080fd5b505160ff168302816142ca57fe5b04905081811061430b5760405162461bcd60e51b815260040180806020018281038252602b815260200180614b35602b913960400191505060405180910390fd5b60065460408051635345cb2960e11b81526001600160a01b0386811660048301529151919092169163a68b965291849160248082019260009290919082900301818588803b15801561435c57600080fd5b505af1158015614370573d6000803e3d6000fd5b50505050507f4959927089ff30362dfc0e79000c912fc2c9cc4ec9d5c1b1e0482fa7c4cea1186143a08383612b31565b60408051918252519081900360200190a161272f565b6040805183815290517f4959927089ff30362dfc0e79000c912fc2c9cc4ec9d5c1b1e0482fa7c4cea1189181900360200190a192915050565b60405182906000906001600160a01b0383169084908381818185875af1925050503d806000811461443c576040519150601f19603f3d011682016040523d82523d6000602084013e614441565b606091505b5050905080613e24576040805162461bcd60e51b8152602060048201526016602482015275151c985b9cd9995c881bd9881155120819985a5b195960521b604482015290519081900360640190fd5b81156144bb576144bb73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee848463ffffffff613e1716565b80156118a4576118a473a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48848363ffffffff613e1716565b604080516b5f5f63616c6c6261636b282960a01b8152905190819003600c0181208082529060008060048382876113885a03f150505050565b6001600160a01b0383166000908152600460205260408120546001600160501b0381169060ff600160a81b8204811691600160a01b90041660646145638184612b31565b6145766145708987612b31565b88612b31565b028161457e57fe5b049350670de0b6b3a7640000810261459685856126da565b60640210156145ec576040805162461bcd60e51b815260206004820152601860248201527f4e65656473206d6f72652070726f66697420696e206574680000000000000000604482015290519081900360640190fd5b5050509392505050565b6001600160a01b03841660009081526004602052604081205481906001600160501b038082169160ff600160a81b8204811692600160a01b830490911691600160501b9004168460646146498186612b31565b61465c6146568d89612b31565b8c612b31565b028161466457fe5b04905064e8d4a5100061468761467a8784613600565b8a64e8d4a51000026126da565b8161468e57fe5b049550600064e8d4a510006146a38785614788565b816146aa57fe5b04905060008111614702576040805162461bcd60e51b815260206004820152601a60248201527f496e636f727265637420656e7472792075736420616d6f756e74000000000000604482015290519081900360640190fd5b61470c8782612b31565b9750670de0b6b3a7640000840261472389836126da565b6064021015614779576040805162461bcd60e51b815260206004820152601860248201527f4e65656473206d6f72652070726f66697420696e207573640000000000000000604482015290519081900360640190fd5b50505050505094509492505050565b6000670de0b6b3a76400006126fc6147a0858561270b565b6002670de0b6b3a76400006126f6565b6000826147bf57506001614886565b6001600160a01b03851615806147f157506001600160a01b03851673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b15614868578115614828576040516001600160a01b0385169084156108fc029085906000818181858888f193505050509050614886565b6040516001600160a01b0385169084156108fc029085906000818181858888f1935050505015801561485e573d6000803e3d6000fd5b5060019050614886565b6148826001600160a01b038616858563ffffffff61488e16565b5060015b949350505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526118a49084906148ed826001600160a01b0316614a93565b61493e576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b6020831061497c5780518252601f19909201916020918201910161495d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146149de576040519150601f19603f3d011682016040523d82523d6000602084013e6149e3565b606091505b509150915081614a3a576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115613e2457808060200190516020811015614a5657600080fd5b5051613e245760405162461bcd60e51b815260040180806020018281038252602a815260200180614c20602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081158015906148865750141592915050565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081019190915290565b6040518060800160405280600490602082028038833950919291505056fe496e636f727265637420616666696c696174652070726f6772616d207061796d656e742070657263656e745374726174656779206973206e6f742076616c696420666f72206d6967726174655065726d697373696f6e2064656e696564000000000000000000000000000000537472617465677920697320616374697665202d20746865726520776173206e6f206c69717569646174696f6e5374726174656779206973206e6f7420657869737473206f722076616c696420666f7220636c6f73655374726174656779206973206e6f7420657869737473206f7220726561647920666f7220636c6f73655361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a7231582038f04c1a51d5cb1354c6c60cdd840dea64b1f69a7f5ed081601d5e51181136e064736f6c63430005110032

Deployed Bytecode

0x6080604052600436106102515760003560e01c80638af8d4c311610139578063bb09d9b7116100b6578063ebbc49651161007a578063ebbc496514610eca578063ee5f4afd14610edf578063f3fef3a314610ef4578063f8806a1314610f2d578063f93f20d814610fb3578063ffb6c79c14610fc857610251565b8063bb09d9b714610cc0578063c63f0dc114610cd5578063d1e1ecba14610d37578063e1ea330014610d6a578063eb21d9c414610e1a57610251565b8063a6f9dae1116100fd578063a6f9dae114610bc5578063a734f06e14610bf8578063ad9d4ba314610c0d578063ae5f8f7214610c33578063b3c18b1614610c6657610251565b80638af8d4c314610a015780638da5cb5b14610a1657806394771d7614610a2b57806398fb838714610a40578063a46c310314610b9257610251565b8063416d4efb116101d25780635f82c67e116101965780635f82c67e146108855780636568a2791461089a57806366408eb014610948578063672c42911461095d57806375f3974b146109b15780638a5e8cc7146109ec57610251565b8063416d4efb14610562578063429b62e5146106295780634ab45d33146106705780635969490d1461068557806359966b24146107d757610251565b806326976e3f1161021957806326976e3f146103b35780632840e1b3146103c85780632bb083fc146103dd578063331934ec1461041057806339ebf823146104be57610251565b8063040141e5146102535780630900f0101461028457806312defc83146102b75780631d8319e4146102de57806325fda7881461039e575b005b34801561025f57600080fd5b50610268611003565b604080516001600160a01b039092168252519081900360200190f35b34801561029057600080fd5b50610251600480360360208110156102a757600080fd5b50356001600160a01b031661101b565b3480156102c357600080fd5b506102cc6110e0565b60408051918252519081900360200190f35b610251600480360360808110156102f457600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b81111561032a57600080fd5b82018360208201111561033c57600080fd5b803590602001918460018302840111600160201b8311171561035d57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506111a0945050505050565b3480156103aa57600080fd5b506102cc611406565b3480156103bf57600080fd5b5061026861140c565b3480156103d457600080fd5b5061026861141b565b3480156103e957600080fd5b506102516004803603602081101561040057600080fd5b50356001600160a01b031661142a565b34801561041c57600080fd5b506102516004803603602081101561043357600080fd5b810190602081018135600160201b81111561044d57600080fd5b82018360208201111561045f57600080fd5b803590602001918460208302840111600160201b8311171561048057600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506114ef945050505050565b3480156104ca57600080fd5b506104f1600480360360208110156104e157600080fd5b50356001600160a01b03166118a9565b604080516001600160501b039a8b168152988a1660208a015260ff978816898201529590961660608801529290961660808601526001600160401b031660a085015293151560c08401526001600160a01b0390931660e083015261ffff166101008201529051908190036101200190f35b610251600480360360a081101561057857600080fd5b6001600160a01b0382351691602081013591604082013591606081013515159181019060a081016080820135600160201b8111156105b557600080fd5b8201836020820111156105c757600080fd5b803590602001918460018302840111600160201b831117156105e857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611928945050505050565b34801561063557600080fd5b5061065c6004803603602081101561064c57600080fd5b50356001600160a01b03166119ce565b604080519115158252519081900360200190f35b34801561067c57600080fd5b506102686119e3565b34801561069157600080fd5b50610251600480360360e08110156106a857600080fd5b810190602081018135600160201b8111156106c257600080fd5b8201836020820111156106d457600080fd5b803590602001918460208302840111600160201b831117156106f557600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092958435956020860135956040810135955060608101351515945060808101351515935060c081019060a00135600160201b81111561076357600080fd5b82018360208201111561077557600080fd5b803590602001918460018302840111600160201b8311171561079657600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506119fb945050505050565b3480156107e357600080fd5b50610251600480360360208110156107fa57600080fd5b810190602081018135600160201b81111561081457600080fd5b82018360208201111561082657600080fd5b803590602001918460208302840111600160201b8311171561084757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611a0f945050505050565b34801561089157600080fd5b50610268611ad4565b3480156108a657600080fd5b50610251600480360360208110156108bd57600080fd5b810190602081018135600160201b8111156108d757600080fd5b8201836020820111156108e957600080fd5b803590602001918460208302840111600160201b8311171561090a57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611aec945050505050565b34801561095457600080fd5b50610268611b9c565b34801561096957600080fd5b50610251600480360360a081101561098057600080fd5b506001600160a01b03813581169160208101359091169060408101359060ff60608201358116916080013516611bb4565b3480156109bd57600080fd5b50610251600480360360408110156109d457600080fd5b506001600160a01b0381351690602001351515611c36565b3480156109f857600080fd5b50610268611cae565b348015610a0d57600080fd5b50610268611cc6565b348015610a2257600080fd5b50610268611cd9565b348015610a3757600080fd5b50610268611ce8565b348015610a4c57600080fd5b50610251600480360360e0811015610a6357600080fd5b810190602081018135600160201b811115610a7d57600080fd5b820183602082011115610a8f57600080fd5b803590602001918460208302840111600160201b83111715610ab057600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092958435956020860135956040810135955060608101351515945060808101351515935060c081019060a00135600160201b811115610b1e57600080fd5b820183602082011115610b3057600080fd5b803590602001918460018302840111600160201b83111715610b5157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611cf7945050505050565b348015610b9e57600080fd5b5061025160048036036020811015610bb557600080fd5b50356001600160a01b0316611f12565b348015610bd157600080fd5b5061025160048036036020811015610be857600080fd5b50356001600160a01b0316611f92565b348015610c0457600080fd5b50610268612001565b61025160048036036020811015610c2357600080fd5b50356001600160a01b0316612019565b348015610c3f57600080fd5b5061065c60048036036020811015610c5657600080fd5b50356001600160a01b0316612160565b348015610c7257600080fd5b50610251600480360360c0811015610c8957600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff608082013581169160a0013516612175565b348015610ccc57600080fd5b506102686121e9565b348015610ce157600080fd5b50610251600480360360e0811015610cf857600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff608082013581169160a08101359091169060c00135612201565b348015610d4357600080fd5b5061025160048036036020811015610d5a57600080fd5b50356001600160a01b0316612274565b348015610d7657600080fd5b5061025160048036036040811015610d8d57600080fd5b810190602081018135600160201b811115610da757600080fd5b820183602082011115610db957600080fd5b803590602001918460208302840111600160201b83111715610dda57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955050505035151590506122e3565b348015610e2657600080fd5b5061025160048036036040811015610e3d57600080fd5b810190602081018135600160201b811115610e5757600080fd5b820183602082011115610e6957600080fd5b803590602001918460208302840111600160201b83111715610e8a57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505050503515159050612387565b348015610ed657600080fd5b5061025161242b565b348015610eeb57600080fd5b506102cc61249c565b348015610f0057600080fd5b5061025160048036036040811015610f1757600080fd5b506001600160a01b0381351690602001356124a2565b348015610f3957600080fd5b50610f6060048036036020811015610f5057600080fd5b50356001600160a01b031661255c565b604080516001600160a01b03909a168a5260208a0198909852888801969096526060880194909452608087019290925260a086015260c085015260e0840152151561010083015251908190036101200190f35b348015610fbf57600080fd5b506102cc6125e1565b348015610fd457600080fd5b5061025160048036036040811015610feb57600080fd5b506001600160a01b0381351690602001351515612662565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6000546001600160a01b03163314611068576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b6001600160a01b0381166110be576040805162461bcd60e51b815260206004820152601860248201527741646472657373206d757374206e6f74206265207a65726f60401b604482015290519081900360640190fd5b600780546001600160a01b0319166001600160a01b0392909216919091179055565b6040805163fc57d4df60e01b81527339aa39c021dfbae8fac545936693ac917d5e756360048201529051600091829164e8d4a5100091731d8aedc9e924730dd3f9641cdb4d1b92b848b4bd9163fc57d4df91602480820192602092909190829003018186803b15801561115257600080fd5b505afa158015611166573d6000803e3d6000fd5b505050506040513d602081101561117c57600080fd5b50518161118557fe5b04905061119a670de0b6b3a7640000826126da565b91505090565b60005a90506111ad614aca565b506001600160a01b0385811660009081526004602090815260409182902082516101208101845281546001600160501b038082168352600160501b8204811694830194909452600160a01b810460ff90811695830195909552600160a81b810485166060830152600160b01b90049092166080830152600101546001600160401b03811660a0830152600160401b8104909216151560c0820152600160481b820490921660e08301819052600160e81b90910461ffff1661010083015233148061128157506000546001600160a01b031633145b8061129b57503360009081526002602052604090205460ff165b6112da576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b60408051633af9e66960e01b81526001600160a01b03881660048201529051600091734ddc2d193948926d02f9b1fe9e1daa0718270ed591633af9e6699160248082019260209290919082900301818787803b15801561133957600080fd5b505af115801561134d573d6000803e3d6000fd5b505050506040513d602081101561136357600080fd5b5051825161010084015191925060009160649161138f916001600160501b039091169061ffff1661270b565b8161139657fe5b0490508082106113d75760405162461bcd60e51b815260040180806020018281038252602d815260200180614ba1602d913960400191505060405180910390fd5b6113e78888886000896000612735565b50505050506113fe6113f9825a612b31565b612b41565b505050505050565b60095481565b6007546001600160a01b031681565b6006546001600160a01b031681565b6000546001600160a01b03163314611477576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b6001600160a01b0381166114cd576040805162461bcd60e51b815260206004820152601860248201527741646472657373206d757374206e6f74206265207a65726f60401b604482015290519081900360640190fd5b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6007546001600160a01b03168061154d576040805162461bcd60e51b815260206004820152601a60248201527f4d6967726174696f6e206973206e6f7420617661696c61626c65000000000000604482015290519081900360640190fd5b60005b82518110156118a457611561614aca565b6004600085848151811061157157fe5b6020908102919091018101516001600160a01b03908116835282820193909352604091820160002082516101208101845281546001600160501b038082168352600160501b8204811694830194909452600160a01b810460ff90811695830195909552600160a81b810485166060830152600160b01b90049092166080830152600101546001600160401b03811660a0830152600160401b8104909216151560c0820152600160481b820490921660e08301819052600160e81b90910461ffff16610100830152909150331461168e576040805162461bcd60e51b815260206004820152601a60248201527f5374726174656779207065726d697373696f6e2064656e696564000000000000604482015290519081900360640190fd5b60808101516001600160501b0316156116d85760405162461bcd60e51b8152600401808060200182810382526021815260200180614b606021913960400191505060405180910390fd5b826001600160a01b031663c63f0dc18260e001518685815181106116f857fe5b60209081029190910181015185519186015160408088015160608901516101008a015183516001600160e01b031960e08b901b1681526001600160a01b0398891660048201529790951660248801526001600160501b03958616604488015294909216606486015260ff9182166084860152921660a484015261ffff1660c48301525160e480830192600092919082900301818387803b15801561179b57600080fd5b505af11580156117af573d6000803e3d6000fd5b505050508382815181106117bf57fe5b60200260200101516001600160a01b0316635b85a60a846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050600060405180830381600087803b15801561181e57600080fd5b505af1158015611832573d6000803e3d6000fd5b5050505061185284838151811061184557fe5b6020026020010151612bfe565b83828151811061185e57fe5b60200260200101516001600160a01b03167f7c9a2d2ec51230d7dbed27f113a325b7e20aef7b049e68b2339257b5edff5bea60405160405180910390a250600101611550565b505050565b600460205260009081526040902080546001909101546001600160501b0380831692600160501b810482169260ff600160a01b8304811693600160a81b8404821693600160b01b900416916001600160401b03811691600160401b820416906001600160a01b03600160481b8204169061ffff600160e81b9091041689565b60005a6001600160a01b03878116600090815260046020526040902060010154919250600160481b9091041633146119a7576040805162461bcd60e51b815260206004820152601a60248201527f5374726174656779207065726d697373696f6e2064656e696564000000000000604482015290519081900360640190fd5b6119b686868686866001612735565b50506119c56113f9825a612b31565b50505050505050565b60026020526000908152604090205460ff1681565b734ddc2d193948926d02f9b1fe9e1daa0718270ed581565b611a0a87878787878787611cf7565b6119c5875b60005a905060005b8251811015611ac657600060046000858481518110611a3257fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002054600160b01b90046001600160501b031611611aa25760405162461bcd60e51b8152600401808060200182810382526029815260200180614bf76029913960400191505060405180910390fd5b611abe838281518110611ab157fe5b6020026020010151612d78565b600101611a17565b506118a46113f9825a612b31565b733d9819210a31b4961b30ef54be2aed79b9c9cd3b81565b6000546001600160a01b03163314611b39576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b60005b8151811015611b9857611b90828281518110611b5457fe5b6020026020010151611b8b30858581518110611b6c57fe5b60200260200101516001600160a01b031661319d90919063ffffffff16565b6124a2565b600101611b3c565b5050565b7339aa39c021dfbae8fac545936693ac917d5e756381565b3360009081526003602052604090205460ff16611c18576040805162461bcd60e51b815260206004820152601b60248201527f536574757020637570207065726d697373696f6e2064656e6965640000000000604482015290519081900360640190fd5b611c2f858585611c266110e0565b86866000613270565b5050505050565b6000546001600160a01b03163314611c83576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b6001600160a01b03919091166000908152600260205260409020805460ff1916911515919091179055565b731d8aedc9e924730dd3f9641cdb4d1b92b848b4bd81565b6eb3f879cb30fe243b4dfee438691c0481565b6000546001600160a01b031681565b6005546001600160a01b031681565b60005a3360009081526002602052604090205490915060ff1680611d2557506000546001600160a01b031633145b611d64576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b6000611d7d611d738989613600565b87620f4240613610565b64e8d4a51000029050611d8e614b16565b8415611e3a5760055460408051631b2d298360e11b81526004810185905290516001600160a01b039092169163365a53069160248082019260009290919082900301818387803b158015611de157600080fd5b505af1158015611df5573d6000803e3d6000fd5b50505050611e3773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8373a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48611e318d8d613600565b88613630565b90505b6000805b8b51811015611e7257611e668c8281518110611e5657fe5b60200260200101518b8b8b613915565b90910190600101611e3e565b5082811015611ec8576040805162461bcd60e51b815260206004820152601b60248201527f4574684166746572436c6f7365206973206e6f7420656e6f7567680000000000604482015290519081900360640190fd5b6040820151151580611edd5750606082015115155b15611ef75760608201516040830151611ef7918d91613bf0565b505050611f076113f9825a612b31565b505050505050505050565b60005a6001600160a01b038316600090815260046020526040902054909150600160b01b90046001600160501b0316611f7c5760405162461bcd60e51b8152600401808060200182810382526029815260200180614bf76029913960400191505060405180910390fd5b611f8582612d78565b6118a46113f9825a612b31565b6000546001600160a01b03163314611fdf576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b6001600160a01b0381166000908152600460205260409020546001600160501b0316612085576040805162461bcd60e51b81526020600482015260166024820152755374726174656779206973206e6f742065786973747360501b604482015290519081900360640190fd5b6001600160a01b0381166000818152600460208190526040808320805469ffffffffffffffffffff198116346001600160501b0392831681019092161790915581516302d35a5960e01b815273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee93810193909352734ddc2d193948926d02f9b1fe9e1daa0718270ed5602484015260448301819052606483018490526084830184905260a4830184905290519093926302d35a5992859260c4808301939282900301818588803b15801561214c57600080fd5b505af11580156119c5573d6000803e3d6000fd5b60036020526000908152604090205460ff1681565b3360009081526003602052604090205460ff166121d9576040805162461bcd60e51b815260206004820152601b60248201527f536574757020637570207065726d697373696f6e2064656e6965640000000000604482015290519081900360640190fd5b6113fe8686868686866000613270565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b3360009081526003602052604090205460ff16612265576040805162461bcd60e51b815260206004820152601b60248201527f536574757020637570207065726d697373696f6e2064656e6965640000000000604482015290519081900360640190fd5b6119c587878787878787613270565b6000546001600160a01b031633146122c1576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b600680546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314612330576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b60005b82518110156118a457816003600085848151811061234d57fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055600101612333565b6000546001600160a01b031633146123d4576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b60005b82518110156118a45781600260008584815181106123f157fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff19169115159190911790556001016123d7565b6001546001600160a01b03163314612478576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b600154600080546001600160a01b0319166001600160a01b03909216919091179055565b60085481565b6000546001600160a01b031633146124ef576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b6001600160a01b03821661253c57600080546040516001600160a01b039091169183156108fc02918491818181858888f19350505050158015612536573d6000803e3d6000fd5b50611b98565b600054611b98906001600160a01b0384811691168363ffffffff613e1716565b6001600160a01b03908116600090815260046020526040902060018101549054600160481b8204909216926001600160501b038084169361ffff600160e81b85041693600160501b820483169360ff600160a01b8404811694600160a81b8504821694600160b01b900416926001600160401b03811692600160401b90910490911690565b604080516370a0823160e01b815230600482015290516000916eb3f879cb30fe243b4dfee438691c04916370a0823191602480820192602092909190829003018186803b15801561263157600080fd5b505afa158015612645573d6000803e3d6000fd5b505050506040513d602081101561265b57600080fd5b5051919050565b6000546001600160a01b031633146126af576040805162461bcd60e51b81526020600482015260116024820152600080516020614b81833981519152604482015290519081900360640190fd5b6001600160a01b03919091166000908152600360205260409020805460ff1916911515919091179055565b6000816126fc6126f285670de0b6b3a764000061270b565b6002855b04613600565b8161270357fe5b049392505050565b60008115806127265750508082028282828161272357fe5b04145b61272f57600080fd5b92915050565b600080612740614aca565b506001600160a01b0388811660009081526004602090815260409182902082516101208101845281546001600160501b03808216808452600160501b8304821695840195909552600160a01b820460ff90811696840196909652600160a81b820486166060840152600160b01b9091041660808201526001909101546001600160401b03811660a0830152600160401b8104909316151560c0820152600160481b830490931660e0840152600160e81b90910461ffff1661010083015215801590612816575060808101516001600160501b0316155b6128515760405162461bcd60e51b8152600401808060200182810382526029815260200180614bce6029913960400191505060405180910390fd5b60408051633af9e66960e01b81526001600160a01b038b16600482015290516000916128e591734ddc2d193948926d02f9b1fe9e1daa0718270ed591633af9e66991602480830192602092919082900301818887803b1580156128b357600080fd5b505af11580156128c7573d6000803e3d6000fd5b505050506040513d60208110156128dd57600080fd5b50518a612b31565b90508415612901576128f982828a8a613e2a565b909550935090505b888815612934576129128183613600565b90508715612934576129318184600001516001600160501b0316612b31565b90505b6000348211156129b1576129488234612b31565b60055460408051631b2d298360e11b81526004810184905290519293506001600160a01b039091169163365a53069160248082019260009290919082900301818387803b15801561299857600080fd5b505af11580156129ac573d6000803e3d6000fd5b505050505b6129b9614b16565b6129c58d848d8c614012565b905060008715612a0957600060646129e489896060015160ff1661270b565b816129eb57fe5b049050612a0581612a008960e001518461422d565b612b31565b9150505b6000612a158483613600565b1115612a3a57600554612a3a906001600160a01b0316612a358584613600565b6143ef565b8b15612a5d578a15612a585785516001600160501b03169450612a5d565b600094505b60e086015160608301516040840151612a7b92918801908f01614490565b612a888660e001516144e6565b612a918e612bfe565b3415612ac55760405133903480156108fc02916000818181858888f19350505050158015612ac3573d6000803e3d6000fd5b505b6001600160a01b038e167f53bb08c62ecc11fdb8b19d8f885288b800b5b6e28ed23f0587dd199872ae42ef8360036020020151870184600260200201518f01604051808381526020018281526020019250505060405180910390a2505050505050965096945050505050565b8082038281111561272f57600080fd5b600080612b4c6125e1565b905080612b5d576000915050612bf9565b61a0aa61374a84010481811115612b715750805b6eb3f879cb30fe243b4dfee438691c046001600160a01b0316636366b936826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015612bc657600080fd5b505af1158015612bda573d6000803e3d6000fd5b505050506040513d6020811015612bf057600080fd5b50600193505050505b919050565b604080516101208101825260008082526020808301828152838501838152606085018481526080860185815260a0870186815260c0880187815260e089018881526101008a018981526001600160a01b039c8d168a5260049098529990972097518854955194519351925169ffffffffffffffffffff199096166001600160501b039182161769ffffffffffffffffffff60501b1916600160501b958216959095029490941760ff60a01b1916600160a01b60ff948516021760ff60a81b1916600160a81b9390921692909202176001600160b01b0316600160b01b9290931691909102919091178455516001909301805492519451915167ffffffffffffffff199093166001600160401b039094169390931760ff60401b1916600160401b94151594909402939093177fffffff0000000000000000000000000000000000000000ffffffffffffffffff16600160481b93909416929092029290921761ffff60e81b1916600160e81b61ffff90921691909102179055565b612d80614aca565b506001600160a01b03808216600081815260046020818152604080842081516101208101835281546001600160501b038082168352600160501b820481168387015260ff600160a01b8304811684870152600160a81b830481166060850152600160b01b9092041660808301526001909201546001600160401b03811660a0830152600160401b8104909216151560c0820152600160481b820490971660e088015261ffff600160e81b909104166101008701528051633af9e66960e01b81529283019490945292519192734ddc2d193948926d02f9b1fe9e1daa0718270ed592633af9e66992602480820193929182900301818787803b158015612e8457600080fd5b505af1158015612e98573d6000803e3d6000fd5b505050506040513d6020811015612eae57600080fd5b50516040805163095ea7b360e01b81526001600160a01b03861660048201526000196024820152905191925073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489163095ea7b39160448082019260009290919082900301818387803b158015612f1757600080fd5b505af1158015612f2b573d6000803e3d6000fd5b5050604080516335d0353d60e21b815273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6004820152734ddc2d193948926d02f9b1fe9e1daa0718270ed5602482015273a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4860448201527339aa39c021dfbae8fac545936693ac917d5e7563606482015290516001600160a01b038716935063d740d4f49250608480830192600092919082900301818387803b158015612fd857600080fd5b505af1158015612fec573d6000803e3d6000fd5b5050505060006064836060015160ff166130296130168587600001516001600160501b0316612b31565b86608001516001600160501b0316612b31565b028161303157fe5b04905060006130448460e001518361422d565b60a08501519091506001600160401b0316600081156130a45760e08601516130889073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48908463ffffffff613e1716565b8560c001511561309f575084516001600160501b03165b6130db565b60006130be888789608001516001600160501b031661451f565b90506130d787600001516001600160501b031682613600565b9150505b801561310c5760e086015161310c9073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee908363ffffffff613e1716565b600061312161311b8784612b31565b85612b31565b60055490915061313a906001600160a01b0316826143ef565b6131478760e001516144e6565b61315088612bfe565b604080518381526020810185905281516001600160a01b038b16927f53bb08c62ecc11fdb8b19d8f885288b800b5b6e28ed23f0587dd199872ae42ef928290030190a25050505050505050565b60006001600160a01b03831615806131d157506001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b156131e757506001600160a01b0381163161272f565b826001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561323d57600080fd5b505afa158015613251573d6000803e3d6000fd5b505050506040513d602081101561326757600080fd5b5051905061272f565b6001600160a01b0386166000908152600460205260409020546001600160501b0316156132db576040805162461bcd60e51b815260206004820152601460248201527314dd1c985d1959de48185b1c9958591e481cd95d60621b604482015290519081900360640190fd5b808061337c5760408051633af9e66960e01b81526001600160a01b03891660048201529051600091734ddc2d193948926d02f9b1fe9e1daa0718270ed591633af9e6699160248082019260209290919082900301818787803b15801561334057600080fd5b505af1158015613354573d6000803e3d6000fd5b505050506040513d602081101561336a57600080fd5b5051905086818161337757fe5b049150505b604051806101200160405280876001600160501b03168152602001866001600160501b031681526020018560ff1681526020018460ff16815260200160006001600160501b0316815260200160006001600160401b03168152602001600015158152602001896001600160a01b031681526020018261ffff1681525060046000896001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a8154816001600160501b0302191690836001600160501b03160217905550602082015181600001600a6101000a8154816001600160501b0302191690836001600160501b0316021790555060408201518160000160146101000a81548160ff021916908360ff16021790555060608201518160000160156101000a81548160ff021916908360ff16021790555060808201518160000160166101000a8154816001600160501b0302191690836001600160501b0316021790555060a08201518160010160006101000a8154816001600160401b0302191690836001600160401b0316021790555060c08201518160010160086101000a81548160ff02191690831515021790555060e08201518160010160096101000a8154816001600160a01b0302191690836001600160a01b0316021790555061010082015181600101601d6101000a81548161ffff021916908361ffff160217905550905050866001600160a01b0316886001600160a01b03167fc505104967ca2886d648964d4dfffad3cd217df1ce0b3d286cf67543d035187888888888604051808581526020018481526020018360ff1660ff1681526020018260ff1660ff16815260200194505050505060405180910390a35050505050505050565b8082018281101561272f57600080fd5b6000816136206126f2868661270b565b8161362757fe5b04949350505050565b613638614b16565b7311111254369792b2ca5d084ab5eea397ca8fa48b60006001600160a01b03881673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1461384a57600019886001600160a01b031663dd62ed3e30856001600160a01b031663e8edc8166040518163ffffffff1660e01b815260040160206040518083038186803b1580156136bf57600080fd5b505afa1580156136d3573d6000803e3d6000fd5b505050506040513d60208110156136e957600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b039384166004820152929091166024830152516044808301926020929190829003018186803b15801561373957600080fd5b505afa15801561374d573d6000803e3d6000fd5b505050506040513d602081101561376357600080fd5b50511461384557876001600160a01b031663095ea7b3836001600160a01b031663e8edc8166040518163ffffffff1660e01b815260040160206040518083038186803b1580156137b257600080fd5b505afa1580156137c6573d6000803e3d6000fd5b505050506040513d60208110156137dc57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b039092166004830152600019602483015251604480830192600092919082900301818387803b15801561382c57600080fd5b505af1158015613840573d6000803e3d6000fd5b505050505b61384d565b50855b60006138686001600160a01b038a163063ffffffff61319d16565b905060006138856001600160a01b0389163063ffffffff61319d16565b9050600060206000885160208a0187896113885a03f150506000516138c26138bc6001600160a01b038b163063ffffffff61319d16565b83612b31565b86526138db83612a006001600160a01b038e163061319d565b602087015285516138ec9089612b31565b60408701526020860151613901908b90612b31565b606087015250939998505050505050505050565b6001600160a01b03841660009081526004602052604081208054600160b01b90046001600160501b0316158015613955575080546001600160501b031615155b6139a6576040805162461bcd60e51b815260206004820152601f60248201527f5374726174656779206973206e6f7420657869737473206f722076616c696400604482015290519081900360640190fd5b60408051633af9e66960e01b81526001600160a01b03881660048201529051600091734ddc2d193948926d02f9b1fe9e1daa0718270ed591633af9e6699160248082019260209290919082900301818787803b158015613a0557600080fd5b505af1158015613a19573d6000803e3d6000fd5b505050506040513d6020811015613a2f57600080fd5b5051604080516395dd919360e01b81526001600160a01b038a1660048201529051919250600091613acc917339aa39c021dfbae8fac545936693ac917d5e7563916395dd919391602480820192602092909190829003018186803b158015613a9657600080fd5b505afa158015613aaa573d6000803e3d6000fd5b505050506040513d6020811015613ac057600080fd5b505187620f4240613610565b64e8d4a510000290506000808815613b56576000613aec8b86868c6145f6565b9597508795935090508715613b325760018601805460ff60401b1916600160401b8a15150217905585549092506001600160501b0316905081613b2f8583612b31565b96505b5060018501805467ffffffffffffffff19166001600160401b038416179055613b82565b6000613b638b868661451f565b8654909150613b7b906001600160501b031682613600565b9150839650505b84546001600160b01b0316600160b01b6001600160501b03851602178555604080518281526020810184905281516001600160a01b038d16927f253535bb9d23118941521a3ebcf52effeeed74d6716b9a2c2e33fee2329988dd928290030190a25050505050949350505050565b60608351604051908082528060200260200182016040528015613c1d578160200160208202803883390190505b5090506000805b8551811015613cac5760046000878381518110613c3d57fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205483516001600160501b0390911690849083908110613c7b57fe5b602002602001018181525050828181518110613c9357fe5b6020026020010151820191508080600101915050613c24565b5060005b85518110156113fe576000613cd8848381518110613cca57fe5b6020026020010151846126da565b90508515613d9d576000613cec8288614788565b905080600460008a8681518110613cff57fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002054600160b01b90046001600160501b03161115613d9b5780600460008a8681518110613d4a57fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002080546001600160501b03600160b01b808304821694909403169092026001600160b01b039092169190911790555b505b8415613e0e576000613daf8287614788565b905080600460008a8681518110613dc257fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020600101805467ffffffffffffffff1981166001600160401b039182169390930116919091179055505b50600101613cb0565b613e2483838360006147b0565b50505050565b8351839060009081906001600160501b0316831115613f4857613e5a8388600001516001600160501b0316612b31565b90508415613f00578315613eb257866040015160ff16606402613e9788600001516001600160501b031689602001516001600160501b0316614788565b662386f26fc10000870281613ea857fe5b0410159150613efb565b866040015160ff16606401606402613ee488600001516001600160501b031689602001516001600160501b0316614788565b662386f26fc10000870281613ef557fe5b04101591505b613f48565b866040015160ff1660640287600001516001600160501b03166064613f2d60648b6060015160ff16612b31565b840281613f3657fe5b046127100281613f4257fe5b04101591505b8115613fdc576000613f7e88600001516001600160501b03166064613f7560648c6060015160ff16612b31565b8502816126f657fe5b905080841015613fd5576040805162461bcd60e51b815260206004820152601d60248201527f65746852657374206c657373207468656e206574684166746572466565000000604482015290519081900360640190fd5b9250614008565b60095442101561400857614005836064613ff88660085461270b565b81613fff57fe5b04612b31565b92505b9450945094915050565b61401a614b16565b604080516395dd919360e01b81526001600160a01b038716600482015290516000917339aa39c021dfbae8fac545936693ac917d5e7563916395dd919391602480820192602092909190829003018186803b15801561407857600080fd5b505afa15801561408c573d6000803e3d6000fd5b505050506040513d60208110156140a257600080fd5b505190506140e473eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486140de8589613600565b87613630565b6040805163095ea7b360e01b81526001600160a01b03891660048201526000196024820152905191935073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489163095ea7b39160448082019260009290919082900301818387803b15801561414b57600080fd5b505af115801561415f573d6000803e3d6000fd5b5050604080516335d0353d60e21b815273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6004820152734ddc2d193948926d02f9b1fe9e1daa0718270ed5602482015273a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4860448201527339aa39c021dfbae8fac545936693ac917d5e7563606482015290516001600160a01b038a16935063d740d4f49250608480830192600092919082900301818387803b15801561420c57600080fd5b505af1158015614220573d6000803e3d6000fd5b5050505050949350505050565b6006546000906001600160a01b0316156143b6576006546040805163b1a1c1cf60e01b81526001600160a01b0386811660048301529151606493929092169163b1a1c1cf91602480820192602092909190829003018186803b15801561429257600080fd5b505afa1580156142a6573d6000803e3d6000fd5b505050506040513d60208110156142bc57600080fd5b505160ff168302816142ca57fe5b04905081811061430b5760405162461bcd60e51b815260040180806020018281038252602b815260200180614b35602b913960400191505060405180910390fd5b60065460408051635345cb2960e11b81526001600160a01b0386811660048301529151919092169163a68b965291849160248082019260009290919082900301818588803b15801561435c57600080fd5b505af1158015614370573d6000803e3d6000fd5b50505050507f4959927089ff30362dfc0e79000c912fc2c9cc4ec9d5c1b1e0482fa7c4cea1186143a08383612b31565b60408051918252519081900360200190a161272f565b6040805183815290517f4959927089ff30362dfc0e79000c912fc2c9cc4ec9d5c1b1e0482fa7c4cea1189181900360200190a192915050565b60405182906000906001600160a01b0383169084908381818185875af1925050503d806000811461443c576040519150601f19603f3d011682016040523d82523d6000602084013e614441565b606091505b5050905080613e24576040805162461bcd60e51b8152602060048201526016602482015275151c985b9cd9995c881bd9881155120819985a5b195960521b604482015290519081900360640190fd5b81156144bb576144bb73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee848463ffffffff613e1716565b80156118a4576118a473a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48848363ffffffff613e1716565b604080516b5f5f63616c6c6261636b282960a01b8152905190819003600c0181208082529060008060048382876113885a03f150505050565b6001600160a01b0383166000908152600460205260408120546001600160501b0381169060ff600160a81b8204811691600160a01b90041660646145638184612b31565b6145766145708987612b31565b88612b31565b028161457e57fe5b049350670de0b6b3a7640000810261459685856126da565b60640210156145ec576040805162461bcd60e51b815260206004820152601860248201527f4e65656473206d6f72652070726f66697420696e206574680000000000000000604482015290519081900360640190fd5b5050509392505050565b6001600160a01b03841660009081526004602052604081205481906001600160501b038082169160ff600160a81b8204811692600160a01b830490911691600160501b9004168460646146498186612b31565b61465c6146568d89612b31565b8c612b31565b028161466457fe5b04905064e8d4a5100061468761467a8784613600565b8a64e8d4a51000026126da565b8161468e57fe5b049550600064e8d4a510006146a38785614788565b816146aa57fe5b04905060008111614702576040805162461bcd60e51b815260206004820152601a60248201527f496e636f727265637420656e7472792075736420616d6f756e74000000000000604482015290519081900360640190fd5b61470c8782612b31565b9750670de0b6b3a7640000840261472389836126da565b6064021015614779576040805162461bcd60e51b815260206004820152601860248201527f4e65656473206d6f72652070726f66697420696e207573640000000000000000604482015290519081900360640190fd5b50505050505094509492505050565b6000670de0b6b3a76400006126fc6147a0858561270b565b6002670de0b6b3a76400006126f6565b6000826147bf57506001614886565b6001600160a01b03851615806147f157506001600160a01b03851673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b15614868578115614828576040516001600160a01b0385169084156108fc029085906000818181858888f193505050509050614886565b6040516001600160a01b0385169084156108fc029085906000818181858888f1935050505015801561485e573d6000803e3d6000fd5b5060019050614886565b6148826001600160a01b038616858563ffffffff61488e16565b5060015b949350505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526118a49084906148ed826001600160a01b0316614a93565b61493e576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b6020831061497c5780518252601f19909201916020918201910161495d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146149de576040519150601f19603f3d011682016040523d82523d6000602084013e6149e3565b606091505b509150915081614a3a576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115613e2457808060200190516020811015614a5657600080fd5b5051613e245760405162461bcd60e51b815260040180806020018281038252602a815260200180614c20602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081158015906148865750141592915050565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081019190915290565b6040518060800160405280600490602082028038833950919291505056fe496e636f727265637420616666696c696174652070726f6772616d207061796d656e742070657263656e745374726174656779206973206e6f742076616c696420666f72206d6967726174655065726d697373696f6e2064656e696564000000000000000000000000000000537472617465677920697320616374697665202d20746865726520776173206e6f206c69717569646174696f6e5374726174656779206973206e6f7420657869737473206f722076616c696420666f7220636c6f73655374726174656779206973206e6f7420657869737473206f7220726561647920666f7220636c6f73655361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a7231582038f04c1a51d5cb1354c6c60cdd840dea64b1f69a7f5ed081601d5e51181136e064736f6c63430005110032

Deployed Bytecode Sourcemap

25181:30239:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20193:81;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20193:81:0;;;:::i;:::-;;;;-1:-1:-1;;;;;20193:81:0;;;;;;;;;;;;;;37498:208;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37498:208:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;37498:208:0;-1:-1:-1;;;;;37498:208:0;;:::i;28695:283::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;28695:283:0;;;:::i;:::-;;;;;;;;;;;;;;;;35602:841;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;35602:841:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;35602:841:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;35602:841:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;35602:841:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;35602:841:0;;-1:-1:-1;35602:841:0;;-1:-1:-1;;;;;35602:841:0:i;26445:28::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26445:28:0;;;:::i;26285:38::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26285:38:0;;;:::i;26248:28::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26248:28:0;;;:::i;36488:178::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36488:178:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;36488:178:0;-1:-1:-1;;;;;36488:178:0;;:::i;33529:1137::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33529:1137:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;33529:1137:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;33529:1137:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;33529:1137:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;33529:1137:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;33529:1137:0;;-1:-1:-1;33529:1137:0;;-1:-1:-1;;;;;33529:1137:0:i;26135:46::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26135:46:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;26135:46:0;-1:-1:-1;;;;;26135:46:0;;:::i;:::-;;;;-1:-1:-1;;;;;26135:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;26135:46:0;;;;;;;;;;;;-1:-1:-1;;;;;26135:46:0;;;;;;;;;;;;;;;;;;;;;;;35114:452;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;35114:452:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;35114:452:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;35114:452:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;35114:452:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;35114:452:0;;-1:-1:-1;35114:452:0;;-1:-1:-1;;;;;35114:452:0:i;26033:38::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26033:38:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;26033:38:0;-1:-1:-1;;;;;26033:38:0;;:::i;:::-;;;;;;;;;;;;;;;;;;19924:81;;8:9:-1;5:2;;;30:1;27;20:12;5:2;19924:81:0;;;:::i;32110:706::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;32110:706:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;32110:706:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;32110:706:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;32110:706:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;32110:706:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;32110:706:0;;;;;;;;;;;;;;;-1:-1:-1;32110:706:0;;;;;;;-1:-1:-1;32110:706:0;;;;;;;-1:-1:-1;32110:706:0;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;32110:706:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;32110:706:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;32110:706:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;32110:706:0;;-1:-1:-1;32110:706:0;;-1:-1:-1;;;;;32110:706:0:i;33172:349::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33172:349:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;33172:349:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;33172:349:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;33172:349:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;33172:349:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;33172:349:0;;-1:-1:-1;33172:349:0;;-1:-1:-1;;;;;33172:349:0:i;19657:80::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;19657:80:0;;;:::i;16019:222::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;16019:222:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;16019:222:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;16019:222:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;16019:222:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;16019:222:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;16019:222:0;;-1:-1:-1;16019:222:0;;-1:-1:-1;;;;;16019:222:0:i;20102:82::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20102:82:0;;;:::i;29081:265::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;29081:265:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;29081:265:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;36674:118::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36674:118:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;36674:118:0;;;;;;;;;;:::i;19744:84::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;19744:84:0;;;:::i;16534:78::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;16534:78:0;;;:::i;52:28::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52:28:0;;;:::i;26216:25::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26216:25:0;;;:::i;30204:1870::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;30204:1870:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;30204:1870:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;30204:1870:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;30204:1870:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;30204:1870:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;30204:1870:0;;;;;;;;;;;;;;;-1:-1:-1;30204:1870:0;;;;;;;-1:-1:-1;30204:1870:0;;;;;;;-1:-1:-1;30204:1870:0;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;30204:1870:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;30204:1870:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;30204:1870:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;30204:1870:0;;-1:-1:-1;30204:1870:0;;-1:-1:-1;;;;;30204:1870:0:i;32884:252::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;32884:252:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;32884:252:0;-1:-1:-1;;;;;32884:252:0;;:::i;311:111::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;311:111:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;311:111:0;-1:-1:-1;;;;;311:111:0;;:::i;19837:80::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;19837:80:0;;;:::i;34674:404::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;34674:404:0;-1:-1:-1;;;;;34674:404:0;;:::i;26078:48::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26078:48:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;26078:48:0;-1:-1:-1;;;;;26078:48:0;;:::i;29391:277::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;29391:277:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;29391:277:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;20014:81::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20014:81:0;;;:::i;29762:360::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;29762:360:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;29762:360:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;37388:102::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37388:102:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;37388:102:0;-1:-1:-1;;;;;37388:102:0;;:::i;37156:224::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37156:224:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;37156:224:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;37156:224:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;37156:224:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;37156:224:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;37156:224:0;;-1:-1:-1;;;;37156:224:0;;;;-1:-1:-1;37156:224:0;:::i;36800:200::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36800:200:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;36800:200:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;36800:200:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;36800:200:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;36800:200:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;36800:200:0;;-1:-1:-1;;;;36800:200:0;;;;-1:-1:-1;36800:200:0;:::i;430:146::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;430:146:0;;;:::i;26386:28::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26386:28:0;;;:::i;15772:239::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;15772:239:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;15772:239:0;;;;;;;;:::i;27856:831::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;27856:831:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;27856:831:0;-1:-1:-1;;;;;27856:831:0;;:::i;:::-;;;;-1:-1:-1;;;;;27856:831:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16659:132;;8:9:-1;5:2;;;30:1;27;20:12;5:2;16659:132:0;;;:::i;37008:140::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37008:140:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;37008:140:0;;;;;;;;;;:::i;20193:81::-;20232:42;20193:81;:::o;37498:208::-;256:5;;-1:-1:-1;;;;;256:5:0;242:10;:19;234:49;;;;;-1:-1:-1;;;234:49:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;234:49:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;37577:30:0;;37569:67;;;;;-1:-1:-1;;;37569:67:0;;;;;;;;;;;;-1:-1:-1;;;37569:67:0;;;;;;;;;;;;;;;37647:15;:51;;-1:-1:-1;;;;;;37647:51:0;-1:-1:-1;;;;;37647:51:0;;;;;;;;;;37498:208::o;28695:283::-;28836:66;;;-1:-1:-1;;;28836:66:0;;20142:42;28836:66;;;;;;28741:7;;;;28905:4;;19786:42;;28836:51;;:66;;;;;;;;;;;;;;;19786:42;28836:66;;;5:2:-1;;;;30:1;27;20:12;5:2;28836:66:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28836:66:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28836:66:0;:73;;;;;;28823:86;;28954:16;18064:8;28964:5;28954:4;:16::i;:::-;28947:23;;;28695:283;:::o;35602:841::-;27319:16;27338:9;27319:28;;35800:24;;:::i;:::-;-1:-1:-1;;;;;;35827:21:0;;;;;;;:10;:21;;;;;;;;;35800:48;;;;;;;;;-1:-1:-1;;;;;35800:48:0;;;;;-1:-1:-1;;;35800:48:0;;;;;;;;;;;-1:-1:-1;;;35800:48:0;;;;;;;;;;;;;-1:-1:-1;;;35800:48:0;;;;;;;;-1:-1:-1;;;35800:48:0;;;;;;;;;;;;-1:-1:-1;;;;;35800:48:0;;;;;;-1:-1:-1;;;35800:48:0;;;;;;;;;;;-1:-1:-1;;;35800:48:0;;;;;;;;;;;-1:-1:-1;;;35800:48:0;;;;;;;;;35940:10;:28;;:64;;-1:-1:-1;35999:5:0;;-1:-1:-1;;;;;35999:5:0;35985:10;:19;35940:64;:99;;;-1:-1:-1;36028:10:0;36021:18;;;;:6;:18;;;;;;;;35940:99;35918:143;;;;;-1:-1:-1;;;35918:143:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;35918:143:0;;;;;;;;;;;;;;;36091:52;;;-1:-1:-1;;;36091:52:0;;-1:-1:-1;;;;;36091:52:0;;;;;;;;36074:14;;19963:42;;36091:41;;:52;;;;;;;;;;;;;;;36074:14;19963:42;36091:52;;;5:2:-1;;;;30:1;27;20:12;5:2;36091:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;36091:52:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;36091:52:0;36176:16;;36194:18;;;;36091:52;;-1:-1:-1;36154:15:0;;36216:3;;36172:41;;-1:-1:-1;;;;;36172:41:0;;;;;;:3;:41::i;:::-;:47;;;;;;36154:65;;36252:10;36240:9;:22;36232:80;;;;-1:-1:-1;;;36232:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36325:110;36362:9;36373:13;36388;36403:5;36410:7;36419:5;36325:22;:110::i;:::-;;;27358:1;;;27370:42;27384:27;27388:11;27401:9;27384:3;:27::i;:::-;27370:13;:42::i;:::-;;35602:841;;;;;:::o;26445:28::-;;;;:::o;26285:38::-;;;-1:-1:-1;;;;;26285:38:0;;:::o;26248:28::-;;;-1:-1:-1;;;;;26248:28:0;;:::o;36488:178::-;256:5;;-1:-1:-1;;;;;256:5:0;242:10;:19;234:49;;;;;-1:-1:-1;;;234:49:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;234:49:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;36564:23:0;;36556:60;;;;;-1:-1:-1;;;36556:60:0;;;;;;;;;;;;-1:-1:-1;;;36556:60:0;;;;;;;;;;;;;;;36627:8;:31;;-1:-1:-1;;;;;;36627:31:0;-1:-1:-1;;;;;36627:31:0;;;;;;;;;;36488:178::o;33529:1137::-;33638:15;;-1:-1:-1;;;;;33638:15:0;33672:38;33664:77;;;;;-1:-1:-1;;;33664:77:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;33758:6;33754:905;33774:10;:17;33770:1;:21;33754:905;;;33813:24;;:::i;:::-;33840:10;:25;33851:10;33862:1;33851:13;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33840:25:0;;;;;;;;;;;;;;;;-1:-1:-1;33840:25:0;33813:52;;;;;;;;;-1:-1:-1;;;;;33813:52:0;;;;;-1:-1:-1;;;33813:52:0;;;;;;;;;;;-1:-1:-1;;;33813:52:0;;;;;;;;;;;;;-1:-1:-1;;;33813:52:0;;;;;;;;-1:-1:-1;;;33813:52:0;;;;;;;;;;;;-1:-1:-1;;;;;33813:52:0;;;;;;-1:-1:-1;;;33813:52:0;;;;;;;;;;;-1:-1:-1;;;33813:52:0;;;;;;;;;;;-1:-1:-1;;;33813:52:0;;;;;;;;;;;-1:-1:-1;33906:10:0;33888:28;33880:67;;;;;-1:-1:-1;;;33880:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;33970:21;;;;-1:-1:-1;;;;;33970:26:0;;33962:72;;;;-1:-1:-1;;;33962:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34051:16;-1:-1:-1;;;;;34051:30:0;;34100:8;:14;;;34133:10;34144:1;34133:13;;;;;;;;;;;;;;;;;;;34165:16;;34200:22;;;;34241;;;;;34282:12;;;;34313:18;;;;34051:295;;-1:-1:-1;;;;;;34051:295:0;;;;;;;-1:-1:-1;;;;;34051:295:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;34051:295:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34165:16;;34051:295;;;;;;;34165:16;34051:295;;;;5:2:-1;;;;30:1;27;20:12;5:2;34051:295:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;34051:295:0;;;;34437:10;34448:1;34437:13;;;;;;;;;;;;;;-1:-1:-1;;;;;34427:42:0;;34478:16;34427:69;;;;;;;;;;;;;-1:-1:-1;;;;;34427:69:0;-1:-1:-1;;;;;34427:69:0;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;34427:69:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;34427:69:0;;;;34565:29;34580:10;34591:1;34580:13;;;;;;;;;;;;;;34565:14;:29::i;:::-;34633:10;34644:1;34633:13;;;;;;;;;;;;;;-1:-1:-1;;;;;34616:31:0;;;;;;;;;;;-1:-1:-1;33793:3:0;;33754:905;;;;33529:1137;;:::o;26135:46::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;26135:46:0;;;;-1:-1:-1;;;26135:46:0;;;;;;-1:-1:-1;;;26135:46:0;;;;;-1:-1:-1;;;26135:46:0;;;;;-1:-1:-1;;;26135:46:0;;;;-1:-1:-1;;;;;26135:46:0;;;-1:-1:-1;;;26135:46:0;;;;-1:-1:-1;;;;;;;;26135:46:0;;;;;-1:-1:-1;;;26135:46:0;;;;;:::o;35114:452::-;27319:16;27338:9;-1:-1:-1;;;;;35353:21:0;;;;;;;:10;:21;;;;;:27;;;27319:28;;-1:-1:-1;;;;35353:27:0;;;;35384:10;35353:41;35345:80;;;;;-1:-1:-1;;;35345:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;35438:120;35475:9;35486:13;35501;35516:16;35534:7;35543:4;35438:22;:120::i;:::-;;;27370:42;27384:27;27388:11;27401:9;27384:3;:27::i;27370:42::-;;35114:452;;;;;;:::o;26033:38::-;;;;;;;;;;;;;;;:::o;19924:81::-;19963:42;19924:81;:::o;32110:706::-;32505:226;32543:10;32568:18;32601:15;32631:9;32655:16;32686:12;32713:7;32505:23;:226::i;:::-;32781:27;32797:10;33172:349;27319:16;27338:9;27319:28;-1:-1:-1;33261:6:0;33256:258;33277:10;:17;33273:1;:21;33256:258;;;33365:1;33324:10;:25;33335:10;33346:1;33335:13;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33324:25:0;;;;;;;;;;;-1:-1:-1;33324:25:0;:38;-1:-1:-1;;;33324:38:0;;-1:-1:-1;;;;;33324:38:0;:42;33316:96;;;;-1:-1:-1;;;33316:96:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33467:35;33488:10;33499:1;33488:13;;;;;;;;;;;;;;33467:20;:35::i;:::-;33296:3;;33256:258;;;;27370:42;27384:27;27388:11;27401:9;27384:3;:27::i;19657:80::-;19695:42;19657:80;:::o;16019:222::-;256:5;;-1:-1:-1;;;;;256:5:0;242:10;:19;234:49;;;;;-1:-1:-1;;;234:49:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;234:49:0;;;;;;;;;;;;;;;16097:9;16093:141;16116:6;:13;16112:1;:17;16093:141;;;16150:72;16159:6;16166:1;16159:9;;;;;;;;;;;;;;16170:51;16215:4;16177:6;16184:1;16177:9;;;;;;;;;;;;;;-1:-1:-1;;;;;16170:36:0;;;:51;;;;:::i;:::-;16150:8;:72::i;:::-;16130:3;;16093:141;;;;16019:222;:::o;20102:82::-;20142:42;20102:82;:::o;29081:265::-;27080:10;27063:28;;;;:16;:28;;;;;;;;27055:68;;;;;-1:-1:-1;;;27055:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;29252:86;29267:6;29275:9;29286:8;29296:16;:14;:16::i;:::-;29314:14;29330:4;29336:1;29252:14;:86::i;:::-;29081:265;;;;;:::o;36674:118::-;256:5;;-1:-1:-1;;;;;256:5:0;242:10;:19;234:49;;;;;-1:-1:-1;;;234:49:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;234:49:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;36760:14:0;;;;;;;;:6;:14;;;;;:24;;-1:-1:-1;;36760:24:0;;;;;;;;;;36674:118::o;19744:84::-;19786:42;19744:84;:::o;16534:78::-;16570:42;16534:78;:::o;52:28::-;;;-1:-1:-1;;;;;52:28:0;;:::o;26216:25::-;;;-1:-1:-1;;;;;26216:25:0;;:::o;30204:1870::-;27319:16;27338:9;27203:10;27196:18;;;;:6;:18;;;;;;27319:28;;-1:-1:-1;27196:18:0;;;:41;;-1:-1:-1;27232:5:0;;-1:-1:-1;;;;;27232:5:0;27218:10;:19;27196:41;27188:71;;;;;-1:-1:-1;;;27188:71:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;27188:71:0;;;;;;;;;;;;;;;30600:17;30620:62;30625:40;30629:18;30649:15;30625:3;:40::i;:::-;30667:9;30678:3;30620:4;:62::i;:::-;30685:4;30620:69;30600:89;;30898:23;;:::i;:::-;30988:12;30984:314;;;31017:8;;:27;;;-1:-1:-1;;;31017:27:0;;;;;;;;;;-1:-1:-1;;;;;31017:8:0;;;;:13;;:27;;;;;:8;;:27;;;;;;;;:8;;:27;;;5:2:-1;;;;30:1;27;20:12;5:2;31017:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;31017:27:0;;;;31103:183;19875:42;31152:12;20053:42;31205:40;31209:18;31229:15;31205:3;:40::i;:::-;31264:7;31103:9;:183::i;:::-;31092:194;;30984:314;31310:18;;31451:167;31472:10;:17;31468:1;:21;31451:167;;;31528:78;31546:10;31557:1;31546:13;;;;;;;;;;;;;;31561:15;31578:9;31589:16;31528:17;:78::i;:::-;31511:95;;;;31491:3;;31451:167;;;;31655:12;31638:13;:29;;31630:69;;;;;-1:-1:-1;;;31630:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;31761:11;;;;:15;;;:34;;-1:-1:-1;31780:11:0;;;;:15;;31761:34;31757:310;;;32030:11;;;;32043;;;;31987:68;;32018:10;;31987:30;:68::i;:::-;27270:1;;;27370:42;27384:27;27388:11;27401:9;27384:3;:27::i;27370:42::-;;30204:1870;;;;;;;;:::o;32884:252::-;27319:16;27338:9;-1:-1:-1;;;;;32964:21:0;;33001:1;32964:21;;;:10;:21;;;;;:34;27319:28;;-1:-1:-1;;;;32964:34:0;;-1:-1:-1;;;;;32964:34:0;32956:92;;;;-1:-1:-1;;;32956:92:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33097:31;33118:9;33097:20;:31::i;:::-;27370:42;27384:27;27388:11;27401:9;27384:3;:27::i;311:111::-;256:5;;-1:-1:-1;;;;;256:5:0;242:10;:19;234:49;;;;;-1:-1:-1;;;234:49:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;234:49:0;;;;;;;;;;;;;;;386:17;:28;;-1:-1:-1;;;;;;386:28:0;-1:-1:-1;;;;;386:28:0;;;;;;;;;;311:111::o;19837:80::-;19875:42;19837:80;:::o;34674:404::-;-1:-1:-1;;;;;34747:21:0;;34779:1;34747:21;;;:10;:21;;;;;:29;-1:-1:-1;;;;;34747:29:0;34739:68;;;;;-1:-1:-1;;;34739:68:0;;;;;;;;;;;;-1:-1:-1;;;34739:68:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;34858:21:0;;34820:13;34858:21;;;:10;:21;;;;;;;;:49;;-1:-1:-1;;34858:49:0;;34836:9;-1:-1:-1;;;;;34858:49:0;;;;;;;;;;;;34962:108;;-1:-1:-1;;;34962:108:0;;19875:42;34962:108;;;;;;;19963:42;34962:108;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34836:9;;34858:21;34962:28;;34836:9;;34962:108;;;;;34820:13;34962:108;;;;;34836:9;34858:21;34962:108;;;5:2:-1;;;;30:1;27;20:12;5:2;34962:108:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;26078:48:0;;;;;;;;;;;;;;;:::o;29391:277::-;27080:10;27063:28;;;;:16;:28;;;;;;;;27055:68;;;;;-1:-1:-1;;;27055:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;29581:79;29596:6;29604:9;29615:8;29625:9;29636:14;29652:4;29658:1;29581:14;:79::i;20014:81::-;20053:42;20014:81;:::o;29762:360::-;27080:10;27063:28;;;;:16;:28;;;;;;;;27055:68;;;;;-1:-1:-1;;;27055:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;30026:88;30041:6;30049:9;30060:8;30070:9;30081:14;30097:4;30103:10;30026:14;:88::i;37388:102::-;256:5;;-1:-1:-1;;;;;256:5:0;242:10;:19;234:49;;;;;-1:-1:-1;;;234:49:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;234:49:0;;;;;;;;;;;;;;;37453:3;:29;;-1:-1:-1;;;;;;37453:29:0;-1:-1:-1;;;;;37453:29:0;;;;;;;;;;37388:102::o;37156:224::-;256:5;;-1:-1:-1;;;;;256:5:0;242:10;:19;234:49;;;;;-1:-1:-1;;;234:49:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;234:49:0;;;;;;;;;;;;;;;37267:6;37262:111;37283:9;:16;37279:1;:20;37262:111;;;37354:7;37321:16;:30;37338:9;37348:1;37338:12;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;37321:30:0;;;;;;;;;;;-1:-1:-1;37321:30:0;:40;;-1:-1:-1;;37321:40:0;;;;;;;;;;-1:-1:-1;37301:3:0;37262:111;;36800:200;256:5;;-1:-1:-1;;;;;256:5:0;242:10;:19;234:49;;;;;-1:-1:-1;;;234:49:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;234:49:0;;;;;;;;;;;;;;;36901:6;36896:97;36917:7;:14;36913:1;:18;36896:97;;;36974:7;36953:6;:18;36960:7;36968:1;36960:10;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;36953:18:0;;;;;;;;;;;-1:-1:-1;36953:18:0;:28;;-1:-1:-1;;36953:28:0;;;;;;;;;;-1:-1:-1;36933:3:0;36896:97;;430:146;493:17;;-1:-1:-1;;;;;493:17:0;479:10;:31;471:61;;;;;-1:-1:-1;;;471:61:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;471:61:0;;;;;;;;;;;;;;;551:17;;;543:25;;-1:-1:-1;;;;;;543:25:0;-1:-1:-1;;;;;551:17:0;;;543:25;;;;;;430:146::o;26386:28::-;;;;:::o;15772:239::-;256:5;;-1:-1:-1;;;;;256:5:0;242:10;:19;234:49;;;;;-1:-1:-1;;;234:49:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;234:49:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;15853:21:0;;15849:155;;15891:5;;;:22;;-1:-1:-1;;;;;15891:5:0;;;;:22;;;;;15906:6;;15891:22;:5;:22;15906:6;15891:5;:22;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;15891:22:0;15849:155;;;15978:5;;15946:46;;-1:-1:-1;;;;;15946:31:0;;;;15978:5;15985:6;15946:46;:31;:46;:::i;27856:831::-;-1:-1:-1;;;;;28194:21:0;;;27926;28194;;;:10;:21;;;;;:27;;;;28242:29;;-1:-1:-1;;;28194:27:0;;;;;;-1:-1:-1;;;;;28242:29:0;;;;28294:31;-1:-1:-1;;;28294:31:0;;;;-1:-1:-1;;;28352:35:0;;;;;28414;-1:-1:-1;;;28414:35:0;;;;;-1:-1:-1;;;28466:25:0;;;;;-1:-1:-1;;;28517:34:0;;;;-1:-1:-1;;;;;28578:35:0;;;-1:-1:-1;;;28642:37:0;;;;;;;27856:831::o;16659:132::-;16742:41;;;-1:-1:-1;;;16742:41:0;;16777:4;16742:41;;;;;;16706:14;;16570:42;;16742:26;;:41;;;;;;;;;;;;;;;16570:42;16742:41;;;5:2:-1;;;;30:1;27;20:12;5:2;16742:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;16742:41:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;16742:41:0;;16659:132;-1:-1:-1;16659:132:0:o;37008:140::-;256:5;;-1:-1:-1;;;;;256:5:0;242:10;:19;234:49;;;;;-1:-1:-1;;;234:49:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;234:49:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;37104:26:0;;;;;;;;:16;:26;;;;;:36;;-1:-1:-1;;37104:36:0;;;;;;;;;;37008:140::o;18488:111::-;18541:6;18590:1;18564:23;18568:11;18572:1;18064:8;18568:3;:11::i;:::-;18585:1;18581;:5;;18564:3;:23::i;:::-;:27;;;;;;;18488:111;-1:-1:-1;;;18488:111:0:o;17496:118::-;17548:6;17575;;;:30;;-1:-1:-1;;17590:5:0;;;17604:1;17599;17590:5;17599:1;17585:15;;;;;:20;17575:30;17567:39;;;;;;17496:118;;;;:::o;45978:3356::-;46213:14;46229:22;46264:24;;:::i;:::-;-1:-1:-1;;;;;;46291:21:0;;;;;;;:10;:21;;;;;;;;;46264:48;;;;;;;;;-1:-1:-1;;;;;46264:48:0;;;;;;-1:-1:-1;;;46264:48:0;;;;;;;;;;;-1:-1:-1;;;46264:48:0;;;;;;;;;;;;;-1:-1:-1;;;46264:48:0;;;;;;;;-1:-1:-1;;;46264:48:0;;;;;;;;;;;;;-1:-1:-1;;;;;46264:48:0;;;;;;-1:-1:-1;;;46264:48:0;;;;;;;;;;;-1:-1:-1;;;46264:48:0;;;;;;;;;-1:-1:-1;;;46264:48:0;;;;;;;;;46331:20;;;;:50;;-1:-1:-1;46355:21:0;;;;-1:-1:-1;;;;;46355:26:0;;46331:50;46323:104;;;;-1:-1:-1;;;46323:104:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46519:52;;;-1:-1:-1;;;46519:52:0;;-1:-1:-1;;;;;46519:52:0;;;;;;;;46494:18;;46515:72;;19963:42;;46519:41;;:52;;;;;;;;;;;;;;46494:18;19963:42;46519:52;;;5:2:-1;;;;30:1;27;20:12;5:2;46519:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;46519:52:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;46519:52:0;46573:13;46515:3;:72::i;:::-;46494:93;;46631:8;46627:158;;;46701:72;46716:8;46726:13;46741;46756:16;46701:14;:72::i;:::-;46656:117;;-1:-1:-1;46656:117:0;-1:-1:-1;46656:117:0;-1:-1:-1;46627:158:0;46819:13;46881:17;;46877:309;;46956:34;46960:14;46976:13;46956:3;:34::i;:::-;46939:51;;47011:16;47007:168;;;47122:37;47126:14;47142:8;:16;;;-1:-1:-1;;;;;47122:37:0;:3;:37::i;:::-;47105:54;;47007:168;47261:9;47289;:26;-1:-1:-1;47285:130:0;;;47339:30;47343:14;47359:9;47339:3;:30::i;:::-;47384:8;;:19;;;-1:-1:-1;;;47384:19:0;;;;;;;;;;47332:37;;-1:-1:-1;;;;;;47384:8:0;;;;:13;;:19;;;;;:8;;:19;;;;;;;;:8;;:19;;;5:2:-1;;;;30:1;27;20:12;5:2;47384:19:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;47384:19:0;;;;47285:130;47586:23;;:::i;:::-;47612:75;47637:9;47648:14;47664:13;47679:7;47612:24;:75::i;:::-;47586:101;-1:-1:-1;47738:17:0;47770:170;;;;47800:8;47847:3;47811:33;47815:14;47831:8;:12;;;47811:33;;:3;:33::i;:::-;:39;;;;;;47800:50;;47880:48;47884:3;47889:38;47907:8;:14;;;47923:3;47889:17;:38::i;:::-;47880:3;:48::i;:::-;47865:63;;47770:170;;48036:1;48010:23;48014:4;48020:12;48010:3;:23::i;:::-;:27;48006:116;;;48075:8;;48054:56;;-1:-1:-1;;;;;48075:8:0;48086:23;48090:4;48096:12;48086:3;:23::i;:::-;48054:12;:56::i;:::-;48138:17;;48134:281;;48176:16;48172:232;;;48286:16;;-1:-1:-1;;;;;48270:32:0;;-1:-1:-1;48172:232:0;;;48387:1;48371:17;;48172:232;48616:14;;;;48662:11;;;;48706;;;;48586:143;;48616:14;48646:27;;;48690;;48586:15;:143::i;:::-;48838:27;48850:8;:14;;;48838:11;:27::i;:::-;48922:25;48937:9;48922:14;:25::i;:::-;49007:9;:13;49003:85;;49037:39;;49045:10;;49066:9;49037:39;;;;;;;;;49066:9;49045:10;49037:39;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;49037:39:0;49003:85;-1:-1:-1;;;;;49239:87:0;;;49282:8;49291:1;49282:11;;;;49266:27;;49313:8;49322:1;49313:11;;;;49297:13;:27;49239:87;;;;;;;;;;;;;;;;;;;;;;;;45978:3356;;;;;;;;;;;;;;;:::o;17386:104::-;17470:5;;;17465:16;;;;17457:25;;;;;16834:412;16892:4;16909:14;16926:17;:15;:17::i;:::-;16909:34;-1:-1:-1;16958:14:0;16954:59;;16996:5;16989:12;;;;;16954:59;17066:5;17057;17046:16;;17045:26;17086:24;;;17082:81;;;-1:-1:-1;17142:9:0;17082:81;16570:42;-1:-1:-1;;;;;17175:25:0;;17201:12;17175:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;17175:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;17175:39:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;17234:4:0;;-1:-1:-1;;;;16834:412:0;;;;:::o;52933:143::-;53020:48;;;;;;;;-1:-1:-1;53020:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52996:21:0;;;;;:10;:21;;;;;;;:72;;;;;;;;;;;;-1:-1:-1;;52996:72:0;;;-1:-1:-1;;;;;52996:72:0;;;;-1:-1:-1;;;;52996:72:0;-1:-1:-1;;;52996:72:0;;;;;;;;;;;-1:-1:-1;;;;52996:72:0;-1:-1:-1;;;53020:48:0;52996:72;;;;;-1:-1:-1;;;;52996:72:0;-1:-1:-1;;;52996:72:0;;;;;;;;;-1:-1:-1;;;;;52996:72:0;-1:-1:-1;;;52996:72:0;;;;;;;;;;;;;;;-1:-1:-1;52996:72:0;;;;;;;;;;;-1:-1:-1;;52996:72:0;;;-1:-1:-1;;;;;52996:72:0;;;;;;;-1:-1:-1;;;;52996:72:0;-1:-1:-1;;;52996:72:0;;;;;;;;;;;;;-1:-1:-1;;;52996:72:0;;;;;;;;;;;;-1:-1:-1;;;;52996:72:0;-1:-1:-1;;;53020:48:0;52996:72;;;;;;;;;;52933:143::o;43914:2056::-;43983:24;;:::i;:::-;-1:-1:-1;;;;;;44010:21:0;;;;;;;:10;:21;;;;;;;;43983:48;;;;;;;;;-1:-1:-1;;;;;43983:48:0;;;;;-1:-1:-1;;;43983:48:0;;;;;;;;;-1:-1:-1;;;43983:48:0;;;;;;;;-1:-1:-1;;;43983:48:0;;;;;;;;-1:-1:-1;;;43983:48:0;;;;;;;;;;;;;-1:-1:-1;;;;;43983:48:0;;;;;;-1:-1:-1;;;43983:48:0;;;;;;;;;;;-1:-1:-1;;;43983:48:0;;;;;;;;;;-1:-1:-1;;;43983:48:0;;;;;;;;44061:52;;-1:-1:-1;;;44061:52:0;;;;;;;;;;;44010:21;;19963:42;;44061:41;;:52;;;;;44010:21;44061:52;;;;;;44010:21;19963:42;44061:52;;;5:2:-1;;;;30:1;27;20:12;5:2;44061:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;44061:52:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;44061:52:0;44309:49;;;-1:-1:-1;;;44309:49:0;;-1:-1:-1;;;;;44309:49:0;;;;;;-1:-1:-1;;44309:49:0;;;;;;44061:52;;-1:-1:-1;20053:42:0;;44309:28;;:49;;;;;-1:-1:-1;;44309:49:0;;;;;;;;-1:-1:-1;20053:42:0;44309:49;;;5:2:-1;;;;30:1;27;20:12;5:2;44309:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;44369:85:0;;;-1:-1:-1;;;44369:85:0;;19875:42;44369:85;;;;19963:42;44369:85;;;;20053:42;44369:85;;;;20142:42;44369:85;;;;;;-1:-1:-1;;;;;44369:29:0;;;-1:-1:-1;44369:29:0;;-1:-1:-1;44369:85:0;;;;;-1:-1:-1;;44369:85:0;;;;;;;-1:-1:-1;44369:29:0;:85;;;5:2:-1;;;;30:1;27;20:12;5:2;44369:85:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;44369:85:0;;;;44522:17;44620:3;44605:8;:12;;;44542:75;;:60;44546:32;44550:9;44561:8;:16;;;-1:-1:-1;;;;;44546:32:0;:3;:32::i;:::-;44580:8;:21;;;-1:-1:-1;;;;;44542:60:0;:3;:60::i;:::-;:75;:81;;;;;;44522:101;;44634:18;44655:47;44673:8;:14;;;44689:12;44655:17;:47::i;:::-;44736:22;;;;44634:68;;-1:-1:-1;;;;;;44715:43:0;:18;44808:17;;44804:512;;44919:14;;;;44880:69;;20053:42;;44935:13;44880:69;:38;:69;:::i;:::-;45024:8;:24;;;45020:97;;;-1:-1:-1;45085:16:0;;-1:-1:-1;;;;;45069:32:0;45020:97;44804:512;;;45166:14;45183:58;45197:9;45208;45219:8;:21;;;-1:-1:-1;;;;;45183:58:0;:13;:58::i;:::-;45166:75;;45272:32;45276:8;:16;;;-1:-1:-1;;;;;45272:32:0;45294:9;45272:3;:32::i;:::-;45256:48;;44804:512;;45365:17;;45361:118;;45437:14;;;;45399:68;;19875:42;;45453:13;45399:68;:37;:68;:::i;:::-;45544:18;45565:49;45569:29;45573:9;45584:13;45569:3;:29::i;:::-;45600:13;45565:3;:49::i;:::-;45646:8;;45544:70;;-1:-1:-1;45625:46:0;;-1:-1:-1;;;;;45646:8:0;45544:70;45625:12;:46::i;:::-;45780:27;45792:8;:14;;;45780:11;:27::i;:::-;45864:25;45879:9;45864:14;:25::i;:::-;45907:55;;;;;;;;;;;;;;-1:-1:-1;;;;;45907:55:0;;;;;;;;;;;43914:2056;;;;;;;;:::o;15428:261::-;15506:7;-1:-1:-1;;;;;15530:21:0;;;;:45;;-1:-1:-1;;;;;;15555:20:0;;13816:42;15555:20;15530:45;15526:156;;;-1:-1:-1;;;;;;15599:11:0;;;15592:18;;15526:156;15650:5;-1:-1:-1;;;;;15650:15:0;;15666:3;15650:20;;;;;;;;;;;;;-1:-1:-1;;;;;15650:20:0;-1:-1:-1;;;;;15650:20:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;15650:20:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;15650:20:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;15650:20:0;;-1:-1:-1;15643:27:0;;41220:893;-1:-1:-1;;;;;41468:21:0;;;;;;:10;:21;;;;;:29;-1:-1:-1;;;;;41468:29:0;:34;41460:67;;;;;-1:-1:-1;;;41460:67:0;;;;;;;;;;;;-1:-1:-1;;;41460:67:0;;;;;;;;;;;;;;;41557:10;41582:14;41578:163;;41630:52;;;-1:-1:-1;;;41630:52:0;;-1:-1:-1;;;;;41630:52:0;;;;;;;;41613:14;;19963:42;;41630:41;;:52;;;;;;;;;;;;;;;41613:14;19963:42;41630:52;;;5:2:-1;;;;30:1;27;20:12;5:2;41630:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;41630:52:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;41630:52:0;;-1:-1:-1;41721:8:0;41630:52;41721:8;41709:20;;;;;41697:32;;41578:163;;41777:235;;;;;;;;41807:8;-1:-1:-1;;;;;41777:235:0;;;;;41838:9;-1:-1:-1;;;;;41777:235:0;;;;;41863:14;41777:235;;;;;;41892:4;41777:235;;;;;;41911:1;-1:-1:-1;;;;;41777:235:0;;;;;41927:1;-1:-1:-1;;;;;41777:235:0;;;;;41943:5;41777:235;;;;;;41963:6;-1:-1:-1;;;;;41777:235:0;;;;;41991:9;41777:235;;;;;41753:10;:21;41764:9;-1:-1:-1;;;;;41753:21:0;-1:-1:-1;;;;;41753:21:0;;;;;;;;;;;;:259;;;;;;;;;;;;;-1:-1:-1;;;;;41753:259:0;;;;;-1:-1:-1;;;;;41753:259:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;41753:259:0;;;;;-1:-1:-1;;;;;41753:259:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;41753:259:0;;;;;-1:-1:-1;;;;;41753:259:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;41753:259:0;;;;;-1:-1:-1;;;;;41753:259:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;41753:259:0;;;;;-1:-1:-1;;;;;41753:259:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42052:9;-1:-1:-1;;;;;42030:75:0;42044:6;-1:-1:-1;;;;;42030:75:0;;42063:8;42073:9;42084:14;42100:4;42030:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41220:893;;;;;;;;:::o;17276:104::-;17360:5;;;17355:16;;;;17347:25;;;;;18116:126;18180:6;18230:4;18203:24;18207:9;18211:1;18214;18207:3;:9::i;18203:24::-;:31;;;;;;;18116:126;-1:-1:-1;;;;18116:126:0:o;51051:1874::-;51245:18;;:::i;:::-;51520:42;51481:19;-1:-1:-1;;;;;51649:34:0;;19875:42;51649:34;51645:274;;-1:-1:-1;;51704:10:0;-1:-1:-1;;;;;51704:20:0;;51733:4;51740:2;-1:-1:-1;;;;;51740:10:0;;:12;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51740:12:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51740:12:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51740:12:0;51704:49;;;-1:-1:-1;;;;;;51704:49:0;;;;;;;-1:-1:-1;;;;;51704:49:0;;;;;;;;;;;;;;;;;;;;;51740:12;;51704:49;;;;;;;;;;;5:2:-1;;;;30:1;27;20:12;5:2;51704:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51704:49:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51704:49:0;:61;51700:144;;51786:10;-1:-1:-1;;;;;51786:18:0;;51805:2;-1:-1:-1;;;;;51805:10:0;;:12;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51805:12:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51805:12:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51805:12:0;51786:42;;;-1:-1:-1;;;;;;51786:42:0;;;;;;;-1:-1:-1;;;;;51786:42:0;;;;;;;-1:-1:-1;;51786:42:0;;;;;;;;;;-1:-1:-1;;51786:42:0;;;;;;;-1:-1:-1;51786:42:0;;;;5:2:-1;;;;30:1;27;20:12;5:2;51786:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51786:42:0;;;;51700:144;51645:274;;;-1:-1:-1;51888:19:0;51645:274;51931:27;51961:44;-1:-1:-1;;;;;51961:29:0;;51999:4;51961:44;:29;:44;:::i;:::-;51931:74;-1:-1:-1;52016:25:0;52044:42;-1:-1:-1;;;;;52044:27:0;;52080:4;52044:42;:27;:42;:::i;:::-;52016:70;;52099:16;52298:2;52295:1;52285:7;52279:14;52272:4;52263:7;52259:18;52248:9;52244:2;52237:4;52232:3;52228:14;52223:78;-1:-1:-1;;52333:1:0;52327:8;52556:69;52560:42;-1:-1:-1;;;;;52560:27:0;;52596:4;52560:42;:27;:42;:::i;:::-;52604:20;52556:3;:69::i;:::-;52547:78;;52675:73;52679:22;52703:44;-1:-1:-1;;;;;52703:29:0;;52741:4;52703:29;:44::i;52675:73::-;52666:6;;;:82;52796:6;;52792:30;;52804:17;52792:3;:30::i;:::-;52783:6;;;:39;:6;52889;;;52864:32;;52868:19;;52864:3;:32::i;:::-;52855:6;;;:41;-1:-1:-1;52855:3:0;;51051:1874;-1:-1:-1;;;;;;;;;51051:1874:0:o;42121:1785::-;-1:-1:-1;;;;;42372:21:0;;42304;42372;;;:10;:21;;;;;42412;;-1:-1:-1;;;42412:21:0;;-1:-1:-1;;;;;42412:21:0;:26;:50;;;;-1:-1:-1;42442:16:0;;-1:-1:-1;;;;;42442:16:0;:20;;42412:50;42404:94;;;;;-1:-1:-1;;;42404:94:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;42528:52;;;-1:-1:-1;;;42528:52:0;;-1:-1:-1;;;;;42528:52:0;;;;;;;;42511:14;;19963:42;;42528:41;;:52;;;;;;;;;;;;;;;42511:14;19963:42;42528:52;;;5:2:-1;;;;30:1;27;20:12;5:2;42528:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;42528:52:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;42528:52:0;42616:53;;;-1:-1:-1;;;42616:53:0;;-1:-1:-1;;;;;42616:53:0;;;;;;;;42528:52;;-1:-1:-1;42591:17:0;;42611:75;;20142:42;;42616;;:53;;;;;42528:52;;42616:53;;;;;;;;20142:42;42616:53;;;5:2:-1;;;;30:1;27;20:12;5:2;42616:53:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;42616:53:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;42616:53:0;42671:9;42682:3;42611:4;:75::i;:::-;42689:4;42611:82;;-1:-1:-1;42706:18:0;;42778:19;;42774:971;;42824:14;42882:64;42900:9;42911;42922:12;42936:9;42882:17;:64::i;:::-;43008:9;;-1:-1:-1;43008:9:0;;42853:93;-1:-1:-1;42853:93:0;-1:-1:-1;43083:319:0;;;;43124:24;;;:43;;-1:-1:-1;;;;43124:43:0;-1:-1:-1;;;43124:43:0;;;;;;;43227:16;;43278:9;;-1:-1:-1;;;;;;43227:16:0;;-1:-1:-1;43278:9:0;43357:29;43361:9;43227:16;43357:3;:29::i;:::-;43341:45;;43083:319;-1:-1:-1;43418:22:0;;;:46;;-1:-1:-1;;43418:46:0;-1:-1:-1;;;;;43418:46:0;;;;;42774:971;;;43530:14;43547:49;43561:9;43572;43583:12;43547:13;:49::i;:::-;43631:16;;43530:66;;-1:-1:-1;43627:32:0;;-1:-1:-1;;;;;43631:16:0;43530:66;43627:3;:32::i;:::-;43611:48;;43721:12;43705:28;;42774:971;;43757:44;;-1:-1:-1;;;;;43757:44:0;-1:-1:-1;;;;;;;;43757:44:0;;;;;;43842:56;;;;;;;;;;;;;;-1:-1:-1;;;;;43842:56:0;;;;;;;;;;;42121:1785;;;;;;;;;;;:::o;53728:1274::-;53926:22;53962:10;:17;53951:29;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;53951:29:0;-1:-1:-1;53926:54:0;-1:-1:-1;53993:17:0;;54128:161;54149:10;:17;54145:1;:21;54128:161;;;54202:10;:25;54213:10;54224:1;54213:13;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;54202:25:0;;;;;;;;;;;-1:-1:-1;54202:25:0;:33;54188:11;;-1:-1:-1;;;;;54202:33:0;;;;54188:8;;54197:1;;54188:11;;;;;;;;;;;:47;;;;;54266:8;54275:1;54266:11;;;;;;;;;;;;;;54250:27;;;;54168:3;;;;;;;54128:161;;;-1:-1:-1;54362:6:0;54357:638;54378:10;:17;54374:1;:21;54357:638;;;54417:18;54438:31;54443:8;54452:1;54443:11;;;;;;;;;;;;;;54456:12;54438:4;:31::i;:::-;54417:52;-1:-1:-1;54490:13:0;;54486:292;;54524:19;54546:30;54551:13;54566:9;54546:4;:30::i;:::-;54524:52;;54640:14;54599:10;:25;54610:10;54621:1;54610:13;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;54599:25:0;;;;;;;;;;;-1:-1:-1;54599:25:0;:38;-1:-1:-1;;;54599:38:0;;-1:-1:-1;;;;;54599:38:0;:55;54595:168;;;54728:14;54679:10;:25;54690:10;54701:1;54690:13;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;54679:25:0;;;;;;;;;;;-1:-1:-1;54679:25:0;:64;;-1:-1:-1;;;;;;;;54679:64:0;;;;;;;;;;;;;-1:-1:-1;;;;;54679:64:0;;;;;;;;;54595:168;54486:292;;54798:13;;54794:190;;54832:19;54854:30;54859:13;54874:9;54854:4;:30::i;:::-;54832:52;;54953:14;54903:10;:25;54914:10;54925:1;54914:13;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;54903:25:0;;;;;;;;;;;-1:-1:-1;54903:25:0;:39;;:65;;-1:-1:-1;;54903:65:0;;-1:-1:-1;;;;;54903:65:0;;;;;;;;;;;;;;-1:-1:-1;54794:190:0;-1:-1:-1;54397:3:0;;54357:638;;13868:140;13957:43;13975:5;13982:2;13986:6;13994:5;13957:17;:43::i;:::-;;13868:140;;;:::o;39405:1772::-;39823:17;;39697:14;;39601:21;;;;-1:-1:-1;;;;;39807:33:0;;;39803:870;;;39874:37;39878:13;39893:9;:17;;;-1:-1:-1;;;;;39874:37:0;:3;:37::i;:::-;39857:54;-1:-1:-1;39932:17:0;;39928:734;;39974:16;39970:479;;;40178:9;:23;;;40173:29;;40205:3;40173:35;40120:48;40125:9;:17;;;-1:-1:-1;;;;;40120:48:0;40144:9;:23;;;-1:-1:-1;;;;;40120:48:0;:4;:48::i;:::-;40089:28;;;:79;;;;;;40088:120;;40076:132;;39970:479;;;40398:9;:23;;;40393:29;;40387:3;:35;40426:3;40386:43;40333:48;40338:9;:17;;;-1:-1:-1;;;;;40333:48:0;40357:9;:23;;;-1:-1:-1;;;;;40333:48:0;:4;:48::i;:::-;40302:28;;;:79;;;;;;40301:128;;40289:140;;39970:479;39928:734;;;40616:9;:23;;;40611:29;;40643:3;40611:35;40589:9;:17;;;-1:-1:-1;;;;;40530:76:0;40574:3;40548:23;40552:3;40557:9;:13;;;40548:23;;:3;:23::i;:::-;40531:14;:40;:46;;;;;;40581:5;40530:56;:76;;;;;;40529:117;;40517:129;;39928:734;40689:9;40685:485;;;40715:16;40734:70;40738:9;:17;;;-1:-1:-1;;;;;40734:70:0;40800:3;40774:23;40778:3;40783:9;:13;;;40774:23;;:3;:23::i;:::-;40757:14;:40;:46;;;;40734:70;40715:89;;40844:11;40827:13;:28;;40819:70;;;;;-1:-1:-1;;;40819:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;40922:11;-1:-1:-1;40685:485:0;;;41034:13;;41028:3;:19;41024:135;;;41084:59;41088:13;41139:3;41103:33;41107:13;41122;;41103:3;:33::i;:::-;:39;;;;;;41084:3;:59::i;:::-;41068:75;;41024:135;39405:1772;;;;;;;;:::o;49342:942::-;49535:23;;:::i;:::-;49839:53;;;-1:-1:-1;;;49839:53:0;;-1:-1:-1;;;;;49839:53:0;;;;;;;;49818:18;;20142:42;;49839;;:53;;;;;;;;;;;;;;;20142:42;49839:53;;;5:2:-1;;;;30:1;27;20:12;5:2;49839:53:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;49839:53:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;49839:53:0;;-1:-1:-1;49916:163:0;19875:42;49961:15;20053:42;50013:33;49839:53;50032:13;50013:3;:33::i;:::-;50061:7;49916:9;:163::i;:::-;50131:49;;;-1:-1:-1;;;50131:49:0;;-1:-1:-1;;;;;50131:49:0;;;;;;-1:-1:-1;;50131:49:0;;;;;;49905:174;;-1:-1:-1;20053:42:0;;50131:28;;:49;;;;;-1:-1:-1;;50131:49:0;;;;;;;;-1:-1:-1;20053:42:0;50131:49;;;5:2:-1;;;;30:1;27;20:12;5:2;50131:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;50191:85:0;;;-1:-1:-1;;;50191:85:0;;19875:42;50191:85;;;;19963:42;50191:85;;;;20053:42;50191:85;;;;20142:42;50191:85;;;;;;-1:-1:-1;;;;;50191:29:0;;;-1:-1:-1;50191:29:0;;-1:-1:-1;50191:85:0;;;;;-1:-1:-1;;50191:85:0;;;;;;;-1:-1:-1;50191:29:0;:85;;;5:2:-1;;;;30:1;27;20:12;5:2;50191:85:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;50191:85:0;;;;49342:942;;;;;;;:::o;53084:636::-;53210:3;;53175:18;;-1:-1:-1;;;;;53210:3:0;:27;53206:507;;53283:3;;:46;;;-1:-1:-1;;;53283:46:0;;-1:-1:-1;;;;;53283:46:0;;;;;;;;;53332:3;;53283;;;;;:30;;:46;;;;;;;;;;;;;;;:3;:46;;;5:2:-1;;;;30:1;27;20:12;5:2;53283:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53283:46:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;53283:46:0;53267:62;;;;:68;;;;;;53254:81;;53371:13;53358:10;:26;53350:82;;;;-1:-1:-1;;;53350:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53506:3;;:64;;;-1:-1:-1;;;53506:64:0;;-1:-1:-1;;;;;53506:64:0;;;;;;;;;:3;;;;;:30;;53543:10;;53506:64;;;;;:3;;:64;;;;;;;;53543:10;53506:3;:64;;;5:2:-1;;;;30:1;27;20:12;5:2;53506:64:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53506:64:0;;;;;53592:44;53605:30;53609:13;53624:10;53605:3;:30::i;:::-;53592:44;;;;;;;;;;;;;;;53206:507;;;53674:27;;;;;;;;;;;;;;;;;53084:636;;;;:::o;50780:263::-;50945:38;;50906:8;;50856:31;;-1:-1:-1;;;;;50945:20:0;;;50972:6;;50856:31;50945:38;50856:31;50945:38;50972:6;50945:20;:38;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;50927:56:0;;;51002:6;50994:41;;;;;-1:-1:-1;;;50994:41:0;;;;;;;;;;;;-1:-1:-1;;;50994:41:0;;;;;;;;;;;;;;50292:480;50472:18;;50468:120;;50507:69;19875:42;50545:14;50561;50507:69;:37;:69;:::i;:::-;50648:18;;50644:121;;50683:70;20053:42;50722:14;50738;50683:70;:38;:70;:::i;55010:334::-;55084:25;;;-1:-1:-1;;;55084:25:0;;;;;;;;;;;;55240:14;;;55084:25;55064:10;;55315:4;55084:25;55064:10;55304:3;55297:4;55292:3;55288:14;55283:43;55191:146;;;;:::o;37754:626::-;-1:-1:-1;;;;;37922:21:0;;37877:17;37922:21;;;:10;:21;;;;;:29;-1:-1:-1;;;;;37922:29:0;;;37984:25;-1:-1:-1;;;37984:25:0;;;;;-1:-1:-1;;;38071:35:0;;;38266:3;38250:13;38266:3;37984:25;38250:3;:13::i;:::-;38203:44;38207:24;38211:10;38223:7;38207:3;:24::i;:::-;38233:13;38203:3;:44::i;:::-;:60;:66;;;;;;38191:78;;18064:8;38324:13;:19;38290:24;38295:9;38306:7;38290:4;:24::i;:::-;38317:3;38290:30;:53;;38282:90;;;;;-1:-1:-1;;;38282:90:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;37754:626;;;;;;;;:::o;38388:1009::-;-1:-1:-1;;;;;38602:21:0;;38534:17;38602:21;;;:10;:21;;;;;:29;38534:17;;-1:-1:-1;;;;;38602:29:0;;;;38664:25;-1:-1:-1;;;38664:25:0;;;;;-1:-1:-1;;;38751:35:0;;;;;;-1:-1:-1;;;38843:35:0;;;38534:17;39013:3;38997:13;39013:3;38664:25;38997:3;:13::i;:::-;38950:44;38954:24;38958:10;38970:7;38954:3;:24::i;:::-;38980:13;38950:3;:44::i;:::-;:60;:66;;;;;;38933:83;;39095:4;39045:47;39050:23;39054:7;39063:9;39050:3;:23::i;:::-;39075:9;39087:4;39075:16;39045:4;:47::i;:::-;:54;;;;;;39029:70;;39112:16;39157:4;39131:23;39136:7;39145:8;39131:4;:23::i;:::-;:30;;;;;;39112:49;;39194:1;39180:11;:15;39172:54;;;;;-1:-1:-1;;;39172:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;39251:31;39255:13;39270:11;39251:3;:31::i;:::-;39239:43;;18064:8;39341:13;:19;39303:28;39308:9;39319:11;39303:4;:28::i;:::-;39334:3;39303:34;:57;;39295:94;;;;;-1:-1:-1;;;39295:94:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;38388:1009;;;;;;;;;;;;;:::o;18250:113::-;18303:6;18064:8;18326:23;18330:9;18334:1;18337;18330:3;:9::i;:::-;18347:1;18064:8;18341:7;;14016:553;14116:4;14137:11;14133:55;;-1:-1:-1;14172:4:0;14165:11;;14133:55;-1:-1:-1;;;;;14204:21:0;;;;:45;;-1:-1:-1;;;;;;14229:20:0;;13816:42;14229:20;14204:45;14200:362;;;14270:7;14266:196;;;14305:33;;-1:-1:-1;;;;;14305:25:0;;;:33;;;;;14331:6;;14305:33;;;;14331:6;14305:25;:33;;;;;;;14298:40;;;;14266:196;14379:37;;-1:-1:-1;;;;;14379:29:0;;;:37;;;;;14409:6;;14379:37;;;;14409:6;14379:29;:37;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;14379:37:0;14442:4;14435:11;;;;14200:362;14494:30;-1:-1:-1;;;;;14494:18:0;;14513:2;14517:6;14494:30;:18;:30;:::i;:::-;-1:-1:-1;14546:4:0;14200:362;14016:553;;;;;;:::o;10460:176::-;10569:58;;;-1:-1:-1;;;;;10569:58:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;10569:58:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;10543:85:0;;10562:5;;13058:27;13066:5;-1:-1:-1;;;;;13058:25:0;;:27::i;:::-;13050:71;;;;;-1:-1:-1;;;13050:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;13195:12;13209:23;13244:5;-1:-1:-1;;;;;13236:19:0;13256:4;13236:25;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;13236:25:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;13194:67:0;;;;13280:7;13272:52;;;;;-1:-1:-1;;;13272:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13341:17;;:21;13337:224;;13483:10;13472:30;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;13472:30:0;13464:85;;;;-1:-1:-1;;;13464:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6843:810;6903:4;7562:20;;7405:66;7602:15;;;;;:42;;-1:-1:-1;7621:23:0;;;7594:51;-1:-1:-1;;6843:810:0:o;25181:30239::-;;;;;;;;;-1:-1:-1;25181:30239:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;-1:-1;25181:30239:0;;;-1:-1:-1;;25181:30239:0:o

Swarm Source

bzzr://38f04c1a51d5cb1354c6c60cdd840dea64b1f69a7f5ed081601d5e51181136e0

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.