ETH Price: $2,539.73 (-4.06%)
Gas: 1 Gwei

Token

Musk Gold Farm ()
 

Overview

Max Total Supply

0 Musk Gold Farm

Holders

0

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 0 Decimals)

Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
MuskGoldFarmV1

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-04-28
*/

pragma solidity ^0.8.9;


// SPDX-License-Identifier: NONE
// 
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)
/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

// 
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

// 
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// 
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)
/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

// 
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

// 
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/ERC20.sol)
/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, _allowances[owner][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = _allowances[owner][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Spend `amount` form the allowance of `owner` toward `spender`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

// 
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

// 
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)
/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

// 
// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)
/**
 * @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 {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. 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.
     *
     * 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.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @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.
     *
     * 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) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // 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 (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): 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), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * 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));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

// 
// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)
/**
 * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
 *
 * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
 * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
 * they need in their contracts using a combination of `abi.encode` and `keccak256`.
 *
 * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
 * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
 * ({_hashTypedDataV4}).
 *
 * The implementation of the domain separator was designed to be as efficient as possible while still properly updating
 * the chain id to protect against replay attacks on an eventual fork of the chain.
 *
 * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
 * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
 *
 * _Available since v3.4._
 */
abstract contract EIP712 {
    /* solhint-disable var-name-mixedcase */
    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
    // invalidate the cached domain separator if the chain id changes.
    bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
    uint256 private immutable _CACHED_CHAIN_ID;
    address private immutable _CACHED_THIS;

    bytes32 private immutable _HASHED_NAME;
    bytes32 private immutable _HASHED_VERSION;
    bytes32 private immutable _TYPE_HASH;

    /* solhint-enable var-name-mixedcase */

    /**
     * @dev Initializes the domain separator and parameter caches.
     *
     * The meaning of `name` and `version` is specified in
     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
     *
     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
     * - `version`: the current major version of the signing domain.
     *
     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
     * contract upgrade].
     */
    constructor(string memory name, string memory version) {
        bytes32 hashedName = keccak256(bytes(name));
        bytes32 hashedVersion = keccak256(bytes(version));
        bytes32 typeHash = keccak256(
            "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
        );
        _HASHED_NAME = hashedName;
        _HASHED_VERSION = hashedVersion;
        _CACHED_CHAIN_ID = block.chainid;
        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
        _CACHED_THIS = address(this);
        _TYPE_HASH = typeHash;
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {
            return _CACHED_DOMAIN_SEPARATOR;
        } else {
            return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
        }
    }

    function _buildDomainSeparator(
        bytes32 typeHash,
        bytes32 nameHash,
        bytes32 versionHash
    ) private view returns (bytes32) {
        return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));
    }

    /**
     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
     * function returns the hash of the fully encoded EIP712 message for this domain.
     *
     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
     *
     * ```solidity
     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
     *     keccak256("Mail(address to,string contents)"),
     *     mailTo,
     *     keccak256(bytes(mailContents))
     * )));
     * address signer = ECDSA.recover(digest, signature);
     * ```
     */
    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
        return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
    }
}

// 
// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)
/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

// 
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol)
/**
 * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 *
 * _Available since v3.4._
 */
abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {
    using Counters for Counters.Counter;

    mapping(address => Counters.Counter) private _nonces;

    // solhint-disable-next-line var-name-mixedcase
    bytes32 private immutable _PERMIT_TYPEHASH =
        keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");

    /**
     * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
     *
     * It's a good idea to use the same `name` that is defined as the ERC20 token name.
     */
    constructor(string memory name) EIP712(name, "1") {}

    /**
     * @dev See {IERC20Permit-permit}.
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual override {
        require(block.timestamp <= deadline, "ERC20Permit: expired deadline");

        bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));

        bytes32 hash = _hashTypedDataV4(structHash);

        address signer = ECDSA.recover(hash, v, r, s);
        require(signer == owner, "ERC20Permit: invalid signature");

        _approve(owner, spender, value);
    }

    /**
     * @dev See {IERC20Permit-nonces}.
     */
    function nonces(address owner) public view virtual override returns (uint256) {
        return _nonces[owner].current();
    }

    /**
     * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view override returns (bytes32) {
        return _domainSeparatorV4();
    }

    /**
     * @dev "Consume a nonce": return the current value and increment.
     *
     * _Available since v4.1._
     */
    function _useNonce(address owner) internal virtual returns (uint256 current) {
        Counters.Counter storage nonce = _nonces[owner];
        current = nonce.current();
        nonce.increment();
    }
}

// 
// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)
/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a / b + (a % b == 0 ? 0 : 1);
    }
}

// 
// OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol)
/**
 * @dev Collection of functions related to array types.
 */
library Arrays {
    /**
     * @dev Searches a sorted `array` and returns the first index that contains
     * a value greater or equal to `element`. If no such index exists (i.e. all
     * values in the array are strictly less than `element`), the array length is
     * returned. Time complexity O(log n).
     *
     * `array` is expected to be sorted in ascending order, and to contain no
     * repeated elements.
     */
    function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
        if (array.length == 0) {
            return 0;
        }

        uint256 low = 0;
        uint256 high = array.length;

        while (low < high) {
            uint256 mid = Math.average(low, high);

            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
            // because Math.average rounds down (it does integer division with truncation).
            if (array[mid] > element) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.
        if (low > 0 && array[low - 1] == element) {
            return low - 1;
        } else {
            return low;
        }
    }
}

// 
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Snapshot.sol)
/**
 * @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and
 * total supply at the time are recorded for later access.
 *
 * This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting.
 * In naive implementations it's possible to perform a "double spend" attack by reusing the same balance from different
 * accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be
 * used to create an efficient ERC20 forking mechanism.
 *
 * Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a
 * snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot
 * id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id
 * and the account address.
 *
 * NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it
 * return `block.number` will trigger the creation of snapshot at the begining of each new block. When overridding this
 * function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract.
 *
 * Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient
 * alternative consider {ERC20Votes}.
 *
 * ==== Gas Costs
 *
 * Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log
 * n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much
 * smaller since identical balances in subsequent snapshots are stored as a single entry.
 *
 * There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is
 * only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent
 * transfers will have normal cost until the next snapshot, and so on.
 */
abstract contract ERC20Snapshot is ERC20 {
    // Inspired by Jordi Baylina's MiniMeToken to record historical balances:
    // https://github.com/Giveth/minimd/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol

    using Arrays for uint256[];
    using Counters for Counters.Counter;

    // Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a
    // Snapshot struct, but that would impede usage of functions that work on an array.
    struct Snapshots {
        uint256[] ids;
        uint256[] values;
    }

    mapping(address => Snapshots) private _accountBalanceSnapshots;
    Snapshots private _totalSupplySnapshots;

    // Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid.
    Counters.Counter private _currentSnapshotId;

    /**
     * @dev Emitted by {_snapshot} when a snapshot identified by `id` is created.
     */
    event Snapshot(uint256 id);

    /**
     * @dev Creates a new snapshot and returns its snapshot id.
     *
     * Emits a {Snapshot} event that contains the same id.
     *
     * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a
     * set of accounts, for example using {AccessControl}, or it may be open to the public.
     *
     * [WARNING]
     * ====
     * While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking,
     * you must consider that it can potentially be used by attackers in two ways.
     *
     * First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow
     * logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target
     * specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs
     * section above.
     *
     * We haven't measured the actual numbers; if this is something you're interested in please reach out to us.
     * ====
     */
    function _snapshot() internal virtual returns (uint256) {
        _currentSnapshotId.increment();

        uint256 currentId = _getCurrentSnapshotId();
        emit Snapshot(currentId);
        return currentId;
    }

    /**
     * @dev Get the current snapshotId
     */
    function _getCurrentSnapshotId() internal view virtual returns (uint256) {
        return _currentSnapshotId.current();
    }

    /**
     * @dev Retrieves the balance of `account` at the time `snapshotId` was created.
     */
    function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) {
        (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]);

        return snapshotted ? value : balanceOf(account);
    }

    /**
     * @dev Retrieves the total supply at the time `snapshotId` was created.
     */
    function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) {
        (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots);

        return snapshotted ? value : totalSupply();
    }

    // Update balance and/or total supply snapshots before the values are modified. This is implemented
    // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations.
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, amount);

        if (from == address(0)) {
            // mint
            _updateAccountSnapshot(to);
            _updateTotalSupplySnapshot();
        } else if (to == address(0)) {
            // burn
            _updateAccountSnapshot(from);
            _updateTotalSupplySnapshot();
        } else {
            // transfer
            _updateAccountSnapshot(from);
            _updateAccountSnapshot(to);
        }
    }

    function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) {
        require(snapshotId > 0, "ERC20Snapshot: id is 0");
        require(snapshotId <= _getCurrentSnapshotId(), "ERC20Snapshot: nonexistent id");

        // When a valid snapshot is queried, there are three possibilities:
        //  a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never
        //  created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds
        //  to this id is the current one.
        //  b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the
        //  requested id, and its value is the one to return.
        //  c) More snapshots were created after the requested one, and the queried value was later modified. There will be
        //  no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is
        //  larger than the requested one.
        //
        // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if
        // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does
        // exactly this.

        uint256 index = snapshots.ids.findUpperBound(snapshotId);

        if (index == snapshots.ids.length) {
            return (false, 0);
        } else {
            return (true, snapshots.values[index]);
        }
    }

    function _updateAccountSnapshot(address account) private {
        _updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account));
    }

    function _updateTotalSupplySnapshot() private {
        _updateSnapshot(_totalSupplySnapshots, totalSupply());
    }

    function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private {
        uint256 currentId = _getCurrentSnapshotId();
        if (_lastSnapshotId(snapshots.ids) < currentId) {
            snapshots.ids.push(currentId);
            snapshots.values.push(currentValue);
        }
    }

    function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) {
        if (ids.length == 0) {
            return 0;
        } else {
            return ids[ids.length - 1];
        }
    }
}

