ETH Price: $2,803.46 (+1.34%)

Contract

0xe3399650433d1Bc990e0C98c92D3E9AA7b331443
 

Overview

ETH Balance

0.100000000000000001 ETH

Eth Value

$280.35 (@ $2,803.46/ETH)

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Setup Strate...105140522020-07-23 6:13:471676 days ago1595484827IN
0xe3399650...A7b331443
0 ETH0.0029304666
Migrate Strategi...103882082020-07-03 19:02:471696 days ago1593802967IN
0xe3399650...A7b331443
0 ETH0.0043259231
Upgrade103869822020-07-03 14:28:271696 days ago1593786507IN
0xe3399650...A7b331443
0 ETH0.0017374840
Collect And Clos...103803202020-07-02 13:46:151697 days ago1593697575IN
0xe3399650...A7b331443
0 ETH0.0445674151.7
Transfer103741432020-07-01 14:44:591698 days ago1593614699IN
0xe3399650...A7b331443
0.1 ETH0.0010940852
Collect And Clos...103737332020-07-01 13:16:311698 days ago1593609391IN
0xe3399650...A7b331443
0 ETH0.0554818956.1
Collect And Clos...103737292020-07-01 13:15:591698 days ago1593609359IN
0xe3399650...A7b331443
0 ETH0.0544664853.9
Collect And Clos...103733772020-07-01 11:55:181698 days ago1593604518IN
0xe3399650...A7b331443
0 ETH0.0511316151.7
Collect And Clos...103733422020-07-01 11:48:581698 days ago1593604138IN
0xe3399650...A7b331443
0 ETH0.0511316151.7
Increase Strateg...103621262020-06-29 17:42:271700 days ago1593452547IN
0xe3399650...A7b331443
0 ETH0.0013876230
Increase Strateg...103619912020-06-29 17:11:151700 days ago1593450675IN
0xe3399650...A7b331443
0 ETH0.0013876230
Increase Strateg...103619292020-06-29 16:55:381700 days ago1593449738IN
0xe3399650...A7b331443
0 ETH0.0015261133
Set Admin Permis...103619022020-06-29 16:48:401700 days ago1593449320IN
0xe3399650...A7b331443
0 ETH0.0017733640
Set Admin Permis...103618832020-06-29 16:45:211700 days ago1593449121IN
0xe3399650...A7b331443
0 ETH0.0018181841
Set Admin Permis...103618822020-06-29 16:45:131700 days ago1593449113IN
0xe3399650...A7b331443
0 ETH0.0018181841
Increase Strateg...103613462020-06-29 14:44:361700 days ago1593441876IN
0xe3399650...A7b331443
0 ETH0.0013475535.283701
Increase Strateg...103611792020-06-29 14:06:321700 days ago1593439592IN
0xe3399650...A7b331443
0 ETH0.0015658741
Cancel Sign103355412020-06-25 14:44:341704 days ago1593096274IN
0xe3399650...A7b331443
0 ETH0.0009395138
Cancel Sign103352062020-06-25 13:35:411704 days ago1593092141IN
0xe3399650...A7b331443
0 ETH0.0020207546.0057
Set Setup Strate...103292012020-06-24 15:09:411705 days ago1593011381IN
0xe3399650...A7b331443
0 ETH0.0023526153
Set Setup Strate...103291732020-06-24 15:03:171705 days ago1593010997IN
0xe3399650...A7b331443
0 ETH0.0025752558
Accept Owner103287842020-06-24 13:42:351705 days ago1593006155IN
0xe3399650...A7b331443
0 ETH0.0014967152
Collect And Clos...103281092020-06-24 11:07:411705 days ago1592996861IN
0xe3399650...A7b331443
0 ETH0.0366553844
Change Owner103044692020-06-20 19:21:471709 days ago1592680907IN
0xe3399650...A7b331443
0 ETH0.0006077614

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block
From
To
105146682020-07-23 8:30:281676 days ago1595493028
0xe3399650...A7b331443
0.81389175 ETH
105146682020-07-23 8:30:281676 days ago1595493028
0xe3399650...A7b331443
87.51405631 ETH
105146682020-07-23 8:30:281676 days ago1595493028
0xe3399650...A7b331443
87.51405631 ETH
105146682020-07-23 8:30:281676 days ago1595493028
0xe3399650...A7b331443
0.81389175 ETH
105146682020-07-23 8:30:281676 days ago1595493028
0xe3399650...A7b331443
87.51405631 ETH
105146682020-07-23 8:30:281676 days ago1595493028
0xe3399650...A7b331443
87.51405631 ETH
105146422020-07-23 8:24:171676 days ago1595492657
0xe3399650...A7b331443
0.3996347 ETH
105146422020-07-23 8:24:171676 days ago1595492657
0xe3399650...A7b331443
43.75702719 ETH
105146422020-07-23 8:24:171676 days ago1595492657
0xe3399650...A7b331443
43.75702719 ETH
105146422020-07-23 8:24:171676 days ago1595492657
0xe3399650...A7b331443
0.3996347 ETH
105146422020-07-23 8:24:171676 days ago1595492657
0xe3399650...A7b331443
43.75702719 ETH
105146422020-07-23 8:24:171676 days ago1595492657
0xe3399650...A7b331443
43.75702719 ETH
103803202020-07-02 13:46:151697 days ago1593697575
0xe3399650...A7b331443
0.98000394 ETH
103803202020-07-02 13:46:151697 days ago1593697575
0xe3399650...A7b331443
0.52000555 ETH
103803202020-07-02 13:46:151697 days ago1593697575
0xe3399650...A7b331443
1.50000949 ETH
103803202020-07-02 13:46:151697 days ago1593697575
0xe3399650...A7b331443
0.52000555 ETH
103803202020-07-02 13:46:151697 days ago1593697575
0xe3399650...A7b331443
0.52000555 ETH
103737332020-07-01 13:16:311698 days ago1593609391
0xe3399650...A7b331443
0.97410302 ETH
103737332020-07-01 13:16:311698 days ago1593609391
0xe3399650...A7b331443
0.52590624 ETH
103737332020-07-01 13:16:311698 days ago1593609391
0xe3399650...A7b331443
1.50000926 ETH
103737332020-07-01 13:16:311698 days ago1593609391
0xe3399650...A7b331443
0.52590624 ETH
103737332020-07-01 13:16:311698 days ago1593609391
0xe3399650...A7b331443
0.52590624 ETH
103737292020-07-01 13:15:591698 days ago1593609359
0xe3399650...A7b331443
0.97145804 ETH
103737292020-07-01 13:15:591698 days ago1593609359
0xe3399650...A7b331443
0.52855122 ETH
103737292020-07-01 13:15:591698 days ago1593609359
0xe3399650...A7b331443
1.50000926 ETH
View All Internal Transactions
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-20
*/

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 {}