// 
// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // 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 (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @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) {
        return a + b;
    }

    /**
     * @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 a - b;
    }

    /**
     * @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) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting 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 a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

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

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

// 
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)
/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is 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.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @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].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// 
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)
/**
 * @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 IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

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

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

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 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'
        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(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - 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(IERC20 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. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

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

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

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

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

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}

// 
// QuickFarm V1
// CREATED FOR MUSK GOLD BY QUICKFARM
contract MuskGoldFarmV1 is Ownable, ReentrancyGuard {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    //////////////////////////////////////////
    // USER DEPOSIT DEFINITION
    //////////////////////////////////////////
    struct UserDeposit {
        uint256 balance; // THE DEPOSITED NUMBER OF TOKENS BY THE USER
        uint256 unlockTime; // TIME WHEN THE USER CAN WITHDRAW FUNDS (BASED ON EPOCH)
        uint256 lastPayout; // BLOCK NUMBER OF THE LAST PAYOUT FOR THIS USER IN THIS POOL
        uint256 totalEarned; // TOTAL NUMBER OF TOKENS THIS USER HAS EARNED
    }

    //////////////////////////////////////////
    // REWARD POOL DEFINITION
    //////////////////////////////////////////
    struct RewardPool {
        IERC20 depositToken; // ADDRESS OF DEPOSITED TOKEN CONTRACT
        bool active; // DETERMINES WHETHER OR NOT THIS POOL IS USABLE
        bool hidden; // FLAG FOR WHETHER UI SHOULD RENDER THIS
        bool uniV2Lp; // SIGNIFIES A IUNISWAPV2PAIR
        bool selfStake; // SIGNIFIES IF THIS IS A 'SINGLE SIDED' SELF STAKE
        bytes32 lpOrigin; // ORIGIN OF LP TOKEN BEING DEPOSITED E.G. SUSHI, UNISWAP, PANCAKE - NULL IF NOT N LP TOKEN
        uint256 lockSeconds; // HOW LONG UNTIL AN LP DEPOSIT CAN BE REMOVED IN SECONDS
        bool lockEnforced; // DETERMINES WHETER TIME LOCKS ARE ENFORCED
        uint256 rewardPerBlock; // HOW MANY TOKENS TO REWARD PER BLOCK FOR THIS POOL
        bytes32 label; // TEXT LABEL STRICTLY FOR READABILITY AND RENDERING
        bytes32 order; // DISPLAY/PRESENTATION ORDER OF THE POOL
        uint256 depositSum; // SUM OF ALL DEPOSITED TOKENS IN THIS POOL
    }

    //////////////////////////////////////////
    // USER FARM STATE DEFINITION
    //////////////////////////////////////////
    struct UserFarmState {
        RewardPool[] pools; // REWARD POOLS
        uint256[] balance; // DEPOSITS BY POOL
        uint256[] unlockTime; // UNLOCK TIME FOR EACH POOL DEPOSIT
        uint256[] pending; // PENDING REWARDS BY POOL
        uint256[] earnings; // EARNINGS BY POOL
        uint256[] depTknBal; // USER BALANCE OF DEPOSIT TOKEN
        uint256[] depTknSupply; // TOTAL SUPPLY OF DEPOSIT TOKEN
        uint256[] reserve0; // RESERVE0 AMOUNT FOR LP TKN0
        uint256[] reserve1; // RESERVE1 AMOUNT FOR LP TKN1
        address[] token0; // ADDRESS OF LP TOKEN 0
        address[] token1; // ADDRESS OF LP TOKEN 1
        uint256 rewardTknBal; // CURRENT USER HOLDINGS OF THE REWARD TOKEN
        uint256 pendingAllPools; // REWARDS PENDING FOR ALL POOLS
        uint256 earningsAllPools; // REWARDS EARNED FOR ALL POOLS
    }

    //////////////////////////////////////////
    // INIT CLASS VARIABLES
    //////////////////////////////////////////
    bytes32 public name; // POOL NAME, FOR DISPLAY ON BLOCK EXPLORER
    IERC20 public rewardToken; // ADDRESS OF THE ERC20 REWARD TOKEN
    address public rewardWallet; // WALLE THAT REWARD TOKENS ARE DRAWN FROM
    uint256 public earliestRewards; // EARLIEST BLOCK REWARDS CAN BE GENERATED FROM (FOR FAIR LAUNCH)
    uint256 public paidOut = 0; // TOTAL AMOUNT OF REWARDS THAT HAVE BEEN PAID OUT

    RewardPool[] public rewardPools; // INFO OF EACH POOL
    address[] public depositAddresses; // LIST OF ADDRESSES THAT CURRENTLY HAVE FUNDS DEPOSITED
    mapping(uint256 => mapping(address => UserDeposit)) public userDeposits; // INFO OF EACH USER THAT STAKES LP TOKENS

    //////////////////////////////////////////
    // EVENTS
    //////////////////////////////////////////
    event Deposit(
        address indexed from,
        address indexed user,
        uint256 indexed pid,
        uint256 amount
    );
    event Withdraw(address indexed user, uint256 indexed pid, uint256 amount);
    event Reward(address indexed user, uint256 indexed pid, uint256 amount);
    event Restake(address indexed user, uint256 indexed pid, uint256 amount);
    event EmergencyWithdraw(
        address indexed user,
        uint256 indexed pid,
        uint256 amount
    );

    //////////////////////////////////////////
    // CONSTRUCTOR
    //////////////////////////////////////////
    constructor(
        IERC20 _rewardToken,
        address _rewardWallet,
        uint256 _earliestRewards
    ) {
        name = "Musk Gold Farm";
        rewardToken = _rewardToken;
        rewardWallet = _rewardWallet;
        earliestRewards = _earliestRewards;
    }

    //////////////////////////////////////////
    // FARM FUNDING CONTROLS
    //////////////////////////////////////////

    // SETS ADDRESS THAT REWARDS ARE TO BE PAID FROM
    function setRewardWallet(address _source) external onlyOwner {
        rewardWallet = _source;
    }

    // FUND THE FARM (JUST DEPOSITS FUNDS INTO THE REWARD WALLET)
    function fund(uint256 _amount) external {
        require(msg.sender != rewardWallet, "Sender is reward wallet");
        rewardToken.safeTransferFrom(
            address(msg.sender),
            rewardWallet,
            _amount
        );
    }

    //////////////////////////////////////////
    // POOL CONTROLS
    //////////////////////////////////////////

    // ADD LP TOKEN REWARD POOL
    function addPool(
        IERC20 _depositToken,
        bool _active,
        bool _hidden,
        bool _uniV2Lp,
        bytes32 _lpOrigin,
        uint256 _lockSeconds,
        bool _lockEnforced,
        uint256 _rewardPerBlock,
        bytes32 _label,
        bytes32 _order
    ) external onlyOwner {
        // MAKE SURE THIS REWARD POOL FOR TOKEN + LOCK DOESN'T ALREADY EXIST
        require(
            poolExists(_depositToken, _lockSeconds) == false,
            "Reward pool for token already exists"
        );

        // IF TOKEN BEING DEPOSITED IS THE SAME AS THE REWARD TOKEN MARK IT AS A SELF STAKE (SINGLE SIDED)
        bool selfStake = false;
        if (_depositToken == rewardToken) {
            selfStake = true;
            _uniV2Lp = false;
        }

        rewardPools.push(
            RewardPool({
                depositToken: _depositToken,
                active: _active,
                hidden: _hidden,
                uniV2Lp: _uniV2Lp,
                selfStake: selfStake, // MARKS IF A "SINGLED SIDED" STAKE OF THE REWARD TOKEN
                lpOrigin: _lpOrigin,
                lockSeconds: _lockSeconds,
                lockEnforced: _lockEnforced,
                rewardPerBlock: _rewardPerBlock,
                label: _label,
                order: _order,
                depositSum: 0
            })
        );
    }

    function setPool(
        // MODIFY AN EXISTING POOL
        uint256 _pid,
        bool _active,
        bool _hidden,
        bool _uniV2Lp,
        bytes32 _lpOrigin,
        uint256 _lockSeconds,
        bool _lockEnforced,
        uint256 _rewardPerBlock,
        bytes32 _label,
        bytes32 _order
    ) external onlyOwner {
        rewardPools[_pid].active = _active;
        rewardPools[_pid].hidden = _hidden;
        rewardPools[_pid].uniV2Lp = _uniV2Lp;
        rewardPools[_pid].lpOrigin = _lpOrigin;
        rewardPools[_pid].lockSeconds = _lockSeconds;
        rewardPools[_pid].lockEnforced = _lockEnforced;
        rewardPools[_pid].rewardPerBlock = _rewardPerBlock;
        rewardPools[_pid].label = _label;
        rewardPools[_pid].order = _order;
    }

    // PAUSES/RESUMES DEPOSITS FOR ALL POOLS
    function setFarmActive(bool _value) public onlyOwner {
        for (uint256 pid = 0; pid < rewardPools.length; ++pid) {
            RewardPool storage pool = rewardPools[pid];
            pool.active = _value;
        }
    }

    // SETS THE EARLIEST BLOCK FROM WHICH TO CALCULATE REWARDS
    function setEarliestRewards(uint256 _value) external onlyOwner {
        require(
            _value >= block.number,
            "Earliest reward block must be greater than the current block"
        );
        earliestRewards = _value;
    }

    //////////////////////////////////////////
    // DEPOSIT/WITHDRAW METHODS
    //////////////////////////////////////////

    // SETS THE "LAST PAYOUT" FOR A USER TO ULTIMATELY DETERMINE HOW MANY REWARDS THEY ARE OWED
    function setLastPayout(UserDeposit storage _deposit) private {
        _deposit.lastPayout = block.number;
        if (_deposit.lastPayout < earliestRewards)
            _deposit.lastPayout = earliestRewards; // FAIR LAUNCH ACCOMODATION
    }

    // DEPOSIT TOKENS (LP OR SIMPLE ERC20) FOR A GIVEN TARGET (USER) WALLET
    function deposit(
        uint256 _pid,
        address _user,
        uint256 _amount
    ) public nonReentrant {
        RewardPool storage pool = rewardPools[_pid];
        require(_amount > 0, "Amount must be greater than zero");
        require(pool.active == true, "This reward pool is inactive");

        UserDeposit storage userDeposit = userDeposits[_pid][_user];

		// SET INITIAL LAST PAYOUT
        if (userDeposit.lastPayout == 0) {
            userDeposit.lastPayout = block.number;
            if (userDeposit.lastPayout < earliestRewards)
                userDeposit.lastPayout = earliestRewards; // FAIR LAUNCH ACCOMODATION
        }

        // COLLECT REWARD ONLY IF ADDRESS DEPOSITING IS THE OWNER OF THE DEPOSIT
        if (userDeposit.balance > 0 && msg.sender == _user) {
            payReward(_pid, _user);
        }

        pool.depositToken.safeTransferFrom(
            address(msg.sender),
            address(this),
            _amount
        ); // DO THE ACTUAL DEPOSIT
        userDeposit.balance = userDeposit.balance.add(_amount); // ADD THE TRANSFERRED AMOUNT TO THE DEPOSIT VALUE
        userDeposit.unlockTime = block.timestamp.add(pool.lockSeconds); // UPDATE THE UNLOCK TIME
        pool.depositSum = pool.depositSum.add(_amount); // KEEP TRACK OF TOTAL DEPOSITS IN THE POOL

        recordAddress(_user); // RECORD THE USER ADDRESS IN THE LIST
        emit Deposit(msg.sender, _user, _pid, _amount);
    }

    // PRIVATE METHOD TO PAY OUT USER REWARDS
    function payReward(uint256 _pid, address _user) private {
        UserDeposit storage userDeposit = userDeposits[_pid][_user]; // FETCH THE DEPOSIT
        uint256 rewardsDue = userPendingPool(_pid, _user); // GET PENDING REWARDS

        if (rewardsDue <= 0) return; // BAIL OUT IF NO REWARD IS DUE

        rewardToken.transferFrom(rewardWallet, _user, rewardsDue);
        emit Reward(_user, _pid, rewardsDue);

        userDeposit.totalEarned = userDeposit.totalEarned.add(rewardsDue); // ADD THE PAYOUT AMOUNT TO TOTAL EARNINGS
        paidOut = paidOut.add(rewardsDue); // ADD AMOUNT TO TOTAL PAIDOUT FOR THE WHOLE FARM

        setLastPayout(userDeposit); // UPDATE THE LAST PAYOUT
    }

    // EXTERNAL METHOD FOR USER'S TO COLLECT REWARDS
    function collectReward(uint256 _pid) external nonReentrant {
        payReward(_pid, msg.sender);
    }

    // RESTAKE REWARDS INTO SINGLE-SIDED POOLS
    function restake(uint256 _pid) external nonReentrant {
        RewardPool storage pool = rewardPools[_pid]; // GET THE POOL
        UserDeposit storage userDeposit = userDeposits[_pid][msg.sender]; // FETCH THE DEPOSIT

        require(
            pool.depositToken == rewardToken,
            "Restake is only available on single-sided staking"
        );

        uint256 rewardsDue = userPendingPool(_pid, msg.sender); // GET PENDING REWARD AMOUNT
        if (rewardsDue <= 0) return; // BAIL OUT IF NO REWARDS ARE TO BE PAID

        pool.depositToken.safeTransferFrom(
            rewardWallet,
            address(this),
            rewardsDue
        ); // MOVE FUNDS FROM THE REWARDS TO THIS CONTRACT
        pool.depositSum = pool.depositSum.add(rewardsDue);

        userDeposit.balance = userDeposit.balance.add(rewardsDue); // ADD THE FUNDS MOVED TO THE USER'S BALANCE
        userDeposit.totalEarned = userDeposit.totalEarned.add(rewardsDue); // ADD FUNDS MOVED TO USER'S TOTAL EARNINGS FOR POOL

        setLastPayout(userDeposit); // UPDATE THE LAST PAYOUT

        paidOut = paidOut.add(rewardsDue); // ADD TO THE TOTAL PAID OUT FOR THE FARM
        emit Restake(msg.sender, _pid, rewardsDue);
    }

    // WITHDRAW LP TOKENS FROM FARM.
    function withdraw(uint256 _pid, uint256 _amount) external nonReentrant {
        RewardPool storage pool = rewardPools[_pid];
        UserDeposit storage userDeposit = userDeposits[_pid][msg.sender];

        if (pool.lockEnforced)
            require(
                userDeposit.unlockTime <= block.timestamp,
                "withdraw: time lock has not passed"
            );
        require(
            userDeposit.balance >= _amount,
            "withdraw: can't withdraw more than deposit"
        );

        payReward(_pid, msg.sender); // PAY OUT ANY REWARDS ACCUMULATED UP TO THIS POINT
        setLastPayout(userDeposit); // UPDATE THE LAST PAYOUT

        userDeposit.unlockTime = block.timestamp.add(pool.lockSeconds); // RESET THE UNLOCK TIME
        userDeposit.balance = userDeposit.balance.sub(_amount); // SUBTRACT THE AMOUNT DEBITED FROM THE BALANCE
        pool.depositToken.safeTransfer(address(msg.sender), _amount); // TRANSFER THE WITHDRAWN AMOUNT BACK TO THE USER
        emit Withdraw(msg.sender, _pid, _amount);

        pool.depositSum = pool.depositSum.sub(_amount); // SUBTRACT THE WITHDRAWN AMOUNT FROM THE POOL DEPOSIT TOTAL
        cleanupAddress(msg.sender);
    }

    // APPEND ADDRESSES THAT HAVE FUNDS DEPOSITED FOR EASY RETRIEVAL
    function recordAddress(address _address) private {
        for (uint256 i = 0; i < depositAddresses.length; i++) {
            address curAddress = depositAddresses[i];
            if (_address == curAddress) return;
        }
        depositAddresses.push(_address);
    }

    // CLEAN ANY ADDRESSES THAT DON'T HAVE ACTIVE DEPOSITS
    function cleanupAddress(address _address) private {
        // CHECK TO SEE IF THE ADDRESS HAS ANY DEPOSITS
        uint256 deposits = 0;
        for (uint256 pid = 0; pid < rewardPools.length; pid++) {
            deposits = deposits.add(userDeposits[pid][_address].balance);
        }

        if (deposits > 0) return; // BAIL OUT IF USER STILL HAS DEPOSITS

        for (uint256 i = 0; i < depositAddresses.length; i++) {
            address curAddress = depositAddresses[i];
            if (_address == curAddress) delete depositAddresses[i]; // REMOVE ADDRESS FROM ARRAY
        }
    }

    //////////////////////////////////////////
    // INFORMATION METHODS
    //////////////////////////////////////////

    // RETURNS THE ARRAY OF POOLS
    function getPools() public view returns (RewardPool[] memory) {
        return rewardPools;
    }

    // RETURNS REWARD TOKENS REMAINING
    function rewardsRemaining() public view returns (uint256) {
        return rewardToken.balanceOf(rewardWallet);
    }

    // RETURNS COUNT OF ADDRESSES WITH DEPOSITS
    function addressCount() external view returns (uint256) {
        return depositAddresses.length;
    }

    // CHECK IF A GIVEN DEPOSIT TOKEN + TIMELOCK COMBINATION ALREADY EXISTS
    function poolExists(IERC20 _depositToken, uint256 _lockSeconds)
        private
        view
        returns (bool)
    {
        for (uint256 pid = 0; pid < rewardPools.length; ++pid) {
            RewardPool storage pool = rewardPools[pid];
            if (
                pool.depositToken == _depositToken &&
                pool.lockSeconds == _lockSeconds
            ) return true;
        }
        return false;
    }

    // RETURNS COUNT OF LP POOLS
    function poolLength() external view returns (uint256) {
        return rewardPools.length;
    }

    // RETURNS SUM OF DEPOSITS IN X POOL
    function poolDepositSum(uint256 _pid) external view returns (uint256) {
        return rewardPools[_pid].depositSum;
    }

    // VIEW FUNCTION TO SEE PENDING REWARDS FOR A USER
    function userPendingPool(uint256 _pid, address _user)
        public
        view
        returns (uint256)
    {
        RewardPool storage pool = rewardPools[_pid];
        UserDeposit storage userDeposit = userDeposits[_pid][_user];

        if (userDeposit.balance == 0) return 0;
        if (earliestRewards > block.number) return 0;

        uint256 precision = 1e36;

        uint256 blocksElapsed = 0;
        if (block.number > userDeposit.lastPayout)
            blocksElapsed = block.number.sub(userDeposit.lastPayout);

        uint256 poolOwnership = userDeposit.balance.mul(precision).div(
            pool.depositSum
        );
        uint256 rewardsDue = blocksElapsed
            .mul(pool.rewardPerBlock)
            .mul(poolOwnership)
            .div(precision);
        return rewardsDue;
    }

    // GETS PENDING REWARDS FOR A GIVEN USER IN ALL POOLS
    function userPendingAll(address _user) public view returns (uint256) {
        uint256 totalReward = 0;
        for (uint256 pid = 0; pid < rewardPools.length; ++pid) {
            uint256 pending = userPendingPool(pid, _user);
            totalReward = totalReward.add(pending);
        }
        return totalReward;
    }

    // RETURNS TOTAL PAID OUT TO A USER FOR A GIVEN POOL
    function userEarnedPool(uint256 _pid, address _user)
        public
        view
        returns (uint256)
    {
        return userDeposits[_pid][_user].totalEarned;
    }

    // RETURNS USER EARNINGS FOR ALL POOLS
    function userEarnedAll(address _user) public view returns (uint256) {
        uint256 totalEarned = 0;
        for (uint256 pid = 0; pid < rewardPools.length; ++pid) {
            totalEarned = totalEarned.add(userDeposits[pid][_user].totalEarned);
        }
        return totalEarned;
    }

    // VIEW FUNCTION FOR TOTAL REWARDS THE FARM HAS YET TO PAY OUT
    function farmTotalPending() external view returns (uint256) {
        uint256 pending = 0;

        for (uint256 i = 0; i < depositAddresses.length; ++i) {
            uint256 userPending = userPendingAll(depositAddresses[i]);
            pending = pending.add(userPending);
        }
        return pending;
    }

    // RETURNS A GIVEN USER'S STATE IN THE FARM IN A SINGLE CALL
    function getUserState(address _user)
        external
        view
        returns (UserFarmState memory)
    {
        uint256[] memory balance = new uint256[](rewardPools.length);
        uint256[] memory pending = new uint256[](rewardPools.length);
        uint256[] memory earned = new uint256[](rewardPools.length);
        uint256[] memory depTknBal = new uint256[](rewardPools.length);
        uint256[] memory depTknSupply = new uint256[](rewardPools.length);
        uint256[] memory depTknReserve0 = new uint256[](rewardPools.length);
        uint256[] memory depTknReserve1 = new uint256[](rewardPools.length);
        address[] memory depTknResTkn0 = new address[](rewardPools.length);
        address[] memory depTknResTkn1 = new address[](rewardPools.length);
        uint256[] memory unlockTime = new uint256[](rewardPools.length);

        for (uint256 pid = 0; pid < rewardPools.length; ++pid) {
            balance[pid] = userDeposits[pid][_user].balance;
            pending[pid] = userPendingPool(pid, _user);
            earned[pid] = userEarnedPool(pid, _user);
            depTknBal[pid] = rewardPools[pid].depositToken.balanceOf(_user);
            depTknSupply[pid] = rewardPools[pid].depositToken.totalSupply();
            unlockTime[pid] = userDeposits[pid][_user].unlockTime;

            if (
                rewardPools[pid].uniV2Lp == true &&
                rewardPools[pid].selfStake == false
            ) {
                IUniswapV2Pair pair = IUniswapV2Pair(
                    address(rewardPools[pid].depositToken)
                );
                (uint256 res0, uint256 res1, uint256 timestamp) = pair
                    .getReserves();
                depTknReserve0[pid] = res0;
                depTknReserve1[pid] = res1;
                depTknResTkn0[pid] = pair.token0();
                depTknResTkn1[pid] = pair.token1();
            }
        }

        return
            UserFarmState(
                rewardPools, // POOLS
                balance, // DEPOSITS BY POOL
                unlockTime, // UNLOCK TIME FOR EACH DEPOSITED POOL
                pending, // PENDING REWARDS BY POOL
                earned, // EARNINGS BY POOL
                depTknBal, // USER BALANCE OF DEPOSIT TOKEN
                depTknSupply, // TOTAL SUPPLY OF DEPOSIT TOKEN
                depTknReserve0, // RESERVE0 AMOUNT FOR LP TKN0
                depTknReserve1, // RESERVE1 AMOUNT FOR LP TKN1
                depTknResTkn0, // ADDRESS OF LP TOKEN 0
                depTknResTkn1, // ADDRESS OF LP TOKEN 1
                rewardToken.balanceOf(_user), // CURRENT USER HOLDINGS OF THE REWARD TOKEN
                userPendingAll(_user), // REWARDS PENDING FOR ALL POOLS
                userEarnedAll(_user) // REWARDS EARNED FOR ALL POOLS
            );
    }

    //////////////////////////////////////////
    // EMERGENCY CONTROLS
    //////////////////////////////////////////

    // WITHDRAW WITHOUT CARING ABOUT REWARDS. EMERGENCY ONLY.
    // THIS WILL WIPE OUT ANY PENDING REWARDS FOR A USER
    function emergencyWithdraw(uint256 _pid) external nonReentrant {
        RewardPool storage pool = rewardPools[_pid]; // GET THE POOL
        UserDeposit storage userDeposit = userDeposits[_pid][msg.sender]; //GET THE DEPOSIT

        pool.depositToken.safeTransfer(
            address(msg.sender),
            userDeposit.balance
        ); // TRANSFER THE DEPOSIT BACK TO THE USER
        pool.depositSum = pool.depositSum.sub(userDeposit.balance); // DECREMENT THE POOL'S OVERALL DEPOSIT SUM
        userDeposit.unlockTime = block.timestamp.add(pool.lockSeconds); // RESET THE UNLOCK TIME
        userDeposit.balance = 0; // SET THE BALANCE TO ZERO AFTER WIRTHDRAWAL
        setLastPayout(userDeposit); // UPDATE THE LAST PAYOUT

        emit EmergencyWithdraw(msg.sender, _pid, userDeposit.balance);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IERC20","name":"_rewardToken","type":"address"},{"internalType":"address","name":"_rewardWallet","type":"address"},{"internalType":"uint256","name":"_earliestRewards","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Restake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Reward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"contract IERC20","name":"_depositToken","type":"address"},{"internalType":"bool","name":"_active","type":"bool"},{"internalType":"bool","name":"_hidden","type":"bool"},{"internalType":"bool","name":"_uniV2Lp","type":"bool"},{"internalType":"bytes32","name":"_lpOrigin","type":"bytes32"},{"internalType":"uint256","name":"_lockSeconds","type":"uint256"},{"internalType":"bool","name":"_lockEnforced","type":"bool"},{"internalType":"uint256","name":"_rewardPerBlock","type":"uint256"},{"internalType":"bytes32","name":"_label","type":"bytes32"},{"internalType":"bytes32","name":"_order","type":"bytes32"}],"name":"addPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"addressCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"collectReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"depositAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"earliestRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"farmTotalPending","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"fund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getPools","outputs":[{"components":[{"internalType":"contract IERC20","name":"depositToken","type":"address"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"bool","name":"hidden","type":"bool"},{"internalType":"bool","name":"uniV2Lp","type":"bool"},{"internalType":"bool","name":"selfStake","type":"bool"},{"internalType":"bytes32","name":"lpOrigin","type":"bytes32"},{"internalType":"uint256","name":"lockSeconds","type":"uint256"},{"internalType":"bool","name":"lockEnforced","type":"bool"},{"internalType":"uint256","name":"rewardPerBlock","type":"uint256"},{"internalType":"bytes32","name":"label","type":"bytes32"},{"internalType":"bytes32","name":"order","type":"bytes32"},{"internalType":"uint256","name":"depositSum","type":"uint256"}],"internalType":"struct MuskGoldFarmV1.RewardPool[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserState","outputs":[{"components":[{"components":[{"internalType":"contract IERC20","name":"depositToken","type":"address"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"bool","name":"hidden","type":"bool"},{"internalType":"bool","name":"uniV2Lp","type":"bool"},{"internalType":"bool","name":"selfStake","type":"bool"},{"internalType":"bytes32","name":"lpOrigin","type":"bytes32"},{"internalType":"uint256","name":"lockSeconds","type":"uint256"},{"internalType":"bool","name":"lockEnforced","type":"bool"},{"internalType":"uint256","name":"rewardPerBlock","type":"uint256"},{"internalType":"bytes32","name":"label","type":"bytes32"},{"internalType":"bytes32","name":"order","type":"bytes32"},{"internalType":"uint256","name":"depositSum","type":"uint256"}],"internalType":"struct MuskGoldFarmV1.RewardPool[]","name":"pools","type":"tuple[]"},{"internalType":"uint256[]","name":"balance","type":"uint256[]"},{"internalType":"uint256[]","name":"unlockTime","type":"uint256[]"},{"internalType":"uint256[]","name":"pending","type":"uint256[]"},{"internalType":"uint256[]","name":"earnings","type":"uint256[]"},{"internalType":"uint256[]","name":"depTknBal","type":"uint256[]"},{"internalType":"uint256[]","name":"depTknSupply","type":"uint256[]"},{"internalType":"uint256[]","name":"reserve0","type":"uint256[]"},{"internalType":"uint256[]","name":"reserve1","type":"uint256[]"},{"internalType":"address[]","name":"token0","type":"address[]"},{"internalType":"address[]","name":"token1","type":"address[]"},{"internalType":"uint256","name":"rewardTknBal","type":"uint256"},{"internalType":"uint256","name":"pendingAllPools","type":"uint256"},{"internalType":"uint256","name":"earningsAllPools","type":"uint256"}],"internalType":"struct MuskGoldFarmV1.UserFarmState","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paidOut","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"poolDepositSum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"restake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardPools","outputs":[{"internalType":"contract IERC20","name":"depositToken","type":"address"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"bool","name":"hidden","type":"bool"},{"internalType":"bool","name":"uniV2Lp","type":"bool"},{"internalType":"bool","name":"selfStake","type":"bool"},{"internalType":"bytes32","name":"lpOrigin","type":"bytes32"},{"internalType":"uint256","name":"lockSeconds","type":"uint256"},{"internalType":"bool","name":"lockEnforced","type":"bool"},{"internalType":"uint256","name":"rewardPerBlock","type":"uint256"},{"internalType":"bytes32","name":"label","type":"bytes32"},{"internalType":"bytes32","name":"order","type":"bytes32"},{"internalType":"uint256","name":"depositSum","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsRemaining","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"setEarliestRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_value","type":"bool"}],"name":"setFarmActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"bool","name":"_active","type":"bool"},{"internalType":"bool","name":"_hidden","type":"bool"},{"internalType":"bool","name":"_uniV2Lp","type":"bool"},{"internalType":"bytes32","name":"_lpOrigin","type":"bytes32"},{"internalType":"uint256","name":"_lockSeconds","type":"uint256"},{"internalType":"bool","name":"_lockEnforced","type":"bool"},{"internalType":"uint256","name":"_rewardPerBlock","type":"uint256"},{"internalType":"bytes32","name":"_label","type":"bytes32"},{"internalType":"bytes32","name":"_order","type":"bytes32"}],"name":"setPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_source","type":"address"}],"name":"setRewardWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userDeposits","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"unlockTime","type":"uint256"},{"internalType":"uint256","name":"lastPayout","type":"uint256"},{"internalType":"uint256","name":"totalEarned","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"userEarnedAll","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"userEarnedPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"userPendingAll","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"userPendingPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405260006006553480156200001657600080fd5b506040516200556a3803806200556a83398181016040528101906200003c9190620002d2565b6200005c620000506200011c60201b60201c565b6200012460201b60201c565b600180819055507f4d75736b20476f6c64204661726d00000000000000000000000000000000000060028190555082600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806005819055505050506200032e565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200021a82620001ed565b9050919050565b60006200022e826200020d565b9050919050565b620002408162000221565b81146200024c57600080fd5b50565b600081519050620002608162000235565b92915050565b62000271816200020d565b81146200027d57600080fd5b50565b600081519050620002918162000266565b92915050565b6000819050919050565b620002ac8162000297565b8114620002b857600080fd5b50565b600081519050620002cc81620002a1565b92915050565b600080600060608486031215620002ee57620002ed620001e8565b5b6000620002fe868287016200024f565b9350506020620003118682870162000280565b92505060406200032486828701620002bb565b9150509250925092565b61522c806200033e6000396000f3fe608060405234801561001057600080fd5b50600436106101fb5760003560e01c80638c29f6c61161011a578063bd3507da116100ad578063e27987781161007c578063e2798778146105a7578063f2fde38b146105d7578063f7c618c1146105f3578063f9c516ea14610611578063fb75b2c714610644576101fb565b8063bd3507da14610523578063c357a19a1461053f578063ca1d209d1461055b578063dbb80a6c14610577576101fb565b8063ad6b37df116100e9578063ad6b37df1461048b578063bb28acdd146104bb578063bc157ac1146104eb578063bce1b52014610507576101fb565b80638c29f6c6146104035780638da5cb5b1461041f578063990a56461461043d5780639d80c8181461046d576101fb565b806346abf39111610192578063673a2a1f11610161578063673a2a1f1461039f578063715018a6146103bd57806375acaf3c146103c757806378c196f3146103e5576101fb565b806346abf3911461030e5780635312ea8e146103495780635958621e146103655780635c76ca2d14610381576101fb565b80631ea088f9116101ce5780631ea088f9146102765780632591ef8914610292578063416ae768146102c2578063441a3e70146102f2576101fb565b806306fdde0314610200578063081e3eda1461021e57806318368f261461023c5780631ce020031461025a575b600080fd5b610208610662565b60405161021591906139f0565b60405180910390f35b610226610668565b6040516102339190613a24565b60405180910390f35b610244610675565b6040516102519190613a24565b60405180910390f35b610274600480360381019061026f9190613b44565b61067b565b005b610290600480360381019061028b9190613c23565b61097c565b005b6102ac60048036038101906102a79190613c23565b610a45565b6040516102b99190613c5f565b60405180910390f35b6102dc60048036038101906102d79190613ca6565b610a84565b6040516102e991906141e6565b60405180910390f35b61030c60048036038101906103079190614208565b6116d8565b005b61032860048036038101906103239190613c23565b61196a565b6040516103409c9b9a99989796959493929190614266565b60405180910390f35b610363600480360381019061035e9190613c23565b611a3b565b005b61037f600480360381019061037a9190613ca6565b611c0a565b005b610389611cca565b6040516103969190613a24565b60405180910390f35b6103a7611cd0565b6040516103b4919061438f565b60405180910390f35b6103c5611e49565b005b6103cf611ed1565b6040516103dc9190613a24565b60405180910390f35b6103ed611f62565b6040516103fa9190613a24565b60405180910390f35b61041d600480360381019061041891906143b1565b612036565b005b610427612284565b6040516104349190613c5f565b60405180910390f35b61045760048036038101906104529190613ca6565b6122ad565b6040516104649190613a24565b60405180910390f35b610475612303565b6040516104829190613a24565b60405180910390f35b6104a560048036038101906104a09190613ca6565b612310565b6040516104b29190613a24565b60405180910390f35b6104d560048036038101906104d09190614490565b6123aa565b6040516104e29190613a24565b60405180910390f35b610505600480360381019061050091906144d0565b61250e565b005b610521600480360381019061051c9190613c23565b61281c565b005b61053d60048036038101906105389190613c23565b612b07565b005b61055960048036038101906105549190614523565b612b69565b005b61057560048036038101906105709190613c23565b612c4d565b005b610591600480360381019061058c9190613c23565b612d52565b60405161059e9190613a24565b60405180910390f35b6105c160048036038101906105bc9190614490565b612d81565b6040516105ce9190613a24565b60405180910390f35b6105f160048036038101906105ec9190613ca6565b612ddf565b005b6105fb612ed7565b6040516106089190614550565b60405180910390f35b61062b60048036038101906106269190614490565b612efd565b60405161063b949392919061456b565b60405180910390f35b61064c612f3a565b6040516106599190613c5f565b60405180910390f35b60025481565b6000600780549050905090565b60055481565b610683612f60565b73ffffffffffffffffffffffffffffffffffffffff166106a1612284565b73ffffffffffffffffffffffffffffffffffffffff16146106f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106ee9061460d565b60405180910390fd5b600015156107058b87612f68565b151514610747576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073e9061469f565b60405180910390fd5b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff1614156107a85760019050600097505b60076040518061018001604052808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c151581526020018b151581526020018a15158152602001831515815260200189815260200188815260200187151581526020018681526020018581526020018481526020016000815250908060018154018082558091505060019003906000526020600020906008020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548160ff02191690831515021790555060408201518160000160156101000a81548160ff02191690831515021790555060608201518160000160166101000a81548160ff02191690831515021790555060808201518160000160176101000a81548160ff02191690831515021790555060a0820151816001015560c0820151816002015560e08201518160030160006101000a81548160ff021916908315150217905550610100820151816004015561012082015181600501556101408201518160060155610160820151816007015550505050505050505050505050565b610984612f60565b73ffffffffffffffffffffffffffffffffffffffff166109a2612284565b73ffffffffffffffffffffffffffffffffffffffff16146109f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ef9061460d565b60405180910390fd5b43811015610a3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3290614731565b60405180910390fd5b8060058190555050565b60088181548110610a5557600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610a8c613968565b600060078054905067ffffffffffffffff811115610aad57610aac614751565b5b604051908082528060200260200182016040528015610adb5781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610aff57610afe614751565b5b604051908082528060200260200182016040528015610b2d5781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610b5157610b50614751565b5b604051908082528060200260200182016040528015610b7f5781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610ba357610ba2614751565b5b604051908082528060200260200182016040528015610bd15781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610bf557610bf4614751565b5b604051908082528060200260200182016040528015610c235781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610c4757610c46614751565b5b604051908082528060200260200182016040528015610c755781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610c9957610c98614751565b5b604051908082528060200260200182016040528015610cc75781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610ceb57610cea614751565b5b604051908082528060200260200182016040528015610d195781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610d3d57610d3c614751565b5b604051908082528060200260200182016040528015610d6b5781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610d8f57610d8e614751565b5b604051908082528060200260200182016040528015610dbd5781602001602082028036833780820191505090505b50905060005b60078054905081101561143d576009600082815260200190815260200160002060008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001548b8281518110610e3757610e36614780565b5b602002602001018181525050610e4d818e6123aa565b8a8281518110610e6057610e5f614780565b5b602002602001018181525050610e76818e612d81565b898281518110610e8957610e88614780565b5b60200260200101818152505060078181548110610ea957610ea8614780565b5b906000526020600020906008020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401610f139190613c5f565b60206040518083038186803b158015610f2b57600080fd5b505afa158015610f3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6391906147c4565b888281518110610f7657610f75614780565b5b60200260200101818152505060078181548110610f9657610f95614780565b5b906000526020600020906008020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561100d57600080fd5b505afa158015611021573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104591906147c4565b87828151811061105857611057614780565b5b6020026020010181815250506009600082815260200190815260200160002060008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101548282815181106110cb576110ca614780565b5b60200260200101818152505060011515600782815481106110ef576110ee614780565b5b906000526020600020906008020160000160169054906101000a900460ff161515148015611153575060001515600782815481106111305761112f614780565b5b906000526020600020906008020160000160179054906101000a900460ff161515145b1561142c5760006007828154811061116e5761116d614780565b5b906000526020600020906008020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008060008373ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156111ed57600080fd5b505afa158015611201573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112259190614873565b63ffffffff1692506dffffffffffffffffffffffffffff1692506dffffffffffffffffffffffffffff169250828a868151811061126557611264614780565b5b6020026020010181815250508189868151811061128557611284614780565b5b6020026020010181815250508373ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156112d757600080fd5b505afa1580156112eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130f91906148db565b88868151811061132257611321614780565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508373ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156113a257600080fd5b505afa1580156113b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113da91906148db565b8786815181106113ed576113ec614780565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505050505b8061143690614937565b9050610dc3565b50604051806101c001604052806007805480602002602001604051908101604052809291908181526020016000905b828210156115b85783829060005260206000209060080201604051806101800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900460ff161515151581526020016000820160159054906101000a900460ff161515151581526020016000820160169054906101000a900460ff161515151581526020016000820160179054906101000a900460ff1615151515815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff161515151581526020016004820154815260200160058201548152602001600682015481526020016007820154815250508152602001906001019061146c565b5050505081526020018b81526020018281526020018a8152602001898152602001888152602001878152602001868152602001858152602001848152602001838152602001600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a082318f6040518263ffffffff1660e01b81526004016116589190613c5f565b60206040518083038186803b15801561167057600080fd5b505afa158015611684573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a891906147c4565b81526020016116b68e6122ad565b81526020016116c48e612310565b8152509a5050505050505050505050919050565b6002600154141561171e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611715906149cc565b60405180910390fd5b600260018190555060006007838154811061173c5761173b614780565b5b9060005260206000209060080201905060006009600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508160030160009054906101000a900460ff16156117ff5742816001015411156117fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f590614a5e565b60405180910390fd5b5b8281600001541015611846576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183d90614af0565b60405180910390fd5b6118508433613033565b61185981613211565b61187082600201544261323790919063ffffffff16565b816001018190555061188f83826000015461324d90919063ffffffff16565b81600001819055506118e633848460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166132639092919063ffffffff16565b833373ffffffffffffffffffffffffffffffffffffffff167ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5688560405161192d9190613a24565b60405180910390a361194c83836007015461324d90919063ffffffff16565b826007018190555061195d336132e9565b5050600180819055505050565b6007818154811061197a57600080fd5b90600052602060002090600802016000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060000160149054906101000a900460ff16908060000160159054906101000a900460ff16908060000160169054906101000a900460ff16908060000160179054906101000a900460ff16908060010154908060020154908060030160009054906101000a900460ff1690806004015490806005015490806006015490806007015490508c565b60026001541415611a81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a78906149cc565b60405180910390fd5b6002600181905550600060078281548110611a9f57611a9e614780565b5b9060005260206000209060080201905060006009600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050611b563382600001548460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166132639092919063ffffffff16565b611b718160000154836007015461324d90919063ffffffff16565b8260070181905550611b9082600201544261323790919063ffffffff16565b816001018190555060008160000181905550611bab81613211565b823373ffffffffffffffffffffffffffffffffffffffff167fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05958360000154604051611bf69190613a24565b60405180910390a350506001808190555050565b611c12612f60565b73ffffffffffffffffffffffffffffffffffffffff16611c30612284565b73ffffffffffffffffffffffffffffffffffffffff1614611c86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7d9061460d565b60405180910390fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60065481565b60606007805480602002602001604051908101604052809291908181526020016000905b82821015611e405783829060005260206000209060080201604051806101800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900460ff161515151581526020016000820160159054906101000a900460ff161515151581526020016000820160169054906101000a900460ff161515151581526020016000820160179054906101000a900460ff1615151515815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff1615151515815260200160048201548152602001600582015481526020016006820154815260200160078201548152505081526020019060010190611cf4565b50505050905090565b611e51612f60565b73ffffffffffffffffffffffffffffffffffffffff16611e6f612284565b73ffffffffffffffffffffffffffffffffffffffff1614611ec5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ebc9061460d565b60405180910390fd5b611ecf6000613468565b565b6000806000905060005b600880549050811015611f5a576000611f3160088381548110611f0157611f00614780565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166122ad565b9050611f46818461323790919063ffffffff16565b92505080611f5390614937565b9050611edb565b508091505090565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b8152600401611fe19190613c5f565b60206040518083038186803b158015611ff957600080fd5b505afa15801561200d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203191906147c4565b905090565b61203e612f60565b73ffffffffffffffffffffffffffffffffffffffff1661205c612284565b73ffffffffffffffffffffffffffffffffffffffff16146120b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a99061460d565b60405180910390fd5b8860078b815481106120c7576120c6614780565b5b906000526020600020906008020160000160146101000a81548160ff0219169083151502179055508760078b8154811061210457612103614780565b5b906000526020600020906008020160000160156101000a81548160ff0219169083151502179055508660078b8154811061214157612140614780565b5b906000526020600020906008020160000160166101000a81548160ff0219169083151502179055508560078b8154811061217e5761217d614780565b5b9060005260206000209060080201600101819055508460078b815481106121a8576121a7614780565b5b9060005260206000209060080201600201819055508360078b815481106121d2576121d1614780565b5b906000526020600020906008020160030160006101000a81548160ff0219169083151502179055508260078b8154811061220f5761220e614780565b5b9060005260206000209060080201600401819055508160078b8154811061223957612238614780565b5b9060005260206000209060080201600501819055508060078b8154811061226357612262614780565b5b90600052602060002090600802016006018190555050505050505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000806000905060005b6007805490508110156122f95760006122d082866123aa565b90506122e5818461323790919063ffffffff16565b925050806122f290614937565b90506122b7565b5080915050919050565b6000600880549050905090565b6000806000905060005b6007805490508110156123a05761238d6009600083815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301548361323790919063ffffffff16565b91508061239990614937565b905061231a565b5080915050919050565b600080600784815481106123c1576123c0614780565b5b9060005260206000209060080201905060006009600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000154141561243d57600092505050612508565b43600554111561245257600092505050612508565b60006ec097ce7bc90715b34b9f100000000090506000826002015443111561248e5761248b83600201544361324d90919063ffffffff16565b90505b60006124bd85600701546124af85876000015461352c90919063ffffffff16565b61354290919063ffffffff16565b905060006124fc846124ee846124e08a600401548861352c90919063ffffffff16565b61352c90919063ffffffff16565b61354290919063ffffffff16565b90508096505050505050505b92915050565b60026001541415612554576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161254b906149cc565b60405180910390fd5b600260018190555060006007848154811061257257612571614780565b5b90600052602060002090600802019050600082116125c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125bc90614b5c565b60405180910390fd5b600115158160000160149054906101000a900460ff1615151461261d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161261490614bc8565b60405180910390fd5b60006009600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000816002015414156126a257438160020181905550600554816002015410156126a15760055481600201819055505b5b600081600001541180156126e157508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b156126f1576126f08585613033565b5b6127423330858560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613558909392919063ffffffff16565b61275983826000015461323790919063ffffffff16565b816000018190555061277882600201544261323790919063ffffffff16565b816001018190555061279783836007015461323790919063ffffffff16565b82600701819055506127a8846135e1565b848473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7866040516128069190613a24565b60405180910390a4505060018081905550505050565b60026001541415612862576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612859906149cc565b60405180910390fd5b60026001819055506000600782815481106128805761287f614780565b5b9060005260206000209060080201905060006009600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168260000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612998576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161298f90614c5a565b60405180910390fd5b60006129a484336123aa565b9050600081116129b657505050612afd565b612a29600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1630838660000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613558909392919063ffffffff16565b612a4081846007015461323790919063ffffffff16565b8360070181905550612a5f81836000015461323790919063ffffffff16565b8260000181905550612a7e81836003015461323790919063ffffffff16565b8260030181905550612a8f82613211565b612aa48160065461323790919063ffffffff16565b600681905550833373ffffffffffffffffffffffffffffffffffffffff167fe2d4f7d2cbc42c0e28598ad885ea0822049fcdecbd5a05e5200be15473ccec0683604051612af19190613a24565b60405180910390a35050505b6001808190555050565b60026001541415612b4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b44906149cc565b60405180910390fd5b6002600181905550612b5f8133613033565b6001808190555050565b612b71612f60565b73ffffffffffffffffffffffffffffffffffffffff16612b8f612284565b73ffffffffffffffffffffffffffffffffffffffff1614612be5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bdc9061460d565b60405180910390fd5b60005b600780549050811015612c4957600060078281548110612c0b57612c0a614780565b5b90600052602060002090600802019050828160000160146101000a81548160ff0219169083151502179055505080612c4290614937565b9050612be8565b5050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415612cde576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cd590614cc6565b60405180910390fd5b612d4f33600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613558909392919063ffffffff16565b50565b600060078281548110612d6857612d67614780565b5b9060005260206000209060080201600701549050919050565b60006009600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030154905092915050565b612de7612f60565b73ffffffffffffffffffffffffffffffffffffffff16612e05612284565b73ffffffffffffffffffffffffffffffffffffffff1614612e5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e529061460d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612ecb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ec290614d58565b60405180910390fd5b612ed481613468565b50565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6009602052816000526040600020602052806000526040600020600091509150508060000154908060010154908060020154908060030154905084565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600033905090565b600080600090505b60078054905081101561302757600060078281548110612f9357612f92614780565b5b906000526020600020906008020190508473ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480156130055750838160020154145b156130155760019250505061302d565b508061302090614937565b9050612f70565b50600090505b92915050565b60006009600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600061309384846123aa565b9050600081116130a457505061320d565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685846040518463ffffffff1660e01b815260040161312593929190614d78565b602060405180830381600087803b15801561313f57600080fd5b505af1158015613153573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131779190614dc4565b50838373ffffffffffffffffffffffffffffffffffffffff167f02a6a2be713fedf52f113c0a759f1c1a23a113476d9b1b1a2a453c910660de4e836040516131bf9190613a24565b60405180910390a36131de81836003015461323790919063ffffffff16565b82600301819055506131fb8160065461323790919063ffffffff16565b60068190555061320a82613211565b50505b5050565b438160020181905550600554816002015410156132345760055481600201819055505b50565b600081836132459190614df1565b905092915050565b6000818361325b9190614e47565b905092915050565b6132e48363a9059cbb60e01b8484604051602401613282929190614e7b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506136eb565b505050565b6000805b600780549050811015613375576133606009600083815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001548361323790919063ffffffff16565b9150808061336d90614937565b9150506132ed565b5060008111156133855750613465565b60005b600880549050811015613462576000600882815481106133ab576133aa614780565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561344e57600882815481106134205761341f614780565b5b9060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b50808061345a90614937565b915050613388565b50505b50565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000818361353a9190614ea4565b905092915050565b600081836135509190614f2d565b905092915050565b6135db846323b872dd60e01b85858560405160240161357993929190614d78565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506136eb565b50505050565b60005b6008805490508110156136835760006008828154811061360757613606614780565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561366f5750506136e8565b50808061367b90614937565b9150506135e4565b506008819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b600061374d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166137b29092919063ffffffff16565b90506000815111156137ad578080602001905181019061376d9190614dc4565b6137ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137a390614fd0565b60405180910390fd5b5b505050565b60606137c184846000856137ca565b90509392505050565b60608247101561380f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161380690615062565b60405180910390fd5b613818856138de565b613857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161384e906150ce565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516138809190615168565b60006040518083038185875af1925050503d80600081146138bd576040519150601f19603f3d011682016040523d82523d6000602084013e6138c2565b606091505b50915091506138d2828286613901565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6060831561391157829050613961565b6000835111156139245782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161395891906151d4565b60405180910390fd5b9392505050565b604051806101c0016040528060608152602001606081526020016060815260200160608152602001606081526020016060815260200160608152602001606081526020016060815260200160608152602001606081526020016000815260200160008152602001600081525090565b6000819050919050565b6139ea816139d7565b82525050565b6000602082019050613a0560008301846139e1565b92915050565b6000819050919050565b613a1e81613a0b565b82525050565b6000602082019050613a396000830184613a15565b92915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613a6f82613a44565b9050919050565b6000613a8182613a64565b9050919050565b613a9181613a76565b8114613a9c57600080fd5b50565b600081359050613aae81613a88565b92915050565b60008115159050919050565b613ac981613ab4565b8114613ad457600080fd5b50565b600081359050613ae681613ac0565b92915050565b613af5816139d7565b8114613b0057600080fd5b50565b600081359050613b1281613aec565b92915050565b613b2181613a0b565b8114613b2c57600080fd5b50565b600081359050613b3e81613b18565b92915050565b6000806000806000806000806000806101408b8d031215613b6857613b67613a3f565b5b6000613b768d828e01613a9f565b9a50506020613b878d828e01613ad7565b9950506040613b988d828e01613ad7565b9850506060613ba98d828e01613ad7565b9750506080613bba8d828e01613b03565b96505060a0613bcb8d828e01613b2f565b95505060c0613bdc8d828e01613ad7565b94505060e0613bed8d828e01613b2f565b935050610100613bff8d828e01613b03565b925050610120613c118d828e01613b03565b9150509295989b9194979a5092959850565b600060208284031215613c3957613c38613a3f565b5b6000613c4784828501613b2f565b91505092915050565b613c5981613a64565b82525050565b6000602082019050613c746000830184613c50565b92915050565b613c8381613a64565b8114613c8e57600080fd5b50565b600081359050613ca081613c7a565b92915050565b600060208284031215613cbc57613cbb613a3f565b5b6000613cca84828501613c91565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6000613d24613d1f613d1a84613a44565b613cff565b613a44565b9050919050565b6000613d3682613d09565b9050919050565b6000613d4882613d2b565b9050919050565b613d5881613d3d565b82525050565b613d6781613ab4565b82525050565b613d76816139d7565b82525050565b613d8581613a0b565b82525050565b61018082016000820151613da26000850182613d4f565b506020820151613db56020850182613d5e565b506040820151613dc86040850182613d5e565b506060820151613ddb6060850182613d5e565b506080820151613dee6080850182613d5e565b5060a0820151613e0160a0850182613d6d565b5060c0820151613e1460c0850182613d7c565b5060e0820151613e2760e0850182613d5e565b50610100820151613e3c610100850182613d7c565b50610120820151613e51610120850182613d6d565b50610140820151613e66610140850182613d6d565b50610160820151613e7b610160850182613d7c565b50505050565b6000613e8d8383613d8b565b6101808301905092915050565b6000602082019050919050565b6000613eb282613cd3565b613ebc8185613cde565b9350613ec783613cef565b8060005b83811015613ef8578151613edf8882613e81565b9750613eea83613e9a565b925050600181019050613ecb565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000613f3d8383613d7c565b60208301905092915050565b6000602082019050919050565b6000613f6182613f05565b613f6b8185613f10565b9350613f7683613f21565b8060005b83811015613fa7578151613f8e8882613f31565b9750613f9983613f49565b925050600181019050613f7a565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613fe981613a64565b82525050565b6000613ffb8383613fe0565b60208301905092915050565b6000602082019050919050565b600061401f82613fb4565b6140298185613fbf565b935061403483613fd0565b8060005b8381101561406557815161404c8882613fef565b975061405783614007565b925050600181019050614038565b5085935050505092915050565b60006101c08301600083015184820360008601526140908282613ea7565b915050602083015184820360208601526140aa8282613f56565b915050604083015184820360408601526140c48282613f56565b915050606083015184820360608601526140de8282613f56565b915050608083015184820360808601526140f88282613f56565b91505060a083015184820360a08601526141128282613f56565b91505060c083015184820360c086015261412c8282613f56565b91505060e083015184820360e08601526141468282613f56565b9150506101008301518482036101008601526141628282613f56565b91505061012083015184820361012086015261417e8282614014565b91505061014083015184820361014086015261419a8282614014565b9150506101608301516141b1610160860182613d7c565b506101808301516141c6610180860182613d7c565b506101a08301516141db6101a0860182613d7c565b508091505092915050565b600060208201905081810360008301526142008184614072565b905092915050565b6000806040838503121561421f5761421e613a3f565b5b600061422d85828601613b2f565b925050602061423e85828601613b2f565b9150509250929050565b61425181613d3d565b82525050565b61426081613ab4565b82525050565b60006101808201905061427c600083018f614248565b614289602083018e614257565b614296604083018d614257565b6142a3606083018c614257565b6142b0608083018b614257565b6142bd60a083018a6139e1565b6142ca60c0830189613a15565b6142d760e0830188614257565b6142e5610100830187613a15565b6142f36101208301866139e1565b6143016101408301856139e1565b61430f610160830184613a15565b9d9c50505050505050505050505050565b600082825260208201905092915050565b600061433c82613cd3565b6143468185614320565b935061435183613cef565b8060005b838110156143825781516143698882613e81565b975061437483613e9a565b925050600181019050614355565b5085935050505092915050565b600060208201905081810360008301526143a98184614331565b905092915050565b6000806000806000806000806000806101408b8d0312156143d5576143d4613a3f565b5b60006143e38d828e01613b2f565b9a505060206143f48d828e01613ad7565b99505060406144058d828e01613ad7565b98505060606144168d828e01613ad7565b97505060806144278d828e01613b03565b96505060a06144388d828e01613b2f565b95505060c06144498d828e01613ad7565b94505060e061445a8d828e01613b2f565b93505061010061446c8d828e01613b03565b92505061012061447e8d828e01613b03565b9150509295989b9194979a5092959850565b600080604083850312156144a7576144a6613a3f565b5b60006144b585828601613b2f565b92505060206144c685828601613c91565b9150509250929050565b6000806000606084860312156144e9576144e8613a3f565b5b60006144f786828701613b2f565b935050602061450886828701613c91565b925050604061451986828701613b2f565b9150509250925092565b60006020828403121561453957614538613a3f565b5b600061454784828501613ad7565b91505092915050565b60006020820190506145656000830184614248565b92915050565b60006080820190506145806000830187613a15565b61458d6020830186613a15565b61459a6040830185613a15565b6145a76060830184613a15565b95945050505050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006145f76020836145b0565b9150614602826145c1565b602082019050919050565b60006020820190508181036000830152614626816145ea565b9050919050565b7f52657761726420706f6f6c20666f7220746f6b656e20616c726561647920657860008201527f6973747300000000000000000000000000000000000000000000000000000000602082015250565b60006146896024836145b0565b91506146948261462d565b604082019050919050565b600060208201905081810360008301526146b88161467c565b9050919050565b7f4561726c696573742072657761726420626c6f636b206d75737420626520677260008201527f6561746572207468616e207468652063757272656e7420626c6f636b00000000602082015250565b600061471b603c836145b0565b9150614726826146bf565b604082019050919050565b6000602082019050818103600083015261474a8161470e565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000815190506147be81613b18565b92915050565b6000602082840312156147da576147d9613a3f565b5b60006147e8848285016147af565b91505092915050565b60006dffffffffffffffffffffffffffff82169050919050565b614814816147f1565b811461481f57600080fd5b50565b6000815190506148318161480b565b92915050565b600063ffffffff82169050919050565b61485081614837565b811461485b57600080fd5b50565b60008151905061486d81614847565b92915050565b60008060006060848603121561488c5761488b613a3f565b5b600061489a86828701614822565b93505060206148ab86828701614822565b92505060406148bc8682870161485e565b9150509250925092565b6000815190506148d581613c7a565b92915050565b6000602082840312156148f1576148f0613a3f565b5b60006148ff848285016148c6565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061494282613a0b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561497557614974614908565b5b600182019050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006149b6601f836145b0565b91506149c182614980565b602082019050919050565b600060208201905081810360008301526149e5816149a9565b9050919050565b7f77697468647261773a2074696d65206c6f636b20686173206e6f74207061737360008201527f6564000000000000000000000000000000000000000000000000000000000000602082015250565b6000614a486022836145b0565b9150614a53826149ec565b604082019050919050565b60006020820190508181036000830152614a7781614a3b565b9050919050565b7f77697468647261773a2063616e2774207769746864726177206d6f726520746860008201527f616e206465706f73697400000000000000000000000000000000000000000000602082015250565b6000614ada602a836145b0565b9150614ae582614a7e565b604082019050919050565b60006020820190508181036000830152614b0981614acd565b9050919050565b7f416d6f756e74206d7573742062652067726561746572207468616e207a65726f600082015250565b6000614b466020836145b0565b9150614b5182614b10565b602082019050919050565b60006020820190508181036000830152614b7581614b39565b9050919050565b7f546869732072657761726420706f6f6c20697320696e61637469766500000000600082015250565b6000614bb2601c836145b0565b9150614bbd82614b7c565b602082019050919050565b60006020820190508181036000830152614be181614ba5565b9050919050565b7f52657374616b65206973206f6e6c7920617661696c61626c65206f6e2073696e60008201527f676c652d7369646564207374616b696e67000000000000000000000000000000602082015250565b6000614c446031836145b0565b9150614c4f82614be8565b604082019050919050565b60006020820190508181036000830152614c7381614c37565b9050919050565b7f53656e646572206973207265776172642077616c6c6574000000000000000000600082015250565b6000614cb06017836145b0565b9150614cbb82614c7a565b602082019050919050565b60006020820190508181036000830152614cdf81614ca3565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614d426026836145b0565b9150614d4d82614ce6565b604082019050919050565b60006020820190508181036000830152614d7181614d35565b9050919050565b6000606082019050614d8d6000830186613c50565b614d9a6020830185613c50565b614da76040830184613a15565b949350505050565b600081519050614dbe81613ac0565b92915050565b600060208284031215614dda57614dd9613a3f565b5b6000614de884828501614daf565b91505092915050565b6000614dfc82613a0b565b9150614e0783613a0b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614e3c57614e3b614908565b5b828201905092915050565b6000614e5282613a0b565b9150614e5d83613a0b565b925082821015614e7057614e6f614908565b5b828203905092915050565b6000604082019050614e906000830185613c50565b614e9d6020830184613a15565b9392505050565b6000614eaf82613a0b565b9150614eba83613a0b565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614ef357614ef2614908565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614f3882613a0b565b9150614f4383613a0b565b925082614f5357614f52614efe565b5b828204905092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000614fba602a836145b0565b9150614fc582614f5e565b604082019050919050565b60006020820190508181036000830152614fe981614fad565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b600061504c6026836145b0565b915061505782614ff0565b604082019050919050565b6000602082019050818103600083015261507b8161503f565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006150b8601d836145b0565b91506150c382615082565b602082019050919050565b600060208201905081810360008301526150e7816150ab565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015615122578082015181840152602081019050615107565b83811115615131576000848401525b50505050565b6000615142826150ee565b61514c81856150f9565b935061515c818560208601615104565b80840191505092915050565b60006151748284615137565b915081905092915050565b600081519050919050565b6000601f19601f8301169050919050565b60006151a68261517f565b6151b081856145b0565b93506151c0818560208601615104565b6151c98161518a565b840191505092915050565b600060208201905081810360008301526151ee818461519b565b90509291505056fea264697066735822122053a06b26212cad34a6fd7eae055a8ce576d89f4f20e69b47266859228cb4bc8564736f6c634300080900330000000000000000000000006069c9223e8a5da1ec49ac5525d4bb757af72cd8000000000000000000000000c0b26eb298b77e49b26dbcc665878a92e854c1b30000000000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101fb5760003560e01c80638c29f6c61161011a578063bd3507da116100ad578063e27987781161007c578063e2798778146105a7578063f2fde38b146105d7578063f7c618c1146105f3578063f9c516ea14610611578063fb75b2c714610644576101fb565b8063bd3507da14610523578063c357a19a1461053f578063ca1d209d1461055b578063dbb80a6c14610577576101fb565b8063ad6b37df116100e9578063ad6b37df1461048b578063bb28acdd146104bb578063bc157ac1146104eb578063bce1b52014610507576101fb565b80638c29f6c6146104035780638da5cb5b1461041f578063990a56461461043d5780639d80c8181461046d576101fb565b806346abf39111610192578063673a2a1f11610161578063673a2a1f1461039f578063715018a6146103bd57806375acaf3c146103c757806378c196f3146103e5576101fb565b806346abf3911461030e5780635312ea8e146103495780635958621e146103655780635c76ca2d14610381576101fb565b80631ea088f9116101ce5780631ea088f9146102765780632591ef8914610292578063416ae768146102c2578063441a3e70146102f2576101fb565b806306fdde0314610200578063081e3eda1461021e57806318368f261461023c5780631ce020031461025a575b600080fd5b610208610662565b60405161021591906139f0565b60405180910390f35b610226610668565b6040516102339190613a24565b60405180910390f35b610244610675565b6040516102519190613a24565b60405180910390f35b610274600480360381019061026f9190613b44565b61067b565b005b610290600480360381019061028b9190613c23565b61097c565b005b6102ac60048036038101906102a79190613c23565b610a45565b6040516102b99190613c5f565b60405180910390f35b6102dc60048036038101906102d79190613ca6565b610a84565b6040516102e991906141e6565b60405180910390f35b61030c60048036038101906103079190614208565b6116d8565b005b61032860048036038101906103239190613c23565b61196a565b6040516103409c9b9a99989796959493929190614266565b60405180910390f35b610363600480360381019061035e9190613c23565b611a3b565b005b61037f600480360381019061037a9190613ca6565b611c0a565b005b610389611cca565b6040516103969190613a24565b60405180910390f35b6103a7611cd0565b6040516103b4919061438f565b60405180910390f35b6103c5611e49565b005b6103cf611ed1565b6040516103dc9190613a24565b60405180910390f35b6103ed611f62565b6040516103fa9190613a24565b60405180910390f35b61041d600480360381019061041891906143b1565b612036565b005b610427612284565b6040516104349190613c5f565b60405180910390f35b61045760048036038101906104529190613ca6565b6122ad565b6040516104649190613a24565b60405180910390f35b610475612303565b6040516104829190613a24565b60405180910390f35b6104a560048036038101906104a09190613ca6565b612310565b6040516104b29190613a24565b60405180910390f35b6104d560048036038101906104d09190614490565b6123aa565b6040516104e29190613a24565b60405180910390f35b610505600480360381019061050091906144d0565b61250e565b005b610521600480360381019061051c9190613c23565b61281c565b005b61053d60048036038101906105389190613c23565b612b07565b005b61055960048036038101906105549190614523565b612b69565b005b61057560048036038101906105709190613c23565b612c4d565b005b610591600480360381019061058c9190613c23565b612d52565b60405161059e9190613a24565b60405180910390f35b6105c160048036038101906105bc9190614490565b612d81565b6040516105ce9190613a24565b60405180910390f35b6105f160048036038101906105ec9190613ca6565b612ddf565b005b6105fb612ed7565b6040516106089190614550565b60405180910390f35b61062b60048036038101906106269190614490565b612efd565b60405161063b949392919061456b565b60405180910390f35b61064c612f3a565b6040516106599190613c5f565b60405180910390f35b60025481565b6000600780549050905090565b60055481565b610683612f60565b73ffffffffffffffffffffffffffffffffffffffff166106a1612284565b73ffffffffffffffffffffffffffffffffffffffff16146106f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106ee9061460d565b60405180910390fd5b600015156107058b87612f68565b151514610747576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073e9061469f565b60405180910390fd5b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff1614156107a85760019050600097505b60076040518061018001604052808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c151581526020018b151581526020018a15158152602001831515815260200189815260200188815260200187151581526020018681526020018581526020018481526020016000815250908060018154018082558091505060019003906000526020600020906008020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548160ff02191690831515021790555060408201518160000160156101000a81548160ff02191690831515021790555060608201518160000160166101000a81548160ff02191690831515021790555060808201518160000160176101000a81548160ff02191690831515021790555060a0820151816001015560c0820151816002015560e08201518160030160006101000a81548160ff021916908315150217905550610100820151816004015561012082015181600501556101408201518160060155610160820151816007015550505050505050505050505050565b610984612f60565b73ffffffffffffffffffffffffffffffffffffffff166109a2612284565b73ffffffffffffffffffffffffffffffffffffffff16146109f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ef9061460d565b60405180910390fd5b43811015610a3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3290614731565b60405180910390fd5b8060058190555050565b60088181548110610a5557600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610a8c613968565b600060078054905067ffffffffffffffff811115610aad57610aac614751565b5b604051908082528060200260200182016040528015610adb5781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610aff57610afe614751565b5b604051908082528060200260200182016040528015610b2d5781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610b5157610b50614751565b5b604051908082528060200260200182016040528015610b7f5781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610ba357610ba2614751565b5b604051908082528060200260200182016040528015610bd15781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610bf557610bf4614751565b5b604051908082528060200260200182016040528015610c235781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610c4757610c46614751565b5b604051908082528060200260200182016040528015610c755781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610c9957610c98614751565b5b604051908082528060200260200182016040528015610cc75781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610ceb57610cea614751565b5b604051908082528060200260200182016040528015610d195781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610d3d57610d3c614751565b5b604051908082528060200260200182016040528015610d6b5781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610d8f57610d8e614751565b5b604051908082528060200260200182016040528015610dbd5781602001602082028036833780820191505090505b50905060005b60078054905081101561143d576009600082815260200190815260200160002060008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001548b8281518110610e3757610e36614780565b5b602002602001018181525050610e4d818e6123aa565b8a8281518110610e6057610e5f614780565b5b602002602001018181525050610e76818e612d81565b898281518110610e8957610e88614780565b5b60200260200101818152505060078181548110610ea957610ea8614780565b5b906000526020600020906008020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401610f139190613c5f565b60206040518083038186803b158015610f2b57600080fd5b505afa158015610f3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6391906147c4565b888281518110610f7657610f75614780565b5b60200260200101818152505060078181548110610f9657610f95614780565b5b906000526020600020906008020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561100d57600080fd5b505afa158015611021573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104591906147c4565b87828151811061105857611057614780565b5b6020026020010181815250506009600082815260200190815260200160002060008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101548282815181106110cb576110ca614780565b5b60200260200101818152505060011515600782815481106110ef576110ee614780565b5b906000526020600020906008020160000160169054906101000a900460ff161515148015611153575060001515600782815481106111305761112f614780565b5b906000526020600020906008020160000160179054906101000a900460ff161515145b1561142c5760006007828154811061116e5761116d614780565b5b906000526020600020906008020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008060008373ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156111ed57600080fd5b505afa158015611201573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112259190614873565b63ffffffff1692506dffffffffffffffffffffffffffff1692506dffffffffffffffffffffffffffff169250828a868151811061126557611264614780565b5b6020026020010181815250508189868151811061128557611284614780565b5b6020026020010181815250508373ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156112d757600080fd5b505afa1580156112eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130f91906148db565b88868151811061132257611321614780565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508373ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156113a257600080fd5b505afa1580156113b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113da91906148db565b8786815181106113ed576113ec614780565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505050505b8061143690614937565b9050610dc3565b50604051806101c001604052806007805480602002602001604051908101604052809291908181526020016000905b828210156115b85783829060005260206000209060080201604051806101800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900460ff161515151581526020016000820160159054906101000a900460ff161515151581526020016000820160169054906101000a900460ff161515151581526020016000820160179054906101000a900460ff1615151515815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff161515151581526020016004820154815260200160058201548152602001600682015481526020016007820154815250508152602001906001019061146c565b5050505081526020018b81526020018281526020018a8152602001898152602001888152602001878152602001868152602001858152602001848152602001838152602001600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a082318f6040518263ffffffff1660e01b81526004016116589190613c5f565b60206040518083038186803b15801561167057600080fd5b505afa158015611684573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a891906147c4565b81526020016116b68e6122ad565b81526020016116c48e612310565b8152509a5050505050505050505050919050565b6002600154141561171e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611715906149cc565b60405180910390fd5b600260018190555060006007838154811061173c5761173b614780565b5b9060005260206000209060080201905060006009600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508160030160009054906101000a900460ff16156117ff5742816001015411156117fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f590614a5e565b60405180910390fd5b5b8281600001541015611846576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183d90614af0565b60405180910390fd5b6118508433613033565b61185981613211565b61187082600201544261323790919063ffffffff16565b816001018190555061188f83826000015461324d90919063ffffffff16565b81600001819055506118e633848460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166132639092919063ffffffff16565b833373ffffffffffffffffffffffffffffffffffffffff167ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5688560405161192d9190613a24565b60405180910390a361194c83836007015461324d90919063ffffffff16565b826007018190555061195d336132e9565b5050600180819055505050565b6007818154811061197a57600080fd5b90600052602060002090600802016000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060000160149054906101000a900460ff16908060000160159054906101000a900460ff16908060000160169054906101000a900460ff16908060000160179054906101000a900460ff16908060010154908060020154908060030160009054906101000a900460ff1690806004015490806005015490806006015490806007015490508c565b60026001541415611a81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a78906149cc565b60405180910390fd5b6002600181905550600060078281548110611a9f57611a9e614780565b5b9060005260206000209060080201905060006009600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050611b563382600001548460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166132639092919063ffffffff16565b611b718160000154836007015461324d90919063ffffffff16565b8260070181905550611b9082600201544261323790919063ffffffff16565b816001018190555060008160000181905550611bab81613211565b823373ffffffffffffffffffffffffffffffffffffffff167fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05958360000154604051611bf69190613a24565b60405180910390a350506001808190555050565b611c12612f60565b73ffffffffffffffffffffffffffffffffffffffff16611c30612284565b73ffffffffffffffffffffffffffffffffffffffff1614611c86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7d9061460d565b60405180910390fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60065481565b60606007805480602002602001604051908101604052809291908181526020016000905b82821015611e405783829060005260206000209060080201604051806101800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900460ff161515151581526020016000820160159054906101000a900460ff161515151581526020016000820160169054906101000a900460ff161515151581526020016000820160179054906101000a900460ff1615151515815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff1615151515815260200160048201548152602001600582015481526020016006820154815260200160078201548152505081526020019060010190611cf4565b50505050905090565b611e51612f60565b73ffffffffffffffffffffffffffffffffffffffff16611e6f612284565b73ffffffffffffffffffffffffffffffffffffffff1614611ec5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ebc9061460d565b60405180910390fd5b611ecf6000613468565b565b6000806000905060005b600880549050811015611f5a576000611f3160088381548110611f0157611f00614780565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166122ad565b9050611f46818461323790919063ffffffff16565b92505080611f5390614937565b9050611edb565b508091505090565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b8152600401611fe19190613c5f565b60206040518083038186803b158015611ff957600080fd5b505afa15801561200d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203191906147c4565b905090565b61203e612f60565b73ffffffffffffffffffffffffffffffffffffffff1661205c612284565b73ffffffffffffffffffffffffffffffffffffffff16146120b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a99061460d565b60405180910390fd5b8860078b815481106120c7576120c6614780565b5b906000526020600020906008020160000160146101000a81548160ff0219169083151502179055508760078b8154811061210457612103614780565b5b906000526020600020906008020160000160156101000a81548160ff0219169083151502179055508660078b8154811061214157612140614780565b5b906000526020600020906008020160000160166101000a81548160ff0219169083151502179055508560078b8154811061217e5761217d614780565b5b9060005260206000209060080201600101819055508460078b815481106121a8576121a7614780565b5b9060005260206000209060080201600201819055508360078b815481106121d2576121d1614780565b5b906000526020600020906008020160030160006101000a81548160ff0219169083151502179055508260078b8154811061220f5761220e614780565b5b9060005260206000209060080201600401819055508160078b8154811061223957612238614780565b5b9060005260206000209060080201600501819055508060078b8154811061226357612262614780565b5b90600052602060002090600802016006018190555050505050505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000806000905060005b6007805490508110156122f95760006122d082866123aa565b90506122e5818461323790919063ffffffff16565b925050806122f290614937565b90506122b7565b5080915050919050565b6000600880549050905090565b6000806000905060005b6007805490508110156123a05761238d6009600083815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301548361323790919063ffffffff16565b91508061239990614937565b905061231a565b5080915050919050565b600080600784815481106123c1576123c0614780565b5b9060005260206000209060080201905060006009600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000154141561243d57600092505050612508565b43600554111561245257600092505050612508565b60006ec097ce7bc90715b34b9f100000000090506000826002015443111561248e5761248b83600201544361324d90919063ffffffff16565b90505b60006124bd85600701546124af85876000015461352c90919063ffffffff16565b61354290919063ffffffff16565b905060006124fc846124ee846124e08a600401548861352c90919063ffffffff16565b61352c90919063ffffffff16565b61354290919063ffffffff16565b90508096505050505050505b92915050565b60026001541415612554576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161254b906149cc565b60405180910390fd5b600260018190555060006007848154811061257257612571614780565b5b90600052602060002090600802019050600082116125c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125bc90614b5c565b60405180910390fd5b600115158160000160149054906101000a900460ff1615151461261d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161261490614bc8565b60405180910390fd5b60006009600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000816002015414156126a257438160020181905550600554816002015410156126a15760055481600201819055505b5b600081600001541180156126e157508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b156126f1576126f08585613033565b5b6127423330858560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613558909392919063ffffffff16565b61275983826000015461323790919063ffffffff16565b816000018190555061277882600201544261323790919063ffffffff16565b816001018190555061279783836007015461323790919063ffffffff16565b82600701819055506127a8846135e1565b848473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7866040516128069190613a24565b60405180910390a4505060018081905550505050565b60026001541415612862576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612859906149cc565b60405180910390fd5b60026001819055506000600782815481106128805761287f614780565b5b9060005260206000209060080201905060006009600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168260000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612998576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161298f90614c5a565b60405180910390fd5b60006129a484336123aa565b9050600081116129b657505050612afd565b612a29600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1630838660000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613558909392919063ffffffff16565b612a4081846007015461323790919063ffffffff16565b8360070181905550612a5f81836000015461323790919063ffffffff16565b8260000181905550612a7e81836003015461323790919063ffffffff16565b8260030181905550612a8f82613211565b612aa48160065461323790919063ffffffff16565b600681905550833373ffffffffffffffffffffffffffffffffffffffff167fe2d4f7d2cbc42c0e28598ad885ea0822049fcdecbd5a05e5200be15473ccec0683604051612af19190613a24565b60405180910390a35050505b6001808190555050565b60026001541415612b4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b44906149cc565b60405180910390fd5b6002600181905550612b5f8133613033565b6001808190555050565b612b71612f60565b73ffffffffffffffffffffffffffffffffffffffff16612b8f612284565b73ffffffffffffffffffffffffffffffffffffffff1614612be5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bdc9061460d565b60405180910390fd5b60005b600780549050811015612c4957600060078281548110612c0b57612c0a614780565b5b90600052602060002090600802019050828160000160146101000a81548160ff0219169083151502179055505080612c4290614937565b9050612be8565b5050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415612cde576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cd590614cc6565b60405180910390fd5b612d4f33600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613558909392919063ffffffff16565b50565b600060078281548110612d6857612d67614780565b5b9060005260206000209060080201600701549050919050565b60006009600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030154905092915050565b612de7612f60565b73ffffffffffffffffffffffffffffffffffffffff16612e05612284565b73ffffffffffffffffffffffffffffffffffffffff1614612e5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e529061460d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612ecb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ec290614d58565b60405180910390fd5b612ed481613468565b50565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6009602052816000526040600020602052806000526040600020600091509150508060000154908060010154908060020154908060030154905084565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600033905090565b600080600090505b60078054905081101561302757600060078281548110612f9357612f92614780565b5b906000526020600020906008020190508473ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480156130055750838160020154145b156130155760019250505061302d565b508061302090614937565b9050612f70565b50600090505b92915050565b60006009600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600061309384846123aa565b9050600081116130a457505061320d565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685846040518463ffffffff1660e01b815260040161312593929190614d78565b602060405180830381600087803b15801561313f57600080fd5b505af1158015613153573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131779190614dc4565b50838373ffffffffffffffffffffffffffffffffffffffff167f02a6a2be713fedf52f113c0a759f1c1a23a113476d9b1b1a2a453c910660de4e836040516131bf9190613a24565b60405180910390a36131de81836003015461323790919063ffffffff16565b82600301819055506131fb8160065461323790919063ffffffff16565b60068190555061320a82613211565b50505b5050565b438160020181905550600554816002015410156132345760055481600201819055505b50565b600081836132459190614df1565b905092915050565b6000818361325b9190614e47565b905092915050565b6132e48363a9059cbb60e01b8484604051602401613282929190614e7b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506136eb565b505050565b6000805b600780549050811015613375576133606009600083815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001548361323790919063ffffffff16565b9150808061336d90614937565b9150506132ed565b5060008111156133855750613465565b60005b600880549050811015613462576000600882815481106133ab576133aa614780565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561344e57600882815481106134205761341f614780565b5b9060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b50808061345a90614937565b915050613388565b50505b50565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000818361353a9190614ea4565b905092915050565b600081836135509190614f2d565b905092915050565b6135db846323b872dd60e01b85858560405160240161357993929190614d78565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506136eb565b50505050565b60005b6008805490508110156136835760006008828154811061360757613606614780565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561366f5750506136e8565b50808061367b90614937565b9150506135e4565b506008819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b600061374d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166137b29092919063ffffffff16565b90506000815111156137ad578080602001905181019061376d9190614dc4565b6137ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137a390614fd0565b60405180910390fd5b5b505050565b60606137c184846000856137ca565b90509392505050565b60608247101561380f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161380690615062565b60405180910390fd5b613818856138de565b613857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161384e906150ce565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516138809190615168565b60006040518083038185875af1925050503d80600081146138bd576040519150601f19603f3d011682016040523d82523d6000602084013e6138c2565b606091505b50915091506138d2828286613901565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6060831561391157829050613961565b6000835111156139245782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161395891906151d4565b60405180910390fd5b9392505050565b604051806101c0016040528060608152602001606081526020016060815260200160608152602001606081526020016060815260200160608152602001606081526020016060815260200160608152602001606081526020016000815260200160008152602001600081525090565b6000819050919050565b6139ea816139d7565b82525050565b6000602082019050613a0560008301846139e1565b92915050565b6000819050919050565b613a1e81613a0b565b82525050565b6000602082019050613a396000830184613a15565b92915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613a6f82613a44565b9050919050565b6000613a8182613a64565b9050919050565b613a9181613a76565b8114613a9c57600080fd5b50565b600081359050613aae81613a88565b92915050565b60008115159050919050565b613ac981613ab4565b8114613ad457600080fd5b50565b600081359050613ae681613ac0565b92915050565b613af5816139d7565b8114613b0057600080fd5b50565b600081359050613b1281613aec565b92915050565b613b2181613a0b565b8114613b2c57600080fd5b50565b600081359050613b3e81613b18565b92915050565b6000806000806000806000806000806101408b8d031215613b6857613b67613a3f565b5b6000613b768d828e01613a9f565b9a50506020613b878d828e01613ad7565b9950506040613b988d828e01613ad7565b9850506060613ba98d828e01613ad7565b9750506080613bba8d828e01613b03565b96505060a0613bcb8d828e01613b2f565b95505060c0613bdc8d828e01613ad7565b94505060e0613bed8d828e01613b2f565b935050610100613bff8d828e01613b03565b925050610120613c118d828e01613b03565b9150509295989b9194979a5092959850565b600060208284031215613c3957613c38613a3f565b5b6000613c4784828501613b2f565b91505092915050565b613c5981613a64565b82525050565b6000602082019050613c746000830184613c50565b92915050565b613c8381613a64565b8114613c8e57600080fd5b50565b600081359050613ca081613c7a565b92915050565b600060208284031215613cbc57613cbb613a3f565b5b6000613cca84828501613c91565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6000613d24613d1f613d1a84613a44565b613cff565b613a44565b9050919050565b6000613d3682613d09565b9050919050565b6000613d4882613d2b565b9050919050565b613d5881613d3d565b82525050565b613d6781613ab4565b82525050565b613d76816139d7565b82525050565b613d8581613a0b565b82525050565b61018082016000820151613da26000850182613d4f565b506020820151613db56020850182613d5e565b506040820151613dc86040850182613d5e565b506060820151613ddb6060850182613d5e565b506080820151613dee6080850182613d5e565b5060a0820151613e0160a0850182613d6d565b5060c0820151613e1460c0850182613d7c565b5060e0820151613e2760e0850182613d5e565b50610100820151613e3c610100850182613d7c565b50610120820151613e51610120850182613d6d565b50610140820151613e66610140850182613d6d565b50610160820151613e7b610160850182613d7c565b50505050565b6000613e8d8383613d8b565b6101808301905092915050565b6000602082019050919050565b6000613eb282613cd3565b613ebc8185613cde565b9350613ec783613cef565b8060005b83811015613ef8578151613edf8882613e81565b9750613eea83613e9a565b925050600181019050613ecb565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000613f3d8383613d7c565b60208301905092915050565b6000602082019050919050565b6000613f6182613f05565b613f6b8185613f10565b9350613f7683613f21565b8060005b83811015613fa7578151613f8e8882613f31565b9750613f9983613f49565b925050600181019050613f7a565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613fe981613a64565b82525050565b6000613ffb8383613fe0565b60208301905092915050565b6000602082019050919050565b600061401f82613fb4565b6140298185613fbf565b935061403483613fd0565b8060005b8381101561406557815161404c8882613fef565b975061405783614007565b925050600181019050614038565b5085935050505092915050565b60006101c08301600083015184820360008601526140908282613ea7565b915050602083015184820360208601526140aa8282613f56565b915050604083015184820360408601526140c48282613f56565b915050606083015184820360608601526140de8282613f56565b915050608083015184820360808601526140f88282613f56565b91505060a083015184820360a08601526141128282613f56565b91505060c083015184820360c086015261412c8282613f56565b91505060e083015184820360e08601526141468282613f56565b9150506101008301518482036101008601526141628282613f56565b91505061012083015184820361012086015261417e8282614014565b91505061014083015184820361014086015261419a8282614014565b9150506101608301516141b1610160860182613d7c565b506101808301516141c6610180860182613d7c565b506101a08301516141db6101a0860182613d7c565b508091505092915050565b600060208201905081810360008301526142008184614072565b905092915050565b6000806040838503121561421f5761421e613a3f565b5b600061422d85828601613b2f565b925050602061423e85828601613b2f565b9150509250929050565b61425181613d3d565b82525050565b61426081613ab4565b82525050565b60006101808201905061427c600083018f614248565b614289602083018e614257565b614296604083018d614257565b6142a3606083018c614257565b6142b0608083018b614257565b6142bd60a083018a6139e1565b6142ca60c0830189613a15565b6142d760e0830188614257565b6142e5610100830187613a15565b6142f36101208301866139e1565b6143016101408301856139e1565b61430f610160830184613a15565b9d9c50505050505050505050505050565b600082825260208201905092915050565b600061433c82613cd3565b6143468185614320565b935061435183613cef565b8060005b838110156143825781516143698882613e81565b975061437483613e9a565b925050600181019050614355565b5085935050505092915050565b600060208201905081810360008301526143a98184614331565b905092915050565b6000806000806000806000806000806101408b8d0312156143d5576143d4613a3f565b5b60006143e38d828e01613b2f565b9a505060206143f48d828e01613ad7565b99505060406144058d828e01613ad7565b98505060606144168d828e01613ad7565b97505060806144278d828e01613b03565b96505060a06144388d828e01613b2f565b95505060c06144498d828e01613ad7565b94505060e061445a8d828e01613b2f565b93505061010061446c8d828e01613b03565b92505061012061447e8d828e01613b03565b9150509295989b9194979a5092959850565b600080604083850312156144a7576144a6613a3f565b5b60006144b585828601613b2f565b92505060206144c685828601613c91565b9150509250929050565b6000806000606084860312156144e9576144e8613a3f565b5b60006144f786828701613b2f565b935050602061450886828701613c91565b925050604061451986828701613b2f565b9150509250925092565b60006020828403121561453957614538613a3f565b5b600061454784828501613ad7565b91505092915050565b60006020820190506145656000830184614248565b92915050565b60006080820190506145806000830187613a15565b61458d6020830186613a15565b61459a6040830185613a15565b6145a76060830184613a15565b95945050505050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006145f76020836145b0565b9150614602826145c1565b602082019050919050565b60006020820190508181036000830152614626816145ea565b9050919050565b7f52657761726420706f6f6c20666f7220746f6b656e20616c726561647920657860008201527f6973747300000000000000000000000000000000000000000000000000000000602082015250565b60006146896024836145b0565b91506146948261462d565b604082019050919050565b600060208201905081810360008301526146b88161467c565b9050919050565b7f4561726c696573742072657761726420626c6f636b206d75737420626520677260008201527f6561746572207468616e207468652063757272656e7420626c6f636b00000000602082015250565b600061471b603c836145b0565b9150614726826146bf565b604082019050919050565b6000602082019050818103600083015261474a8161470e565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000815190506147be81613b18565b92915050565b6000602082840312156147da576147d9613a3f565b5b60006147e8848285016147af565b91505092915050565b60006dffffffffffffffffffffffffffff82169050919050565b614814816147f1565b811461481f57600080fd5b50565b6000815190506148318161480b565b92915050565b600063ffffffff82169050919050565b61485081614837565b811461485b57600080fd5b50565b60008151905061486d81614847565b92915050565b60008060006060848603121561488c5761488b613a3f565b5b600061489a86828701614822565b93505060206148ab86828701614822565b92505060406148bc8682870161485e565b9150509250925092565b6000815190506148d581613c7a565b92915050565b6000602082840312156148f1576148f0613a3f565b5b60006148ff848285016148c6565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061494282613a0b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561497557614974614908565b5b600182019050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006149b6601f836145b0565b91506149c182614980565b602082019050919050565b600060208201905081810360008301526149e5816149a9565b9050919050565b7f77697468647261773a2074696d65206c6f636b20686173206e6f74207061737360008201527f6564000000000000000000000000000000000000000000000000000000000000602082015250565b6000614a486022836145b0565b9150614a53826149ec565b604082019050919050565b60006020820190508181036000830152614a7781614a3b565b9050919050565b7f77697468647261773a2063616e2774207769746864726177206d6f726520746860008201527f616e206465706f73697400000000000000000000000000000000000000000000602082015250565b6000614ada602a836145b0565b9150614ae582614a7e565b604082019050919050565b60006020820190508181036000830152614b0981614acd565b9050919050565b7f416d6f756e74206d7573742062652067726561746572207468616e207a65726f600082015250565b6000614b466020836145b0565b9150614b5182614b10565b602082019050919050565b60006020820190508181036000830152614b7581614b39565b9050919050565b7f546869732072657761726420706f6f6c20697320696e61637469766500000000600082015250565b6000614bb2601c836145b0565b9150614bbd82614b7c565b602082019050919050565b60006020820190508181036000830152614be181614ba5565b9050919050565b7f52657374616b65206973206f6e6c7920617661696c61626c65206f6e2073696e60008201527f676c652d7369646564207374616b696e67000000000000000000000000000000602082015250565b6000614c446031836145b0565b9150614c4f82614be8565b604082019050919050565b60006020820190508181036000830152614c7381614c37565b9050919050565b7f53656e646572206973207265776172642077616c6c6574000000000000000000600082015250565b6000614cb06017836145b0565b9150614cbb82614c7a565b602082019050919050565b60006020820190508181036000830152614cdf81614ca3565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614d426026836145b0565b9150614d4d82614ce6565b604082019050919050565b60006020820190508181036000830152614d7181614d35565b9050919050565b6000606082019050614d8d6000830186613c50565b614d9a6020830185613c50565b614da76040830184613a15565b949350505050565b600081519050614dbe81613ac0565b92915050565b600060208284031215614dda57614dd9613a3f565b5b6000614de884828501614daf565b91505092915050565b6000614dfc82613a0b565b9150614e0783613a0b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614e3c57614e3b614908565b5b828201905092915050565b6000614e5282613a0b565b9150614e5d83613a0b565b925082821015614e7057614e6f614908565b5b828203905092915050565b6000604082019050614e906000830185613c50565b614e9d6020830184613a15565b9392505050565b6000614eaf82613a0b565b9150614eba83613a0b565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614ef357614ef2614908565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614f3882613a0b565b9150614f4383613a0b565b925082614f5357614f52614efe565b5b828204905092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000614fba602a836145b0565b9150614fc582614f5e565b604082019050919050565b60006020820190508181036000830152614fe981614fad565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b600061504c6026836145b0565b915061505782614ff0565b604082019050919050565b6000602082019050818103600083015261507b8161503f565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006150b8601d836145b0565b91506150c382615082565b602082019050919050565b600060208201905081810360008301526150e7816150ab565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015615122578082015181840152602081019050615107565b83811115615131576000848401525b50505050565b6000615142826150ee565b61514c81856150f9565b935061515c818560208601615104565b80840191505092915050565b60006151748284615137565b915081905092915050565b600081519050919050565b6000601f19601f8301169050919050565b60006151a68261517f565b6151b081856145b0565b93506151c0818560208601615104565b6151c98161518a565b840191505092915050565b600060208201905081810360008301526151ee818461519b565b90509291505056fea264697066735822122053a06b26212cad34a6fd7eae055a8ce576d89f4f20e69b47266859228cb4bc8564736f6c63430008090033

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

0000000000000000000000006069c9223e8a5da1ec49ac5525d4bb757af72cd8000000000000000000000000c0b26eb298b77e49b26dbcc665878a92e854c1b30000000000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _rewardToken (address): 0x6069c9223e8a5DA1ec49ac5525d4BB757Af72Cd8
Arg [1] : _rewardWallet (address): 0xC0B26eB298b77E49B26Dbcc665878a92e854c1B3
Arg [2] : _earliestRewards (uint256): 0

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000006069c9223e8a5da1ec49ac5525d4bb757af72cd8
Arg [1] : 000000000000000000000000c0b26eb298b77e49b26dbcc665878a92e854c1b3
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

78002:22430:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80817:19;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93853:98;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81033:30;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83295:1409;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;85865:249;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81281:33;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96494:2857;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90435:1224;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81222:31;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;99605:824;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82703:102;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81136:26;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92858:99;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5300:103;;;:::i;:::-;;96098:322;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93005:119;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;84712:797;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4649:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95098:330;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93181:105;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95724:298;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94189:842;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86681:1481;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;89147:1242;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;88986:105;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;85563:230;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82880:254;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94001:124;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95494:178;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5558:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80887:25;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81378:71;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;80956:27;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80817:19;;;;:::o;93853:98::-;93898:7;93925:11;:18;;;;93918:25;;93853:98;:::o;81033:30::-;;;;:::o;83295:1409::-;4880:12;:10;:12::i;:::-;4869:23;;:7;:5;:7::i;:::-;:23;;;4861:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;83765:5:::1;83722:48;;:39;83733:13;83748:12;83722:10;:39::i;:::-;:48;;;83700:134;;;;;;;;;;;;:::i;:::-;;;;;;;;;83955:14;84009:11;;;;;;;;;;;83992:28;;:13;:28;;;83988:108;;;84049:4;84037:16;;84079:5;84068:16;;83988:108;84108:11;84139:546;;;;;;;;84183:13;84139:546;;;;;;84223:7;84139:546;;;;;;84257:7;84139:546;;;;;;84292:8;84139:546;;;;;;84330:9;84139:546;;;;;;84424:9;84139:546;;;;84465:12;84139:546;;;;84510:13;84139:546;;;;;;84558:15;84139:546;;;;84599:6;84139:546;;;;84631:6;84139:546;;;;84668:1;84139:546;;::::0;84108:588:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83611:1093;83295:1409:::0;;;;;;;;;;:::o;85865:249::-;4880:12;:10;:12::i;:::-;4869:23;;:7;:5;:7::i;:::-;:23;;;4861:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;85971:12:::1;85961:6;:22;;85939:132;;;;;;;;;;;;:::i;:::-;;;;;;;;;86100:6;86082:15;:24;;;;85865:249:::0;:::o;81281:33::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;96494:2857::-;96581:20;;:::i;:::-;96619:24;96660:11;:18;;;;96646:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96619:60;;96690:24;96731:11;:18;;;;96717:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96690:60;;96761:23;96801:11;:18;;;;96787:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96761:59;;96831:26;96874:11;:18;;;;96860:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96831:62;;96904:29;96950:11;:18;;;;96936:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96904:65;;96980:31;97028:11;:18;;;;97014:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96980:67;;97058:31;97106:11;:18;;;;97092:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97058:67;;97136:30;97183:11;:18;;;;97169:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97136:66;;97213:30;97260:11;:18;;;;97246:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97213:66;;97290:27;97334:11;:18;;;;97320:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97290:63;;97371:11;97366:1063;97394:11;:18;;;;97388:3;:24;97366:1063;;;97451:12;:17;97464:3;97451:17;;;;;;;;;;;:24;97469:5;97451:24;;;;;;;;;;;;;;;:32;;;97436:7;97444:3;97436:12;;;;;;;;:::i;:::-;;;;;;;:47;;;;;97513:27;97529:3;97534:5;97513:15;:27::i;:::-;97498:7;97506:3;97498:12;;;;;;;;:::i;:::-;;;;;;;:42;;;;;97569:26;97584:3;97589:5;97569:14;:26::i;:::-;97555:6;97562:3;97555:11;;;;;;;;:::i;:::-;;;;;;;:40;;;;;97627:11;97639:3;97627:16;;;;;;;;:::i;:::-;;;;;;;;;;;;:29;;;;;;;;;;;;:39;;;97667:5;97627:46;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;97610:9;97620:3;97610:14;;;;;;;;:::i;:::-;;;;;;;:63;;;;;97708:11;97720:3;97708:16;;;;;;;;:::i;:::-;;;;;;;;;;;;:29;;;;;;;;;;;;:41;;;:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;97688:12;97701:3;97688:17;;;;;;;;:::i;:::-;;;;;;;:63;;;;;97784:12;:17;97797:3;97784:17;;;;;;;;;;;:24;97802:5;97784:24;;;;;;;;;;;;;;;:35;;;97766:10;97777:3;97766:15;;;;;;;;:::i;:::-;;;;;;;:53;;;;;97886:4;97858:32;;:11;97870:3;97858:16;;;;;;;;:::i;:::-;;;;;;;;;;;;:24;;;;;;;;;;;;:32;;;:88;;;;;97941:5;97911:35;;:11;97923:3;97911:16;;;;;;;;:::i;:::-;;;;;;;;;;;;:26;;;;;;;;;;;;:35;;;97858:88;97836:582;;;97981:19;98048:11;98060:3;98048:16;;;;;;;;:::i;:::-;;;;;;;;;;;;:29;;;;;;;;;;;;97981:116;;98117:12;98131;98145:17;98166:4;:38;;;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;98116:90;;;;;;;;;;;;98247:4;98225:14;98240:3;98225:19;;;;;;;;:::i;:::-;;;;;;;:26;;;;;98292:4;98270:14;98285:3;98270:19;;;;;;;;:::i;:::-;;;;;;;:26;;;;;98336:4;:11;;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;98315;98329:3;98315:18;;;;;;;;:::i;:::-;;;;;;;:34;;;;;;;;;;;98389:4;:11;;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;98368;98382:3;98368:18;;;;;;;;:::i;:::-;;;;;;;:34;;;;;;;;;;;97962:456;;;;97836:582;97414:5;;;;:::i;:::-;;;97366:1063;;;;98461:882;;;;;;;;98493:11;98461:882;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;98532:7;98461:882;;;;98578:10;98461:882;;;;98646:7;98461:882;;;;98699:6;98461:882;;;;98744:9;98461:882;;;;98805:12;98461:882;;;;98869:14;98461:882;;;;98933:14;98461:882;;;;98997:13;98461:882;;;;99054:13;98461:882;;;;99111:11;;;;;;;;;;;:21;;;99133:5;99111:28;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;98461:882;;;;99203:21;99218:5;99203:14;:21::i;:::-;98461:882;;;;99276:20;99290:5;99276:13;:20::i;:::-;98461:882;;;98441:902;;;;;;;;;;;;96494:2857;;;:::o;90435:1224::-;7838:1;8436:7;;:19;;8428:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;7838:1;8569:7;:18;;;;90517:23:::1;90543:11;90555:4;90543:17;;;;;;;;:::i;:::-;;;;;;;;;;;;90517:43;;90571:31;90605:12;:18;90618:4;90605:18;;;;;;;;;;;:30;90624:10;90605:30;;;;;;;;;;;;;;;90571:64;;90652:4;:17;;;;;;;;;;;;90648:173;;;90736:15;90710:11;:22;;;:41;;90684:137;;;;;;;;;;;;:::i;:::-;;;;;;;;;90648:173;90877:7;90854:11;:19;;;:30;;90832:122;;;;;;;;;;;;:::i;:::-;;;;;;;;;90967:27;90977:4;90983:10;90967:9;:27::i;:::-;91057:26;91071:11;91057:13;:26::i;:::-;91147:37;91167:4;:16;;;91147:15;:19;;:37;;;;:::i;:::-;91122:11;:22;;:62;;;;91242:32;91266:7;91242:11;:19;;;:23;;:32;;;;:::i;:::-;91220:11;:19;;:54;;;;91333:60;91372:10;91385:7;91333:4;:17;;;;;;;;;;;;:30;;;;:60;;;;;:::i;:::-;91480:4;91468:10;91459:35;;;91486:7;91459:35;;;;;;:::i;:::-;;;;;;;;91525:28;91545:7;91525:4;:15;;;:19;;:28;;;;:::i;:::-;91507:4;:15;;:46;;;;91625:26;91640:10;91625:14;:26::i;:::-;90506:1153;;7794:1:::0;8748:7;:22;;;;90435:1224;;:::o;81222:31::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;99605:824::-;7838:1;8436:7;;:19;;8428:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;7838:1;8569:7;:18;;;;99679:23:::1;99705:11;99717:4;99705:17;;;;;;;;:::i;:::-;;;;;;;;;;;;99679:43;;99749:31;99783:12;:18;99796:4;99783:18;;;;;;;;;;;:30;99802:10;99783:30;;;;;;;;;;;;;;;99749:64;;99844:109;99897:10;99923:11;:19;;;99844:4;:17;;;;;;;;;;;;:30;;;;:109;;;;;:::i;:::-;100023:40;100043:11;:19;;;100023:4;:15;;;:19;;:40;;;;:::i;:::-;100005:4;:15;;:58;;;;100143:37;100163:4;:16;;;100143:15;:19;;:37;;;;:::i;:::-;100118:11;:22;;:62;;;;100238:1;100216:11;:19;;:23;;;;100295:26;100309:11;100295:13;:26::i;:::-;100395:4;100383:10;100365:56;;;100401:11;:19;;;100365:56;;;;;;:::i;:::-;;;;;;;;99668:761;;7794:1:::0;8748:7;:22;;;;99605:824;:::o;82703:102::-;4880:12;:10;:12::i;:::-;4869:23;;:7;:5;:7::i;:::-;:23;;;4861:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;82790:7:::1;82775:12;;:22;;;;;;;;;;;;;;;;;;82703:102:::0;:::o;81136:26::-;;;;:::o;92858:99::-;92899:19;92938:11;92931:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92858:99;:::o;5300:103::-;4880:12;:10;:12::i;:::-;4869:23;;:7;:5;:7::i;:::-;:23;;;4861:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;5365:30:::1;5392:1;5365:18;:30::i;:::-;5300:103::o:0;96098:322::-;96149:7;96169:15;96187:1;96169:19;;96206:9;96201:187;96225:16;:23;;;;96221:1;:27;96201:187;;;96270:19;96292:35;96307:16;96324:1;96307:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;96292:14;:35::i;:::-;96270:57;;96352:24;96364:11;96352:7;:11;;:24;;;;:::i;:::-;96342:34;;96255:133;96250:3;;;;:::i;:::-;;;96201:187;;;;96405:7;96398:14;;;96098:322;:::o;93005:119::-;93054:7;93081:11;;;;;;;;;;;:21;;;93103:12;;;;;;;;;;;93081:35;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;93074:42;;93005:119;:::o;84712:797::-;4880:12;:10;:12::i;:::-;4869:23;;:7;:5;:7::i;:::-;:23;;;4861:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;85094:7:::1;85067:11;85079:4;85067:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:24;;;:34;;;;;;;;;;;;;;;;;;85139:7;85112:11;85124:4;85112:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:24;;;:34;;;;;;;;;;;;;;;;;;85185:8;85157:11;85169:4;85157:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:25;;;:36;;;;;;;;;;;;;;;;;;85233:9;85204:11;85216:4;85204:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:26;;:38;;;;85285:12;85253:11;85265:4;85253:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:29;;:44;;;;85341:13;85308:11;85320:4;85308:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:30;;;:46;;;;;;;;;;;;;;;;;;85400:15;85365:11;85377:4;85365:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:32;;:50;;;;85452:6;85426:11;85438:4;85426:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:23;;:32;;;;85495:6;85469:11;85481:4;85469:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:23;;:32;;;;84712:797:::0;;;;;;;;;;:::o;4649:87::-;4695:7;4722:6;;;;;;;;;;;4715:13;;4649:87;:::o;95098:330::-;95158:7;95178:19;95200:1;95178:23;;95217:11;95212:180;95240:11;:18;;;;95234:3;:24;95212:180;;;95282:15;95300:27;95316:3;95321:5;95300:15;:27::i;:::-;95282:45;;95356:24;95372:7;95356:11;:15;;:24;;;;:::i;:::-;95342:38;;95267:125;95260:5;;;;:::i;:::-;;;95212:180;;;;95409:11;95402:18;;;95098:330;;;:::o;93181:105::-;93228:7;93255:16;:23;;;;93248:30;;93181:105;:::o;95724:298::-;95783:7;95803:19;95825:1;95803:23;;95842:11;95837:149;95865:11;:18;;;;95859:3;:24;95837:149;;;95921:53;95937:12;:17;95950:3;95937:17;;;;;;;;;;;:24;95955:5;95937:24;;;;;;;;;;;;;;;:36;;;95921:11;:15;;:53;;;;:::i;:::-;95907:67;;95885:5;;;;:::i;:::-;;;95837:149;;;;96003:11;95996:18;;;95724:298;;;:::o;94189:842::-;94291:7;94316:23;94342:11;94354:4;94342:17;;;;;;;;:::i;:::-;;;;;;;;;;;;94316:43;;94370:31;94404:12;:18;94417:4;94404:18;;;;;;;;;;;:25;94423:5;94404:25;;;;;;;;;;;;;;;94370:59;;94469:1;94446:11;:19;;;:24;94442:38;;;94479:1;94472:8;;;;;;94442:38;94513:12;94495:15;;:30;94491:44;;;94534:1;94527:8;;;;;;94491:44;94548:17;94568:4;94548:24;;94585:21;94640:11;:22;;;94625:12;:37;94621:112;;;94693:40;94710:11;:22;;;94693:12;:16;;:40;;;;:::i;:::-;94677:56;;94621:112;94746:21;94770:79;94823:4;:15;;;94770:34;94794:9;94770:11;:19;;;:23;;:34;;;;:::i;:::-;:38;;:79;;;;:::i;:::-;94746:103;;94860:18;94881:114;94985:9;94881:85;94952:13;94881:52;94913:4;:19;;;94881:13;:31;;:52;;;;:::i;:::-;:70;;:85;;;;:::i;:::-;:103;;:114;;;;:::i;:::-;94860:135;;95013:10;95006:17;;;;;;;;94189:842;;;;;:::o;86681:1481::-;7838:1;8436:7;;:19;;8428:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;7838:1;8569:7;:18;;;;86809:23:::1;86835:11;86847:4;86835:17;;;;;;;;:::i;:::-;;;;;;;;;;;;86809:43;;86881:1;86871:7;:11;86863:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;86953:4;86938:19;;:4;:11;;;;;;;;;;;;:19;;;86930:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;87003:31;87037:12;:18;87050:4;87037:18;;;;;;;;;;;:25;87056:5;87037:25;;;;;;;;;;;;;;;87003:59;;87135:1;87109:11;:22;;;:27;87105:243;;;87178:12;87153:11;:22;;:37;;;;87234:15;;87209:11;:22;;;:40;87205:103;;;87293:15;;87268:11;:22;;:40;;;;87205:103;87105:243;87468:1;87446:11;:19;;;:23;:46;;;;;87487:5;87473:19;;:10;:19;;;87446:46;87442:101;;;87509:22;87519:4;87525:5;87509:9;:22::i;:::-;87442:101;87555:129;87612:10;87646:4;87666:7;87555:4;:17;;;;;;;;;;;;:34;;;;:129;;;;;;:::i;:::-;87742:32;87766:7;87742:11;:19;;;:23;;:32;;;;:::i;:::-;87720:11;:19;;:54;;;;87861:37;87881:4;:16;;;87861:15;:19;;:37;;;;:::i;:::-;87836:11;:22;;:62;;;;87953:28;87973:7;87953:4;:15;;;:19;;:28;;;;:::i;:::-;87935:4;:15;;:46;;;;88038:20;88052:5;88038:13;:20::i;:::-;88140:4;88133:5;88113:41;;88121:10;88113:41;;;88146:7;88113:41;;;;;;:::i;:::-;;;;;;;;86798:1364;;7794:1:::0;8748:7;:22;;;;86681:1481;;;:::o;89147:1242::-;7838:1;8436:7;;:19;;8428:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;7838:1;8569:7;:18;;;;89211:23:::1;89237:11;89249:4;89237:17;;;;;;;;:::i;:::-;;;;;;;;;;;;89211:43;;89281:31;89315:12;:18;89328:4;89315:18;;;;;;;;;;;:30;89334:10;89315:30;;;;;;;;;;;;;;;89281:64;;89422:11;;;;;;;;;;;89401:32;;:4;:17;;;;;;;;;;;;:32;;;89379:131;;;;;;;;;;;;:::i;:::-;;;;;;;;;89523:18;89544:33;89560:4;89566:10;89544:15;:33::i;:::-;89523:54;;89635:1;89621:10;:15;89617:28;;89638:7;;;;;89617:28;89698:125;89747:12;;;;;;;;;;;89782:4;89802:10;89698:4;:17;;;;;;;;;;;;:34;;;;:125;;;;;;:::i;:::-;89900:31;89920:10;89900:4;:15;;;:19;;:31;;;;:::i;:::-;89882:4;:15;;:49;;;;89966:35;89990:10;89966:11;:19;;;:23;;:35;;;;:::i;:::-;89944:11;:19;;:57;;;;90083:39;90111:10;90083:11;:23;;;:27;;:39;;;;:::i;:::-;90057:11;:23;;:65;;;;90188:26;90202:11;90188:13;:26::i;:::-;90263:23;90275:10;90263:7;;:11;;:23;;;;:::i;:::-;90253:7;:33;;;;90364:4;90352:10;90344:37;;;90370:10;90344:37;;;;;;:::i;:::-;;;;;;;;89200:1189;;;8600:1;7794::::0;8748:7;:22;;;;89147:1242;:::o;88986:105::-;7838:1;8436:7;;:19;;8428:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;7838:1;8569:7;:18;;;;89056:27:::1;89066:4;89072:10;89056:9;:27::i;:::-;7794:1:::0;8748:7;:22;;;;88986:105;:::o;85563:230::-;4880:12;:10;:12::i;:::-;4869:23;;:7;:5;:7::i;:::-;:23;;;4861:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;85632:11:::1;85627:159;85655:11;:18;;;;85649:3;:24;85627:159;;;85697:23;85723:11;85735:3;85723:16;;;;;;;;:::i;:::-;;;;;;;;;;;;85697:42;;85768:6;85754:4;:11;;;:20;;;;;;;;;;;;;;;;;;85682:104;85675:5;;;;:::i;:::-;;;85627:159;;;;85563:230:::0;:::o;82880:254::-;82953:12;;;;;;;;;;;82939:26;;:10;:26;;;;82931:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;83004:122;83055:10;83081:12;;;;;;;;;;;83108:7;83004:11;;;;;;;;;;;:28;;;;:122;;;;;;:::i;:::-;82880:254;:::o;94001:124::-;94062:7;94089:11;94101:4;94089:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:28;;;94082:35;;94001:124;;;:::o;95494:178::-;95595:7;95627:12;:18;95640:4;95627:18;;;;;;;;;;;:25;95646:5;95627:25;;;;;;;;;;;;;;;:37;;;95620:44;;95494:178;;;;:::o;5558:201::-;4880:12;:10;:12::i;:::-;4869:23;;:7;:5;:7::i;:::-;:23;;;4861:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;5667:1:::1;5647:22;;:8;:22;;;;5639:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;5723:28;5742:8;5723:18;:28::i;:::-;5558:201:::0;:::o;80887:25::-;;;;;;;;;;;;;:::o;81378:71::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;80956:27::-;;;;;;;;;;;;;:::o;3456:98::-;3509:7;3536:10;3529:17;;3456:98;:::o;93371:440::-;93484:4;93511:11;93525:1;93511:15;;93506:275;93534:11;:18;;;;93528:3;:24;93506:275;;;93576:23;93602:11;93614:3;93602:16;;;;;;;;:::i;:::-;;;;;;;;;;;;93576:42;;93676:13;93655:34;;:4;:17;;;;;;;;;;;;:34;;;:87;;;;;93730:12;93710:4;:16;;;:32;93655:87;93633:136;;;93765:4;93758:11;;;;;;93633:136;93561:220;93554:5;;;;:::i;:::-;;;93506:275;;;;93798:5;93791:12;;93371:440;;;;;:::o;88217:707::-;88284:31;88318:12;:18;88331:4;88318:18;;;;;;;;;;;:25;88337:5;88318:25;;;;;;;;;;;;;;;88284:59;;88375:18;88396:28;88412:4;88418:5;88396:15;:28::i;:::-;88375:49;;88478:1;88464:10;:15;88460:28;;88481:7;;;;88460:28;88532:11;;;;;;;;;;;:24;;;88557:12;;;;;;;;;;;88571:5;88578:10;88532:57;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;88619:4;88612:5;88605:31;;;88625:10;88605:31;;;;;;:::i;:::-;;;;;;;;88675:39;88703:10;88675:11;:23;;;:27;;:39;;;;:::i;:::-;88649:11;:23;;:65;;;;88778:23;88790:10;88778:7;;:11;;:23;;;;:::i;:::-;88768:7;:33;;;;88864:26;88878:11;88864:13;:26::i;:::-;88273:651;;88217:707;;;:::o;86350:246::-;86444:12;86422:8;:19;;:34;;;;86493:15;;86471:8;:19;;;:37;86467:93;;;86545:15;;86523:8;:19;;:37;;;;86467:93;86350:246;:::o;59008:98::-;59066:7;59097:1;59093;:5;;;;:::i;:::-;59086:12;;59008:98;;;;:::o;59389:::-;59447:7;59478:1;59474;:5;;;;:::i;:::-;59467:12;;59389:98;;;;:::o;72195:211::-;72312:86;72332:5;72362:23;;;72387:2;72391:5;72339:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72312:19;:86::i;:::-;72195:211;;;:::o;92084:605::-;92202:16;92238:11;92233:142;92261:11;:18;;;;92255:3;:24;92233:142;;;92314:49;92327:12;:17;92340:3;92327:17;;;;;;;;;;;:27;92345:8;92327:27;;;;;;;;;;;;;;;:35;;;92314:8;:12;;:49;;;;:::i;:::-;92303:60;;92281:5;;;;;:::i;:::-;;;;92233:142;;;;92402:1;92391:8;:12;92387:25;;;92405:7;;;92387:25;92468:9;92463:219;92487:16;:23;;;;92483:1;:27;92463:219;;;92532:18;92553:16;92570:1;92553:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;92532:40;;92603:10;92591:22;;:8;:22;;;92587:54;;;92622:16;92639:1;92622:19;;;;;;;;:::i;:::-;;;;;;;;;;92615:26;;;;;;;;;;;92587:54;92517:165;92512:3;;;;;:::i;:::-;;;;92463:219;;;;92134:555;92084:605;;:::o;5919:191::-;5993:16;6012:6;;;;;;;;;;;5993:25;;6038:8;6029:6;;:17;;;;;;;;;;;;;;;;;;6093:8;6062:40;;6083:8;6062:40;;;;;;;;;;;;5982:128;5919:191;:::o;59746:98::-;59804:7;59835:1;59831;:5;;;;:::i;:::-;59824:12;;59746:98;;;;:::o;60145:::-;60203:7;60234:1;60230;:5;;;;:::i;:::-;60223:12;;60145:98;;;;:::o;72414:248::-;72558:96;72578:5;72608:27;;;72637:4;72643:2;72647:5;72585:68;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72558:19;:96::i;:::-;72414:248;;;;:::o;91737:279::-;91802:9;91797:170;91821:16;:23;;;;91817:1;:27;91797:170;;;91866:18;91887:16;91904:1;91887:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;91866:40;;91937:10;91925:22;;:8;:22;;;91921:35;;;91949:7;;;;91921:35;91851:116;91846:3;;;;;:::i;:::-;;;;91797:170;;;;91977:16;91999:8;91977:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91737:279;;:::o;74768:716::-;75192:23;75218:69;75246:4;75218:69;;;;;;;;;;;;;;;;;75226:5;75218:27;;;;:69;;;;;:::i;:::-;75192:95;;75322:1;75302:10;:17;:21;75298:179;;;75399:10;75388:30;;;;;;;;;;;;:::i;:::-;75380:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;75298:179;74838:646;74768:716;;:::o;67071:229::-;67208:12;67240:52;67262:6;67270:4;67276:1;67279:12;67240:21;:52::i;:::-;67233:59;;67071:229;;;;;:::o;68191:510::-;68361:12;68419:5;68394:21;:30;;68386:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;68486:18;68497:6;68486:10;:18::i;:::-;68478:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;68552:12;68566:23;68593:6;:11;;68612:5;68619:4;68593:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68551:73;;;;68642:51;68659:7;68668:10;68680:12;68642:16;:51::i;:::-;68635:58;;;;68191:510;;;;;;:::o;64326:326::-;64386:4;64643:1;64621:7;:19;;;:23;64614:30;;64326:326;;;:::o;70877:712::-;71027:12;71056:7;71052:530;;;71087:10;71080:17;;;;71052:530;71221:1;71201:10;:17;:21;71197:374;;;71399:10;71393:17;71460:15;71447:10;71443:2;71439:19;71432:44;71197:374;71542:12;71535:20;;;;;;;;;;;:::i;:::-;;;;;;;;70877:712;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:77:1:-;44:7;73:5;62:16;;7:77;;;:::o;90:118::-;177:24;195:5;177:24;:::i;:::-;172:3;165:37;90:118;;:::o;214:222::-;307:4;345:2;334:9;330:18;322:26;;358:71;426:1;415:9;411:17;402:6;358:71;:::i;:::-;214:222;;;;:::o;442:77::-;479:7;508:5;497:16;;442:77;;;:::o;525:118::-;612:24;630:5;612:24;:::i;:::-;607:3;600:37;525:118;;:::o;649:222::-;742:4;780:2;769:9;765:18;757:26;;793:71;861:1;850:9;846:17;837:6;793:71;:::i;:::-;649:222;;;;:::o;958:117::-;1067:1;1064;1057:12;1204:126;1241:7;1281:42;1274:5;1270:54;1259:65;;1204:126;;;:::o;1336:96::-;1373:7;1402:24;1420:5;1402:24;:::i;:::-;1391:35;;1336:96;;;:::o;1438:109::-;1488:7;1517:24;1535:5;1517:24;:::i;:::-;1506:35;;1438:109;;;:::o;1553:148::-;1639:37;1670:5;1639:37;:::i;:::-;1632:5;1629:48;1619:76;;1691:1;1688;1681:12;1619:76;1553:148;:::o;1707:165::-;1766:5;1804:6;1791:20;1782:29;;1820:46;1860:5;1820:46;:::i;:::-;1707:165;;;;:::o;1878:90::-;1912:7;1955:5;1948:13;1941:21;1930:32;;1878:90;;;:::o;1974:116::-;2044:21;2059:5;2044:21;:::i;:::-;2037:5;2034:32;2024:60;;2080:1;2077;2070:12;2024:60;1974:116;:::o;2096:133::-;2139:5;2177:6;2164:20;2155:29;;2193:30;2217:5;2193:30;:::i;:::-;2096:133;;;;:::o;2235:122::-;2308:24;2326:5;2308:24;:::i;:::-;2301:5;2298:35;2288:63;;2347:1;2344;2337:12;2288:63;2235:122;:::o;2363:139::-;2409:5;2447:6;2434:20;2425:29;;2463:33;2490:5;2463:33;:::i;:::-;2363:139;;;;:::o;2508:122::-;2581:24;2599:5;2581:24;:::i;:::-;2574:5;2571:35;2561:63;;2620:1;2617;2610:12;2561:63;2508:122;:::o;2636:139::-;2682:5;2720:6;2707:20;2698:29;;2736:33;2763:5;2736:33;:::i;:::-;2636:139;;;;:::o;2781:1643::-;2922:6;2930;2938;2946;2954;2962;2970;2978;2986;2994;3043:3;3031:9;3022:7;3018:23;3014:33;3011:120;;;3050:79;;:::i;:::-;3011:120;3170:1;3195:66;3253:7;3244:6;3233:9;3229:22;3195:66;:::i;:::-;3185:76;;3141:130;3310:2;3336:50;3378:7;3369:6;3358:9;3354:22;3336:50;:::i;:::-;3326:60;;3281:115;3435:2;3461:50;3503:7;3494:6;3483:9;3479:22;3461:50;:::i;:::-;3451:60;;3406:115;3560:2;3586:50;3628:7;3619:6;3608:9;3604:22;3586:50;:::i;:::-;3576:60;;3531:115;3685:3;3712:53;3757:7;3748:6;3737:9;3733:22;3712:53;:::i;:::-;3702:63;;3656:119;3814:3;3841:53;3886:7;3877:6;3866:9;3862:22;3841:53;:::i;:::-;3831:63;;3785:119;3943:3;3970:50;4012:7;4003:6;3992:9;3988:22;3970:50;:::i;:::-;3960:60;;3914:116;4069:3;4096:53;4141:7;4132:6;4121:9;4117:22;4096:53;:::i;:::-;4086:63;;4040:119;4198:3;4225:53;4270:7;4261:6;4250:9;4246:22;4225:53;:::i;:::-;4215:63;;4169:119;4327:3;4354:53;4399:7;4390:6;4379:9;4375:22;4354:53;:::i;:::-;4344:63;;4298:119;2781:1643;;;;;;;;;;;;;:::o;4430:329::-;4489:6;4538:2;4526:9;4517:7;4513:23;4509:32;4506:119;;;4544:79;;:::i;:::-;4506:119;4664:1;4689:53;4734:7;4725:6;4714:9;4710:22;4689:53;:::i;:::-;4679:63;;4635:117;4430:329;;;;:::o;4765:118::-;4852:24;4870:5;4852:24;:::i;:::-;4847:3;4840:37;4765:118;;:::o;4889:222::-;4982:4;5020:2;5009:9;5005:18;4997:26;;5033:71;5101:1;5090:9;5086:17;5077:6;5033:71;:::i;:::-;4889:222;;;;:::o;5117:122::-;5190:24;5208:5;5190:24;:::i;:::-;5183:5;5180:35;5170:63;;5229:1;5226;5219:12;5170:63;5117:122;:::o;5245:139::-;5291:5;5329:6;5316:20;5307:29;;5345:33;5372:5;5345:33;:::i;:::-;5245:139;;;;:::o;5390:329::-;5449:6;5498:2;5486:9;5477:7;5473:23;5469:32;5466:119;;;5504:79;;:::i;:::-;5466:119;5624:1;5649:53;5694:7;5685:6;5674:9;5670:22;5649:53;:::i;:::-;5639:63;;5595:117;5390:329;;;;:::o;5725:142::-;5820:6;5854:5;5848:12;5838:22;;5725:142;;;:::o;5873:202::-;5990:11;6024:6;6019:3;6012:19;6064:4;6059:3;6055:14;6040:29;;5873:202;;;;:::o;6081:160::-;6176:4;6199:3;6191:11;;6229:4;6224:3;6220:14;6212:22;;6081:160;;;:::o;6247:60::-;6275:3;6296:5;6289:12;;6247:60;;;:::o;6313:142::-;6363:9;6396:53;6414:34;6423:24;6441:5;6423:24;:::i;:::-;6414:34;:::i;:::-;6396:53;:::i;:::-;6383:66;;6313:142;;;:::o;6461:126::-;6511:9;6544:37;6575:5;6544:37;:::i;:::-;6531:50;;6461:126;;;:::o;6593:139::-;6656:9;6689:37;6720:5;6689:37;:::i;:::-;6676:50;;6593:139;;;:::o;6738:147::-;6828:50;6872:5;6828:50;:::i;:::-;6823:3;6816:63;6738:147;;:::o;6891:99::-;6962:21;6977:5;6962:21;:::i;:::-;6957:3;6950:34;6891:99;;:::o;6996:108::-;7073:24;7091:5;7073:24;:::i;:::-;7068:3;7061:37;6996:108;;:::o;7110:::-;7187:24;7205:5;7187:24;:::i;:::-;7182:3;7175:37;7110:108;;:::o;7300:2301::-;7443:6;7438:3;7434:16;7540:4;7533:5;7529:16;7523:23;7559:76;7629:4;7624:3;7620:14;7606:12;7559:76;:::i;:::-;7460:185;7729:4;7722:5;7718:16;7712:23;7748:57;7799:4;7794:3;7790:14;7776:12;7748:57;:::i;:::-;7655:160;7899:4;7892:5;7888:16;7882:23;7918:57;7969:4;7964:3;7960:14;7946:12;7918:57;:::i;:::-;7825:160;8070:4;8063:5;8059:16;8053:23;8089:57;8140:4;8135:3;8131:14;8117:12;8089:57;:::i;:::-;7995:161;8243:4;8236:5;8232:16;8226:23;8262:57;8313:4;8308:3;8304:14;8290:12;8262:57;:::i;:::-;8166:163;8415:4;8408:5;8404:16;8398:23;8434:63;8491:4;8486:3;8482:14;8468:12;8434:63;:::i;:::-;8339:168;8596:4;8589:5;8585:16;8579:23;8615:63;8672:4;8667:3;8663:14;8649:12;8615:63;:::i;:::-;8517:171;8778:4;8771:5;8767:16;8761:23;8797:57;8848:4;8843:3;8839:14;8825:12;8797:57;:::i;:::-;8698:166;8956:6;8949:5;8945:18;8939:25;8977:65;9034:6;9029:3;9025:16;9011:12;8977:65;:::i;:::-;8874:178;9135:6;9128:5;9124:18;9118:25;9156:65;9213:6;9208:3;9204:16;9190:12;9156:65;:::i;:::-;9062:169;9314:6;9307:5;9303:18;9297:25;9335:65;9392:6;9387:3;9383:16;9369:12;9335:65;:::i;:::-;9241:169;9498:6;9491:5;9487:18;9481:25;9519:65;9576:6;9571:3;9567:16;9553:12;9519:65;:::i;:::-;9420:174;7412:2189;7300:2301;;:::o;9607:293::-;9732:10;9753:102;9851:3;9843:6;9753:102;:::i;:::-;9887:6;9882:3;9878:16;9864:30;;9607:293;;;;:::o;9906:141::-;10004:4;10036;10031:3;10027:14;10019:22;;9906:141;;;:::o;10133:936::-;10298:3;10327:82;10403:5;10327:82;:::i;:::-;10425:104;10522:6;10517:3;10425:104;:::i;:::-;10418:111;;10553:84;10631:5;10553:84;:::i;:::-;10660:7;10691:1;10676:368;10701:6;10698:1;10695:13;10676:368;;;10777:6;10771:13;10804:119;10919:3;10904:13;10804:119;:::i;:::-;10797:126;;10946:88;11027:6;10946:88;:::i;:::-;10936:98;;10736:308;10723:1;10720;10716:9;10711:14;;10676:368;;;10680:14;11060:3;11053:10;;10303:766;;;10133:936;;;;:::o;11075:114::-;11142:6;11176:5;11170:12;11160:22;;11075:114;;;:::o;11195:174::-;11284:11;11318:6;11313:3;11306:19;11358:4;11353:3;11349:14;11334:29;;11195:174;;;;:::o;11375:132::-;11442:4;11465:3;11457:11;;11495:4;11490:3;11486:14;11478:22;;11375:132;;;:::o;11513:179::-;11582:10;11603:46;11645:3;11637:6;11603:46;:::i;:::-;11681:4;11676:3;11672:14;11658:28;;11513:179;;;;:::o;11698:113::-;11768:4;11800;11795:3;11791:14;11783:22;;11698:113;;;:::o;11847:712::-;11956:3;11985:54;12033:5;11985:54;:::i;:::-;12055:76;12124:6;12119:3;12055:76;:::i;:::-;12048:83;;12155:56;12205:5;12155:56;:::i;:::-;12234:7;12265:1;12250:284;12275:6;12272:1;12269:13;12250:284;;;12351:6;12345:13;12378:63;12437:3;12422:13;12378:63;:::i;:::-;12371:70;;12464:60;12517:6;12464:60;:::i;:::-;12454:70;;12310:224;12297:1;12294;12290:9;12285:14;;12250:284;;;12254:14;12550:3;12543:10;;11961:598;;;11847:712;;;;:::o;12565:114::-;12632:6;12666:5;12660:12;12650:22;;12565:114;;;:::o;12685:174::-;12774:11;12808:6;12803:3;12796:19;12848:4;12843:3;12839:14;12824:29;;12685:174;;;;:::o;12865:132::-;12932:4;12955:3;12947:11;;12985:4;12980:3;12976:14;12968:22;;12865:132;;;:::o;13003:108::-;13080:24;13098:5;13080:24;:::i;:::-;13075:3;13068:37;13003:108;;:::o;13117:179::-;13186:10;13207:46;13249:3;13241:6;13207:46;:::i;:::-;13285:4;13280:3;13276:14;13262:28;;13117:179;;;;:::o;13302:113::-;13372:4;13404;13399:3;13395:14;13387:22;;13302:113;;;:::o;13451:712::-;13560:3;13589:54;13637:5;13589:54;:::i;:::-;13659:76;13728:6;13723:3;13659:76;:::i;:::-;13652:83;;13759:56;13809:5;13759:56;:::i;:::-;13838:7;13869:1;13854:284;13879:6;13876:1;13873:13;13854:284;;;13955:6;13949:13;13982:63;14041:3;14026:13;13982:63;:::i;:::-;13975:70;;14068:60;14121:6;14068:60;:::i;:::-;14058:70;;13914:224;13901:1;13898;13894:9;13889:14;;13854:284;;;13858:14;14154:3;14147:10;;13565:598;;;13451:712;;;;:::o;14251:3901::-;14382:3;14418:6;14413:3;14409:16;14508:4;14501:5;14497:16;14491:23;14561:3;14555:4;14551:14;14544:4;14539:3;14535:14;14528:38;14587:159;14741:4;14727:12;14587:159;:::i;:::-;14579:167;;14435:322;14842:4;14835:5;14831:16;14825:23;14895:3;14889:4;14885:14;14878:4;14873:3;14869:14;14862:38;14921:103;15019:4;15005:12;14921:103;:::i;:::-;14913:111;;14767:268;15123:4;15116:5;15112:16;15106:23;15176:3;15170:4;15166:14;15159:4;15154:3;15150:14;15143:38;15202:103;15300:4;15286:12;15202:103;:::i;:::-;15194:111;;15045:271;15401:4;15394:5;15390:16;15384:23;15454:3;15448:4;15444:14;15437:4;15432:3;15428:14;15421:38;15480:103;15578:4;15564:12;15480:103;:::i;:::-;15472:111;;15326:268;15680:4;15673:5;15669:16;15663:23;15733:3;15727:4;15723:14;15716:4;15711:3;15707:14;15700:38;15759:103;15857:4;15843:12;15759:103;:::i;:::-;15751:111;;15604:269;15960:4;15953:5;15949:16;15943:23;16013:3;16007:4;16003:14;15996:4;15991:3;15987:14;15980:38;16039:103;16137:4;16123:12;16039:103;:::i;:::-;16031:111;;15883:270;16243:4;16236:5;16232:16;16226:23;16296:3;16290:4;16286:14;16279:4;16274:3;16270:14;16263:38;16322:103;16420:4;16406:12;16322:103;:::i;:::-;16314:111;;16163:273;16522:4;16515:5;16511:16;16505:23;16575:3;16569:4;16565:14;16558:4;16553:3;16549:14;16542:38;16601:103;16699:4;16685:12;16601:103;:::i;:::-;16593:111;;16446:269;16801:6;16794:5;16790:18;16784:25;16858:3;16852:4;16848:14;16839:6;16834:3;16830:16;16823:40;16884:103;16982:4;16968:12;16884:103;:::i;:::-;16876:111;;16725:273;17082:6;17075:5;17071:18;17065:25;17139:3;17133:4;17129:14;17120:6;17115:3;17111:16;17104:40;17165:103;17263:4;17249:12;17165:103;:::i;:::-;17157:111;;17008:271;17363:6;17356:5;17352:18;17346:25;17420:3;17414:4;17410:14;17401:6;17396:3;17392:16;17385:40;17446:103;17544:4;17530:12;17446:103;:::i;:::-;17438:111;;17289:271;17650:6;17643:5;17639:18;17633:25;17671:65;17728:6;17723:3;17719:16;17705:12;17671:65;:::i;:::-;17570:176;17839:6;17832:5;17828:18;17822:25;17860:65;17917:6;17912:3;17908:16;17894:12;17860:65;:::i;:::-;17756:179;18029:6;18022:5;18018:18;18012:25;18050:65;18107:6;18102:3;18098:16;18084:12;18050:65;:::i;:::-;17945:180;18142:4;18135:11;;14387:3765;14251:3901;;;;:::o;18158:397::-;18313:4;18351:2;18340:9;18336:18;18328:26;;18400:9;18394:4;18390:20;18386:1;18375:9;18371:17;18364:47;18428:120;18543:4;18534:6;18428:120;:::i;:::-;18420:128;;18158:397;;;;:::o;18561:474::-;18629:6;18637;18686:2;18674:9;18665:7;18661:23;18657:32;18654:119;;;18692:79;;:::i;:::-;18654:119;18812:1;18837:53;18882:7;18873:6;18862:9;18858:22;18837:53;:::i;:::-;18827:63;;18783:117;18939:2;18965:53;19010:7;19001:6;18990:9;18986:22;18965:53;:::i;:::-;18955:63;;18910:118;18561:474;;;;;:::o;19041:157::-;19141:50;19185:5;19141:50;:::i;:::-;19136:3;19129:63;19041:157;;:::o;19204:109::-;19285:21;19300:5;19285:21;:::i;:::-;19280:3;19273:34;19204:109;;:::o;19319:1411::-;19705:4;19743:3;19732:9;19728:19;19720:27;;19757:84;19838:1;19827:9;19823:17;19814:6;19757:84;:::i;:::-;19851:66;19913:2;19902:9;19898:18;19889:6;19851:66;:::i;:::-;19927;19989:2;19978:9;19974:18;19965:6;19927:66;:::i;:::-;20003;20065:2;20054:9;20050:18;20041:6;20003:66;:::i;:::-;20079:67;20141:3;20130:9;20126:19;20117:6;20079:67;:::i;:::-;20156:73;20224:3;20213:9;20209:19;20200:6;20156:73;:::i;:::-;20239;20307:3;20296:9;20292:19;20283:6;20239:73;:::i;:::-;20322:67;20384:3;20373:9;20369:19;20360:6;20322:67;:::i;:::-;20399:73;20467:3;20456:9;20452:19;20443:6;20399:73;:::i;:::-;20482;20550:3;20539:9;20535:19;20526:6;20482:73;:::i;:::-;20565:74;20634:3;20623:9;20619:19;20609:7;20565:74;:::i;:::-;20649;20718:3;20707:9;20703:19;20693:7;20649:74;:::i;:::-;19319:1411;;;;;;;;;;;;;;;:::o;20736:212::-;20863:11;20897:6;20892:3;20885:19;20937:4;20932:3;20928:14;20913:29;;20736:212;;;;:::o;21034:956::-;21209:3;21238:82;21314:5;21238:82;:::i;:::-;21336:114;21443:6;21438:3;21336:114;:::i;:::-;21329:121;;21474:84;21552:5;21474:84;:::i;:::-;21581:7;21612:1;21597:368;21622:6;21619:1;21616:13;21597:368;;;21698:6;21692:13;21725:119;21840:3;21825:13;21725:119;:::i;:::-;21718:126;;21867:88;21948:6;21867:88;:::i;:::-;21857:98;;21657:308;21644:1;21641;21637:9;21632:14;;21597:368;;;21601:14;21981:3;21974:10;;21214:776;;;21034:956;;;;:::o;21996:485::-;22195:4;22233:2;22222:9;22218:18;22210:26;;22282:9;22276:4;22272:20;22268:1;22257:9;22253:17;22246:47;22310:164;22469:4;22460:6;22310:164;:::i;:::-;22302:172;;21996:485;;;;:::o;22487:1617::-;22615:6;22623;22631;22639;22647;22655;22663;22671;22679;22687;22736:3;22724:9;22715:7;22711:23;22707:33;22704:120;;;22743:79;;:::i;:::-;22704:120;22863:1;22888:53;22933:7;22924:6;22913:9;22909:22;22888:53;:::i;:::-;22878:63;;22834:117;22990:2;23016:50;23058:7;23049:6;23038:9;23034:22;23016:50;:::i;:::-;23006:60;;22961:115;23115:2;23141:50;23183:7;23174:6;23163:9;23159:22;23141:50;:::i;:::-;23131:60;;23086:115;23240:2;23266:50;23308:7;23299:6;23288:9;23284:22;23266:50;:::i;:::-;23256:60;;23211:115;23365:3;23392:53;23437:7;23428:6;23417:9;23413:22;23392:53;:::i;:::-;23382:63;;23336:119;23494:3;23521:53;23566:7;23557:6;23546:9;23542:22;23521:53;:::i;:::-;23511:63;;23465:119;23623:3;23650:50;23692:7;23683:6;23672:9;23668:22;23650:50;:::i;:::-;23640:60;;23594:116;23749:3;23776:53;23821:7;23812:6;23801:9;23797:22;23776:53;:::i;:::-;23766:63;;23720:119;23878:3;23905:53;23950:7;23941:6;23930:9;23926:22;23905:53;:::i;:::-;23895:63;;23849:119;24007:3;24034:53;24079:7;24070:6;24059:9;24055:22;24034:53;:::i;:::-;24024:63;;23978:119;22487:1617;;;;;;;;;;;;;:::o;24110:474::-;24178:6;24186;24235:2;24223:9;24214:7;24210:23;24206:32;24203:119;;;24241:79;;:::i;:::-;24203:119;24361:1;24386:53;24431:7;24422:6;24411:9;24407:22;24386:53;:::i;:::-;24376:63;;24332:117;24488:2;24514:53;24559:7;24550:6;24539:9;24535:22;24514:53;:::i;:::-;24504:63;;24459:118;24110:474;;;;;:::o;24590:619::-;24667:6;24675;24683;24732:2;24720:9;24711:7;24707:23;24703:32;24700:119;;;24738:79;;:::i;:::-;24700:119;24858:1;24883:53;24928:7;24919:6;24908:9;24904:22;24883:53;:::i;:::-;24873:63;;24829:117;24985:2;25011:53;25056:7;25047:6;25036:9;25032:22;25011:53;:::i;:::-;25001:63;;24956:118;25113:2;25139:53;25184:7;25175:6;25164:9;25160:22;25139:53;:::i;:::-;25129:63;;25084:118;24590:619;;;;;:::o;25215:323::-;25271:6;25320:2;25308:9;25299:7;25295:23;25291:32;25288:119;;;25326:79;;:::i;:::-;25288:119;25446:1;25471:50;25513:7;25504:6;25493:9;25489:22;25471:50;:::i;:::-;25461:60;;25417:114;25215:323;;;;:::o;25544:248::-;25650:4;25688:2;25677:9;25673:18;25665:26;;25701:84;25782:1;25771:9;25767:17;25758:6;25701:84;:::i;:::-;25544:248;;;;:::o;25798:553::-;25975:4;26013:3;26002:9;25998:19;25990:27;;26027:71;26095:1;26084:9;26080:17;26071:6;26027:71;:::i;:::-;26108:72;26176:2;26165:9;26161:18;26152:6;26108:72;:::i;:::-;26190;26258:2;26247:9;26243:18;26234:6;26190:72;:::i;:::-;26272;26340:2;26329:9;26325:18;26316:6;26272:72;:::i;:::-;25798:553;;;;;;;:::o;26357:169::-;26441:11;26475:6;26470:3;26463:19;26515:4;26510:3;26506:14;26491:29;;26357:169;;;;:::o;26532:182::-;26672:34;26668:1;26660:6;26656:14;26649:58;26532:182;:::o;26720:366::-;26862:3;26883:67;26947:2;26942:3;26883:67;:::i;:::-;26876:74;;26959:93;27048:3;26959:93;:::i;:::-;27077:2;27072:3;27068:12;27061:19;;26720:366;;;:::o;27092:419::-;27258:4;27296:2;27285:9;27281:18;27273:26;;27345:9;27339:4;27335:20;27331:1;27320:9;27316:17;27309:47;27373:131;27499:4;27373:131;:::i;:::-;27365:139;;27092:419;;;:::o;27517:223::-;27657:34;27653:1;27645:6;27641:14;27634:58;27726:6;27721:2;27713:6;27709:15;27702:31;27517:223;:::o;27746:366::-;27888:3;27909:67;27973:2;27968:3;27909:67;:::i;:::-;27902:74;;27985:93;28074:3;27985:93;:::i;:::-;28103:2;28098:3;28094:12;28087:19;;27746:366;;;:::o;28118:419::-;28284:4;28322:2;28311:9;28307:18;28299:26;;28371:9;28365:4;28361:20;28357:1;28346:9;28342:17;28335:47;28399:131;28525:4;28399:131;:::i;:::-;28391:139;;28118:419;;;:::o;28543:247::-;28683:34;28679:1;28671:6;28667:14;28660:58;28752:30;28747:2;28739:6;28735:15;28728:55;28543:247;:::o;28796:366::-;28938:3;28959:67;29023:2;29018:3;28959:67;:::i;:::-;28952:74;;29035:93;29124:3;29035:93;:::i;:::-;29153:2;29148:3;29144:12;29137:19;;28796:366;;;:::o;29168:419::-;29334:4;29372:2;29361:9;29357:18;29349:26;;29421:9;29415:4;29411:20;29407:1;29396:9;29392:17;29385:47;29449:131;29575:4;29449:131;:::i;:::-;29441:139;;29168:419;;;:::o;29593:180::-;29641:77;29638:1;29631:88;29738:4;29735:1;29728:15;29762:4;29759:1;29752:15;29779:180;29827:77;29824:1;29817:88;29924:4;29921:1;29914:15;29948:4;29945:1;29938:15;29965:143;30022:5;30053:6;30047:13;30038:22;;30069:33;30096:5;30069:33;:::i;:::-;29965:143;;;;:::o;30114:351::-;30184:6;30233:2;30221:9;30212:7;30208:23;30204:32;30201:119;;;30239:79;;:::i;:::-;30201:119;30359:1;30384:64;30440:7;30431:6;30420:9;30416:22;30384:64;:::i;:::-;30374:74;;30330:128;30114:351;;;;:::o;30471:114::-;30508:7;30548:30;30541:5;30537:42;30526:53;;30471:114;;;:::o;30591:122::-;30664:24;30682:5;30664:24;:::i;:::-;30657:5;30654:35;30644:63;;30703:1;30700;30693:12;30644:63;30591:122;:::o;30719:143::-;30776:5;30807:6;30801:13;30792:22;;30823:33;30850:5;30823:33;:::i;:::-;30719:143;;;;:::o;30868:93::-;30904:7;30944:10;30937:5;30933:22;30922:33;;30868:93;;;:::o;30967:120::-;31039:23;31056:5;31039:23;:::i;:::-;31032:5;31029:34;31019:62;;31077:1;31074;31067:12;31019:62;30967:120;:::o;31093:141::-;31149:5;31180:6;31174:13;31165:22;;31196:32;31222:5;31196:32;:::i;:::-;31093:141;;;;:::o;31240:661::-;31327:6;31335;31343;31392:2;31380:9;31371:7;31367:23;31363:32;31360:119;;;31398:79;;:::i;:::-;31360:119;31518:1;31543:64;31599:7;31590:6;31579:9;31575:22;31543:64;:::i;:::-;31533:74;;31489:128;31656:2;31682:64;31738:7;31729:6;31718:9;31714:22;31682:64;:::i;:::-;31672:74;;31627:129;31795:2;31821:63;31876:7;31867:6;31856:9;31852:22;31821:63;:::i;:::-;31811:73;;31766:128;31240:661;;;;;:::o;31907:143::-;31964:5;31995:6;31989:13;31980:22;;32011:33;32038:5;32011:33;:::i;:::-;31907:143;;;;:::o;32056:351::-;32126:6;32175:2;32163:9;32154:7;32150:23;32146:32;32143:119;;;32181:79;;:::i;:::-;32143:119;32301:1;32326:64;32382:7;32373:6;32362:9;32358:22;32326:64;:::i;:::-;32316:74;;32272:128;32056:351;;;;:::o;32413:180::-;32461:77;32458:1;32451:88;32558:4;32555:1;32548:15;32582:4;32579:1;32572:15;32599:233;32638:3;32661:24;32679:5;32661:24;:::i;:::-;32652:33;;32707:66;32700:5;32697:77;32694:103;;;32777:18;;:::i;:::-;32694:103;32824:1;32817:5;32813:13;32806:20;;32599:233;;;:::o;32838:181::-;32978:33;32974:1;32966:6;32962:14;32955:57;32838:181;:::o;33025:366::-;33167:3;33188:67;33252:2;33247:3;33188:67;:::i;:::-;33181:74;;33264:93;33353:3;33264:93;:::i;:::-;33382:2;33377:3;33373:12;33366:19;;33025:366;;;:::o;33397:419::-;33563:4;33601:2;33590:9;33586:18;33578:26;;33650:9;33644:4;33640:20;33636:1;33625:9;33621:17;33614:47;33678:131;33804:4;33678:131;:::i;:::-;33670:139;;33397:419;;;:::o;33822:221::-;33962:34;33958:1;33950:6;33946:14;33939:58;34031:4;34026:2;34018:6;34014:15;34007:29;33822:221;:::o;34049:366::-;34191:3;34212:67;34276:2;34271:3;34212:67;:::i;:::-;34205:74;;34288:93;34377:3;34288:93;:::i;:::-;34406:2;34401:3;34397:12;34390:19;;34049:366;;;:::o;34421:419::-;34587:4;34625:2;34614:9;34610:18;34602:26;;34674:9;34668:4;34664:20;34660:1;34649:9;34645:17;34638:47;34702:131;34828:4;34702:131;:::i;:::-;34694:139;;34421:419;;;:::o;34846:229::-;34986:34;34982:1;34974:6;34970:14;34963:58;35055:12;35050:2;35042:6;35038:15;35031:37;34846:229;:::o;35081:366::-;35223:3;35244:67;35308:2;35303:3;35244:67;:::i;:::-;35237:74;;35320:93;35409:3;35320:93;:::i;:::-;35438:2;35433:3;35429:12;35422:19;;35081:366;;;:::o;35453:419::-;35619:4;35657:2;35646:9;35642:18;35634:26;;35706:9;35700:4;35696:20;35692:1;35681:9;35677:17;35670:47;35734:131;35860:4;35734:131;:::i;:::-;35726:139;;35453:419;;;:::o;35878:182::-;36018:34;36014:1;36006:6;36002:14;35995:58;35878:182;:::o;36066:366::-;36208:3;36229:67;36293:2;36288:3;36229:67;:::i;:::-;36222:74;;36305:93;36394:3;36305:93;:::i;:::-;36423:2;36418:3;36414:12;36407:19;;36066:366;;;:::o;36438:419::-;36604:4;36642:2;36631:9;36627:18;36619:26;;36691:9;36685:4;36681:20;36677:1;36666:9;36662:17;36655:47;36719:131;36845:4;36719:131;:::i;:::-;36711:139;;36438:419;;;:::o;36863:178::-;37003:30;36999:1;36991:6;36987:14;36980:54;36863:178;:::o;37047:366::-;37189:3;37210:67;37274:2;37269:3;37210:67;:::i;:::-;37203:74;;37286:93;37375:3;37286:93;:::i;:::-;37404:2;37399:3;37395:12;37388:19;;37047:366;;;:::o;37419:419::-;37585:4;37623:2;37612:9;37608:18;37600:26;;37672:9;37666:4;37662:20;37658:1;37647:9;37643:17;37636:47;37700:131;37826:4;37700:131;:::i;:::-;37692:139;;37419:419;;;:::o;37844:236::-;37984:34;37980:1;37972:6;37968:14;37961:58;38053:19;38048:2;38040:6;38036:15;38029:44;37844:236;:::o;38086:366::-;38228:3;38249:67;38313:2;38308:3;38249:67;:::i;:::-;38242:74;;38325:93;38414:3;38325:93;:::i;:::-;38443:2;38438:3;38434:12;38427:19;;38086:366;;;:::o;38458:419::-;38624:4;38662:2;38651:9;38647:18;38639:26;;38711:9;38705:4;38701:20;38697:1;38686:9;38682:17;38675:47;38739:131;38865:4;38739:131;:::i;:::-;38731:139;;38458:419;;;:::o;38883:173::-;39023:25;39019:1;39011:6;39007:14;39000:49;38883:173;:::o;39062:366::-;39204:3;39225:67;39289:2;39284:3;39225:67;:::i;:::-;39218:74;;39301:93;39390:3;39301:93;:::i;:::-;39419:2;39414:3;39410:12;39403:19;;39062:366;;;:::o;39434:419::-;39600:4;39638:2;39627:9;39623:18;39615:26;;39687:9;39681:4;39677:20;39673:1;39662:9;39658:17;39651:47;39715:131;39841:4;39715:131;:::i;:::-;39707:139;;39434:419;;;:::o;39859:225::-;39999:34;39995:1;39987:6;39983:14;39976:58;40068:8;40063:2;40055:6;40051:15;40044:33;39859:225;:::o;40090:366::-;40232:3;40253:67;40317:2;40312:3;40253:67;:::i;:::-;40246:74;;40329:93;40418:3;40329:93;:::i;:::-;40447:2;40442:3;40438:12;40431:19;;40090:366;;;:::o;40462:419::-;40628:4;40666:2;40655:9;40651:18;40643:26;;40715:9;40709:4;40705:20;40701:1;40690:9;40686:17;40679:47;40743:131;40869:4;40743:131;:::i;:::-;40735:139;;40462:419;;;:::o;40887:442::-;41036:4;41074:2;41063:9;41059:18;41051:26;;41087:71;41155:1;41144:9;41140:17;41131:6;41087:71;:::i;:::-;41168:72;41236:2;41225:9;41221:18;41212:6;41168:72;:::i;:::-;41250;41318:2;41307:9;41303:18;41294:6;41250:72;:::i;:::-;40887:442;;;;;;:::o;41335:137::-;41389:5;41420:6;41414:13;41405:22;;41436:30;41460:5;41436:30;:::i;:::-;41335:137;;;;:::o;41478:345::-;41545:6;41594:2;41582:9;41573:7;41569:23;41565:32;41562:119;;;41600:79;;:::i;:::-;41562:119;41720:1;41745:61;41798:7;41789:6;41778:9;41774:22;41745:61;:::i;:::-;41735:71;;41691:125;41478:345;;;;:::o;41829:305::-;41869:3;41888:20;41906:1;41888:20;:::i;:::-;41883:25;;41922:20;41940:1;41922:20;:::i;:::-;41917:25;;42076:1;42008:66;42004:74;42001:1;41998:81;41995:107;;;42082:18;;:::i;:::-;41995:107;42126:1;42123;42119:9;42112:16;;41829:305;;;;:::o;42140:191::-;42180:4;42200:20;42218:1;42200:20;:::i;:::-;42195:25;;42234:20;42252:1;42234:20;:::i;:::-;42229:25;;42273:1;42270;42267:8;42264:34;;;42278:18;;:::i;:::-;42264:34;42323:1;42320;42316:9;42308:17;;42140:191;;;;:::o;42337:332::-;42458:4;42496:2;42485:9;42481:18;42473:26;;42509:71;42577:1;42566:9;42562:17;42553:6;42509:71;:::i;:::-;42590:72;42658:2;42647:9;42643:18;42634:6;42590:72;:::i;:::-;42337:332;;;;;:::o;42675:348::-;42715:7;42738:20;42756:1;42738:20;:::i;:::-;42733:25;;42772:20;42790:1;42772:20;:::i;:::-;42767:25;;42960:1;42892:66;42888:74;42885:1;42882:81;42877:1;42870:9;42863:17;42859:105;42856:131;;;42967:18;;:::i;:::-;42856:131;43015:1;43012;43008:9;42997:20;;42675:348;;;;:::o;43029:180::-;43077:77;43074:1;43067:88;43174:4;43171:1;43164:15;43198:4;43195:1;43188:15;43215:185;43255:1;43272:20;43290:1;43272:20;:::i;:::-;43267:25;;43306:20;43324:1;43306:20;:::i;:::-;43301:25;;43345:1;43335:35;;43350:18;;:::i;:::-;43335:35;43392:1;43389;43385:9;43380:14;;43215:185;;;;:::o;43406:229::-;43546:34;43542:1;43534:6;43530:14;43523:58;43615:12;43610:2;43602:6;43598:15;43591:37;43406:229;:::o;43641:366::-;43783:3;43804:67;43868:2;43863:3;43804:67;:::i;:::-;43797:74;;43880:93;43969:3;43880:93;:::i;:::-;43998:2;43993:3;43989:12;43982:19;;43641:366;;;:::o;44013:419::-;44179:4;44217:2;44206:9;44202:18;44194:26;;44266:9;44260:4;44256:20;44252:1;44241:9;44237:17;44230:47;44294:131;44420:4;44294:131;:::i;:::-;44286:139;;44013:419;;;:::o;44438:225::-;44578:34;44574:1;44566:6;44562:14;44555:58;44647:8;44642:2;44634:6;44630:15;44623:33;44438:225;:::o;44669:366::-;44811:3;44832:67;44896:2;44891:3;44832:67;:::i;:::-;44825:74;;44908:93;44997:3;44908:93;:::i;:::-;45026:2;45021:3;45017:12;45010:19;;44669:366;;;:::o;45041:419::-;45207:4;45245:2;45234:9;45230:18;45222:26;;45294:9;45288:4;45284:20;45280:1;45269:9;45265:17;45258:47;45322:131;45448:4;45322:131;:::i;:::-;45314:139;;45041:419;;;:::o;45466:179::-;45606:31;45602:1;45594:6;45590:14;45583:55;45466:179;:::o;45651:366::-;45793:3;45814:67;45878:2;45873:3;45814:67;:::i;:::-;45807:74;;45890:93;45979:3;45890:93;:::i;:::-;46008:2;46003:3;45999:12;45992:19;;45651:366;;;:::o;46023:419::-;46189:4;46227:2;46216:9;46212:18;46204:26;;46276:9;46270:4;46266:20;46262:1;46251:9;46247:17;46240:47;46304:131;46430:4;46304:131;:::i;:::-;46296:139;;46023:419;;;:::o;46448:98::-;46499:6;46533:5;46527:12;46517:22;;46448:98;;;:::o;46552:147::-;46653:11;46690:3;46675:18;;46552:147;;;;:::o;46705:307::-;46773:1;46783:113;46797:6;46794:1;46791:13;46783:113;;;46882:1;46877:3;46873:11;46867:18;46863:1;46858:3;46854:11;46847:39;46819:2;46816:1;46812:10;46807:15;;46783:113;;;46914:6;46911:1;46908:13;46905:101;;;46994:1;46985:6;46980:3;46976:16;46969:27;46905:101;46754:258;46705:307;;;:::o;47018:373::-;47122:3;47150:38;47182:5;47150:38;:::i;:::-;47204:88;47285:6;47280:3;47204:88;:::i;:::-;47197:95;;47301:52;47346:6;47341:3;47334:4;47327:5;47323:16;47301:52;:::i;:::-;47378:6;47373:3;47369:16;47362:23;;47126:265;47018:373;;;;:::o;47397:271::-;47527:3;47549:93;47638:3;47629:6;47549:93;:::i;:::-;47542:100;;47659:3;47652:10;;47397:271;;;;:::o;47674:99::-;47726:6;47760:5;47754:12;47744:22;;47674:99;;;:::o;47779:102::-;47820:6;47871:2;47867:7;47862:2;47855:5;47851:14;47847:28;47837:38;;47779:102;;;:::o;47887:364::-;47975:3;48003:39;48036:5;48003:39;:::i;:::-;48058:71;48122:6;48117:3;48058:71;:::i;:::-;48051:78;;48138:52;48183:6;48178:3;48171:4;48164:5;48160:16;48138:52;:::i;:::-;48215:29;48237:6;48215:29;:::i;:::-;48210:3;48206:39;48199:46;;47979:272;47887:364;;;;:::o;48257:313::-;48370:4;48408:2;48397:9;48393:18;48385:26;;48457:9;48451:4;48447:20;48443:1;48432:9;48428:17;48421:47;48485:78;48558:4;48549:6;48485:78;:::i;:::-;48477:86;;48257:313;;;;:::o

Swarm Source

ipfs://53a06b26212cad34a6fd7eae055a8ce576d89f4f20e69b47266859228cb4bc85
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.