// ECDSA operations for signature

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * NOTE: This call _does not revert_ if the signature is invalid, or
     * if the signer is otherwise unable to be retrieved. In those scenarios,
     * the zero address is returned.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        // Check the signature length
        if (signature.length != 65) {
            return (address(0));
        }

        // Divide the signature in r, s and v variables
        bytes32 r;
        bytes32 s;
        uint8 v;

        // ecrecover takes the signature parameters, and the only way to get them
        // currently is to use assembly.
        // solhint-disable-next-line no-inline-assembly
        assembly {
            r := mload(add(signature, 0x20))
            s := mload(add(signature, 0x40))
            v := byte(0, mload(add(signature, 0x60)))
        }

        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return address(0);
        }

        if (v != 27 && v != 28) {
            return address(0);
        }

        // If the signature is valid (and not malleable), return the signer address
        return ecrecover(hash, v, r, s);
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * replicates the behavior of the
     * https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`]
     * JSON-RPC method.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }
}

contract SignatureHelper {

    // ** CONSTANTS **

    // EIP191 header for EIP712 prefix
    bytes2 constant internal EIP191_HEADER = 0x1901;

    // EIP712 Domain Name value
    string constant internal EIP712_DOMAIN_NAME = "DF.Help";

    // EIP712 Domain Version value
    string constant internal EIP712_DOMAIN_VERSION = "1.0";

    // Hash of the EIP712 Domain Separator Schema
    bytes32 constant internal EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(abi.encodePacked(
        "EIP712Domain(",
        "string name,",
        "string version,",
        "uint256 chainId,",
        "address verifyingContract",
        ")"
    ));
}

contract CloseSignatureLogic is SignatureHelper {

    // ** CONSTANTS **

    // Hash of the EIP712 IncreaseStrategyUsd struct
    bytes32 constant internal EIP712_DEAL_STRUCT_SCHEMA_HASH = keccak256(abi.encodePacked(
        "IncreaseStrategyUsd(",
        "address dfWallet,",
        "uint256 coefficient,",
        "uint256 valueUsdc,",
        "uint256 minEntryEthPrice,",
        "uint256 maxEntryEthPrice,",
        "uint256 expireTime,",
        "uint256 signNonce,",
        ")"
    ));

    // ** Immutable Storage **

    // Hash of the EIP712 Domain Separator data
    bytes32 public EIP712_DOMAIN_HASH;

    constructor() public {
        EIP712_DOMAIN_HASH = keccak256(abi.encode(
            EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,
            keccak256(bytes(EIP712_DOMAIN_NAME)),
            keccak256(bytes(EIP712_DOMAIN_VERSION)),
            1,
            address(this)
        ));
    }

    // Returns the EIP712 hash of an IncreaseStrategyUsd
    function _getUsdIncreaseStrategyHash(
        address _dfWallet,
        uint[6] memory _params
    )
        internal
        view
        returns(bytes32)
    {
        // compute the overall signed struct hash
        bytes32 structHash = keccak256(abi.encodePacked(
            EIP712_DEAL_STRUCT_SCHEMA_HASH,
            _dfWallet,   // dfWallet
            _params[0],  // coefficient
            _params[1],  // valueUsdc
            _params[2],  // minEntryEthPrice
            _params[3],  // maxEntryEthPrice
            _params[4],  // expireTime
            _params[5]   // signNonce
        ));

        // compute eip712 compliant hash
        return keccak256(abi.encodePacked(
            EIP191_HEADER,
            EIP712_DOMAIN_HASH,
            structHash
        ));
    }
}

// ** 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 IComptroller {
    function enterMarkets(address[] calldata cTokens) external returns (uint256[] memory);

    function exitMarket(address cToken) external returns (uint256);

    function getAssetsIn(address account) external view returns (address[] memory);

    function getAccountLiquidity(address account) external view returns (uint256, uint256, uint256);

    function markets(address cTokenAddress) external view returns (bool, 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;

    // setup empty strategy (without deposit)
    function setupStrategy(
        address _owner, address _dfWallet, uint8 _profitPercent, uint8 _fee
    ) 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;

}

interface IDfStrategyCallback {

    function __callback(
        bool _isStrategyClosed,
        uint _closingType
    ) external returns(bool success);

}

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

    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

    // canceled or used signs
    mapping(address => mapping(uint256 => bool)) public signedNonces;

    // ** EVENTS **

    event AfterExchangeRefund(address indexed user, uint ethToRefund, uint usdToRefund);

    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]);
        _;
    }

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

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

    modifier onlyUsdIncreaseVerified(
        address _dfWallet,
        bytes memory _signature,    // dfWallet user signature is v, r, s for ECDSA
        uint[8] memory _params      // coef [0], valueUsdc [1],
                                    // entryEthPrice [2], minEntryEthPrice [3], maxEntryEthPrice [4],
                                    // expireTime [5], signNonce [6], ethType[7]
    ) {
        // check signature
        require(
            isUsdIncreaseVerified(
                /* dfWallet, signature,
                coef, valueUsdc, entryEthPrice, minEntryEthPrice, maxEntryEthPrice, expireTime, signNonce */
                _dfWallet, _signature,
                [_params[0], _params[1], _params[2], _params[3], _params[4], _params[5], _params[6]]
            )
        );

        // signNonce for dfWallet is used
        signedNonces[_dfWallet][_params[6]] = true;
        _;
    }

    // ** CONSTRUCTOR **

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

    // ** 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);
    // }

    /// @notice Returns the maximum amount of borrow amount available
    /// @dev Due to rounding errors the result is - 100 wei from the exact amount
    function getMaxBorrow(address _cBorrowToken, address _wallet) public view returns (uint) {
        (, uint liquidityInEth, ) = IComptroller(COMPTROLLER).getAccountLiquidity(_wallet);

        if (_cBorrowToken == CETH_ADDRESS) {
            return liquidityInEth;
        }

        uint ethPrice = ICompoundOracle(COMPOUND_ORACLE).getUnderlyingPrice(_cBorrowToken);
        uint liquidityInToken = wdiv(liquidityInEth, ethPrice);

        return sub(liquidityInToken, 100); // cut off 100 wei to handle rounding issues
    }

    function isUsdIncreaseVerified(
        address _dfWallet,
        bytes memory _signature,    // dfWallet user signature is v, r, s for ECDSA
        uint[7] memory _params      // coef [0], valueUsdc [1],
                                    // entryEthPrice [2], minEntryEthPrice [3], maxEntryEthPrice [4],
                                    // expireTime [5], signNonce [6]
    ) public view returns(bool) {
        require(_params[3] <= _params[4]);

        // sign is expired, used or canceled
        if (now > _params[5] ||
            signedNonces[_dfWallet][_params[6]]) {
            return false;
        }

        // entryEthPrice is too high or low
        if (_params[2] < _params[3] || _params[2] > _params[4]) {
            return false;
        }

        // This recreates the message hash that was signed on the client
        bytes32 hash = _getUsdIncreaseStrategyHash(
            /* dfWallet,
            coef, valueUsdc, minEntryEthPrice, maxEntryEthPrice, expireTime, signNonce */
            _dfWallet,
            [_params[0], _params[1], _params[3], _params[4], _params[5], _params[6]]
        );

        // Verify that the message's signer is the owner of _dfWallet
        return (
            strategies[_dfWallet].owner == hash.recover(_signature)
        );
    }

    // * 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);
    }

    // setup empty strategy (without deposit)
    function setupStrategy(
        address _owner, address _dfWallet, uint8 _profitPercent, uint8 _fee
    ) public hasSetupStrategyPermission {
        _setupStrategy(_owner, _dfWallet, 0, 0, _profitPercent, _fee, 0);
    }

    // ** ONLY_OWNER_OR_ADMIN functions **

    function increaseStrategyUsdWithSign(
        address _dfWallet,
        bytes memory _signature,    // dfWallet user signature is v, r, s for ECDSA
        uint[8] memory _params,     // coef [0], valueUsdc [1],
                                    // entryEthPrice [2], minEntryEthPrice [3], maxEntryEthPrice [4],
                                    // expireTime [5], signNonce [6], ethType[7]
        bytes memory _exData        // data for 1inch exchange
    ) public
        useGasToken
        onlyOwnerOrAdmin
        onlyUsdIncreaseVerified(_dfWallet, _signature, _params)
    {
        _increaseStrategyUsd(
            /* _dfWallet, _coef, _valueUsdc, _entryEthPrice, _exData, _ethType */
            _dfWallet, _params[0], _params[1], _params[2], _exData, _params[7]
        );
    }

    // 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);

        // 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);
            // close strategy internal
            _strategyCloseHelper(_dfWallets[i]);
        }
    }

    function migrateStrategies(address[] memory _dfWallets) public {
        IDfFinanceClose migrationAddress = upgradedAddress;
        require(migrationAddress != IDfFinanceClose(0));

        for(uint i = 0; i < _dfWallets.length; i++) {
            Strategy memory strategy = strategies[_dfWallets[i]];
            require(strategy.owner == msg.sender);
            require(strategy.ethForRedeem == 0);

            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);

        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);

        _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]);

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

        require(ethLocked < ethInitial);

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

    function cancelSign(address _dfWallet, uint _signNonce) public returns(bool) {
        require(msg.sender == strategies[_dfWallet].owner);

        signedNonces[_dfWallet][_signNonce] = true;
        return true;
    }

    // ** ONLY_OWNER functions **

    function setLoanPool(address _loanAddr) public onlyOwner {
        require(_loanAddr != address(0));
        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));
        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);
    }

    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);

        usdProfit = sub(usdToWithdraw, usdOriginal);

        require(wdiv(usdProfit, usdOriginal) * 100 >= profitPercent * WAD);
    }

    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);

            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].owner == address(0));

        uint extraCoef = _extraCoef;
        if (extraCoef == 0 && _deposit > 0) {
            uint ethLocked = ICToken(CETH_ADDRESS).balanceOfUnderlying(_dfWallet);
            extraCoef = (ethLocked * 100) / _deposit;  // in percent (ex. 150 == 150%)
        }

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

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

    function _increaseStrategyUsd(
        address _dfWallet,
        uint _coef,
        uint _valueUsdc,
        uint _entryEthPrice,
        bytes memory _exData,
        uint _ethType
    ) internal {
        Strategy memory strategy = strategies[_dfWallet];

        require(strategy.owner != address(0) && strategy.ethForRedeem == 0);
        require(_coef >= 150 && _coef <= 300, "Invalid coefficient");

        // transfer valueUsdc USDC from strategy owner to this contract
        IToken(USDC_ADDRESS).universalTransferFrom(strategy.owner, address(this), _valueUsdc);

        uint extraUsdc = _valueUsdc * (_coef - 100) / 100;
        uint totalUsdcForLoanEth = add(_valueUsdc, extraUsdc);

        // take an eth loan
        uint totalLoanEth = wdiv(totalUsdcForLoanEth * 1e12, _entryEthPrice);
        loanPool.loan(totalLoanEth);

        // deposit ETH and borrow USDC
        _depositToDfWallet(_dfWallet, totalLoanEth, extraUsdc);

        /**
            exResult[2] - extra ToTokens after exchange – ETH
            exResult[3] - extra FromTokens after exchange – USDC
         */
        uint[4] memory exResult = _exchange(
            IToken(USDC_ADDRESS), totalUsdcForLoanEth,
            _ethType == 0 ? IToken(WETH_ADDRESS) : IToken(ETH_ADDRESS), totalLoanEth,
            _exData
        );

        if (_ethType == 0) {
            IToken(WETH_ADDRESS).withdraw(IToken(WETH_ADDRESS).balanceOf(address(this)));
        }

        // deposited eth after increase
        uint addedEth = wdiv(_valueUsdc * 1e12, _entryEthPrice);
        uint depositAfter = add(strategy.deposit, addedEth);

        // UPD Strategy states
        strategies[_dfWallet].deposit = uint80(depositAfter);
        strategies[_dfWallet].entryEthPrice = uint80(
            wdiv(add(wmul(strategy.deposit, strategy.entryEthPrice), wmul(addedEth, _entryEthPrice)), depositAfter)
        );
        strategies[_dfWallet].extraCoef = uint16((ICToken(CETH_ADDRESS).balanceOfUnderlying(_dfWallet) * 100) / depositAfter);

        // return an eth loan to LoanPool contract
        _transferEth(address(loanPool), totalLoanEth);

        // return short change to strategy owner (rest ETH and USDC)
        _paybackExtraExchangeProfit(strategy.owner, exResult[2], exResult[3]);
    }

    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);

        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

        // call strategy owner's callback function (without revert if callback does not exist)
        _callbackTo(
            strategy.owner,                                                 // callback to address
            false,                                                          // isStrategyClosed
            (_amountUsdToBuy > 0) ? (_onlyProfitInUsd ? 3 : 2) : 1      // closingType
        );

        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,                                                 // callback to address
            true,                                                           // isStrategyClosed
            (usdToWithdraw > 0) ? (strategy.onlyProfitInUsd ? 3 : 2) : 1    // closingType
        );

        // 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);

        // 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,                                                 // callback to address
            true,                                                           // isStrategyClosed
            (_minAmountUsd > 0) ? (_onlyProfitInUsd ? 3 : 2) : 1        // closingType
        );

        // 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);
    }

    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);

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

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

    function _depositToDfWallet(
        address _dfWallet,
        uint256 ethToDeposit,
        uint256 usdcForExtract
    ) internal {

        // mint cEther and borrow USDC
        IDfWallet(_dfWallet).deposit.value(ethToDeposit)(
            ETH_ADDRESS, CETH_ADDRESS, ethToDeposit, USDC_ADDRESS, CUSDC_ADDRESS, usdcForExtract
        );

        // Needs more 15 percent in collateral
        uint maxBorrowUsdc = getMaxBorrow(CUSDC_ADDRESS, _dfWallet);
        require(maxBorrowUsdc > 0 && (maxBorrowUsdc * 100 / (maxBorrowUsdc + usdcForExtract) >= 15));
    }

    function _paybackExtraExchangeProfit(
        address _userAddr,
        uint256 _extraEth,
        uint256 _extraUsd
    ) internal {

        uint ethForPayback = _extraEth;
        uint usdForPayback = _extraUsd;

        // transfer more than need gas for transfer
        if (ethForPayback > tx.gasprice * 21000 * 2) {
            IToken(ETH_ADDRESS).universalTransfer(_userAddr, ethForPayback);
        } else {
            ethForPayback = 0;
        }

        // transfer more than 0.5 USDC
        if (usdForPayback > 0.5e6) {
            IToken(USDC_ADDRESS).universalTransfer(_userAddr, usdForPayback);
        } else {
            usdForPayback = 0;
        }

        // Refund ETH and USDC to user Log
        emit AfterExchangeRefund(_userAddr, ethForPayback, usdForPayback);
    }

    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,
        bool _isStrategyClosed,
        uint _closingType
    ) internal {
        bytes memory data = abi.encodeWithSelector(IDfStrategyCallback(_to).__callback.selector, _isStrategyClosed, _closingType);

        // call without revert if function does not exist
        (bool success, bytes memory returndata) = address(_to).call(data);

        // verify that the callback function returns true
        if (success && returndata.length > 0) {
            require(abi.decode(returndata, (bool)));
        }
    }

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

}

Contract Security Audit

Contract ABI

[{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"ethToRefund","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"usdToRefund","type":"uint256"}],"name":"AfterExchangeRefund","type":"event"},{"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":"EIP712_DOMAIN_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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","name":"_dfWallet","type":"address"},{"internalType":"uint256","name":"_signNonce","type":"uint256"}],"name":"cancelSign","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","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":"_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":[{"internalType":"address","name":"_cBorrowToken","type":"address"},{"internalType":"address","name":"_wallet","type":"address"}],"name":"getMaxBorrow","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":false,"inputs":[{"internalType":"address","name":"_dfWallet","type":"address"},{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"uint256[8]","name":"_params","type":"uint256[8]"},{"internalType":"bytes","name":"_exData","type":"bytes"}],"name":"increaseStrategyUsdWithSign","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_dfWallet","type":"address"},{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"uint256[7]","name":"_params","type":"uint256[7]"}],"name":"isUsdIncreaseVerified","outputs":[{"internalType":"bool","name":"","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":"_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":"_owner","type":"address"},{"internalType":"address","name":"_dfWallet","type":"address"},{"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"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"signedNonces","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","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"}]

608060405234801561001057600080fd5b50604080516c08a92a06e626488dedac2d2dc5609b1b6020808301919091526b1cdd1c9a5b99c81b985b594b60a21b602d8301526e1cdd1c9a5b99c81d995c9cda5bdb8b608a1b60398301526f1d5a5b9d0c8d4d8818da185a5b92590b60821b60488301527f6164647265737320766572696679696e67436f6e7472616374000000000000006058830152602960f81b6071830152825160528184030181526072830180855281519183019190912060b284018552600790915266044462e48656c760cc1b6092909301929092528251808401845260038152620312e360ec1b908201528251808201929092527fa2ee92ca0a650bc21a90913eb5d509f29c8f53f7631178996f5a00a9621d26ba828401527fe6bbd6277e1bf288eed5e8d1780f9a50b239e86b153736bceebccf4ea79d90b360608301526001608083018190523060a0808501919091528451808503909101815260c0909301909352815191810191909120600090815582546001600160a01b03199081163317845560068054909116739edae6aab4b0f0f8146051ab353593209982d6b617905573ba3eeeb0cf1584ee565f34fcaba74d3e73268c0b9052600490527fbec71b602860a2b561618ed8b47300edebf96dc2830a4b5624a65b69a7087759805460ff1916909117905561581b80620002036000396000f3fe6080604052600436106102675760003560e01c806370eca0ec11610144578063bb09d9b7116100b6578063eb21d9c41161007a578063eb21d9c4146110cb578063ebbc49651461117b578063ee5f4afd14611190578063f3fef3a3146111a5578063f8806a13146111de578063f93f20d81461126457610267565b8063bb09d9b714610f5c578063c63f0dc114610f71578063d1e1ecba14610fd3578063e1ea330014611006578063e306f779146110b657610267565b806398fb83871161010857806398fb838714610d0f578063a6f9dae114610e61578063a734f06e14610e94578063ad9d4ba314610ea9578063ae5f8f7214610ecf578063b3c18b1614610f0257610267565b806370eca0ec14610bcd5780638a5e8cc714610cbb5780638af8d4c314610cd05780638da5cb5b14610ce557806394771d7614610cfa57610267565b806339ebf823116101dd57806359966b24116101a157806359966b24146108855780635f5008d1146109335780635f82c67e146109815780636568a2791461099657806366408eb014610a445780636caf516a14610a5957610267565b806339ebf82314610580578063416d4efb14610624578063429b62e5146106eb5780634ab45d331461071e5780635969490d1461073357610267565b80631ec18ec01161022f5780631ec18ec01461041357806325fda7881461046057806326976e3f146104755780632840e1b31461048a5780632bb083fc1461049f578063331934ec146104d257610267565b8063040141e5146102695780630900f0101461029a5780630ae538f1146102cd57806310e5ebc41461031a5780631d8319e414610353575b005b34801561027557600080fd5b5061027e611279565b604080516001600160a01b039092168252519081900360200190f35b3480156102a657600080fd5b50610267600480360360208110156102bd57600080fd5b50356001600160a01b0316611291565b3480156102d957600080fd5b50610306600480360360408110156102f057600080fd5b506001600160a01b038135169060200135611319565b604080519115158252519081900360200190f35b34801561032657600080fd5b506103066004803603604081101561033d57600080fd5b506001600160a01b038135169060200135611385565b6102676004803603608081101561036957600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b81111561039f57600080fd5b8201836020820111156103b157600080fd5b803590602001918460018302840111600160201b831117156103d257600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506113a5945050505050565b34801561041f57600080fd5b5061044e6004803603604081101561043657600080fd5b506001600160a01b03813581169160200135166115a3565b60408051918252519081900360200190f35b34801561046c57600080fd5b5061044e61170e565b34801561048157600080fd5b5061027e611714565b34801561049657600080fd5b5061027e611723565b3480156104ab57600080fd5b50610267600480360360208110156104c257600080fd5b50356001600160a01b0316611732565b3480156104de57600080fd5b50610267600480360360208110156104f557600080fd5b810190602081018135600160201b81111561050f57600080fd5b82018360208201111561052157600080fd5b803590602001918460208302840111600160201b8311171561054257600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506117ba945050505050565b34801561058c57600080fd5b506105b3600480360360208110156105a357600080fd5b50356001600160a01b0316611ab2565b604080516001600160501b039a8b168152988a1660208a015260ff978816898201529590961660608801529290961660808601526001600160401b031660a085015293151560c08401526001600160a01b0390931660e083015261ffff166101008201529051908190036101200190f35b610267600480360360a081101561063a57600080fd5b6001600160a01b0382351691602081013591604082013591606081013515159181019060a081016080820135600160201b81111561067757600080fd5b82018360208201111561068957600080fd5b803590602001918460018302840111600160201b831117156106aa57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611b31945050505050565b3480156106f757600080fd5b506103066004803603602081101561070e57600080fd5b50356001600160a01b0316611b8f565b34801561072a57600080fd5b5061027e611ba4565b34801561073f57600080fd5b50610267600480360360e081101561075657600080fd5b810190602081018135600160201b81111561077057600080fd5b82018360208201111561078257600080fd5b803590602001918460208302840111600160201b831117156107a357600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092958435956020860135956040810135955060608101351515945060808101351515935060c081019060a00135600160201b81111561081157600080fd5b82018360208201111561082357600080fd5b803590602001918460018302840111600160201b8311171561084457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611bbc945050505050565b34801561089157600080fd5b50610267600480360360208110156108a857600080fd5b810190602081018135600160201b8111156108c257600080fd5b8201836020820111156108d457600080fd5b803590602001918460208302840111600160201b831117156108f557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611bd0945050505050565b34801561093f57600080fd5b506102676004803603608081101561095657600080fd5b506001600160a01b03813581169160208101359091169060ff60408201358116916060013516611c63565b34801561098d57600080fd5b5061027e611c96565b3480156109a257600080fd5b50610267600480360360208110156109b957600080fd5b810190602081018135600160201b8111156109d357600080fd5b8201836020820111156109e557600080fd5b803590602001918460208302840111600160201b83111715610a0657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611cae945050505050565b348015610a5057600080fd5b5061027e611d64565b348015610a6557600080fd5b506102676004803603610160811015610a7d57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b811115610aa757600080fd5b820183602082011115610ab957600080fd5b803590602001918460018302840111600160201b83111715610ada57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051610100818101909252939695948181019493509150600890839083908082843760009201919091525091949392602081019250359050600160201b811115610b5957600080fd5b820183602082011115610b6b57600080fd5b803590602001918460018302840111600160201b83111715610b8c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611d7c945050505050565b348015610bd957600080fd5b506103066004803603610120811015610bf157600080fd5b6001600160a01b038235169190810190604081016020820135600160201b811115610c1b57600080fd5b820183602082011115610c2d57600080fd5b803590602001918460018302840111600160201b83111715610c4e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805160e08181019092529396959481810194935091506007908390839080828437600092019190915250919450611ed49350505050565b348015610cc757600080fd5b5061027e61203f565b348015610cdc57600080fd5b5061027e612057565b348015610cf157600080fd5b5061027e61206a565b348015610d0657600080fd5b5061027e612079565b348015610d1b57600080fd5b50610267600480360360e0811015610d3257600080fd5b810190602081018135600160201b811115610d4c57600080fd5b820183602082011115610d5e57600080fd5b803590602001918460208302840111600160201b83111715610d7f57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092958435956020860135956040810135955060608101351515945060808101351515935060c081019060a00135600160201b811115610ded57600080fd5b820183602082011115610dff57600080fd5b803590602001918460018302840111600160201b83111715610e2057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612088945050505050565b348015610e6d57600080fd5b5061026760048036036020811015610e8457600080fd5b50356001600160a01b0316612219565b348015610ea057600080fd5b5061027e61228e565b61026760048036036020811015610ebf57600080fd5b50356001600160a01b03166122a0565b348015610edb57600080fd5b5061030660048036036020811015610ef257600080fd5b50356001600160a01b031661239c565b348015610f0e57600080fd5b50610267600480360360c0811015610f2557600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff608082013581169160a00135166123b1565b348015610f6857600080fd5b5061027e6123dd565b348015610f7d57600080fd5b50610267600480360360e0811015610f9457600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff608082013581169160a08101359091169060c001356123ef565b348015610fdf57600080fd5b5061026760048036036020811015610ff657600080fd5b50356001600160a01b031661241a565b34801561101257600080fd5b506102676004803603604081101561102957600080fd5b810190602081018135600160201b81111561104357600080fd5b82018360208201111561105557600080fd5b803590602001918460208302840111600160201b8311171561107657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550505050351515905061248f565b3480156110c257600080fd5b5061044e612539565b3480156110d757600080fd5b50610267600480360360408110156110ee57600080fd5b810190602081018135600160201b81111561110857600080fd5b82018360208201111561111a57600080fd5b803590602001918460208302840111600160201b8311171561113b57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550505050351515905061253f565b34801561118757600080fd5b506102676125e9565b34801561119c57600080fd5b5061044e612660565b3480156111b157600080fd5b50610267600480360360408110156111c857600080fd5b506001600160a01b038135169060200135612666565b3480156111ea57600080fd5b506112116004803603602081101561120157600080fd5b50356001600160a01b0316612727565b604080516001600160a01b03909a168a5260208a0198909852888801969096526060880194909452608087019290925260a086015260c085015260e0840152151561010083015251908190036101200190f35b34801561127057600080fd5b5061044e6127ac565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6001546001600160a01b031633146112e4576040805162461bcd60e51b815260206004820152601160248201527014195c9b5a5cdcda5bdb8819195b9a5959607a1b604482015290519081900360640190fd5b6001600160a01b0381166112f757600080fd5b600880546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b03808316600090815260056020526040812060010154909133600160481b909204161461134c57600080fd5b506001600160a01b0382166000908152600b602090815260408083208484529091529020805460ff191660019081179091555b92915050565b600b60209081526000928352604080842090915290825290205460ff1681565b60005a90506113b2615712565b506001600160a01b0385811660009081526005602090815260409182902082516101208101845281546001600160501b038082168352600160501b8204811694830194909452600160a01b810460ff90811695830195909552600160a81b810485166060830152600160b01b90049092166080830152600101546001600160401b03811660a0830152600160401b8104909216151560c0820152600160481b820490921660e08301819052600160e81b90910461ffff1661010083015233148061148657506001546001600160a01b031633145b806114a057503360009081526003602052604090205460ff165b6114a957600080fd5b60408051633af9e66960e01b81526001600160a01b03881660048201529051600091734ddc2d193948926d02f9b1fe9e1daa0718270ed591633af9e6699160248082019260209290919082900301818787803b15801561150857600080fd5b505af115801561151c573d6000803e3d6000fd5b505050506040513d602081101561153257600080fd5b5051825161010084015191925060009160649161155e916001600160501b039091169061ffff1661282d565b8161156557fe5b04905080821061157457600080fd5b6115848888886000896000612851565b505050505061159b611596825a612c3e565b612c4e565b505050505050565b60408051635ec88c7960e01b81526001600160a01b038316600482015290516000918291733d9819210a31b4961b30ef54be2aed79b9c9cd3b91635ec88c79916024808301926060929190829003018186803b15801561160257600080fd5b505afa158015611616573d6000803e3d6000fd5b505050506040513d606081101561162c57600080fd5b506020015190506001600160a01b038416734ddc2d193948926d02f9b1fe9e1daa0718270ed5141561165f57905061137f565b6040805163fc57d4df60e01b81526001600160a01b03861660048201529051600091731d8aedc9e924730dd3f9641cdb4d1b92b848b4bd9163fc57d4df91602480820192602092909190829003018186803b1580156116bd57600080fd5b505afa1580156116d1573d6000803e3d6000fd5b505050506040513d60208110156116e757600080fd5b5051905060006116f78383612d0b565b9050611704816064612c3e565b9695505050505050565b600a5481565b6008546001600160a01b031681565b6007546001600160a01b031681565b6001546001600160a01b03163314611785576040805162461bcd60e51b815260206004820152601160248201527014195c9b5a5cdcda5bdb8819195b9a5959607a1b604482015290519081900360640190fd5b6001600160a01b03811661179857600080fd5b600680546001600160a01b0319166001600160a01b0392909216919091179055565b6008546001600160a01b0316806117d057600080fd5b60005b8251811015611aad576117e4615712565b600560008584815181106117f457fe5b6020908102919091018101516001600160a01b03908116835282820193909352604091820160002082516101208101845281546001600160501b038082168352600160501b8204811694830194909452600160a01b810460ff90811695830195909552600160a81b810485166060830152600160b01b90049092166080830152600101546001600160401b03811660a0830152600160401b8104909216151560c0820152600160481b820490921660e08301819052600160e81b90910461ffff1661010083015290915033146118c957600080fd5b60808101516001600160501b0316156118e157600080fd5b826001600160a01b031663c63f0dc18260e0015186858151811061190157fe5b60209081029190910181015185519186015160408088015160608901516101008a015183516001600160e01b031960e08b901b1681526001600160a01b0398891660048201529790951660248801526001600160501b03958616604488015294909216606486015260ff9182166084860152921660a484015261ffff1660c48301525160e480830192600092919082900301818387803b1580156119a457600080fd5b505af11580156119b8573d6000803e3d6000fd5b505050508382815181106119c857fe5b60200260200101516001600160a01b0316635b85a60a846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050600060405180830381600087803b158015611a2757600080fd5b505af1158015611a3b573d6000803e3d6000fd5b50505050611a5b848381518110611a4e57fe5b6020026020010151612d3c565b838281518110611a6757fe5b60200260200101516001600160a01b03167f7c9a2d2ec51230d7dbed27f113a325b7e20aef7b049e68b2339257b5edff5bea60405160405180910390a2506001016117d3565b505050565b600560205260009081526040902080546001909101546001600160501b0380831692600160501b810482169260ff600160a01b8304811693600160a81b8404821693600160b01b900416916001600160401b03811691600160401b820416906001600160a01b03600160481b8204169061ffff600160e81b9091041689565b60005a6001600160a01b03878116600090815260056020526040902060010154919250600160481b909104163314611b6857600080fd5b611b7786868686866001612851565b5050611b86611596825a612c3e565b50505050505050565b60036020526000908152604090205460ff1681565b734ddc2d193948926d02f9b1fe9e1daa0718270ed581565b611bcb87878787878787612088565b611b86875b60005a905060005b8251811015611c5557600060056000858481518110611bf357fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002054600160b01b90046001600160501b031611611c3157600080fd5b611c4d838281518110611c4057fe5b6020026020010151612eb6565b600101611bd8565b50611aad611596825a612c3e565b3360009081526004602052604090205460ff16611c7f57600080fd5b611c908484600080868660006132da565b50505050565b733d9819210a31b4961b30ef54be2aed79b9c9cd3b81565b6001546001600160a01b03163314611d01576040805162461bcd60e51b815260206004820152601160248201527014195c9b5a5cdcda5bdb8819195b9a5959607a1b604482015290519081900360640190fd5b60005b8151811015611d6057611d58828281518110611d1c57fe5b6020026020010151611d5330858581518110611d3457fe5b60200260200101516001600160a01b031661363f90919063ffffffff16565b612666565b600101611d04565b5050565b7339aa39c021dfbae8fac545936693ac917d5e756381565b60005a3360009081526003602052604090205490915060ff1680611daa57506001546001600160a01b031633145b611db357600080fd5b848484611e6983836040518060e0016040528085600060088110611dd357fe5b6020020151815260200185600160088110611dea57fe5b6020020151815260200185600260088110611e0157fe5b6020020151815260200185600360088110611e1857fe5b6020020151815260200185600460088110611e2f57fe5b6020020151815260200185600560088110611e4657fe5b6020020151815260200185600660088110611e5d57fe5b60200201519052611ed4565b611e7257600080fd5b6001600160a01b0383166000908152600b6020908152604080832060c08501518452825291829020805460ff191660011790558751908801519188015160e0890151611ec4938c939290918a9061370c565b50505061159b611596825a612c3e565b608081015160608201516000911015611eec57600080fd5b60a0820151421180611f2557506001600160a01b0384166000908152600b6020908152604080832060c0860151845290915290205460ff165b15611f3257506000612038565b606082015160408301511080611f4f575060808201516040830151115b15611f5c57506000612038565b6000611ff9856040518060c0016040528086600060078110611f7a57fe5b6020020151815260200186600160078110611f9157fe5b6020020151815260200186600360078110611fa857fe5b6020020151815260200186600460078110611fbf57fe5b6020020151815260200186600560078110611fd657fe5b6020020151815260200186600660078110611fed57fe5b60200201519052613c3e565b905061200b818563ffffffff613e1716565b6001600160a01b03868116600090815260056020526040902060010154600160481b900481169116149150505b9392505050565b731d8aedc9e924730dd3f9641cdb4d1b92b848b4bd81565b6eb3f879cb30fe243b4dfee438691c0481565b6001546001600160a01b031681565b6006546001600160a01b031681565b60005a3360009081526003602052604090205490915060ff16806120b657506001546001600160a01b031633145b6120bf57600080fd5b60006120d86120ce8989613f05565b87620f4240613f15565b64e8d4a510000290506120e961575e565b84156121895760065460408051631b2d298360e11b81526004810185905290516001600160a01b039092169163365a53069160248082019260009290919082900301818387803b15801561213c57600080fd5b505af1158015612150573d6000803e3d6000fd5b5050505061218660008051602061577d8339815191528360008051602061579d8339815191526121808d8d613f05565b88613f35565b90505b6000805b8b518110156121c1576121b58c82815181106121a557fe5b60200260200101518b8b8b614214565b9091019060010161218d565b50828110156121cf57600080fd5b60408201511515806121e45750606082015115155b156121fe57606082015160408301516121fe918d916144da565b50505061220e611596825a612c3e565b505050505050505050565b6001546001600160a01b0316331461226c576040805162461bcd60e51b815260206004820152601160248201527014195c9b5a5cdcda5bdb8819195b9a5959607a1b604482015290519081900360640190fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60008051602061577d83398151915281565b6001600160a01b0381166000908152600560205260409020546001600160501b03166122cb57600080fd5b6001600160a01b038116600081815260056020526040808220805469ffffffffffffffffffff198116346001600160501b0392831681019092161790915581516302d35a5960e01b815260008051602061577d8339815191526004820152734ddc2d193948926d02f9b1fe9e1daa0718270ed5602482015260448101829052606481018490526084810184905260a4810184905291519093926302d35a5992859260c4808301939282900301818588803b15801561238857600080fd5b505af1158015611b86573d6000803e3d6000fd5b60046020526000908152604090205460ff1681565b3360009081526004602052604090205460ff166123cd57600080fd5b61159b86868686868660006132da565b60008051602061579d83398151915281565b3360009081526004602052604090205460ff1661240b57600080fd5b611b86878787878787876132da565b6001546001600160a01b0316331461246d576040805162461bcd60e51b815260206004820152601160248201527014195c9b5a5cdcda5bdb8819195b9a5959607a1b604482015290519081900360640190fd5b600780546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146124e2576040805162461bcd60e51b815260206004820152601160248201527014195c9b5a5cdcda5bdb8819195b9a5959607a1b604482015290519081900360640190fd5b60005b8251811015611aad5781600460008584815181106124ff57fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff19169115159190911790556001016124e5565b60005481565b6001546001600160a01b03163314612592576040805162461bcd60e51b815260206004820152601160248201527014195c9b5a5cdcda5bdb8819195b9a5959607a1b604482015290519081900360640190fd5b60005b8251811015611aad5781600360008584815181106125af57fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055600101612595565b6002546001600160a01b0316331461263c576040805162461bcd60e51b815260206004820152601160248201527014195c9b5a5cdcda5bdb8819195b9a5959607a1b604482015290519081900360640190fd5b600254600180546001600160a01b0319166001600160a01b03909216919091179055565b60095481565b6001546001600160a01b031633146126b9576040805162461bcd60e51b815260206004820152601160248201527014195c9b5a5cdcda5bdb8819195b9a5959607a1b604482015290519081900360640190fd5b6001600160a01b038216612707576001546040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015612701573d6000803e3d6000fd5b50611d60565b600154611d60906001600160a01b0384811691168363ffffffff61470116565b6001600160a01b03908116600090815260056020526040902060018101549054600160481b8204909216926001600160501b038084169361ffff600160e81b85041693600160501b820483169360ff600160a01b8404811694600160a81b8504821694600160b01b900416926001600160401b03811692600160401b90910490911690565b604080516370a0823160e01b815230600482015290516000916eb3f879cb30fe243b4dfee438691c04916370a0823191602480820192602092909190829003018186803b1580156127fc57600080fd5b505afa158015612810573d6000803e3d6000fd5b505050506040513d602081101561282657600080fd5b5051919050565b60008115806128485750508082028282828161284557fe5b04145b61137f57600080fd5b60008061285c615712565b506001600160a01b0388811660009081526005602090815260409182902082516101208101845281546001600160501b03808216808452600160501b8304821695840195909552600160a01b820460ff90811696840196909652600160a81b820486166060840152600160b01b9091041660808201526001909101546001600160401b03811660a0830152600160401b8104909316151560c0820152600160481b830490931660e0840152600160e81b90910461ffff1661010083015215801590612932575060808101516001600160501b0316155b61293b57600080fd5b60408051633af9e66960e01b81526001600160a01b038b16600482015290516000916129cf91734ddc2d193948926d02f9b1fe9e1daa0718270ed591633af9e66991602480830192602092919082900301818887803b15801561299d57600080fd5b505af11580156129b1573d6000803e3d6000fd5b505050506040513d60208110156129c757600080fd5b50518a612c3e565b905084156129eb576129e382828a8a61470e565b909550935090505b888815612a1e576129fc8183613f05565b90508715612a1e57612a1b8184600001516001600160501b0316612c3e565b90505b600034821115612a9b57612a328234612c3e565b60065460408051631b2d298360e11b81526004810184905290519293506001600160a01b039091169163365a53069160248082019260009290919082900301818387803b158015612a8257600080fd5b505af1158015612a96573d6000803e3d6000fd5b505050505b612aa361575e565b612aaf8d848d8c6148ae565b905060008715612af35760006064612ace89896060015160ff1661282d565b81612ad557fe5b049050612aef81612aea8960e0015184614aab565b612c3e565b9150505b6000612aff8483613f05565b1115612b2457600654612b24906001600160a01b0316612b1f8584613f05565b614c3b565b8b15612b47578a15612b425785516001600160501b03169450612b47565b600094505b60e086015160608301516040840151612b6592918801908f01614c9b565b612b958660e00151600160008f11612b7e576001612b8d565b8d612b8a576002612b8d565b60035b60ff16614ce5565b612b9e8e612d3c565b3415612bd25760405133903480156108fc02916000818181858888f19350505050158015612bd0573d6000803e3d6000fd5b505b6001600160a01b038e167f53bb08c62ecc11fdb8b19d8f885288b800b5b6e28ed23f0587dd199872ae42ef8360036020020151870184600260200201518f01604051808381526020018281526020019250505060405180910390a2505050505050965096945050505050565b8082038281111561137f57600080fd5b600080612c596127ac565b905080612c6a576000915050612d06565b61a0aa61374a84010481811115612c7e5750805b6eb3f879cb30fe243b4dfee438691c046001600160a01b0316636366b936826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015612cd357600080fd5b505af1158015612ce7573d6000803e3d6000fd5b505050506040513d6020811015612cfd57600080fd5b50600193505050505b919050565b600081612d2d612d2385670de0b6b3a764000061282d565b6002855b04613f05565b81612d3457fe5b049392505050565b604080516101208101825260008082526020808301828152838501838152606085018481526080860185815260a0870186815260c0880187815260e089018881526101008a018981526001600160a01b039c8d168a5260059098529990972097518854955194519351925169ffffffffffffffffffff199096166001600160501b039182161769ffffffffffffffffffff60501b1916600160501b958216959095029490941760ff60a01b1916600160a01b60ff948516021760ff60a81b1916600160a81b9390921692909202176001600160b01b0316600160b01b9290931691909102919091178455516001909301805492519451915167ffffffffffffffff199093166001600160401b039094169390931760ff60401b1916600160401b94151594909402939093177fffffff0000000000000000000000000000000000000000ffffffffffffffffff16600160481b93909416929092029290921761ffff60e81b1916600160e81b61ffff90921691909102179055565b612ebe615712565b506001600160a01b03808216600081815260056020908152604080832081516101208101835281546001600160501b038082168352600160501b820481168387015260ff600160a01b8304811684870152600160a81b830481166060850152600160b01b9092041660808301526001909201546001600160401b03811660a0830152600160401b8104909216151560c0820152600160481b820490961660e087015261ffff600160e81b909104166101008601528051633af9e66960e01b81526004810194909452519192734ddc2d193948926d02f9b1fe9e1daa0718270ed592633af9e6699260248084019391929182900301818787803b158015612fc357600080fd5b505af1158015612fd7573d6000803e3d6000fd5b505050506040513d6020811015612fed57600080fd5b50516040805163095ea7b360e01b81526001600160a01b03861660048201526000196024820152905191925060008051602061579d8339815191529163095ea7b39160448082019260009290919082900301818387803b15801561305057600080fd5b505af1158015613064573d6000803e3d6000fd5b5050604080516335d0353d60e21b815260008051602061577d8339815191526004820152734ddc2d193948926d02f9b1fe9e1daa0718270ed5602482015260008051602061579d83398151915260448201527339aa39c021dfbae8fac545936693ac917d5e7563606482015290516001600160a01b038716935063d740d4f49250608480830192600092919082900301818387803b15801561310557600080fd5b505af1158015613119573d6000803e3d6000fd5b5050505060006064836060015160ff166131566131438587600001516001600160501b0316612c3e565b86608001516001600160501b0316612c3e565b028161315e57fe5b04905060006131718460e0015183614aab565b60a08501519091506001600160401b0316600081156131cb5760e08601516131af9060008051602061579d833981519152908463ffffffff61470116565b8560c00151156131c6575084516001600160501b03165b613202565b60006131e5888789608001516001600160501b0316614e02565b90506131fe87600001516001600160501b031682613f05565b9150505b801561322d5760e086015161322d9060008051602061577d833981519152908363ffffffff61470116565b600061324261323c8784612c3e565b85612c3e565b60065490915061325b906001600160a01b031682614c3b565b6132848760e00151600160008611613274576001612b8d565b8960c00151612b8a576002612b8d565b61328d88612d3c565b604080518381526020810185905281516001600160a01b038b16927f53bb08c62ecc11fdb8b19d8f885288b800b5b6e28ed23f0587dd199872ae42ef928290030190a25050505050505050565b6001600160a01b03868116600090815260056020526040902060010154600160481b9004161561330957600080fd5b80801580156133185750600086115b156133bb5760408051633af9e66960e01b81526001600160a01b03891660048201529051600091734ddc2d193948926d02f9b1fe9e1daa0718270ed591633af9e6699160248082019260209290919082900301818787803b15801561337c57600080fd5b505af1158015613390573d6000803e3d6000fd5b505050506040513d60208110156133a657600080fd5b505190508660648202816133b657fe5b049150505b604051806101200160405280876001600160501b03168152602001866001600160501b031681526020018560ff1681526020018460ff16815260200160006001600160501b0316815260200160006001600160401b03168152602001600015158152602001896001600160a01b031681526020018261ffff1681525060056000896001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a8154816001600160501b0302191690836001600160501b03160217905550602082015181600001600a6101000a8154816001600160501b0302191690836001600160501b0316021790555060408201518160000160146101000a81548160ff021916908360ff16021790555060608201518160000160156101000a81548160ff021916908360ff16021790555060808201518160000160166101000a8154816001600160501b0302191690836001600160501b0316021790555060a08201518160010160006101000a8154816001600160401b0302191690836001600160401b0316021790555060c08201518160010160086101000a81548160ff02191690831515021790555060e08201518160010160096101000a8154816001600160a01b0302191690836001600160a01b0316021790555061010082015181600101601d6101000a81548161ffff021916908361ffff160217905550905050866001600160a01b0316886001600160a01b03167fc505104967ca2886d648964d4dfffad3cd217df1ce0b3d286cf67543d035187888888888604051808581526020018481526020018360ff1660ff1681526020018260ff1660ff16815260200194505050505060405180910390a35050505050505050565b60006001600160a01b038316158061366d57506001600160a01b03831660008051602061577d833981519152145b1561368357506001600160a01b0381163161137f565b826001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156136d957600080fd5b505afa1580156136ed573d6000803e3d6000fd5b505050506040513d602081101561370357600080fd5b5051905061137f565b613714615712565b506001600160a01b0386811660009081526005602090815260409182902082516101208101845281546001600160501b038082168352600160501b8204811694830194909452600160a01b810460ff90811695830195909552600160a81b810485166060830152600160b01b90049092166080830152600101546001600160401b03811660a0830152600160401b8104909216151560c0820152600160481b820490921660e08301819052600160e81b90910461ffff16610100830152158015906137ea575060808101516001600160501b0316155b6137f357600080fd5b60968610158015613806575061012c8611155b61384d576040805162461bcd60e51b8152602060048201526013602482015272125b9d985b1a590818dbd959999a58da595b9d606a1b604482015290519081900360640190fd5b60e08101516138739060008051602061579d83398151915290308863ffffffff614e9116565b6064606319870186020460006138898783613f05565b9050600061389e8264e8d4a510000288612d0b565b60065460408051631b2d298360e11b81526004810184905290519293506001600160a01b039091169163365a53069160248082019260009290919082900301818387803b1580156138ee57600080fd5b505af1158015613902573d6000803e3d6000fd5b505050506139118a8285614fd7565b61391961575e565b61396360008051602061579d8339815191528488156139465760008051602061577d83398151915261395c565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25b858b613f35565b905085613a4657604080516370a0823160e01b8152306004820152905173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291632e1a7d4d9183916370a08231916024808301926020929190829003018186803b1580156139c357600080fd5b505afa1580156139d7573d6000803e3d6000fd5b505050506040513d60208110156139ed57600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b158015613a2d57600080fd5b505af1158015613a41573d6000803e3d6000fd5b505050505b6000613a598a64e8d4a51000028a612d0b565b90506000613a7487600001516001600160501b031683613f05565b6001600160a01b038e166000908152600560209081526040909120805469ffffffffffffffffffff19166001600160501b03848116919091179091558951918a0151929350613ae492613ade92613acf9290811691166150e8565b613ad9858e6150e8565b613f05565b82612d0b565b6001600160a01b038e16600081815260056020908152604080832080546001600160501b0396909616600160501b0269ffffffffffffffffffff60501b19909616959095179094558351633af9e66960e01b8152600481019390935292518493734ddc2d193948926d02f9b1fe9e1daa0718270ed593633af9e66993602480830194928390030190829087803b158015613b7d57600080fd5b505af1158015613b91573d6000803e3d6000fd5b505050506040513d6020811015613ba757600080fd5b505160640281613bb357fe5b04600560008f6001600160a01b03166001600160a01b03168152602001908152602001600020600101601d6101000a81548161ffff021916908361ffff160217905550613c15600660009054906101000a90046001600160a01b031685614c3b565b60e087015160408401516060850151613c2f929190615110565b50505050505050505050505050565b6040805173092dcc6e4cac2e6caa6e8e4c2e8cacef2aae6c8560631b602080830191909152701859191c995cdcc8191995d85b1b195d0b607a1b6034830152731d5a5b9d0c8d4d8818dbd959999a58da595b9d0b60621b6045830152711d5a5b9d0c8d4d881d985b1d59555cd918cb60721b60598301527f75696e74323536206d696e456e74727945746850726963652c00000000000000606b8301527f75696e74323536206d6178456e74727945746850726963652c000000000000006084830152721d5a5b9d0c8d4d88195e1c1a5c99551a5b594b606a1b609d830152711d5a5b9d0c8d4d881cda59db939bdb98d94b60721b60b0830152602960f81b60c2830152825160a381840301815260c3830184528051908201208451858301518686015160608089015160808a015160a0909a015160e389019690965299901b6bffffffffffffffffffffffff19166101038701526101178601929092526101378501526101578401526101778301959095526101978201939093526101b780820194909452815180820390940184526101d78101825283519383019390932060005461190160f01b6101f78601526101f985015261021980850191909152815180850390910181526102399093019052815191012090565b60008151604114613e2a5750600061137f565b60208201516040830151606084015160001a7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115613e70576000935050505061137f565b8060ff16601b14158015613e8857508060ff16601c14155b15613e99576000935050505061137f565b6040805160008152602080820180845289905260ff8416828401526060820186905260808201859052915160019260a0808401939192601f1981019281900390910190855afa158015613ef0573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b8082018281101561137f57600080fd5b600081613f25612d23868661282d565b81613f2c57fe5b04949350505050565b613f3d61575e565b7311111254369792b2ca5d084ab5eea397ca8fa48b60006001600160a01b03881660008051602061577d8339815191521461414957600019886001600160a01b031663dd62ed3e30856001600160a01b031663e8edc8166040518163ffffffff1660e01b815260040160206040518083038186803b158015613fbe57600080fd5b505afa158015613fd2573d6000803e3d6000fd5b505050506040513d6020811015613fe857600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b039384166004820152929091166024830152516044808301926020929190829003018186803b15801561403857600080fd5b505afa15801561404c573d6000803e3d6000fd5b505050506040513d602081101561406257600080fd5b50511461414457876001600160a01b031663095ea7b3836001600160a01b031663e8edc8166040518163ffffffff1660e01b815260040160206040518083038186803b1580156140b157600080fd5b505afa1580156140c5573d6000803e3d6000fd5b505050506040513d60208110156140db57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b039092166004830152600019602483015251604480830192600092919082900301818387803b15801561412b57600080fd5b505af115801561413f573d6000803e3d6000fd5b505050505b61414c565b50855b60006141676001600160a01b038a163063ffffffff61363f16565b905060006141846001600160a01b0389163063ffffffff61363f16565b9050600060206000885160208a0187896113885a03f150506000516141c16141bb6001600160a01b038b163063ffffffff61363f16565b83612c3e565b86526141da83612aea6001600160a01b038e163061363f565b602087015285516141eb9089612c3e565b60408701526020860151614200908b90612c3e565b606087015250939998505050505050505050565b6001600160a01b03841660009081526005602052604081208054600160b01b90046001600160501b0316158015614254575080546001600160501b031615155b61425d57600080fd5b60408051633af9e66960e01b81526001600160a01b03881660048201529051600091734ddc2d193948926d02f9b1fe9e1daa0718270ed591633af9e6699160248082019260209290919082900301818787803b1580156142bc57600080fd5b505af11580156142d0573d6000803e3d6000fd5b505050506040513d60208110156142e657600080fd5b5051604080516395dd919360e01b81526001600160a01b038a1660048201529051919250600091614383917339aa39c021dfbae8fac545936693ac917d5e7563916395dd919391602480820192602092909190829003018186803b15801561434d57600080fd5b505afa158015614361573d6000803e3d6000fd5b505050506040513d602081101561437757600080fd5b505187620f4240613f15565b64e8d4a51000029050600080881561440d5760006143a38b86868c6151c4565b95975087959350905087156143e95760018601805460ff60401b1916600160401b8a15150217905585549092506001600160501b03169050816143e68583612c3e565b96505b5060018501805467ffffffffffffffff19166001600160401b038416179055614439565b600061441a8b8686614e02565b8654909150614432906001600160501b031682613f05565b9150839650505b84546001600160b01b0316600160b01b6001600160501b03851602178555600185015461448a90600160481b90046001600160a01b031660008b61447e576001612b8d565b89612b8a576002612b8d565b604080518281526020810184905281516001600160a01b038d16927f253535bb9d23118941521a3ebcf52effeeed74d6716b9a2c2e33fee2329988dd928290030190a25050505050949350505050565b60608351604051908082528060200260200182016040528015614507578160200160208202803883390190505b5090506000805b8551811015614596576005600087838151811061452757fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205483516001600160501b039091169084908390811061456557fe5b60200260200101818152505082818151811061457d57fe5b602002602001015182019150808060010191505061450e565b5060005b855181101561159b5760006145c28483815181106145b457fe5b602002602001015184612d0b565b905085156146875760006145d682886150e8565b905080600560008a86815181106145e957fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002054600160b01b90046001600160501b031611156146855780600560008a868151811061463457fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002080546001600160501b03600160b01b808304821694909403169092026001600160b01b039092169190911790555b505b84156146f857600061469982876150e8565b905080600560008a86815181106146ac57fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020600101805467ffffffffffffffff1981166001600160401b039182169390930116919091179055505b5060010161459a565b611c9083838360006152c6565b8351839060009081906001600160501b031683111561482c5761473e8388600001516001600160501b0316612c3e565b905084156147e457831561479657866040015160ff1660640261477b88600001516001600160501b031689602001516001600160501b03166150e8565b662386f26fc1000087028161478c57fe5b04101591506147df565b866040015160ff166064016064026147c888600001516001600160501b031689602001516001600160501b03166150e8565b662386f26fc100008702816147d957fe5b04101591505b61482c565b866040015160ff1660640287600001516001600160501b0316606461481160648b6060015160ff16612c3e565b84028161481a57fe5b04612710028161482657fe5b04101591505b811561487857600061486288600001516001600160501b0316606461485960648c6060015160ff16612c3e565b850281612d2757fe5b90508084101561487157600080fd5b92506148a4565b600a544210156148a4576148a18360646148948660095461282d565b8161489b57fe5b04612c3e565b92505b9450945094915050565b6148b661575e565b604080516395dd919360e01b81526001600160a01b038716600482015290516000917339aa39c021dfbae8fac545936693ac917d5e7563916395dd919391602480820192602092909190829003018186803b15801561491457600080fd5b505afa158015614928573d6000803e3d6000fd5b505050506040513d602081101561493e57600080fd5b5051905061497460008051602061577d8339815191528660008051602061579d83398151915261496e8589613f05565b87613f35565b6040805163095ea7b360e01b81526001600160a01b03891660048201526000196024820152905191935060008051602061579d8339815191529163095ea7b39160448082019260009290919082900301818387803b1580156149d557600080fd5b505af11580156149e9573d6000803e3d6000fd5b5050604080516335d0353d60e21b815260008051602061577d8339815191526004820152734ddc2d193948926d02f9b1fe9e1daa0718270ed5602482015260008051602061579d83398151915260448201527339aa39c021dfbae8fac545936693ac917d5e7563606482015290516001600160a01b038a16935063d740d4f49250608480830192600092919082900301818387803b158015614a8a57600080fd5b505af1158015614a9e573d6000803e3d6000fd5b5050505050949350505050565b6007546000906001600160a01b031615614c02576007546040805163b1a1c1cf60e01b81526001600160a01b0386811660048301529151606493929092169163b1a1c1cf91602480820192602092909190829003018186803b158015614b1057600080fd5b505afa158015614b24573d6000803e3d6000fd5b505050506040513d6020811015614b3a57600080fd5b505160ff16830281614b4857fe5b049050818110614b5757600080fd5b60075460408051635345cb2960e11b81526001600160a01b0386811660048301529151919092169163a68b965291849160248082019260009290919082900301818588803b158015614ba857600080fd5b505af1158015614bbc573d6000803e3d6000fd5b50505050507f4959927089ff30362dfc0e79000c912fc2c9cc4ec9d5c1b1e0482fa7c4cea118614bec8383612c3e565b60408051918252519081900360200190a161137f565b6040805183815290517f4959927089ff30362dfc0e79000c912fc2c9cc4ec9d5c1b1e0482fa7c4cea1189181900360200190a192915050565b60405182906000906001600160a01b0383169084908381818185875af1925050503d8060008114614c88576040519150601f19603f3d011682016040523d82523d6000602084013e614c8d565b606091505b5050905080611c9057600080fd5b8115614cc057614cc060008051602061577d833981519152848463ffffffff61470116565b8015611aad57611aad60008051602061579d833981519152848363ffffffff61470116565b604080518315156024820152604480820184905282518083039091018152606490910182526020810180516001600160e01b031663163d5ccb60e11b1781529151815191926000926060926001600160a01b0389169286928291908083835b60208310614d635780518252601f199092019160209182019101614d44565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114614dc5576040519150601f19603f3d011682016040523d82523d6000602084013e614dca565b606091505b5091509150818015614ddd575060008151115b1561159b57808060200190516020811015614df757600080fd5b505161159b57600080fd5b6001600160a01b0383166000908152600560205260408120546001600160501b0381169060ff600160a81b8204811691600160a01b9004166064614e468184612c3e565b614e59614e538987612c3e565b88612c3e565b0281614e6157fe5b049350670de0b6b3a76400008102614e798585612d0b565b6064021015614e8757600080fd5b5050509392505050565b80614e9b57611c90565b6001600160a01b0384161580614ec757506001600160a01b03841660008051602061577d833981519152145b15614fbc576001600160a01b03831633148015614ee45750803410155b614f29576040805162461bcd60e51b81526020600482015260116024820152706d73672e76616c7565206973207a65726f60781b604482015290519081900360640190fd5b6001600160a01b0382163014614f71576040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015614f6f573d6000803e3d6000fd5b505b80341115614fb757336108fc614f8d348463ffffffff61539e16565b6040518115909202916000818181858888f19350505050158015614fb5573d6000803e3d6000fd5b505b611c90565b611c906001600160a01b03851684848463ffffffff6153e016565b604080516302d35a5960e01b815260008051602061577d8339815191526004820152734ddc2d193948926d02f9b1fe9e1daa0718270ed560248201526044810184905260008051602061579d83398151915260648201527339aa39c021dfbae8fac545936693ac917d5e7563608482015260a4810183905290516001600160a01b038516916302d35a5991859160c48082019260009290919082900301818588803b15801561508557600080fd5b505af1158015615099573d6000803e3d6000fd5b505050505060006150be7339aa39c021dfbae8fac545936693ac917d5e7563856115a3565b90506000811180156150df5750600f82820182606402816150db57fe5b0410155b611c9057600080fd5b6000670de0b6b3a7640000612d2d615100858561282d565b6002670de0b6b3a7640000612d27565b818161a4103a028211156151425761513d60008051602061577d833981519152868463ffffffff61470116565b615147565b600091505b6207a1208111156151765761517160008051602061579d833981519152868363ffffffff61470116565b61517a565b5060005b604080518381526020810183905281516001600160a01b038816927fdddff4ef7188926ed3a880dc4fb218d20fd267fa666fa7d76f7eb05e94f27e47928290030190a25050505050565b6001600160a01b03841660009081526005602052604081205481906001600160501b038082169160ff600160a81b8204811692600160a01b830490911691600160501b9004168460646152178186612c3e565b61522a6152248d89612c3e565b8c612c3e565b028161523257fe5b04905064e8d4a510006152556152488784613f05565b8a64e8d4a5100002612d0b565b8161525c57fe5b049550600064e8d4a5100061527187856150e8565b8161527857fe5b0490506000811161528857600080fd5b6152928782612c3e565b9750670de0b6b3a764000084026152a98983612d0b565b60640210156152b757600080fd5b50505050505094509492505050565b6000826152d557506001615396565b6001600160a01b038516158061530157506001600160a01b03851660008051602061577d833981519152145b15615378578115615338576040516001600160a01b0385169084156108fc029085906000818181858888f193505050509050615396565b6040516001600160a01b0385169084156108fc029085906000818181858888f1935050505015801561536e573d6000803e3d6000fd5b5060019050615396565b6153926001600160a01b038616858563ffffffff61543a16565b5060015b949350505050565b600061203883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061548c565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611c90908590615523565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611aad908490615523565b6000818484111561551b5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156154e05781810151838201526020016154c8565b50505050905090810190601f16801561550d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b615535826001600160a01b03166156db565b615586576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106155c45780518252601f1990920191602091820191016155a5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114615626576040519150601f19603f3d011682016040523d82523d6000602084013e61562b565b606091505b509150915081615682576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115611c905780806020019051602081101561569e57600080fd5b5051611c905760405162461bcd60e51b815260040180806020018281038252602a8152602001806157bd602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081158015906153965750141592915050565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081019190915290565b6040518060800160405280600490602082028038833950919291505056fe000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb485361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a72315820af507effa288a92fae8ba7d6314290832dfc80c36f591a14da6091af1c3413e264736f6c63430005110032

Deployed Bytecode

0x6080604052600436106102675760003560e01c806370eca0ec11610144578063bb09d9b7116100b6578063eb21d9c41161007a578063eb21d9c4146110cb578063ebbc49651461117b578063ee5f4afd14611190578063f3fef3a3146111a5578063f8806a13146111de578063f93f20d81461126457610267565b8063bb09d9b714610f5c578063c63f0dc114610f71578063d1e1ecba14610fd3578063e1ea330014611006578063e306f779146110b657610267565b806398fb83871161010857806398fb838714610d0f578063a6f9dae114610e61578063a734f06e14610e94578063ad9d4ba314610ea9578063ae5f8f7214610ecf578063b3c18b1614610f0257610267565b806370eca0ec14610bcd5780638a5e8cc714610cbb5780638af8d4c314610cd05780638da5cb5b14610ce557806394771d7614610cfa57610267565b806339ebf823116101dd57806359966b24116101a157806359966b24146108855780635f5008d1146109335780635f82c67e146109815780636568a2791461099657806366408eb014610a445780636caf516a14610a5957610267565b806339ebf82314610580578063416d4efb14610624578063429b62e5146106eb5780634ab45d331461071e5780635969490d1461073357610267565b80631ec18ec01161022f5780631ec18ec01461041357806325fda7881461046057806326976e3f146104755780632840e1b31461048a5780632bb083fc1461049f578063331934ec146104d257610267565b8063040141e5146102695780630900f0101461029a5780630ae538f1146102cd57806310e5ebc41461031a5780631d8319e414610353575b005b34801561027557600080fd5b5061027e611279565b604080516001600160a01b039092168252519081900360200190f35b3480156102a657600080fd5b50610267600480360360208110156102bd57600080fd5b50356001600160a01b0316611291565b3480156102d957600080fd5b50610306600480360360408110156102f057600080fd5b506001600160a01b038135169060200135611319565b604080519115158252519081900360200190f35b34801561032657600080fd5b506103066004803603604081101561033d57600080fd5b506001600160a01b038135169060200135611385565b6102676004803603608081101561036957600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b81111561039f57600080fd5b8201836020820111156103b157600080fd5b803590602001918460018302840111600160201b831117156103d257600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506113a5945050505050565b34801561041f57600080fd5b5061044e6004803603604081101561043657600080fd5b506001600160a01b03813581169160200135166115a3565b60408051918252519081900360200190f35b34801561046c57600080fd5b5061044e61170e565b34801561048157600080fd5b5061027e611714565b34801561049657600080fd5b5061027e611723565b3480156104ab57600080fd5b50610267600480360360208110156104c257600080fd5b50356001600160a01b0316611732565b3480156104de57600080fd5b50610267600480360360208110156104f557600080fd5b810190602081018135600160201b81111561050f57600080fd5b82018360208201111561052157600080fd5b803590602001918460208302840111600160201b8311171561054257600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506117ba945050505050565b34801561058c57600080fd5b506105b3600480360360208110156105a357600080fd5b50356001600160a01b0316611ab2565b604080516001600160501b039a8b168152988a1660208a015260ff978816898201529590961660608801529290961660808601526001600160401b031660a085015293151560c08401526001600160a01b0390931660e083015261ffff166101008201529051908190036101200190f35b610267600480360360a081101561063a57600080fd5b6001600160a01b0382351691602081013591604082013591606081013515159181019060a081016080820135600160201b81111561067757600080fd5b82018360208201111561068957600080fd5b803590602001918460018302840111600160201b831117156106aa57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611b31945050505050565b3480156106f757600080fd5b506103066004803603602081101561070e57600080fd5b50356001600160a01b0316611b8f565b34801561072a57600080fd5b5061027e611ba4565b34801561073f57600080fd5b50610267600480360360e081101561075657600080fd5b810190602081018135600160201b81111561077057600080fd5b82018360208201111561078257600080fd5b803590602001918460208302840111600160201b831117156107a357600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092958435956020860135956040810135955060608101351515945060808101351515935060c081019060a00135600160201b81111561081157600080fd5b82018360208201111561082357600080fd5b803590602001918460018302840111600160201b8311171561084457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611bbc945050505050565b34801561089157600080fd5b50610267600480360360208110156108a857600080fd5b810190602081018135600160201b8111156108c257600080fd5b8201836020820111156108d457600080fd5b803590602001918460208302840111600160201b831117156108f557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611bd0945050505050565b34801561093f57600080fd5b506102676004803603608081101561095657600080fd5b506001600160a01b03813581169160208101359091169060ff60408201358116916060013516611c63565b34801561098d57600080fd5b5061027e611c96565b3480156109a257600080fd5b50610267600480360360208110156109b957600080fd5b810190602081018135600160201b8111156109d357600080fd5b8201836020820111156109e557600080fd5b803590602001918460208302840111600160201b83111715610a0657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611cae945050505050565b348015610a5057600080fd5b5061027e611d64565b348015610a6557600080fd5b506102676004803603610160811015610a7d57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b811115610aa757600080fd5b820183602082011115610ab957600080fd5b803590602001918460018302840111600160201b83111715610ada57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051610100818101909252939695948181019493509150600890839083908082843760009201919091525091949392602081019250359050600160201b811115610b5957600080fd5b820183602082011115610b6b57600080fd5b803590602001918460018302840111600160201b83111715610b8c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611d7c945050505050565b348015610bd957600080fd5b506103066004803603610120811015610bf157600080fd5b6001600160a01b038235169190810190604081016020820135600160201b811115610c1b57600080fd5b820183602082011115610c2d57600080fd5b803590602001918460018302840111600160201b83111715610c4e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805160e08181019092529396959481810194935091506007908390839080828437600092019190915250919450611ed49350505050565b348015610cc757600080fd5b5061027e61203f565b348015610cdc57600080fd5b5061027e612057565b348015610cf157600080fd5b5061027e61206a565b348015610d0657600080fd5b5061027e612079565b348015610d1b57600080fd5b50610267600480360360e0811015610d3257600080fd5b810190602081018135600160201b811115610d4c57600080fd5b820183602082011115610d5e57600080fd5b803590602001918460208302840111600160201b83111715610d7f57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092958435956020860135956040810135955060608101351515945060808101351515935060c081019060a00135600160201b811115610ded57600080fd5b820183602082011115610dff57600080fd5b803590602001918460018302840111600160201b83111715610e2057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612088945050505050565b348015610e6d57600080fd5b5061026760048036036020811015610e8457600080fd5b50356001600160a01b0316612219565b348015610ea057600080fd5b5061027e61228e565b61026760048036036020811015610ebf57600080fd5b50356001600160a01b03166122a0565b348015610edb57600080fd5b5061030660048036036020811015610ef257600080fd5b50356001600160a01b031661239c565b348015610f0e57600080fd5b50610267600480360360c0811015610f2557600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff608082013581169160a00135166123b1565b348015610f6857600080fd5b5061027e6123dd565b348015610f7d57600080fd5b50610267600480360360e0811015610f9457600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff608082013581169160a08101359091169060c001356123ef565b348015610fdf57600080fd5b5061026760048036036020811015610ff657600080fd5b50356001600160a01b031661241a565b34801561101257600080fd5b506102676004803603604081101561102957600080fd5b810190602081018135600160201b81111561104357600080fd5b82018360208201111561105557600080fd5b803590602001918460208302840111600160201b8311171561107657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550505050351515905061248f565b3480156110c257600080fd5b5061044e612539565b3480156110d757600080fd5b50610267600480360360408110156110ee57600080fd5b810190602081018135600160201b81111561110857600080fd5b82018360208201111561111a57600080fd5b803590602001918460208302840111600160201b8311171561113b57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550505050351515905061253f565b34801561118757600080fd5b506102676125e9565b34801561119c57600080fd5b5061044e612660565b3480156111b157600080fd5b50610267600480360360408110156111c857600080fd5b506001600160a01b038135169060200135612666565b3480156111ea57600080fd5b506112116004803603602081101561120157600080fd5b50356001600160a01b0316612727565b604080516001600160a01b03909a168a5260208a0198909852888801969096526060880194909452608087019290925260a086015260c085015260e0840152151561010083015251908190036101200190f35b34801561127057600080fd5b5061044e6127ac565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6001546001600160a01b031633146112e4576040805162461bcd60e51b815260206004820152601160248201527014195c9b5a5cdcda5bdb8819195b9a5959607a1b604482015290519081900360640190fd5b6001600160a01b0381166112f757600080fd5b600880546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b03808316600090815260056020526040812060010154909133600160481b909204161461134c57600080fd5b506001600160a01b0382166000908152600b602090815260408083208484529091529020805460ff191660019081179091555b92915050565b600b60209081526000928352604080842090915290825290205460ff1681565b60005a90506113b2615712565b506001600160a01b0385811660009081526005602090815260409182902082516101208101845281546001600160501b038082168352600160501b8204811694830194909452600160a01b810460ff90811695830195909552600160a81b810485166060830152600160b01b90049092166080830152600101546001600160401b03811660a0830152600160401b8104909216151560c0820152600160481b820490921660e08301819052600160e81b90910461ffff1661010083015233148061148657506001546001600160a01b031633145b806114a057503360009081526003602052604090205460ff165b6114a957600080fd5b60408051633af9e66960e01b81526001600160a01b03881660048201529051600091734ddc2d193948926d02f9b1fe9e1daa0718270ed591633af9e6699160248082019260209290919082900301818787803b15801561150857600080fd5b505af115801561151c573d6000803e3d6000fd5b505050506040513d602081101561153257600080fd5b5051825161010084015191925060009160649161155e916001600160501b039091169061ffff1661282d565b8161156557fe5b04905080821061157457600080fd5b6115848888886000896000612851565b505050505061159b611596825a612c3e565b612c4e565b505050505050565b60408051635ec88c7960e01b81526001600160a01b038316600482015290516000918291733d9819210a31b4961b30ef54be2aed79b9c9cd3b91635ec88c79916024808301926060929190829003018186803b15801561160257600080fd5b505afa158015611616573d6000803e3d6000fd5b505050506040513d606081101561162c57600080fd5b506020015190506001600160a01b038416734ddc2d193948926d02f9b1fe9e1daa0718270ed5141561165f57905061137f565b6040805163fc57d4df60e01b81526001600160a01b03861660048201529051600091731d8aedc9e924730dd3f9641cdb4d1b92b848b4bd9163fc57d4df91602480820192602092909190829003018186803b1580156116bd57600080fd5b505afa1580156116d1573d6000803e3d6000fd5b505050506040513d60208110156116e757600080fd5b5051905060006116f78383612d0b565b9050611704816064612c3e565b9695505050505050565b600a5481565b6008546001600160a01b031681565b6007546001600160a01b031681565b6001546001600160a01b03163314611785576040805162461bcd60e51b815260206004820152601160248201527014195c9b5a5cdcda5bdb8819195b9a5959607a1b604482015290519081900360640190fd5b6001600160a01b03811661179857600080fd5b600680546001600160a01b0319166001600160a01b0392909216919091179055565b6008546001600160a01b0316806117d057600080fd5b60005b8251811015611aad576117e4615712565b600560008584815181106117f457fe5b6020908102919091018101516001600160a01b03908116835282820193909352604091820160002082516101208101845281546001600160501b038082168352600160501b8204811694830194909452600160a01b810460ff90811695830195909552600160a81b810485166060830152600160b01b90049092166080830152600101546001600160401b03811660a0830152600160401b8104909216151560c0820152600160481b820490921660e08301819052600160e81b90910461ffff1661010083015290915033146118c957600080fd5b60808101516001600160501b0316156118e157600080fd5b826001600160a01b031663c63f0dc18260e0015186858151811061190157fe5b60209081029190910181015185519186015160408088015160608901516101008a015183516001600160e01b031960e08b901b1681526001600160a01b0398891660048201529790951660248801526001600160501b03958616604488015294909216606486015260ff9182166084860152921660a484015261ffff1660c48301525160e480830192600092919082900301818387803b1580156119a457600080fd5b505af11580156119b8573d6000803e3d6000fd5b505050508382815181106119c857fe5b60200260200101516001600160a01b0316635b85a60a846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050600060405180830381600087803b158015611a2757600080fd5b505af1158015611a3b573d6000803e3d6000fd5b50505050611a5b848381518110611a4e57fe5b6020026020010151612d3c565b838281518110611a6757fe5b60200260200101516001600160a01b03167f7c9a2d2ec51230d7dbed27f113a325b7e20aef7b049e68b2339257b5edff5bea60405160405180910390a2506001016117d3565b505050565b600560205260009081526040902080546001909101546001600160501b0380831692600160501b810482169260ff600160a01b8304811693600160a81b8404821693600160b01b900416916001600160401b03811691600160401b820416906001600160a01b03600160481b8204169061ffff600160e81b9091041689565b60005a6001600160a01b03878116600090815260056020526040902060010154919250600160481b909104163314611b6857600080fd5b611b7786868686866001612851565b5050611b86611596825a612c3e565b50505050505050565b60036020526000908152604090205460ff1681565b734ddc2d193948926d02f9b1fe9e1daa0718270ed581565b611bcb87878787878787612088565b611b86875b60005a905060005b8251811015611c5557600060056000858481518110611bf357fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002054600160b01b90046001600160501b031611611c3157600080fd5b611c4d838281518110611c4057fe5b6020026020010151612eb6565b600101611bd8565b50611aad611596825a612c3e565b3360009081526004602052604090205460ff16611c7f57600080fd5b611c908484600080868660006132da565b50505050565b733d9819210a31b4961b30ef54be2aed79b9c9cd3b81565b6001546001600160a01b03163314611d01576040805162461bcd60e51b815260206004820152601160248201527014195c9b5a5cdcda5bdb8819195b9a5959607a1b604482015290519081900360640190fd5b60005b8151811015611d6057611d58828281518110611d1c57fe5b6020026020010151611d5330858581518110611d3457fe5b60200260200101516001600160a01b031661363f90919063ffffffff16565b612666565b600101611d04565b5050565b7339aa39c021dfbae8fac545936693ac917d5e756381565b60005a3360009081526003602052604090205490915060ff1680611daa57506001546001600160a01b031633145b611db357600080fd5b848484611e6983836040518060e0016040528085600060088110611dd357fe5b6020020151815260200185600160088110611dea57fe5b6020020151815260200185600260088110611e0157fe5b6020020151815260200185600360088110611e1857fe5b6020020151815260200185600460088110611e2f57fe5b6020020151815260200185600560088110611e4657fe5b6020020151815260200185600660088110611e5d57fe5b60200201519052611ed4565b611e7257600080fd5b6001600160a01b0383166000908152600b6020908152604080832060c08501518452825291829020805460ff191660011790558751908801519188015160e0890151611ec4938c939290918a9061370c565b50505061159b611596825a612c3e565b608081015160608201516000911015611eec57600080fd5b60a0820151421180611f2557506001600160a01b0384166000908152600b6020908152604080832060c0860151845290915290205460ff165b15611f3257506000612038565b606082015160408301511080611f4f575060808201516040830151115b15611f5c57506000612038565b6000611ff9856040518060c0016040528086600060078110611f7a57fe5b6020020151815260200186600160078110611f9157fe5b6020020151815260200186600360078110611fa857fe5b6020020151815260200186600460078110611fbf57fe5b6020020151815260200186600560078110611fd657fe5b6020020151815260200186600660078110611fed57fe5b60200201519052613c3e565b905061200b818563ffffffff613e1716565b6001600160a01b03868116600090815260056020526040902060010154600160481b900481169116149150505b9392505050565b731d8aedc9e924730dd3f9641cdb4d1b92b848b4bd81565b6eb3f879cb30fe243b4dfee438691c0481565b6001546001600160a01b031681565b6006546001600160a01b031681565b60005a3360009081526003602052604090205490915060ff16806120b657506001546001600160a01b031633145b6120bf57600080fd5b60006120d86120ce8989613f05565b87620f4240613f15565b64e8d4a510000290506120e961575e565b84156121895760065460408051631b2d298360e11b81526004810185905290516001600160a01b039092169163365a53069160248082019260009290919082900301818387803b15801561213c57600080fd5b505af1158015612150573d6000803e3d6000fd5b5050505061218660008051602061577d8339815191528360008051602061579d8339815191526121808d8d613f05565b88613f35565b90505b6000805b8b518110156121c1576121b58c82815181106121a557fe5b60200260200101518b8b8b614214565b9091019060010161218d565b50828110156121cf57600080fd5b60408201511515806121e45750606082015115155b156121fe57606082015160408301516121fe918d916144da565b50505061220e611596825a612c3e565b505050505050505050565b6001546001600160a01b0316331461226c576040805162461bcd60e51b815260206004820152601160248201527014195c9b5a5cdcda5bdb8819195b9a5959607a1b604482015290519081900360640190fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60008051602061577d83398151915281565b6001600160a01b0381166000908152600560205260409020546001600160501b03166122cb57600080fd5b6001600160a01b038116600081815260056020526040808220805469ffffffffffffffffffff198116346001600160501b0392831681019092161790915581516302d35a5960e01b815260008051602061577d8339815191526004820152734ddc2d193948926d02f9b1fe9e1daa0718270ed5602482015260448101829052606481018490526084810184905260a4810184905291519093926302d35a5992859260c4808301939282900301818588803b15801561238857600080fd5b505af1158015611b86573d6000803e3d6000fd5b60046020526000908152604090205460ff1681565b3360009081526004602052604090205460ff166123cd57600080fd5b61159b86868686868660006132da565b60008051602061579d83398151915281565b3360009081526004602052604090205460ff1661240b57600080fd5b611b86878787878787876132da565b6001546001600160a01b0316331461246d576040805162461bcd60e51b815260206004820152601160248201527014195c9b5a5cdcda5bdb8819195b9a5959607a1b604482015290519081900360640190fd5b600780546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146124e2576040805162461bcd60e51b815260206004820152601160248201527014195c9b5a5cdcda5bdb8819195b9a5959607a1b604482015290519081900360640190fd5b60005b8251811015611aad5781600460008584815181106124ff57fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff19169115159190911790556001016124e5565b60005481565b6001546001600160a01b03163314612592576040805162461bcd60e51b815260206004820152601160248201527014195c9b5a5cdcda5bdb8819195b9a5959607a1b604482015290519081900360640190fd5b60005b8251811015611aad5781600360008584815181106125af57fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055600101612595565b6002546001600160a01b0316331461263c576040805162461bcd60e51b815260206004820152601160248201527014195c9b5a5cdcda5bdb8819195b9a5959607a1b604482015290519081900360640190fd5b600254600180546001600160a01b0319166001600160a01b03909216919091179055565b60095481565b6001546001600160a01b031633146126b9576040805162461bcd60e51b815260206004820152601160248201527014195c9b5a5cdcda5bdb8819195b9a5959607a1b604482015290519081900360640190fd5b6001600160a01b038216612707576001546040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015612701573d6000803e3d6000fd5b50611d60565b600154611d60906001600160a01b0384811691168363ffffffff61470116565b6001600160a01b03908116600090815260056020526040902060018101549054600160481b8204909216926001600160501b038084169361ffff600160e81b85041693600160501b820483169360ff600160a01b8404811694600160a81b8504821694600160b01b900416926001600160401b03811692600160401b90910490911690565b604080516370a0823160e01b815230600482015290516000916eb3f879cb30fe243b4dfee438691c04916370a0823191602480820192602092909190829003018186803b1580156127fc57600080fd5b505afa158015612810573d6000803e3d6000fd5b505050506040513d602081101561282657600080fd5b5051919050565b60008115806128485750508082028282828161284557fe5b04145b61137f57600080fd5b60008061285c615712565b506001600160a01b0388811660009081526005602090815260409182902082516101208101845281546001600160501b03808216808452600160501b8304821695840195909552600160a01b820460ff90811696840196909652600160a81b820486166060840152600160b01b9091041660808201526001909101546001600160401b03811660a0830152600160401b8104909316151560c0820152600160481b830490931660e0840152600160e81b90910461ffff1661010083015215801590612932575060808101516001600160501b0316155b61293b57600080fd5b60408051633af9e66960e01b81526001600160a01b038b16600482015290516000916129cf91734ddc2d193948926d02f9b1fe9e1daa0718270ed591633af9e66991602480830192602092919082900301818887803b15801561299d57600080fd5b505af11580156129b1573d6000803e3d6000fd5b505050506040513d60208110156129c757600080fd5b50518a612c3e565b905084156129eb576129e382828a8a61470e565b909550935090505b888815612a1e576129fc8183613f05565b90508715612a1e57612a1b8184600001516001600160501b0316612c3e565b90505b600034821115612a9b57612a328234612c3e565b60065460408051631b2d298360e11b81526004810184905290519293506001600160a01b039091169163365a53069160248082019260009290919082900301818387803b158015612a8257600080fd5b505af1158015612a96573d6000803e3d6000fd5b505050505b612aa361575e565b612aaf8d848d8c6148ae565b905060008715612af35760006064612ace89896060015160ff1661282d565b81612ad557fe5b049050612aef81612aea8960e0015184614aab565b612c3e565b9150505b6000612aff8483613f05565b1115612b2457600654612b24906001600160a01b0316612b1f8584613f05565b614c3b565b8b15612b47578a15612b425785516001600160501b03169450612b47565b600094505b60e086015160608301516040840151612b6592918801908f01614c9b565b612b958660e00151600160008f11612b7e576001612b8d565b8d612b8a576002612b8d565b60035b60ff16614ce5565b612b9e8e612d3c565b3415612bd25760405133903480156108fc02916000818181858888f19350505050158015612bd0573d6000803e3d6000fd5b505b6001600160a01b038e167f53bb08c62ecc11fdb8b19d8f885288b800b5b6e28ed23f0587dd199872ae42ef8360036020020151870184600260200201518f01604051808381526020018281526020019250505060405180910390a2505050505050965096945050505050565b8082038281111561137f57600080fd5b600080612c596127ac565b905080612c6a576000915050612d06565b61a0aa61374a84010481811115612c7e5750805b6eb3f879cb30fe243b4dfee438691c046001600160a01b0316636366b936826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015612cd357600080fd5b505af1158015612ce7573d6000803e3d6000fd5b505050506040513d6020811015612cfd57600080fd5b50600193505050505b919050565b600081612d2d612d2385670de0b6b3a764000061282d565b6002855b04613f05565b81612d3457fe5b049392505050565b604080516101208101825260008082526020808301828152838501838152606085018481526080860185815260a0870186815260c0880187815260e089018881526101008a018981526001600160a01b039c8d168a5260059098529990972097518854955194519351925169ffffffffffffffffffff199096166001600160501b039182161769ffffffffffffffffffff60501b1916600160501b958216959095029490941760ff60a01b1916600160a01b60ff948516021760ff60a81b1916600160a81b9390921692909202176001600160b01b0316600160b01b9290931691909102919091178455516001909301805492519451915167ffffffffffffffff199093166001600160401b039094169390931760ff60401b1916600160401b94151594909402939093177fffffff0000000000000000000000000000000000000000ffffffffffffffffff16600160481b93909416929092029290921761ffff60e81b1916600160e81b61ffff90921691909102179055565b612ebe615712565b506001600160a01b03808216600081815260056020908152604080832081516101208101835281546001600160501b038082168352600160501b820481168387015260ff600160a01b8304811684870152600160a81b830481166060850152600160b01b9092041660808301526001909201546001600160401b03811660a0830152600160401b8104909216151560c0820152600160481b820490961660e087015261ffff600160e81b909104166101008601528051633af9e66960e01b81526004810194909452519192734ddc2d193948926d02f9b1fe9e1daa0718270ed592633af9e6699260248084019391929182900301818787803b158015612fc357600080fd5b505af1158015612fd7573d6000803e3d6000fd5b505050506040513d6020811015612fed57600080fd5b50516040805163095ea7b360e01b81526001600160a01b03861660048201526000196024820152905191925060008051602061579d8339815191529163095ea7b39160448082019260009290919082900301818387803b15801561305057600080fd5b505af1158015613064573d6000803e3d6000fd5b5050604080516335d0353d60e21b815260008051602061577d8339815191526004820152734ddc2d193948926d02f9b1fe9e1daa0718270ed5602482015260008051602061579d83398151915260448201527339aa39c021dfbae8fac545936693ac917d5e7563606482015290516001600160a01b038716935063d740d4f49250608480830192600092919082900301818387803b15801561310557600080fd5b505af1158015613119573d6000803e3d6000fd5b5050505060006064836060015160ff166131566131438587600001516001600160501b0316612c3e565b86608001516001600160501b0316612c3e565b028161315e57fe5b04905060006131718460e0015183614aab565b60a08501519091506001600160401b0316600081156131cb5760e08601516131af9060008051602061579d833981519152908463ffffffff61470116565b8560c00151156131c6575084516001600160501b03165b613202565b60006131e5888789608001516001600160501b0316614e02565b90506131fe87600001516001600160501b031682613f05565b9150505b801561322d5760e086015161322d9060008051602061577d833981519152908363ffffffff61470116565b600061324261323c8784612c3e565b85612c3e565b60065490915061325b906001600160a01b031682614c3b565b6132848760e00151600160008611613274576001612b8d565b8960c00151612b8a576002612b8d565b61328d88612d3c565b604080518381526020810185905281516001600160a01b038b16927f53bb08c62ecc11fdb8b19d8f885288b800b5b6e28ed23f0587dd199872ae42ef928290030190a25050505050505050565b6001600160a01b03868116600090815260056020526040902060010154600160481b9004161561330957600080fd5b80801580156133185750600086115b156133bb5760408051633af9e66960e01b81526001600160a01b03891660048201529051600091734ddc2d193948926d02f9b1fe9e1daa0718270ed591633af9e6699160248082019260209290919082900301818787803b15801561337c57600080fd5b505af1158015613390573d6000803e3d6000fd5b505050506040513d60208110156133a657600080fd5b505190508660648202816133b657fe5b049150505b604051806101200160405280876001600160501b03168152602001866001600160501b031681526020018560ff1681526020018460ff16815260200160006001600160501b0316815260200160006001600160401b03168152602001600015158152602001896001600160a01b031681526020018261ffff1681525060056000896001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a8154816001600160501b0302191690836001600160501b03160217905550602082015181600001600a6101000a8154816001600160501b0302191690836001600160501b0316021790555060408201518160000160146101000a81548160ff021916908360ff16021790555060608201518160000160156101000a81548160ff021916908360ff16021790555060808201518160000160166101000a8154816001600160501b0302191690836001600160501b0316021790555060a08201518160010160006101000a8154816001600160401b0302191690836001600160401b0316021790555060c08201518160010160086101000a81548160ff02191690831515021790555060e08201518160010160096101000a8154816001600160a01b0302191690836001600160a01b0316021790555061010082015181600101601d6101000a81548161ffff021916908361ffff160217905550905050866001600160a01b0316886001600160a01b03167fc505104967ca2886d648964d4dfffad3cd217df1ce0b3d286cf67543d035187888888888604051808581526020018481526020018360ff1660ff1681526020018260ff1660ff16815260200194505050505060405180910390a35050505050505050565b60006001600160a01b038316158061366d57506001600160a01b03831660008051602061577d833981519152145b1561368357506001600160a01b0381163161137f565b826001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156136d957600080fd5b505afa1580156136ed573d6000803e3d6000fd5b505050506040513d602081101561370357600080fd5b5051905061137f565b613714615712565b506001600160a01b0386811660009081526005602090815260409182902082516101208101845281546001600160501b038082168352600160501b8204811694830194909452600160a01b810460ff90811695830195909552600160a81b810485166060830152600160b01b90049092166080830152600101546001600160401b03811660a0830152600160401b8104909216151560c0820152600160481b820490921660e08301819052600160e81b90910461ffff16610100830152158015906137ea575060808101516001600160501b0316155b6137f357600080fd5b60968610158015613806575061012c8611155b61384d576040805162461bcd60e51b8152602060048201526013602482015272125b9d985b1a590818dbd959999a58da595b9d606a1b604482015290519081900360640190fd5b60e08101516138739060008051602061579d83398151915290308863ffffffff614e9116565b6064606319870186020460006138898783613f05565b9050600061389e8264e8d4a510000288612d0b565b60065460408051631b2d298360e11b81526004810184905290519293506001600160a01b039091169163365a53069160248082019260009290919082900301818387803b1580156138ee57600080fd5b505af1158015613902573d6000803e3d6000fd5b505050506139118a8285614fd7565b61391961575e565b61396360008051602061579d8339815191528488156139465760008051602061577d83398151915261395c565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25b858b613f35565b905085613a4657604080516370a0823160e01b8152306004820152905173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291632e1a7d4d9183916370a08231916024808301926020929190829003018186803b1580156139c357600080fd5b505afa1580156139d7573d6000803e3d6000fd5b505050506040513d60208110156139ed57600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b158015613a2d57600080fd5b505af1158015613a41573d6000803e3d6000fd5b505050505b6000613a598a64e8d4a51000028a612d0b565b90506000613a7487600001516001600160501b031683613f05565b6001600160a01b038e166000908152600560209081526040909120805469ffffffffffffffffffff19166001600160501b03848116919091179091558951918a0151929350613ae492613ade92613acf9290811691166150e8565b613ad9858e6150e8565b613f05565b82612d0b565b6001600160a01b038e16600081815260056020908152604080832080546001600160501b0396909616600160501b0269ffffffffffffffffffff60501b19909616959095179094558351633af9e66960e01b8152600481019390935292518493734ddc2d193948926d02f9b1fe9e1daa0718270ed593633af9e66993602480830194928390030190829087803b158015613b7d57600080fd5b505af1158015613b91573d6000803e3d6000fd5b505050506040513d6020811015613ba757600080fd5b505160640281613bb357fe5b04600560008f6001600160a01b03166001600160a01b03168152602001908152602001600020600101601d6101000a81548161ffff021916908361ffff160217905550613c15600660009054906101000a90046001600160a01b031685614c3b565b60e087015160408401516060850151613c2f929190615110565b50505050505050505050505050565b6040805173092dcc6e4cac2e6caa6e8e4c2e8cacef2aae6c8560631b602080830191909152701859191c995cdcc8191995d85b1b195d0b607a1b6034830152731d5a5b9d0c8d4d8818dbd959999a58da595b9d0b60621b6045830152711d5a5b9d0c8d4d881d985b1d59555cd918cb60721b60598301527f75696e74323536206d696e456e74727945746850726963652c00000000000000606b8301527f75696e74323536206d6178456e74727945746850726963652c000000000000006084830152721d5a5b9d0c8d4d88195e1c1a5c99551a5b594b606a1b609d830152711d5a5b9d0c8d4d881cda59db939bdb98d94b60721b60b0830152602960f81b60c2830152825160a381840301815260c3830184528051908201208451858301518686015160608089015160808a015160a0909a015160e389019690965299901b6bffffffffffffffffffffffff19166101038701526101178601929092526101378501526101578401526101778301959095526101978201939093526101b780820194909452815180820390940184526101d78101825283519383019390932060005461190160f01b6101f78601526101f985015261021980850191909152815180850390910181526102399093019052815191012090565b60008151604114613e2a5750600061137f565b60208201516040830151606084015160001a7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115613e70576000935050505061137f565b8060ff16601b14158015613e8857508060ff16601c14155b15613e99576000935050505061137f565b6040805160008152602080820180845289905260ff8416828401526060820186905260808201859052915160019260a0808401939192601f1981019281900390910190855afa158015613ef0573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b8082018281101561137f57600080fd5b600081613f25612d23868661282d565b81613f2c57fe5b04949350505050565b613f3d61575e565b7311111254369792b2ca5d084ab5eea397ca8fa48b60006001600160a01b03881660008051602061577d8339815191521461414957600019886001600160a01b031663dd62ed3e30856001600160a01b031663e8edc8166040518163ffffffff1660e01b815260040160206040518083038186803b158015613fbe57600080fd5b505afa158015613fd2573d6000803e3d6000fd5b505050506040513d6020811015613fe857600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b039384166004820152929091166024830152516044808301926020929190829003018186803b15801561403857600080fd5b505afa15801561404c573d6000803e3d6000fd5b505050506040513d602081101561406257600080fd5b50511461414457876001600160a01b031663095ea7b3836001600160a01b031663e8edc8166040518163ffffffff1660e01b815260040160206040518083038186803b1580156140b157600080fd5b505afa1580156140c5573d6000803e3d6000fd5b505050506040513d60208110156140db57600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b039092166004830152600019602483015251604480830192600092919082900301818387803b15801561412b57600080fd5b505af115801561413f573d6000803e3d6000fd5b505050505b61414c565b50855b60006141676001600160a01b038a163063ffffffff61363f16565b905060006141846001600160a01b0389163063ffffffff61363f16565b9050600060206000885160208a0187896113885a03f150506000516141c16141bb6001600160a01b038b163063ffffffff61363f16565b83612c3e565b86526141da83612aea6001600160a01b038e163061363f565b602087015285516141eb9089612c3e565b60408701526020860151614200908b90612c3e565b606087015250939998505050505050505050565b6001600160a01b03841660009081526005602052604081208054600160b01b90046001600160501b0316158015614254575080546001600160501b031615155b61425d57600080fd5b60408051633af9e66960e01b81526001600160a01b03881660048201529051600091734ddc2d193948926d02f9b1fe9e1daa0718270ed591633af9e6699160248082019260209290919082900301818787803b1580156142bc57600080fd5b505af11580156142d0573d6000803e3d6000fd5b505050506040513d60208110156142e657600080fd5b5051604080516395dd919360e01b81526001600160a01b038a1660048201529051919250600091614383917339aa39c021dfbae8fac545936693ac917d5e7563916395dd919391602480820192602092909190829003018186803b15801561434d57600080fd5b505afa158015614361573d6000803e3d6000fd5b505050506040513d602081101561437757600080fd5b505187620f4240613f15565b64e8d4a51000029050600080881561440d5760006143a38b86868c6151c4565b95975087959350905087156143e95760018601805460ff60401b1916600160401b8a15150217905585549092506001600160501b03169050816143e68583612c3e565b96505b5060018501805467ffffffffffffffff19166001600160401b038416179055614439565b600061441a8b8686614e02565b8654909150614432906001600160501b031682613f05565b9150839650505b84546001600160b01b0316600160b01b6001600160501b03851602178555600185015461448a90600160481b90046001600160a01b031660008b61447e576001612b8d565b89612b8a576002612b8d565b604080518281526020810184905281516001600160a01b038d16927f253535bb9d23118941521a3ebcf52effeeed74d6716b9a2c2e33fee2329988dd928290030190a25050505050949350505050565b60608351604051908082528060200260200182016040528015614507578160200160208202803883390190505b5090506000805b8551811015614596576005600087838151811061452757fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205483516001600160501b039091169084908390811061456557fe5b60200260200101818152505082818151811061457d57fe5b602002602001015182019150808060010191505061450e565b5060005b855181101561159b5760006145c28483815181106145b457fe5b602002602001015184612d0b565b905085156146875760006145d682886150e8565b905080600560008a86815181106145e957fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002054600160b01b90046001600160501b031611156146855780600560008a868151811061463457fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002080546001600160501b03600160b01b808304821694909403169092026001600160b01b039092169190911790555b505b84156146f857600061469982876150e8565b905080600560008a86815181106146ac57fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020600101805467ffffffffffffffff1981166001600160401b039182169390930116919091179055505b5060010161459a565b611c9083838360006152c6565b8351839060009081906001600160501b031683111561482c5761473e8388600001516001600160501b0316612c3e565b905084156147e457831561479657866040015160ff1660640261477b88600001516001600160501b031689602001516001600160501b03166150e8565b662386f26fc1000087028161478c57fe5b04101591506147df565b866040015160ff166064016064026147c888600001516001600160501b031689602001516001600160501b03166150e8565b662386f26fc100008702816147d957fe5b04101591505b61482c565b866040015160ff1660640287600001516001600160501b0316606461481160648b6060015160ff16612c3e565b84028161481a57fe5b04612710028161482657fe5b04101591505b811561487857600061486288600001516001600160501b0316606461485960648c6060015160ff16612c3e565b850281612d2757fe5b90508084101561487157600080fd5b92506148a4565b600a544210156148a4576148a18360646148948660095461282d565b8161489b57fe5b04612c3e565b92505b9450945094915050565b6148b661575e565b604080516395dd919360e01b81526001600160a01b038716600482015290516000917339aa39c021dfbae8fac545936693ac917d5e7563916395dd919391602480820192602092909190829003018186803b15801561491457600080fd5b505afa158015614928573d6000803e3d6000fd5b505050506040513d602081101561493e57600080fd5b5051905061497460008051602061577d8339815191528660008051602061579d83398151915261496e8589613f05565b87613f35565b6040805163095ea7b360e01b81526001600160a01b03891660048201526000196024820152905191935060008051602061579d8339815191529163095ea7b39160448082019260009290919082900301818387803b1580156149d557600080fd5b505af11580156149e9573d6000803e3d6000fd5b5050604080516335d0353d60e21b815260008051602061577d8339815191526004820152734ddc2d193948926d02f9b1fe9e1daa0718270ed5602482015260008051602061579d83398151915260448201527339aa39c021dfbae8fac545936693ac917d5e7563606482015290516001600160a01b038a16935063d740d4f49250608480830192600092919082900301818387803b158015614a8a57600080fd5b505af1158015614a9e573d6000803e3d6000fd5b5050505050949350505050565b6007546000906001600160a01b031615614c02576007546040805163b1a1c1cf60e01b81526001600160a01b0386811660048301529151606493929092169163b1a1c1cf91602480820192602092909190829003018186803b158015614b1057600080fd5b505afa158015614b24573d6000803e3d6000fd5b505050506040513d6020811015614b3a57600080fd5b505160ff16830281614b4857fe5b049050818110614b5757600080fd5b60075460408051635345cb2960e11b81526001600160a01b0386811660048301529151919092169163a68b965291849160248082019260009290919082900301818588803b158015614ba857600080fd5b505af1158015614bbc573d6000803e3d6000fd5b50505050507f4959927089ff30362dfc0e79000c912fc2c9cc4ec9d5c1b1e0482fa7c4cea118614bec8383612c3e565b60408051918252519081900360200190a161137f565b6040805183815290517f4959927089ff30362dfc0e79000c912fc2c9cc4ec9d5c1b1e0482fa7c4cea1189181900360200190a192915050565b60405182906000906001600160a01b0383169084908381818185875af1925050503d8060008114614c88576040519150601f19603f3d011682016040523d82523d6000602084013e614c8d565b606091505b5050905080611c9057600080fd5b8115614cc057614cc060008051602061577d833981519152848463ffffffff61470116565b8015611aad57611aad60008051602061579d833981519152848363ffffffff61470116565b604080518315156024820152604480820184905282518083039091018152606490910182526020810180516001600160e01b031663163d5ccb60e11b1781529151815191926000926060926001600160a01b0389169286928291908083835b60208310614d635780518252601f199092019160209182019101614d44565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114614dc5576040519150601f19603f3d011682016040523d82523d6000602084013e614dca565b606091505b5091509150818015614ddd575060008151115b1561159b57808060200190516020811015614df757600080fd5b505161159b57600080fd5b6001600160a01b0383166000908152600560205260408120546001600160501b0381169060ff600160a81b8204811691600160a01b9004166064614e468184612c3e565b614e59614e538987612c3e565b88612c3e565b0281614e6157fe5b049350670de0b6b3a76400008102614e798585612d0b565b6064021015614e8757600080fd5b5050509392505050565b80614e9b57611c90565b6001600160a01b0384161580614ec757506001600160a01b03841660008051602061577d833981519152145b15614fbc576001600160a01b03831633148015614ee45750803410155b614f29576040805162461bcd60e51b81526020600482015260116024820152706d73672e76616c7565206973207a65726f60781b604482015290519081900360640190fd5b6001600160a01b0382163014614f71576040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015614f6f573d6000803e3d6000fd5b505b80341115614fb757336108fc614f8d348463ffffffff61539e16565b6040518115909202916000818181858888f19350505050158015614fb5573d6000803e3d6000fd5b505b611c90565b611c906001600160a01b03851684848463ffffffff6153e016565b604080516302d35a5960e01b815260008051602061577d8339815191526004820152734ddc2d193948926d02f9b1fe9e1daa0718270ed560248201526044810184905260008051602061579d83398151915260648201527339aa39c021dfbae8fac545936693ac917d5e7563608482015260a4810183905290516001600160a01b038516916302d35a5991859160c48082019260009290919082900301818588803b15801561508557600080fd5b505af1158015615099573d6000803e3d6000fd5b505050505060006150be7339aa39c021dfbae8fac545936693ac917d5e7563856115a3565b90506000811180156150df5750600f82820182606402816150db57fe5b0410155b611c9057600080fd5b6000670de0b6b3a7640000612d2d615100858561282d565b6002670de0b6b3a7640000612d27565b818161a4103a028211156151425761513d60008051602061577d833981519152868463ffffffff61470116565b615147565b600091505b6207a1208111156151765761517160008051602061579d833981519152868363ffffffff61470116565b61517a565b5060005b604080518381526020810183905281516001600160a01b038816927fdddff4ef7188926ed3a880dc4fb218d20fd267fa666fa7d76f7eb05e94f27e47928290030190a25050505050565b6001600160a01b03841660009081526005602052604081205481906001600160501b038082169160ff600160a81b8204811692600160a01b830490911691600160501b9004168460646152178186612c3e565b61522a6152248d89612c3e565b8c612c3e565b028161523257fe5b04905064e8d4a510006152556152488784613f05565b8a64e8d4a5100002612d0b565b8161525c57fe5b049550600064e8d4a5100061527187856150e8565b8161527857fe5b0490506000811161528857600080fd5b6152928782612c3e565b9750670de0b6b3a764000084026152a98983612d0b565b60640210156152b757600080fd5b50505050505094509492505050565b6000826152d557506001615396565b6001600160a01b038516158061530157506001600160a01b03851660008051602061577d833981519152145b15615378578115615338576040516001600160a01b0385169084156108fc029085906000818181858888f193505050509050615396565b6040516001600160a01b0385169084156108fc029085906000818181858888f1935050505015801561536e573d6000803e3d6000fd5b5060019050615396565b6153926001600160a01b038616858563ffffffff61543a16565b5060015b949350505050565b600061203883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061548c565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611c90908590615523565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611aad908490615523565b6000818484111561551b5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156154e05781810151838201526020016154c8565b50505050905090810190601f16801561550d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b615535826001600160a01b03166156db565b615586576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106155c45780518252601f1990920191602091820191016155a5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114615626576040519150601f19603f3d011682016040523d82523d6000602084013e61562b565b606091505b509150915081615682576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115611c905780806020019051602081101561569e57600080fd5b5051611c905760405162461bcd60e51b815260040180806020018281038252602a8152602001806157bd602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081158015906153965750141592915050565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081019190915290565b6040518060800160405280600490602082028038833950919291505056fe000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb485361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a72315820af507effa288a92fae8ba7d6314290832dfc80c36f591a14da6091af1c3413e264736f6c63430005110032

Deployed Bytecode Sourcemap

32239:39132: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;;;;;;;;;;;;;;48730:180;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48730:180:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;48730:180:0;-1:-1:-1;;;;;48730:180:0;;:::i;47462:223::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;47462:223:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;47462:223:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;33687:64;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33687:64:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;33687:64:0;;;;;;;;:::i;46669:785::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;46669:785:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;46669:785:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;46669:785: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;46669:785:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;46669:785:0;;-1:-1:-1;46669:785:0;;-1:-1:-1;;;;;46669:785:0:i;37238:536::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37238:536:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;37238:536:0;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;33580:28;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33580:28:0;;;:::i;33420:38::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33420:38:0;;;:::i;33383:28::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33383:28:0;;;:::i;47730:150::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;47730:150:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;47730:150:0;-1:-1:-1;;;;;47730:150:0;;:::i;44735:1040::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;44735:1040:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;44735:1040:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;44735:1040:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;44735:1040: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;44735:1040:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;44735:1040:0;;-1:-1:-1;44735:1040:0;;-1:-1:-1;;;;;44735:1040:0:i;33270:46::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33270:46:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;33270:46:0;-1:-1:-1;;;;;33270:46:0;;:::i;:::-;;;;-1:-1:-1;;;;;33270:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33270:46:0;;;;;;;;;;;;-1:-1:-1;;;;;33270:46:0;;;;;;;;;;;;;;;;;;;;;;;46197:436;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;46197:436:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;46197:436:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;46197:436: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;46197:436:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;46197:436:0;;-1:-1:-1;46197:436:0;;-1:-1:-1;;;;;46197:436:0:i;33168:38::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33168:38:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;33168:38:0;-1:-1:-1;;;;;33168:38:0;;:::i;19924:81::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;19924:81:0;;;:::i;43343:706::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;43343:706:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;43343:706:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;43343:706:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;43343: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;43343:706:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;43343:706:0;;;;;;;;;;;;;;;-1:-1:-1;43343:706:0;;;;;;;-1:-1:-1;43343:706:0;;;;;;;-1:-1:-1;43343:706:0;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;43343:706:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;43343: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;43343:706:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;43343:706:0;;-1:-1:-1;43343:706:0;;-1:-1:-1;;;;;43343:706:0:i;44423:304::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;44423:304:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;44423:304:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;44423:304:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;44423:304: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;44423:304:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;44423:304:0;;-1:-1:-1;44423:304:0;;-1:-1:-1;;;;;44423:304:0:i;40330:225::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40330:225:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;40330:225: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;40609:810::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40609:810:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;40609:810:0;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;40609:810:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;40609:810: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;40609:810:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;;40609:810:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;40609:810:0;-1:-1:-1;40609:810:0;;;;;;;;;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;40609:810:0;;;;;;;;-1:-1:-1;40609:810:0;;-1:-1:-1;;;;5:28;;2:2;;;46:1;43;36:12;2:2;40609:810:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;40609:810: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;40609:810:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;40609:810:0;;-1:-1:-1;40609:810:0;;-1:-1:-1;;;;;40609:810:0:i;37782:1331::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37782:1331:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;37782:1331:0;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;37782:1331:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;37782:1331: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;37782:1331:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;;37782:1331:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;37782:1331:0;-1:-1:-1;37782:1331:0;;;;;;;;;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;37782:1331:0;;-1:-1:-1;37782:1331:0;;-1:-1:-1;;;;37782:1331: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;33351:25::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33351:25:0;;;:::i;41455:1852::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41455:1852:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;41455:1852:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;41455:1852:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;41455:1852: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;41455:1852:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;41455:1852:0;;;;;;;;;;;;;;;-1:-1:-1;41455:1852:0;;;;;;;-1:-1:-1;41455:1852:0;;;;;;;-1:-1:-1;41455:1852:0;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;41455:1852:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;41455:1852: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;41455:1852:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;41455:1852:0;;-1:-1:-1;41455:1852:0;;-1:-1:-1;;;;;41455:1852: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;45783:378::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;45783:378:0;-1:-1:-1;;;;;45783:378:0;;:::i;33213:48::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33213:48:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;33213:48:0;-1:-1:-1;;;;;33213:48:0;;:::i;39544:277::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39544:277:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;39544:277:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;20014:81::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20014:81:0;;;:::i;39915:360::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39915:360:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;39915:360:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;48620:102::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48620:102:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;48620:102:0;-1:-1:-1;;;;;48620:102:0;;:::i;48388:224::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48388:224:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;48388:224:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;48388:224:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;48388: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;48388:224:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;48388:224:0;;-1:-1:-1;;;;48388:224:0;;;;-1:-1:-1;48388:224:0;:::i;25403:33::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25403:33:0;;;:::i;48023:200::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48023:200:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;48023:200:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;48023:200:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;48023: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;48023:200:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;48023:200:0;;-1:-1:-1;;;;48023:200:0;;;;-1:-1:-1;48023:200:0;:::i;430:146::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;430:146:0;;;:::i;33521:28::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33521: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;35939:831::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;35939:831:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;35939:831:0;-1:-1:-1;;;;;35939:831:0;;:::i;:::-;;;;-1:-1:-1;;;;;35939:831:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16659:132;;8:9:-1;5:2;;;30:1;27;20:12;5:2;16659:132:0;;;:::i;20193:81::-;20232:42;20193:81;:::o;48730:180::-;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;;;;;48809:30:0;;48801:39;;;;;;48851:15;:51;;-1:-1:-1;;;;;;48851:51:0;-1:-1:-1;;;;;48851:51:0;;;;;;;;;;48730:180::o;47462:223::-;-1:-1:-1;;;;;47572:21:0;;;47533:4;47572:21;;;:10;:21;;;;;:27;;;47533:4;;47558:10;-1:-1:-1;;;47572:27:0;;;;47558:41;47550:50;;;;;;-1:-1:-1;;;;;;47613:23:0;;;;;;:12;:23;;;;;;;;:35;;;;;;;;:42;;-1:-1:-1;;47613:42:0;47651:4;47613:42;;;;;;47462:223;;;;;:::o;33687:64::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;46669:785::-;34598:16;34617:9;34598:28;;46881:24;;:::i;:::-;-1:-1:-1;;;;;;46908:21:0;;;;;;;:10;:21;;;;;;;;;46881:48;;;;;;;;;-1:-1:-1;;;;;46881:48:0;;;;;-1:-1:-1;;;46881:48:0;;;;;;;;;;;-1:-1:-1;;;46881:48:0;;;;;;;;;;;;;-1:-1:-1;;;46881:48:0;;;;;;;;-1:-1:-1;;;46881:48:0;;;;;;;;;;;;-1:-1:-1;;;;;46881:48:0;;;;;;-1:-1:-1;;;46881:48:0;;;;;;;;;;;-1:-1:-1;;;46881:48:0;;;;;;;;;;;-1:-1:-1;;;46881:48:0;;;;;;;;;47021:10;:28;;:64;;-1:-1:-1;47080:5:0;;-1:-1:-1;;;;;47080:5:0;47066:10;:19;47021:64;:99;;;-1:-1:-1;47109:10:0;47102:18;;;;:6;:18;;;;;;;;47021:99;46999:122;;;;;;47151:52;;;-1:-1:-1;;;47151:52:0;;-1:-1:-1;;;;;47151:52:0;;;;;;;;47134:14;;19963:42;;47151:41;;:52;;;;;;;;;;;;;;;47134:14;19963:42;47151:52;;;5:2:-1;;;;30:1;27;20:12;5:2;47151:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;47151:52:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;47151:52:0;47236:16;;47254:18;;;;47151:52;;-1:-1:-1;47214:15:0;;47276:3;;47232:41;;-1:-1:-1;;;;;47232:41:0;;;;;;:3;:41::i;:::-;:47;;;;;;47214:65;;47312:10;47300:9;:22;47292:31;;;;;;47336:110;47373:9;47384:13;47399;47414:5;47421:7;47430:5;47336:22;:110::i;:::-;;;34637:1;;;34649:42;34663:27;34667:11;34680:9;34663:3;:27::i;:::-;34649:13;:42::i;:::-;;46669:785;;;;;:::o;37238:536::-;37366:54;;;-1:-1:-1;;;37366:54:0;;-1:-1:-1;;;;;37366:54:0;;;;;;;;37321:4;;;;19695:42;;37366:45;;:54;;;;;;;;;;;;;;19695:42;37366:54;;;5:2:-1;;;;30:1;27;20:12;5:2;37366:54:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;37366:54:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;37366:54:0;;;;-1:-1:-1;;;;;;37437:29:0;;19963:42;37437:29;37433:83;;;37490:14;-1:-1:-1;37483:21:0;;37433:83;37544:66;;;-1:-1:-1;;;37544:66:0;;-1:-1:-1;;;;;37544:66:0;;;;;;;;37528:13;;19786:42;;37544:51;;:66;;;;;;;;;;;;;;;19786:42;37544:66;;;5:2:-1;;;;30:1;27;20:12;5:2;37544:66:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;37544:66:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;37544:66:0;;-1:-1:-1;37621:21:0;37645:30;37650:14;37544:66;37645:4;:30::i;:::-;37621:54;;37695:26;37699:16;37717:3;37695;:26::i;:::-;37688:33;37238:536;-1:-1:-1;;;;;;37238:536:0:o;33580:28::-;;;;:::o;33420:38::-;;;-1:-1:-1;;;;;33420:38:0;;:::o;33383:28::-;;;-1:-1:-1;;;;;33383:28:0;;:::o;47730:150::-;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;;;;;47806:23:0;;47798:32;;;;;;47841:8;:31;;-1:-1:-1;;;;;;47841:31:0;-1:-1:-1;;;;;47841:31:0;;;;;;;;;;47730:150::o;44735:1040::-;44844:15;;-1:-1:-1;;;;;44844:15:0;44878:38;44870:47;;;;;;44934:6;44930:838;44950:10;:17;44946:1;:21;44930:838;;;44989:24;;:::i;:::-;45016:10;:25;45027:10;45038:1;45027:13;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;45016:25:0;;;;;;;;;;;;;;;;-1:-1:-1;45016:25:0;44989:52;;;;;;;;;-1:-1:-1;;;;;44989:52:0;;;;;-1:-1:-1;;;44989:52:0;;;;;;;;;;;-1:-1:-1;;;44989:52:0;;;;;;;;;;;;;-1:-1:-1;;;44989:52:0;;;;;;;;-1:-1:-1;;;44989:52:0;;;;;;;;;;;;-1:-1:-1;;;;;44989:52:0;;;;;;-1:-1:-1;;;44989:52:0;;;;;;;;;;;-1:-1:-1;;;44989:52:0;;;;;;;;;;;-1:-1:-1;;;44989:52:0;;;;;;;;;;;-1:-1:-1;45082:10:0;45064:28;45056:37;;;;;;45116:21;;;;-1:-1:-1;;;;;45116:26:0;;45108:35;;;;;;45160:16;-1:-1:-1;;;;;45160:30:0;;45209:8;:14;;;45242:10;45253:1;45242:13;;;;;;;;;;;;;;;;;;;45274:16;;45309:22;;;;45350;;;;;45391:12;;;;45422:18;;;;45160:295;;-1:-1:-1;;;;;;45160:295:0;;;;;;;-1:-1:-1;;;;;45160:295:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;45160:295:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45274:16;;45160:295;;;;;;;45274:16;45160:295;;;;5:2:-1;;;;30:1;27;20:12;5:2;45160:295:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;45160:295:0;;;;45546:10;45557:1;45546:13;;;;;;;;;;;;;;-1:-1:-1;;;;;45536:42:0;;45587:16;45536:69;;;;;;;;;;;;;-1:-1:-1;;;;;45536:69:0;-1:-1:-1;;;;;45536:69:0;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;45536:69:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;45536:69:0;;;;45674:29;45689:10;45700:1;45689:13;;;;;;;;;;;;;;45674:14;:29::i;:::-;45742:10;45753:1;45742:13;;;;;;;;;;;;;;-1:-1:-1;;;;;45725:31:0;;;;;;;;;;;-1:-1:-1;44969:3:0;;44930:838;;;;44735:1040;;:::o;33270:46::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33270:46:0;;;;-1:-1:-1;;;33270:46:0;;;;;;-1:-1:-1;;;33270:46:0;;;;;-1:-1:-1;;;33270:46:0;;;;;-1:-1:-1;;;33270:46:0;;;;-1:-1:-1;;;;;33270:46:0;;;-1:-1:-1;;;33270:46:0;;;;-1:-1:-1;;;;;;;;33270:46:0;;;;;-1:-1:-1;;;33270:46:0;;;;;:::o;46197:436::-;34598:16;34617:9;-1:-1:-1;;;;;46450:21:0;;;;;;;:10;:21;;;;;:27;;;34598:28;;-1:-1:-1;;;;46450:27:0;;;;46481:10;46450:41;46442:50;;;;;;46505:120;46542:9;46553:13;46568;46583:16;46601:7;46610:4;46505:22;:120::i;:::-;;;34649:42;34663:27;34667:11;34680:9;34663:3;:27::i;34649:42::-;;46197:436;;;;;;:::o;33168:38::-;;;;;;;;;;;;;;;:::o;19924:81::-;19963:42;19924:81;:::o;43343:706::-;43738:226;43776:10;43801:18;43834:15;43864:9;43888:16;43919:12;43946:7;43738:23;:226::i;:::-;44014:27;44030:10;44423:304;34598:16;34617:9;34598:28;-1:-1:-1;44512:6:0;44507:213;44528:10;:17;44524:1;:21;44507:213;;;44616:1;44575:10;:25;44586:10;44597:1;44586:13;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;44575:25:0;;;;;;;;;;;-1:-1:-1;44575:25:0;:38;-1:-1:-1;;;44575:38:0;;-1:-1:-1;;;;;44575:38:0;:42;44567:51;;;;;;44673:35;44694:10;44705:1;44694:13;;;;;;;;;;;;;;44673:20;:35::i;:::-;44547:3;;44507:213;;;;34649:42;34663:27;34667:11;34680:9;34663:3;:27::i;40330:225::-;34411:10;34394:28;;;;:16;:28;;;;;;;;34386:37;;;;;;40483:64;40498:6;40506:9;40517:1;40520;40523:14;40539:4;40545:1;40483:14;:64::i;:::-;40330:225;;;;:::o;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;40609:810::-;34598:16;34617:9;34503:10;34496:18;;;;:6;:18;;;;;;34598:28;;-1:-1:-1;34496:18:0;;;:41;;-1:-1:-1;34532:5:0;;-1:-1:-1;;;;;34532:5:0;34518:10;:19;34496:41;34488:50;;;;;;41168:9;41179:10;41191:7;35172:330;35363:9;35374:10;35172:330;;;;;;;;35404:7;35412:1;35404:10;;;;;;;;;;;35172:330;;;;35416:7;35424:1;35416:10;;;;;;;;;;;35172:330;;;;35428:7;35436:1;35428:10;;;;;;;;;;;35172:330;;;;35440:7;35448:1;35440:10;;;;;;;;;;;35172:330;;;;35452:7;35460:1;35452:10;;;;;;;;;;;35172:330;;;;35464:7;35472:1;35464:10;;;;;;;;;;;35172:330;;;;35476:7;35484:1;35476:10;;;;;;;;;;;35172:330;;:21;:330::i;:::-;35150:363;;;;;;-1:-1:-1;;;;;35569:23:0;;;;;;:12;:23;;;;;;;;35593:10;;;;35569:35;;;;;;;;:42;;-1:-1:-1;;35569:42:0;35607:4;35569:42;;;41345:10;;41357;;;;41369;;;;41390;;;;41216:195;;41334:9;;41345:10;41357;;41381:7;;41216:20;:195::i;:::-;34549:1;;;34649:42;34663:27;34667:11;34680:9;34663:3;:27::i;37782:1331::-;38231:10;;;;38217;;;;38192:4;;-1:-1:-1;38217:24:0;38209:33;;;;;;38311:10;;;;38305:3;:16;;:68;;-1:-1:-1;;;;;;38338:23:0;;;;;;:12;:23;;;;;;;;38362:10;;;;38338:35;;;;;;;;;;38305:68;38301:113;;;-1:-1:-1;38397:5:0;38390:12;;38301:113;38488:10;;;;38475;;;;:23;;:50;;-1:-1:-1;38515:10:0;;;;38502;;;;:23;38475:50;38471:95;;;-1:-1:-1;38549:5:0;38542:12;;38471:95;38652:12;38667:266;38826:9;38667:266;;;;;;;;38851:7;38859:1;38851:10;;;;;;;;;;;38667:266;;;;38863:7;38871:1;38863:10;;;;;;;;;;;38667:266;;;;38875:7;38883:1;38875:10;;;;;;;;;;;38667:266;;;;38887:7;38895:1;38887:10;;;;;;;;;;;38667:266;;;;38899:7;38907:1;38899:10;;;;;;;;;;;38667:266;;;;38911:7;38919:1;38911:10;;;;;;;;;;;38667:266;;:27;:266::i;:::-;38652:281;-1:-1:-1;39070:24:0;38652:281;39083:10;39070:24;:12;:24;:::i;:::-;-1:-1:-1;;;;;39039:21:0;;;;;;;:10;:21;;;;;:27;;;-1:-1:-1;;;39039:27:0;;;;:55;;;;-1:-1:-1;;37782:1331:0;;;;;;:::o;19744:84::-;19786:42;19744:84;:::o;16534:78::-;16570:42;16534:78;:::o;52:28::-;;;-1:-1:-1;;;;;52:28:0;;:::o;33351:25::-;;;-1:-1:-1;;;;;33351:25:0;;:::o;41455:1852::-;34598:16;34617:9;34503:10;34496:18;;;;:6;:18;;;;;;34598:28;;-1:-1:-1;34496:18:0;;;:41;;-1:-1:-1;34532:5:0;;-1:-1:-1;;;;;34532:5:0;34518:10;:19;34496:41;34488:50;;;;;;41864:17;41884:62;41889:40;41893:18;41913:15;41889:3;:40::i;:::-;41931:9;41942:3;41884:4;:62::i;:::-;41949:4;41884:69;41864:89;;42162:23;;:::i;:::-;42252:12;42248:314;;;42281:8;;:27;;;-1:-1:-1;;;42281:27:0;;;;;;;;;;-1:-1:-1;;;;;42281:8:0;;;;:13;;:27;;;;;:8;;:27;;;;;;;;:8;;:27;;;5:2:-1;;;;30:1;27;20:12;5:2;42281:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;42281:27:0;;;;42367:183;-1:-1:-1;;;;;;;;;;;42416:12:0;-1:-1:-1;;;;;;;;;;;42469:40:0;42473:18;42493:15;42469:3;:40::i;:::-;42528:7;42367:9;:183::i;:::-;42356:194;;42248:314;42574:18;;42715:167;42736:10;:17;42732:1;:21;42715:167;;;42792:78;42810:10;42821:1;42810:13;;;;;;;;;;;;;;42825:15;42842:9;42853:16;42792:17;:78::i;:::-;42775:95;;;;42755:3;;42715:167;;;;42919:12;42902:13;:29;;42894:38;;;;;;42994:11;;;;:15;;;:34;;-1:-1:-1;43013:11:0;;;;:15;;42994:34;42990:310;;;43263:11;;;;43276;;;;43220:68;;43251:10;;43220:30;:68::i;:::-;34549:1;;;34649:42;34663:27;34667:11;34680:9;34663:3;:27::i;34649:42::-;;41455:1852;;;;;;;;:::o;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::-;-1:-1:-1;;;;;;;;;;;19837:80:0;:::o;45783:378::-;-1:-1:-1;;;;;45856:21:0;;45888:1;45856:21;;;:10;:21;;;;;:29;-1:-1:-1;;;;;45856:29:0;45848:42;;;;;;-1:-1:-1;;;;;45941:21:0;;45903:13;45941:21;;;:10;:21;;;;;;:49;;-1:-1:-1;;45941:49:0;;45919:9;-1:-1:-1;;;;;45941:49:0;;;;;;;;;;;;46045:108;;-1:-1:-1;;;46045:108:0;;-1:-1:-1;;;;;;;;;;;46045:108:0;;;;19963:42;46045:108;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45919:9;;45941:21;46045:28;;45919:9;;46045:108;;;;;45903:13;46045:108;;;;;45919:9;45941:21;46045:108;;;5:2:-1;;;;30:1;27;20:12;5:2;46045:108:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;33213:48:0;;;;;;;;;;;;;;;:::o;39544:277::-;34411:10;34394:28;;;;:16;:28;;;;;;;;34386:37;;;;;;39734:79;39749:6;39757:9;39768:8;39778:9;39789:14;39805:4;39811:1;39734:14;:79::i;20014:81::-;-1:-1:-1;;;;;;;;;;;20014:81:0;:::o;39915:360::-;34411:10;34394:28;;;;:16;:28;;;;;;;;34386:37;;;;;;40179:88;40194:6;40202:9;40213:8;40223:9;40234:14;40250:4;40256:10;40179:14;:88::i;48620: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;;;;;;;;;;;;;;;48685:3;:29;;-1:-1:-1;;;;;;48685:29:0;-1:-1:-1;;;;;48685:29:0;;;;;;;;;;48620:102::o;48388: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;;;;;;;;;;;;;;;48499:6;48494:111;48515:9;:16;48511:1;:20;48494:111;;;48586:7;48553:16;:30;48570:9;48580:1;48570:12;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;48553:30:0;;;;;;;;;;;-1:-1:-1;48553:30:0;:40;;-1:-1:-1;;48553:40:0;;;;;;;;;;-1:-1:-1;48533:3:0;48494:111;;25403:33;;;;:::o;48023: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;;;;;;;;;;;;;;;48124:6;48119:97;48140:7;:14;48136:1;:18;48119:97;;;48197:7;48176:6;:18;48183:7;48191:1;48183:10;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;48176:18:0;;;;;;;;;;;-1:-1:-1;48176:18:0;:28;;-1:-1:-1;;48176:28:0;;;;;;;;;;-1:-1:-1;48156:3:0;48119: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;33521: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:5;: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;35939:831::-;-1:-1:-1;;;;;36277:21:0;;;36009;36277;;;:10;:21;;;;;:27;;;;36325:29;;-1:-1:-1;;;36277:27:0;;;;;;-1:-1:-1;;;;;36325:29:0;;;;36377:31;-1:-1:-1;;;36377:31:0;;;;-1:-1:-1;;;36435:35:0;;;;;36497;-1:-1:-1;;;36497:35:0;;;;;-1:-1:-1;;;36549:25:0;;;;;-1:-1:-1;;;36600:34:0;;;;-1:-1:-1;;;;;36661:35:0;;;-1:-1:-1;;;36725:37:0;;;;;;;35939: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;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;;;;;60113:3592;60348:14;60364:22;60399:24;;:::i;:::-;-1:-1:-1;;;;;;60426:21:0;;;;;;;:10;:21;;;;;;;;;60399:48;;;;;;;;;-1:-1:-1;;;;;60399:48:0;;;;;;-1:-1:-1;;;60399:48:0;;;;;;;;;;;-1:-1:-1;;;60399:48:0;;;;;;;;;;;;;-1:-1:-1;;;60399:48:0;;;;;;;;-1:-1:-1;;;60399:48:0;;;;;;;;;;;;;-1:-1:-1;;;;;60399:48:0;;;;;;-1:-1:-1;;;60399:48:0;;;;;;;;;;;-1:-1:-1;;;60399:48:0;;;;;;;;;-1:-1:-1;;;60399:48:0;;;;;;;;;60466:20;;;;:50;;-1:-1:-1;60490:21:0;;;;-1:-1:-1;;;;;60490:26:0;;60466:50;60458:59;;;;;;60609:52;;;-1:-1:-1;;;60609:52:0;;-1:-1:-1;;;;;60609:52:0;;;;;;;;60584:18;;60605:72;;19963:42;;60609:41;;:52;;;;;;;;;;;;;;60584:18;19963:42;60609:52;;;5:2:-1;;;;30:1;27;20:12;5:2;60609:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60609:52:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;60609:52:0;60663:13;60605:3;:72::i;:::-;60584:93;;60721:8;60717:158;;;60791:72;60806:8;60816:13;60831;60846:16;60791:14;:72::i;:::-;60746:117;;-1:-1:-1;60746:117:0;-1:-1:-1;60746:117:0;-1:-1:-1;60717:158:0;60909:13;60971:17;;60967:309;;61046:34;61050:14;61066:13;61046:3;:34::i;:::-;61029:51;;61101:16;61097:168;;;61212:37;61216:14;61232:8;:16;;;-1:-1:-1;;;;;61212:37:0;:3;:37::i;:::-;61195:54;;61097:168;61351:9;61379;:26;-1:-1:-1;61375:130:0;;;61429:30;61433:14;61449:9;61429:3;:30::i;:::-;61474:8;;:19;;;-1:-1:-1;;;61474:19:0;;;;;;;;;;61422:37;;-1:-1:-1;;;;;;61474:8:0;;;;:13;;:19;;;;;:8;;:19;;;;;;;;:8;;:19;;;5:2:-1;;;;30:1;27;20:12;5:2;61474:19:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;61474:19:0;;;;61375:130;61676:23;;:::i;:::-;61702:75;61727:9;61738:14;61754:13;61769:7;61702:24;:75::i;:::-;61676:101;-1:-1:-1;61828:17:0;61860:170;;;;61890:8;61937:3;61901:33;61905:14;61921:8;:12;;;61901:33;;:3;:33::i;:::-;:39;;;;;;61890:50;;61970:48;61974:3;61979:38;61997:8;:14;;;62013:3;61979:17;:38::i;:::-;61970:3;:48::i;:::-;61955:63;;61860:170;;62126:1;62100:23;62104:4;62110:12;62100:3;:23::i;:::-;:27;62096:116;;;62165:8;;62144:56;;-1:-1:-1;;;;;62165:8:0;62176:23;62180:4;62186:12;62176:3;:23::i;:::-;62144:12;:56::i;:::-;62228:17;;62224:281;;62266:16;62262:232;;;62376:16;;-1:-1:-1;;;;;62360:32:0;;-1:-1:-1;62262:232:0;;;62477:1;62461:17;;62262:232;62706:14;;;;62752:11;;;;62796;;;;62676:143;;62706:14;62736:27;;;62780;;62676:15;:143::i;:::-;62928:308;62954:8;:14;;;63054:4;63168:1;63152:13;:17;63151:52;;63202:1;63151:52;;;63174:16;:24;;63197:1;63174:24;;;63193:1;63174:24;62928:308;;:11;:308::i;:::-;63293:25;63308:9;63293:14;:25::i;:::-;63378:9;:13;63374:85;;63408:39;;63416:10;;63437:9;63408:39;;;;;;;;;63437:9;63416:10;63408:39;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63408:39:0;63374:85;-1:-1:-1;;;;;63610:87:0;;;63653:8;63662:1;63653:11;;;;63637:27;;63684:8;63693:1;63684:11;;;;63668:13;:27;63610:87;;;;;;;;;;;;;;;;;;;;;;;;60113:3592;;;;;;;;;;;;;;;:::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;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;67278:143::-;67365:48;;;;;;;;-1:-1:-1;67365:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;67341:21:0;;;;;:10;:21;;;;;;;:72;;;;;;;;;;;;-1:-1:-1;;67341:72:0;;;-1:-1:-1;;;;;67341:72:0;;;;-1:-1:-1;;;;67341:72:0;-1:-1:-1;;;67341:72:0;;;;;;;;;;;-1:-1:-1;;;;67341:72:0;-1:-1:-1;;;67365:48:0;67341:72;;;;;-1:-1:-1;;;;67341:72:0;-1:-1:-1;;;67341:72:0;;;;;;;;;-1:-1:-1;;;;;67341:72:0;-1:-1:-1;;;67341:72:0;;;;;;;;;;;;;;;-1:-1:-1;67341:72:0;;;;;;;;;;;-1:-1:-1;;67341:72:0;;;-1:-1:-1;;;;;67341:72:0;;;;;;;-1:-1:-1;;;;67341:72:0;-1:-1:-1;;;67341:72:0;;;;;;;;;;;;;-1:-1:-1;;;67341:72:0;;;;;;;;;;;;-1:-1:-1;;;;67341:72:0;-1:-1:-1;;;67365:48:0;67341:72;;;;;;;;;;67278:143::o;57764:2341::-;57833:24;;:::i;:::-;-1:-1:-1;;;;;;57860:21:0;;;;;;;:10;:21;;;;;;;;57833:48;;;;;;;;;-1:-1:-1;;;;;57833:48:0;;;;;-1:-1:-1;;;57833:48:0;;;;;;;;;-1:-1:-1;;;57833:48:0;;;;;;;;-1:-1:-1;;;57833:48:0;;;;;;;;-1:-1:-1;;;57833:48:0;;;;;;;;;;;;;-1:-1:-1;;;;;57833:48:0;;;;;;-1:-1:-1;;;57833:48:0;;;;;;;;;;;-1:-1:-1;;;57833:48:0;;;;;;;;;;-1:-1:-1;;;57833:48:0;;;;;;;;57911:52;;-1:-1:-1;;;57911:52:0;;;;;;;;;;57860:21;;19963:42;;57911:41;;:52;;;;;57860:21;;57911:52;;;;;;57860:21;19963:42;57911:52;;;5:2:-1;;;;30:1;27;20:12;5:2;57911:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57911:52:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57911:52:0;58159:49;;;-1:-1:-1;;;58159:49:0;;-1:-1:-1;;;;;58159:49:0;;;;;;-1:-1:-1;;58159:49:0;;;;;;57911:52;;-1:-1:-1;;;;;;;;;;;;20053:42:0;58159:28;;:49;;;;;-1:-1:-1;;58159:49:0;;;;;;;;-1:-1:-1;20053:42:0;58159:49;;;5:2:-1;;;;30:1;27;20:12;5:2;58159:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;58219:85:0;;;-1:-1:-1;;;58219:85:0;;-1:-1:-1;;;;;;;;;;;58219:85:0;;;;19963:42;58219:85;;;;-1:-1:-1;;;;;;;;;;;58219:85:0;;;;20142:42;58219:85;;;;;;-1:-1:-1;;;;;58219:29:0;;;-1:-1:-1;58219:29:0;;-1:-1:-1;58219:85:0;;;;;-1:-1:-1;;58219:85:0;;;;;;;-1:-1:-1;58219:29:0;:85;;;5:2:-1;;;;30:1;27;20:12;5:2;58219:85:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58219:85:0;;;;58372:17;58470:3;58455:8;:12;;;58392:75;;:60;58396:32;58400:9;58411:8;:16;;;-1:-1:-1;;;;;58396:32:0;:3;:32::i;:::-;58430:8;:21;;;-1:-1:-1;;;;;58392:60:0;:3;:60::i;:::-;:75;:81;;;;;;58372:101;;58484:18;58505:47;58523:8;:14;;;58539:12;58505:17;:47::i;:::-;58586:22;;;;58484:68;;-1:-1:-1;;;;;;58565:43:0;:18;58658:17;;58654:512;;58769:14;;;;58730:69;;-1:-1:-1;;;;;;;;;;;20053:42:0;58785:13;58730:69;:38;:69;:::i;:::-;58874:8;:24;;;58870:97;;;-1:-1:-1;58935:16:0;;-1:-1:-1;;;;;58919:32:0;58870:97;58654:512;;;59016:14;59033:58;59047:9;59058;59069:8;:21;;;-1:-1:-1;;;;;59033:58:0;:13;:58::i;:::-;59016:75;;59122:32;59126:8;:16;;;-1:-1:-1;;;;;59122:32:0;59144:9;59122:3;:32::i;:::-;59106:48;;58654:512;;59215:17;;59211:118;;59287:14;;;;59249:68;;-1:-1:-1;;;;;;;;;;;19875:42:0;59303:13;59249:68;:37;:68;:::i;:::-;59394:18;59415:49;59419:29;59423:9;59434:13;59419:3;:29::i;:::-;59450:13;59415:3;:49::i;:::-;59496:8;;59394:70;;-1:-1:-1;59475:46:0;;-1:-1:-1;;;;;59496:8:0;59394:70;59475:12;:46::i;:::-;59630:312;59656:8;:14;;;59756:4;59870:1;59854:13;:17;59853:60;;59912:1;59853:60;;;59876:8;:24;;;:32;;59907:1;59876:32;;59630:312;59999:25;60014:9;59999:14;:25::i;:::-;60042:55;;;;;;;;;;;;;;-1:-1:-1;;;;;60042:55:0;;;;;;;;;;;57764:2341;;;;;;;;:::o;52305:933::-;-1:-1:-1;;;;;52553:21:0;;;52592:1;52553:21;;;:10;:21;;;;;:27;;;-1:-1:-1;;;52553:27:0;;;:41;52545:50;;;;;;52625:10;52650:14;;:30;;;;;52679:1;52668:8;:12;52650:30;52646:220;;;52714:52;;;-1:-1:-1;;;52714:52:0;;-1:-1:-1;;;;;52714:52:0;;;;;;;;52697:14;;19963:42;;52714:41;;:52;;;;;;;;;;;;;;;52697:14;19963:42;52714:52;;;5:2:-1;;;;30:1;27;20:12;5:2;52714:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52714:52:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;52714:52:0;;-1:-1:-1;52813:8:0;52806:3;52794:15;;52813:8;52793:28;;;;;52781:40;;52646:220;;52902:235;;;;;;;;52932:8;-1:-1:-1;;;;;52902:235:0;;;;;52963:9;-1:-1:-1;;;;;52902:235:0;;;;;52988:14;52902:235;;;;;;53017:4;52902:235;;;;;;53036:1;-1:-1:-1;;;;;52902:235:0;;;;;53052:1;-1:-1:-1;;;;;52902:235:0;;;;;53068:5;52902:235;;;;;;53088:6;-1:-1:-1;;;;;52902:235:0;;;;;53116:9;52902:235;;;;;52878:10;:21;52889:9;-1:-1:-1;;;;;52878:21:0;-1:-1:-1;;;;;52878:21:0;;;;;;;;;;;;:259;;;;;;;;;;;;;-1:-1:-1;;;;;52878:259:0;;;;;-1:-1:-1;;;;;52878:259:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52878:259:0;;;;;-1:-1:-1;;;;;52878:259:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52878:259:0;;;;;-1:-1:-1;;;;;52878:259:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52878:259:0;;;;;-1:-1:-1;;;;;52878:259:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52878:259:0;;;;;-1:-1:-1;;;;;52878:259:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53177:9;-1:-1:-1;;;;;53155:75:0;53169:6;-1:-1:-1;;;;;53155:75:0;;53188:8;53198:9;53209:14;53225:4;53155:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52305:933;;;;;;;;:::o;15428:261::-;15506:7;-1:-1:-1;;;;;15530:21:0;;;;:45;;-1:-1:-1;;;;;;15555:20:0;;-1:-1:-1;;;;;;;;;;;15555:20:0;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;;53246:2335;53463:24;;:::i;:::-;-1:-1:-1;;;;;;53490:21:0;;;;;;;:10;:21;;;;;;;;;53463:48;;;;;;;;;-1:-1:-1;;;;;53463:48:0;;;;;-1:-1:-1;;;53463:48:0;;;;;;;;;;;-1:-1:-1;;;53463:48:0;;;;;;;;;;;;;-1:-1:-1;;;53463:48:0;;;;;;;;-1:-1:-1;;;53463:48:0;;;;;;;;;;;;-1:-1:-1;;;;;53463:48:0;;;;;;-1:-1:-1;;;53463:48:0;;;;;;;;;;;-1:-1:-1;;;53463:48:0;;;;;;;;;;;-1:-1:-1;;;53463:48:0;;;;;;;;;53532:28;;;;:58;;-1:-1:-1;53564:21:0;;;;-1:-1:-1;;;;;53564:26:0;;53532:58;53524:67;;;;;;53619:3;53610:5;:12;;:28;;;;;53635:3;53626:5;:12;;53610:28;53602:60;;;;;-1:-1:-1;;;53602:60:0;;;;;;;;;;;;-1:-1:-1;;;53602:60:0;;;;;;;;;;;;;;;53791:14;;;;53748:85;;-1:-1:-1;;;;;;;;;;;20053:42:0;53815:4;53822:10;53748:85;:42;:85;:::i;:::-;53892:3;-1:-1:-1;;53877:11:0;;53863:26;;:32;53846:14;53933:26;53863;:32;53933:3;:26::i;:::-;53906:53;;54001:17;54021:48;54026:19;54048:4;54026:26;54054:14;54021:4;:48::i;:::-;54080:8;;:27;;;-1:-1:-1;;;54080:27:0;;;;;;;;;;54001:68;;-1:-1:-1;;;;;;54080:8:0;;;;:13;;:27;;;;;:8;;:27;;;;;;;;:8;;:27;;;5:2:-1;;;;30:1;27;20:12;5:2;54080:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54080:27:0;;;;54160:54;54179:9;54190:12;54204:9;54160:18;:54::i;:::-;54386:23;;:::i;:::-;54412:185;-1:-1:-1;;;;;;;;;;;54458:19:0;54492:13;;:58;;-1:-1:-1;;;;;;;;;;;54492:58:0;;;20232:42;54492:58;54552:12;54579:7;54412:9;:185::i;:::-;54386:211;-1:-1:-1;54614:13:0;54610:122;;54674:45;;;-1:-1:-1;;;54674:45:0;;54713:4;54674:45;;;;;;20232:42;;54644:29;;20232:42;;54674:30;;:45;;;;;;;;;;;;;;20232:42;54674:45;;;5:2:-1;;;;30:1;27;20:12;5:2;54674:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54674:45:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54674:45:0;54644:76;;;-1:-1:-1;;;;;;54644:76:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;54644:76:0;;;;;;;-1:-1:-1;54644:76:0;;;;5:2:-1;;;;30:1;27;20:12;5:2;54644:76:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54644:76:0;;;;54610:122;54785:13;54801:39;54806:10;54819:4;54806:17;54825:14;54801:4;:39::i;:::-;54785:55;;54851:17;54871:31;54875:8;:16;;;-1:-1:-1;;;;;54871:31:0;54893:8;54871:3;:31::i;:::-;-1:-1:-1;;;;;54947:21:0;;;;;;:10;:21;;;;;;;;:52;;-1:-1:-1;;54947:52:0;-1:-1:-1;;;;;54947:52:0;;;;;;;;;;55083:16;;55101:22;;;;54947:52;;-1:-1:-1;55069:103:0;;55074:83;;55078:46;;;;;;;:4;:46::i;:::-;55126:30;55131:8;55141:14;55126:4;:30::i;:::-;55074:3;:83::i;:::-;55159:12;55069:4;:103::i;:::-;-1:-1:-1;;;;;55010:21:0;;;;;;:10;:21;;;;;;;;:173;;-1:-1:-1;;;;;55010:173:0;;;;-1:-1:-1;;;55010:173:0;-1:-1:-1;;;;55010:173:0;;;;;;;;;;55236:52;;-1:-1:-1;;;55236:52:0;;;;;;;;;;;55298:12;;19963:42;;55236:41;;:52;;;;;;;;;;;;;19963:42;55236:52;;;5:2:-1;;;;30:1;27;20:12;5:2;55236:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;55236:52:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;55236:52:0;55291:3;55236:58;55235:75;;;;;;55194:10;:21;55205:9;-1:-1:-1;;;;;55194:21:0;-1:-1:-1;;;;;55194:21:0;;;;;;;;;;;;:31;;;:117;;;;;;;;;;;;;;;;;;55376:45;55397:8;;;;;;;;;-1:-1:-1;;;;;55397:8:0;55408:12;55376;:45::i;:::-;55532:14;;;;55548:11;;;;55561;;;;55504:69;;55532:14;55548:11;55504:27;:69::i;:::-;53246:2335;;;;;;;;;;;;;:::o;25803:818::-;25007:303;;;-1:-1:-1;;;25007:303:0;;;;;;;;-1:-1:-1;;;25007:303:0;;;;-1:-1:-1;;;25007:303:0;;;;-1:-1:-1;;;25007:303:0;;;;;;;;;;;;;;-1:-1:-1;;;25007:303:0;;;;-1:-1:-1;;;25007:303:0;;;;-1:-1:-1;;;25007:303:0;;;;;;22:32:-1;26:21;;;22:32;6:49;;25007:303:0;;;;;24997:314;;;;;;26178:10;;26219;;;;26258;;;;26304;;;;;26350;;;;26390;;;;;26064:362;;;;;;;;;;-1:-1:-1;;26064:362:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;26064:362:0;;;;;26054:373;;;;;;;;;-1:-1:-1;26558:18:0;-1:-1:-1;;;26499:113:0;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;26499:113:0;;;;;;26489:124;;;;;;25803:818::o;21652:1930::-;21730:7;21793:9;:16;21813:2;21793:22;21789:74;;-1:-1:-1;21848:1:0;21832:19;;21789:74;22224:4;22209:20;;22203:27;22270:4;22255:20;;22249:27;22324:4;22309:20;;22303:27;21932:9;22295:36;23254:66;23241:79;;23237:129;;;23352:1;23337:17;;;;;;;23237:129;23382:1;:7;;23387:2;23382:7;;:18;;;;;23393:1;:7;;23398:2;23393:7;;23382:18;23378:68;;;23432:1;23417:17;;;;;;;23378:68;23550:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;23550:24:0;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;23550:24:0;;-1:-1:-1;;23550:24:0;;;21652:1930;-1:-1:-1;;;;;;;21652:1930:0: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;65396:1874::-;65590:18;;:::i;:::-;65865:42;65826:19;-1:-1:-1;;;;;65994:34:0;;-1:-1:-1;;;;;;;;;;;65994:34:0;65990:274;;-1:-1:-1;;66049:10:0;-1:-1:-1;;;;;66049:20:0;;66078:4;66085:2;-1:-1:-1;;;;;66085:10:0;;:12;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;66085:12:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;66085:12:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;66085:12:0;66049:49;;;-1:-1:-1;;;;;;66049:49:0;;;;;;;-1:-1:-1;;;;;66049:49:0;;;;;;;;;;;;;;;;;;;;;66085:12;;66049:49;;;;;;;;;;;5:2:-1;;;;30:1;27;20:12;5:2;66049:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;66049:49:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;66049:49:0;:61;66045:144;;66131:10;-1:-1:-1;;;;;66131:18:0;;66150:2;-1:-1:-1;;;;;66150:10:0;;:12;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;66150:12:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;66150:12:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;66150:12:0;66131:42;;;-1:-1:-1;;;;;;66131:42:0;;;;;;;-1:-1:-1;;;;;66131:42:0;;;;;;;-1:-1:-1;;66131:42:0;;;;;;;;;;-1:-1:-1;;66131:42:0;;;;;;;-1:-1:-1;66131:42:0;;;;5:2:-1;;;;30:1;27;20:12;5:2;66131:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;66131:42:0;;;;66045:144;65990:274;;;-1:-1:-1;66233:19:0;65990:274;66276:27;66306:44;-1:-1:-1;;;;;66306:29:0;;66344:4;66306:44;:29;:44;:::i;:::-;66276:74;-1:-1:-1;66361:25:0;66389:42;-1:-1:-1;;;;;66389:27:0;;66425:4;66389:42;:27;:42;:::i;:::-;66361:70;;66444:16;66643:2;66640:1;66630:7;66624:14;66617:4;66608:7;66604:18;66593:9;66589:2;66582:4;66577:3;66573:14;66568:78;-1:-1:-1;;66678:1:0;66672:8;66901:69;66905:42;-1:-1:-1;;;;;66905:27:0;;66941:4;66905:42;:27;:42;:::i;:::-;66949:20;66901:3;:69::i;:::-;66892:78;;67020:73;67024:22;67048:44;-1:-1:-1;;;;;67048:29:0;;67086:4;67048:29;:44::i;67020:73::-;67011:6;;;:82;67141:6;;67137:30;;67149:17;67137:3;:30::i;:::-;67128:6;;;:39;:6;67234;;;67209:32;;67213:19;;67209:3;:32::i;:::-;67200:6;;;:41;-1:-1:-1;67200:3:0;;65396:1874;-1:-1:-1;;;;;;;;;65396:1874:0:o;55589:2167::-;-1:-1:-1;;;;;55840:21:0;;55772;55840;;;:10;:21;;;;;55880;;-1:-1:-1;;;55880:21:0;;-1:-1:-1;;;;;55880:21:0;:26;:50;;;;-1:-1:-1;55910:16:0;;-1:-1:-1;;;;;55910:16:0;:20;;55880:50;55872:59;;;;;;55961:52;;;-1:-1:-1;;;55961:52:0;;-1:-1:-1;;;;;55961:52:0;;;;;;;;55944:14;;19963:42;;55961:41;;:52;;;;;;;;;;;;;;;55944:14;19963:42;55961:52;;;5:2:-1;;;;30:1;27;20:12;5:2;55961:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;55961:52:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;55961:52:0;56049:53;;;-1:-1:-1;;;56049:53:0;;-1:-1:-1;;;;;56049:53:0;;;;;;;;55961:52;;-1:-1:-1;56024:17:0;;56044:75;;20142:42;;56049;;:53;;;;;55961:52;;56049:53;;;;;;;;20142:42;56049:53;;;5:2:-1;;;;30:1;27;20:12;5:2;56049:53:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56049:53:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;56049:53:0;56104:9;56115:3;56044:4;:75::i;:::-;56122:4;56044:82;;-1:-1:-1;56139:18:0;;56211:19;;56207:971;;56257:14;56315:64;56333:9;56344;56355:12;56369:9;56315:17;:64::i;:::-;56441:9;;-1:-1:-1;56441:9:0;;56286:93;-1:-1:-1;56286:93:0;-1:-1:-1;56516:319:0;;;;56557:24;;;:43;;-1:-1:-1;;;;56557:43:0;-1:-1:-1;;;56557:43:0;;;;;;;56660:16;;56711:9;;-1:-1:-1;;;;;;56660:16:0;;-1:-1:-1;56711:9:0;56790:29;56794:9;56660:16;56790:3;:29::i;:::-;56774:45;;56516:319;-1:-1:-1;56851:22:0;;;:46;;-1:-1:-1;;56851:46:0;-1:-1:-1;;;;;56851:46:0;;;;;56207:971;;;56963:14;56980:49;56994:9;57005;57016:12;56980:13;:49::i;:::-;57064:16;;56963:66;;-1:-1:-1;57060:32:0;;-1:-1:-1;;;;;57064:16:0;56963:66;57060:3;:32::i;:::-;57044:48;;57154:12;57138:28;;56207:971;;57190:44;;-1:-1:-1;;;;;57190:44:0;-1:-1:-1;;;;;;;;57190:44:0;;;;;;-1:-1:-1;57392:14:0;;;57366:308;;-1:-1:-1;;;57392:14:0;;-1:-1:-1;;;;;57392:14:0;-1:-1:-1;57590:19:0;57589:54;;57642:1;57589:54;;;57614:16;:24;;57637:1;57614:24;;57366:308;57692:56;;;;;;;;;;;;;;-1:-1:-1;;;;;57692:56:0;;;;;;;;;;;55589:2167;;;;;;;;;;;:::o;69441:1274::-;69639:22;69675:10;:17;69664:29;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;69664:29:0;-1:-1:-1;69639:54:0;-1:-1:-1;69706:17:0;;69841:161;69862:10;:17;69858:1;:21;69841:161;;;69915:10;:25;69926:10;69937:1;69926:13;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;69915:25:0;;;;;;;;;;;-1:-1:-1;69915:25:0;:33;69901:11;;-1:-1:-1;;;;;69915:33:0;;;;69901:8;;69910:1;;69901:11;;;;;;;;;;;:47;;;;;69979:8;69988:1;69979:11;;;;;;;;;;;;;;69963:27;;;;69881:3;;;;;;;69841:161;;;-1:-1:-1;70075:6:0;70070:638;70091:10;:17;70087:1;:21;70070:638;;;70130:18;70151:31;70156:8;70165:1;70156:11;;;;;;;;;;;;;;70169:12;70151:4;:31::i;:::-;70130:52;-1:-1:-1;70203:13:0;;70199:292;;70237:19;70259:30;70264:13;70279:9;70259:4;:30::i;:::-;70237:52;;70353:14;70312:10;:25;70323:10;70334:1;70323:13;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;70312:25:0;;;;;;;;;;;-1:-1:-1;70312:25:0;:38;-1:-1:-1;;;70312:38:0;;-1:-1:-1;;;;;70312:38:0;:55;70308:168;;;70441:14;70392:10;:25;70403:10;70414:1;70403:13;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;70392:25:0;;;;;;;;;;;-1:-1:-1;70392:25:0;:64;;-1:-1:-1;;;;;;;;70392:64:0;;;;;;;;;;;;;-1:-1:-1;;;;;70392:64:0;;;;;;;;;70308:168;70199:292;;70511:13;;70507:190;;70545:19;70567:30;70572:13;70587:9;70567:4;:30::i;:::-;70545:52;;70666:14;70616:10;:25;70627:10;70638:1;70627:13;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;70616:25:0;;;;;;;;;;;-1:-1:-1;70616:25:0;:39;;:65;;-1:-1:-1;;70616:65:0;;-1:-1:-1;;;;;70616:65:0;;;;;;;;;;;;;;-1:-1:-1;70507:190:0;-1:-1:-1;70110:3:0;;70070:638;;13868:140;13957:43;13975:5;13982:2;13986:6;13994:5;13957:17;:43::i;50523:1739::-;50941:17;;50815:14;;50719:21;;;;-1:-1:-1;;;;;50925:33:0;;;50921:870;;;50992:37;50996:13;51011:9;:17;;;-1:-1:-1;;;;;50992:37:0;:3;:37::i;:::-;50975:54;-1:-1:-1;51050:17:0;;51046:734;;51092:16;51088:479;;;51296:9;:23;;;51291:29;;51323:3;51291:35;51238:48;51243:9;:17;;;-1:-1:-1;;;;;51238:48:0;51262:9;:23;;;-1:-1:-1;;;;;51238:48:0;:4;:48::i;:::-;51207:28;;;:79;;;;;;51206:120;;51194:132;;51088:479;;;51516:9;:23;;;51511:29;;51505:3;:35;51544:3;51504:43;51451:48;51456:9;:17;;;-1:-1:-1;;;;;51451:48:0;51475:9;:23;;;-1:-1:-1;;;;;51451:48:0;:4;:48::i;:::-;51420:28;;;:79;;;;;;51419:128;;51407:140;;51088:479;51046:734;;;51734:9;:23;;;51729:29;;51761:3;51729:35;51707:9;:17;;;-1:-1:-1;;;;;51648:76:0;51692:3;51666:23;51670:3;51675:9;:13;;;51666:23;;:3;:23::i;:::-;51649:14;:40;:46;;;;;;51699:5;51648:56;:76;;;;;;51647:117;;51635:129;;51046:734;51807:9;51803:452;;;51833:16;51852:70;51856:9;:17;;;-1:-1:-1;;;;;51852:70:0;51918:3;51892:23;51896:3;51901:9;:13;;;51892:23;;:3;:23::i;:::-;51875:14;:40;:46;;;;51852:70;51833:89;;51962:11;51945:13;:28;;51937:37;;;;;;52007:11;-1:-1:-1;51803:452:0;;;52119:13;;52113:3;:19;52109:135;;;52169:59;52173:13;52224:3;52188:33;52192:13;52207;;52188:3;:33::i;:::-;:39;;;;;;52169:3;:59::i;:::-;52153:75;;52109:135;50523:1739;;;;;;;;:::o;63713:942::-;63906:23;;:::i;:::-;64210:53;;;-1:-1:-1;;;64210:53:0;;-1:-1:-1;;;;;64210:53:0;;;;;;;;64189:18;;20142:42;;64210;;:53;;;;;;;;;;;;;;;20142:42;64210:53;;;5:2:-1;;;;30:1;27;20:12;5:2;64210:53:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64210:53:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;64210:53:0;;-1:-1:-1;64287:163:0;-1:-1:-1;;;;;;;;;;;64332:15:0;-1:-1:-1;;;;;;;;;;;64384:33:0;64210:53;64403:13;64384:3;:33::i;:::-;64432:7;64287:9;:163::i;:::-;64502:49;;;-1:-1:-1;;;64502:49:0;;-1:-1:-1;;;;;64502:49:0;;;;;;-1:-1:-1;;64502:49:0;;;;;;64276:174;;-1:-1:-1;;;;;;;;;;;;20053:42:0;64502:28;;:49;;;;;-1:-1:-1;;64502:49:0;;;;;;;;-1:-1:-1;20053:42:0;64502:49;;;5:2:-1;;;;30:1;27;20:12;5:2;64502:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;64562:85:0;;;-1:-1:-1;;;64562:85:0;;-1:-1:-1;;;;;;;;;;;64562:85:0;;;;19963:42;64562:85;;;;-1:-1:-1;;;;;;;;;;;64562:85:0;;;;20142:42;64562:85;;;;;;-1:-1:-1;;;;;64562:29:0;;;-1:-1:-1;64562:29:0;;-1:-1:-1;64562:85:0;;;;;-1:-1:-1;;64562:85:0;;;;;;;-1:-1:-1;64562:29:0;:85;;;5:2:-1;;;;30:1;27;20:12;5:2;64562:85:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64562:85:0;;;;63713:942;;;;;;;:::o;67429:589::-;67555:3;;67520:18;;-1:-1:-1;;;;;67555:3:0;:27;67551:460;;67628:3;;:46;;;-1:-1:-1;;;67628:46:0;;-1:-1:-1;;;;;67628:46:0;;;;;;;;;67677:3;;67628;;;;;:30;;:46;;;;;;;;;;;;;;;:3;:46;;;5:2:-1;;;;30:1;27;20:12;5:2;67628:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67628:46:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;67628:46:0;67612:62;;;;:68;;;;;;67599:81;;67716:13;67703:10;:26;67695:35;;;;;;67804:3;;:64;;;-1:-1:-1;;;67804:64:0;;-1:-1:-1;;;;;67804:64:0;;;;;;;;;:3;;;;;:30;;67841:10;;67804:64;;;;;:3;;:64;;;;;;;;67841:10;67804:3;:64;;;5:2:-1;;;;30:1;27;20:12;5:2;67804:64:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67804:64:0;;;;;67890:44;67903:30;67907:13;67922:10;67903:3;:30::i;:::-;67890:44;;;;;;;;;;;;;;;67551:460;;;67972:27;;;;;;;;;;;;;;;;;67429:589;;;;:::o;65151:237::-;65316:38;;65277:8;;65227:31;;-1:-1:-1;;;;;65316:20:0;;;65343:6;;65227:31;65316:38;65227:31;65316:38;65343:6;65316: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;;65298:56:0;;;65373:6;65365:15;;;;;64663:480;64843:18;;64839:120;;64878:69;-1:-1:-1;;;;;;;;;;;64916:14:0;64932;64878:69;:37;:69;:::i;:::-;65019:18;;65015:121;;65054:70;-1:-1:-1;;;;;;;;;;;65093:14:0;65109;65054:70;:38;:70;:::i;70723:572::-;70874:101;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;70874:101:0;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;71089:23:0;;;;70874:101;;-1:-1:-1;;70854:17:0;;-1:-1:-1;;;;;70897:35:0;;;70874:101;;71089:23;;25:18:-1;71089:23:0;;25:18:-1;36:153;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;;;71089:23: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;;71047:65:0;;;;71188:7;:32;;;;;71219:1;71199:10;:17;:21;71188:32;71184:104;;;71256:10;71245:30;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71245:30:0;71237:39;;;;;48958:598;-1:-1:-1;;;;;49126:21:0;;49081:17;49126:21;;;:10;:21;;;;;:29;-1:-1:-1;;;;;49126:29:0;;;49188:25;-1:-1:-1;;;49188:25:0;;;;;-1:-1:-1;;;49275:35:0;;;49470:3;49454:13;49470:3;49188:25;49454:3;:13::i;:::-;49407:44;49411:24;49415:10;49427:7;49411:3;:24::i;:::-;49437:13;49407:3;:44::i;:::-;:60;:66;;;;;;49395:78;;18064:8;49528:13;:19;49494:24;49499:9;49510:7;49494:4;:24::i;:::-;49521:3;49494:30;:53;;49486:62;;;;;;48958:598;;;;;;;;:::o;14787:633::-;14898:11;14894:50;;14926:7;;14894:50;-1:-1:-1;;;;;14960:21:0;;;;:45;;-1:-1:-1;;;;;;14985:20:0;;-1:-1:-1;;;;;;;;;;;14985:20:0;14960:45;14956:457;;;-1:-1:-1;;;;;15030:18:0;;15038:10;15030:18;:41;;;;;15065:6;15052:9;:19;;15030:41;15022:71;;;;;-1:-1:-1;;;15022:71:0;;;;;;;;;;;;-1:-1:-1;;;15022:71:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;15112:19:0;;15126:4;15112:19;15108:97;;15152:37;;-1:-1:-1;;;;;15152:29:0;;;:37;;;;;15182:6;;15152:37;;;;15182:6;15152:29;:37;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;15152:37:0;15108:97;15235:6;15223:9;:18;15219:110;;;15262:10;:51;15282:30;15290:9;15305:6;15282:30;:22;:30;:::i;:::-;15262:51;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;15262:51:0;15219:110;14956:457;;;15361:40;-1:-1:-1;;;;;15361:22:0;;15384:4;15390:2;15394:6;15361:40;:22;:40;:::i;68026:578::-;68215:158;;;-1:-1:-1;;;68215:158:0;;-1:-1:-1;;;;;;;;;;;68215:158:0;;;;19963:42;68215:158;;;;;;;;;;-1:-1:-1;;;;;;;;;;;68215:158:0;;;;20142:42;68215:158;;;;;;;;;;;;-1:-1:-1;;;;;68215:28:0;;;;;68250:12;;68215:158;;;;;-1:-1:-1;;68215:158:0;;;;;;;;68250:12;68215:28;:158;;;5:2:-1;;;;30:1;27;20:12;5:2;68215:158:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68215:158:0;;;;;68434:18;68455:38;20142:42;68483:9;68455:12;:38::i;:::-;68434:59;;68528:1;68512:13;:17;:83;;;;;68592:2;68573:14;68557:13;:30;68534:13;68550:3;68534:19;:54;;;;;;:60;;68512:83;68504:92;;;;;18250:113;18303:6;18064:8;18326:23;18330:9;18334:1;18337;18330:3;:9::i;:::-;18347:1;18064:8;18341:7;;68612:821;68783:9;68824;68919:23;:11;:23;68903:39;;68899:185;;;68959:63;-1:-1:-1;;;;;;;;;;;68997:9:0;69008:13;68959:63;:37;:63;:::i;:::-;68899:185;;;69071:1;69055:17;;68899:185;69156:5;69140:13;:21;69136:168;;;69178:64;-1:-1:-1;;;;;;;;;;;69217:9:0;69228:13;69178:64;:38;:64;:::i;:::-;69136:168;;;-1:-1:-1;69291:1:0;69136:168;69365:60;;;;;;;;;;;;;;-1:-1:-1;;;;;69365:60:0;;;;;;;;;;;68612:821;;;;;:::o;49564:951::-;-1:-1:-1;;;;;49778:21:0;;49710:17;49778:21;;;:10;:21;;;;;:29;49710:17;;-1:-1:-1;;;;;49778:29:0;;;;49840:25;-1:-1:-1;;;49840:25:0;;;;;-1:-1:-1;;;49927:35:0;;;;;;-1:-1:-1;;;50019:35:0;;;49710:17;50189:3;50173:13;50189:3;49840:25;50173:3;:13::i;:::-;50126:44;50130:24;50134:10;50146:7;50130:3;:24::i;:::-;50156:13;50126:3;:44::i;:::-;:60;:66;;;;;;50109:83;;50271:4;50221:47;50226:23;50230:7;50239:9;50226:3;:23::i;:::-;50251:9;50263:4;50251:16;50221:4;:47::i;:::-;:54;;;;;;50205:70;;50288:16;50333:4;50307:23;50312:7;50321:8;50307:4;:23::i;:::-;:30;;;;;;50288:49;;50370:1;50356:11;:15;50348:24;;;;;;50397:31;50401:13;50416:11;50397:3;:31::i;:::-;50385:43;;18064:8;50487:13;:19;50449:28;50454:9;50465:11;50449:4;:28::i;:::-;50480:3;50449:34;:57;;50441:66;;;;;;49564:951;;;;;;;;;;;;;:::o;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;;-1:-1:-1;;;;;;;;;;;14229:20:0;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;2070:136::-;2128:7;2155:43;2159:1;2162;2155:43;;;;;;;;;;;;;;;;;:3;:43::i;10644:204::-;10771:68;;;-1:-1:-1;;;;;10771:68:0;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;10771:68:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;10745:95:0;;10764:5;;10745:18;:95::i;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;;10543:18;:85::i;2543:192::-;2629:7;2665:12;2657:6;;;;2649:29;;;;-1:-1:-1;;;2649:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;2649:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;2701:5:0;;;2543:192::o;12454:1114::-;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;32239:39132::-;;;;;;;;;-1:-1:-1;32239:39132:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;-1:-1;32239:39132:0;;;-1:-1:-1;;32239:39132:0:o

Swarm Source

bzzr://af507effa288a92fae8ba7d6314290832dfc80c36f591a14da6091af1c3413e2

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.