ETH Price: $3,312.55 (-3.30%)

Token

Friends With Art (FWA)
 

Overview

Max Total Supply

53 FWA

Holders

37

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Filtered by Token Holder
nichamilton.eth
Balance
2 FWA

Value
$0.00
0x518201899E316bf98c957C73e1326b77672Fe52b
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:
ArtVault

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-04-10
*/

// SPDX-License-Identifier: UNLICENSED AND MIT

// File: @openzeppelin/contracts/GSN/Context.sol

pragma solidity ^0.6.0;

/*
 * @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 GSN 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 payable) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

// File: @openzeppelin/contracts/access/Ownable.sol

pragma solidity ^0.6.0;

/**
 * @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.
 */
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() internal {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view 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 {
        emit OwnershipTransferred(_owner, address(0));
        _owner = 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"
        );
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol

pragma solidity ^0.6.0;

/**
 * @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 `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, 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 `sender` to `recipient` 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 sender,
        address recipient,
        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
    );
}

// File: @openzeppelin/contracts/math/SafeMath.sol

pragma solidity ^0.6.0;

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

        return c;
    }

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

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

        return c;
    }

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

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

        return c;
    }

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

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

        return c;
    }

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

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

// File: @openzeppelin/contracts/utils/Address.sol

pragma solidity ^0.6.2;

/**
 * @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
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies in extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            size := extcodesize(account)
        }
        return size > 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"
        );

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (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"
        );
        return _functionCallWithValue(target, data, value, errorMessage);
    }

    function _functionCallWithValue(
        address target,
        bytes memory data,
        uint256 weiValue,
        string memory errorMessage
    ) private returns (bytes memory) {
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) =
            target.call{value: weiValue}(data);
        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

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// File: @openzeppelin/contracts/token/ERC20/ERC20.sol

pragma solidity ^0.6.0;

/**
 * @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 guidelines: functions revert instead
 * of 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 {
    using SafeMath for uint256;
    using Address for address;

    mapping(address => uint256) private _balances;

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with
     * a default value of 18.
     *
     * To select a different value for {decimals}, use {_setupDecimals}.
     *
     * All three of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name, string memory symbol) public {
        _name = name;
        _symbol = symbol;
        _decimals = 18;
    }

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

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view 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 {_setupDecimals} is
     * called.
     *
     * 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 returns (uint8) {
        return _decimals;
    }

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

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

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount)
        public
        virtual
        override
        returns (bool)
    {
        _transfer(_msgSender(), recipient, 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}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount)
        public
        virtual
        override
        returns (bool)
    {
        _approve(_msgSender(), 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};
     *
     * Requirements:
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(
            sender,
            _msgSender(),
            _allowances[sender][_msgSender()].sub(
                amount,
                "ERC20: transfer amount exceeds allowance"
            )
        );
        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)
    {
        _approve(
            _msgSender(),
            spender,
            _allowances[_msgSender()][spender].add(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)
    {
        _approve(
            _msgSender(),
            spender,
            _allowances[_msgSender()][spender].sub(
                subtractedValue,
                "ERC20: decreased allowance below zero"
            )
        );
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is 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:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        _balances[sender] = _balances[sender].sub(
            amount,
            "ERC20: transfer amount exceeds balance"
        );
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, 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
     *
     * - `to` 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 = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(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);

        _balances[account] = _balances[account].sub(
            amount,
            "ERC20: burn amount exceeds balance"
        );
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(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 Sets {decimals} to a value other than the default one of 18.
     *
     * WARNING: This function should only be called from the constructor. Most
     * applications that interact with token contracts will not expect
     * {decimals} to ever change, and may work incorrectly if it does.
     */
    function _setupDecimals(uint8 decimals_) internal {
        _decimals = decimals_;
    }

    /**
     * @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 to 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 {}
}

// File: @openzeppelin/contracts/token/ERC20/ERC20Burnable.sol

pragma solidity ^0.6.0;

/**
 * @dev Extension of {ERC20} that allows token holders to destroy both their own
 * tokens and those that they have an allowance for, in a way that can be
 * recognized off-chain (via event analysis).
 */
abstract contract ERC20Burnable is Context, ERC20 {
    /**
     * @dev Destroys `amount` tokens from the caller.
     *
     * See {ERC20-_burn}.
     */
    function burn(uint256 amount) public virtual {
        _burn(_msgSender(), amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, deducting from the caller's
     * allowance.
     *
     * See {ERC20-_burn} and {ERC20-allowance}.
     *
     * Requirements:
     *
     * - the caller must have allowance for ``accounts``'s tokens of at least
     * `amount`.
     */
    function burnFrom(address account, uint256 amount) public virtual {
        uint256 decreasedAllowance =
            allowance(account, _msgSender()).sub(
                amount,
                "ERC20: burn amount exceeds allowance"
            );

        _approve(account, _msgSender(), decreasedAllowance);
        _burn(account, amount);
    }
}

// File: @openzeppelin/contracts/introspection/IERC165.sol

pragma solidity ^0.6.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// File: @openzeppelin/contracts/introspection/ERC165.sol

pragma solidity ^0.6.0;

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts may inherit from this and call {_registerInterface} to declare
 * their support of an interface.
 */
contract ERC165 is IERC165 {
    /*
     * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
     */
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;

    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    constructor() internal {
        // Derived contracts need only register support for their own interfaces,
        // we register support for ERC165 itself here
        _registerInterface(_INTERFACE_ID_ERC165);
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     *
     * Time complexity O(1), guaranteed to always use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId)
        public
        view
        override
        returns (bool)
    {
        return _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See {IERC165-supportsInterface}.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal virtual {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol

pragma solidity ^0.6.2;

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(
        address indexed from,
        address indexed to,
        uint256 indexed tokenId
    );

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(
        address indexed owner,
        address indexed approved,
        uint256 indexed tokenId
    );

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(
        address indexed owner,
        address indexed operator,
        bool approved
    );

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId)
        external
        view
        returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator)
        external
        view
        returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}

// File: @openzeppelin/contracts/token/ERC1155/IERC1155.sol

pragma solidity ^0.6.2;

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 id,
        uint256 value
    );

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(
        address indexed account,
        address indexed operator,
        bool approved
    );

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id)
        external
        view
        returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external
        view
        returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator)
        external
        view
        returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

// File: @openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol

pragma solidity ^0.6.0;

/**
 * _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {
    /**
        @dev Handles the receipt of a single ERC1155 token type. This function is
        called at the end of a `safeTransferFrom` after the balance has been updated.
        To accept the transfer, this must return
        `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
        (i.e. 0xf23a6e61, or its own function selector).
        @param operator The address which initiated the transfer (i.e. msg.sender)
        @param from The address which previously owned the token
        @param id The ID of the token being transferred
        @param value The amount of tokens being transferred
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
    */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
        @dev Handles the receipt of a multiple ERC1155 token types. This function
        is called at the end of a `safeBatchTransferFrom` after the balances have
        been updated. To accept the transfer(s), this must return
        `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
        (i.e. 0xbc197c81, or its own function selector).
        @param operator The address which initiated the batch transfer (i.e. msg.sender)
        @param from The address which previously owned the token
        @param ids An array containing ids of each token being transferred (order and length must match values array)
        @param values An array containing amounts of each token being transferred (order and length must match ids array)
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
    */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

// File: @openzeppelin/contracts/token/ERC1155/ERC1155Receiver.sol

pragma solidity ^0.6.0;

/**
 * @dev _Available since v3.1._
 */
abstract contract ERC1155Receiver is ERC165, IERC1155Receiver {
    constructor() public {
        _registerInterface(
            ERC1155Receiver(0).onERC1155Received.selector ^
                ERC1155Receiver(0).onERC1155BatchReceived.selector
        );
    }
}

// File: @openzeppelin/contracts/utils/EnumerableSet.sol

pragma solidity ^0.6.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.0.0, only sets of type `address` (`AddressSet`) and `uint256`
 * (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            bytes32 lastvalue = set._values[lastIndex];

            // Move the last value to the index where the value to delete is
            set._values[toDeleteIndex] = lastvalue;
            // Update the index for the moved value
            set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value)
        private
        view
        returns (bool)
    {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index)
        private
        view
        returns (bytes32)
    {
        require(
            set._values.length > index,
            "EnumerableSet: index out of bounds"
        );
        return set._values[index];
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value)
        internal
        returns (bool)
    {
        return _add(set._inner, bytes32(uint256(value)));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value)
        internal
        returns (bool)
    {
        return _remove(set._inner, bytes32(uint256(value)));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value)
        internal
        view
        returns (bool)
    {
        return _contains(set._inner, bytes32(uint256(value)));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index)
        internal
        view
        returns (address)
    {
        return address(uint256(_at(set._inner, index)));
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value)
        internal
        returns (bool)
    {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value)
        internal
        view
        returns (bool)
    {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index)
        internal
        view
        returns (uint256)
    {
        return uint256(_at(set._inner, index));
    }
}

// File: contracts/Rats.sol

pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;

contract ArtVault is ERC20, ERC20Burnable, ERC165, Ownable {
    using EnumerableSet for EnumerableSet.AddressSet;

    bool public allowEmergencyAccess;
    address payable public donationAddress;
    address public requiredTokenAddress;
    uint256 public requiredTokenAmount;
    uint256 public maxAmount;
    EnumerableSet.AddressSet private allowedErc721Contracts;
    EnumerableSet.AddressSet private allowedErc1155Contracts;

    bytes4 immutable onErc721SuccessfulResult =
        bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"));
    bytes4 immutable onErc1155SuccessfulResult =
        bytes4(
            keccak256(
                "onERC1155Received(address,address,uint256,uint256,bytes)"
            )
        );

    event DepositedToken(address from);
    event DepositedERC721(address from, address tokenAddress, uint256 tokenId);
    event DepositedERC1155(
        address from,
        address tokenAddress,
        uint256 tokenId,
        uint256 amount
    );
    event WithdrewToken(address from);
    event WithdrewERC721(address from, address tokenAddress, uint256 tokenId);
    event WithdrewERC1155(
        address from,
        address tokenAddress,
        uint256 tokenId,
        uint256 amount
    );

    constructor(
        address requiredTokenAddress_,
        uint256 requiredTokenAmount_,
        string memory tokenName,
        string memory tokenSymbol,
        uint256 maxAmount_
    ) public ERC20(tokenName, tokenSymbol) ERC20Burnable() Ownable() {
        allowEmergencyAccess = true;
        donationAddress = (payable(owner()));
        requiredTokenAddress = requiredTokenAddress_;
        requiredTokenAmount = requiredTokenAmount_;
        maxAmount = maxAmount_;

        // from ERC1155Receiver.sol
        _registerInterface(
            ERC1155Receiver(0).onERC1155Received.selector ^
                ERC1155Receiver(0).onERC1155BatchReceived.selector
        );
    }

    function revokeEmergencyAccess() public onlyOwner {
        allowEmergencyAccess = false;
    }

    function changeDonationAddress(address payable newAddress)
        public
        onlyOwner
    {
        donationAddress = newAddress;
    }

    modifier onlyEmergencyAccess() {
        require(msg.sender == owner(), "must be owner");
        require(allowEmergencyAccess, "emergency access not allowed");
        _;
    }

    // ---- receive callbacks ----
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4) {
        _requireTokenBalance(from);

        address receivingErc721ContractAddress = msg.sender;
        IERC721 receivingErc721Contract =
            IERC721(receivingErc721ContractAddress);

        // ensure address is whitelisted
        require(
            allowedErc721Contracts.contains(receivingErc721ContractAddress),
            "contract not whitelisted"
        );
        // ensure we have the nft
        require(
            receivingErc721Contract.ownerOf(tokenId) == address(this),
            "dont own erc721"
        );
        // emit event
        emit DepositedERC721(from, receivingErc721ContractAddress, tokenId);
        // take action
        _giveTokenOrWithdrawArt(from, data);
        return onErc721SuccessfulResult;
    }

    function onERC1155Received(
        address operator,
        address from,
        uint256 tokenId,
        uint256 amountTokens,
        bytes calldata data
    ) external returns (bytes4) {
        _requireTokenBalance(from);

        address receivingErc1155ContractAddress = msg.sender;
        IERC1155 receivingErc1155Contract =
            IERC1155(receivingErc1155ContractAddress);
        // ensure address is whitelisted
        require(
            allowedErc1155Contracts.contains(receivingErc1155ContractAddress),
            "contract not whitelisted"
        );
        // ensure we have the nft and didn't have prior
        require(amountTokens > 0, "must have non-zero amountTokens");
        uint256 ourCurrentBalance =
            receivingErc1155Contract.balanceOf(address(this), tokenId);
        require(ourCurrentBalance == amountTokens, "Already had ERC1155");

        // emit event
        emit DepositedERC1155(
            from,
            receivingErc1155ContractAddress,
            tokenId,
            amountTokens
        );
        // take action
        _giveTokenOrWithdrawArt(from, data);
        return onErc1155SuccessfulResult;
    }

    function swapTokensForERC721Art(
        address contractAddressToSend,
        uint256 tokenIdToSend
    ) external payable {
        _requireTokenBalance(msg.sender);

        // burn erc20 from user
        emit DepositedToken(msg.sender);
        _burn(msg.sender, 1 ether);

        // send art
        _sendERC721Art(contractAddressToSend, tokenIdToSend, msg.sender);
    }

    function swapTokensForERC1155Art(
        address contractAddressToSend,
        uint256 tokenIdToSend
    ) external payable {
        _requireTokenBalance(msg.sender);

        // burn erc20 from user
        emit DepositedToken(msg.sender);
        _burn(msg.sender, 1 ether);

        // send art
        _sendERC1155Art(contractAddressToSend, tokenIdToSend, msg.sender);
    }

    function withdrawDonations() public {
        Address.sendValue(donationAddress, address(this).balance);
    }

    function maxSupply() public view returns (uint256) {
        return maxAmount;
    }

    function maxTokensCreated() public view returns (bool) {
        return totalSupply() >= maxSupply();
    }

    function _sendERC721Art(
        address contractAddressToSend,
        uint256 tokenIdToSend,
        address recipient
    ) private {
        IERC721 sendingErc721Contract = IERC721(contractAddressToSend);
        sendingErc721Contract.safeTransferFrom(
            address(this),
            recipient,
            tokenIdToSend
        );

        emit WithdrewERC721(recipient, contractAddressToSend, tokenIdToSend);
    }

    function _sendERC1155Art(
        address contractAddressToSend,
        uint256 tokenIdToSend,
        address recipient
    ) private {
        IERC1155 sendingErc1155Contract = IERC1155(contractAddressToSend);
        uint256 balance =
            sendingErc1155Contract.balanceOf(address(this), tokenIdToSend);
        require(balance > 0, "doesnt hold any balance");

        sendingErc1155Contract.safeTransferFrom(
            address(this),
            recipient,
            tokenIdToSend,
            balance,
            ""
        );

        emit WithdrewERC1155(
            recipient,
            contractAddressToSend,
            tokenIdToSend,
            balance
        );
    }

    function _giveTokenOrWithdrawArt(address from, bytes calldata data)
        private
    {
        if (data.length == 0) {
            // send tokens
            if (maxTokensCreated()) {
                revert("Max tokens created");
            }
            _mint(from, 1 ether);
            emit WithdrewToken(from);
        } else {
            // do swap
            (
                address contractAddressToSend,
                uint256 tokenIdToSend,
                bool isErc1155
            ) = abi.decode(data, (address, uint256, bool));
            if (isErc1155) {
                _sendERC1155Art(contractAddressToSend, tokenIdToSend, from);
            } else {
                _sendERC721Art(contractAddressToSend, tokenIdToSend, from);
            }
        }
    }

    function _requireTokenBalance(address user) private view {
        if (requiredTokenAddress != address(0)) {
            uint256 balance = IERC20(requiredTokenAddress).balanceOf(user);
            require(
                requiredTokenAmount <= balance,
                "insufficient balance of required token"
            );
        }
    }

    // ------ allowedContracts fns -------
    function getAllowedContractsLength(bool isErc721)
        public
        view
        returns (uint256)
    {
        EnumerableSet.AddressSet storage allowedAddresses =
            isErc721 ? allowedErc721Contracts : allowedErc1155Contracts;
        return allowedAddresses.length();
    }

    function getAllowedContracts(
        bool isErc721,
        uint256 start,
        uint256 end
    ) public view returns (address[] memory) {
        EnumerableSet.AddressSet storage allowedAddresses =
            isErc721 ? allowedErc721Contracts : allowedErc1155Contracts;
        address[] memory re = new address[](end - start);
        for (uint256 i = start; i < end; i++) {
            re[i - start] = allowedAddresses.at(i);
        }
        return re;
    }

    function addAllowedContracts(
        bool isErc721,
        address[] memory contractAddresses
    ) public onlyOwner {
        EnumerableSet.AddressSet storage allowedAddresses =
            isErc721 ? allowedErc721Contracts : allowedErc1155Contracts;
        for (uint256 i = 0; i < contractAddresses.length; ++i) {
            allowedAddresses.add(contractAddresses[i]);
        }
    }

    // ----- emergency functions ------
    function emergencyRemoveAllowedContracts(
        bool isErc721,
        address[] memory contractAddresses
    ) public onlyEmergencyAccess {
        EnumerableSet.AddressSet storage allowedAddresses =
            isErc721 ? allowedErc721Contracts : allowedErc1155Contracts;
        for (uint256 i = 0; i < contractAddresses.length; ++i) {
            allowedAddresses.remove(contractAddresses[i]);
        }
    }

    function emergencyMint(address account, uint256 amount)
        public
        onlyEmergencyAccess
    {
        _mint(account, amount);
    }

    function emergencyBurn(address account, uint256 amount)
        public
        onlyEmergencyAccess
    {
        _burn(account, amount);
    }

    function emergencyExecute(
        address targetAddress,
        bytes calldata targetCallData
    ) public onlyEmergencyAccess returns (bool) {
        (bool success, ) = targetAddress.call(targetCallData);
        return success;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"requiredTokenAddress_","type":"address"},{"internalType":"uint256","name":"requiredTokenAmount_","type":"uint256"},{"internalType":"string","name":"tokenName","type":"string"},{"internalType":"string","name":"tokenSymbol","type":"string"},{"internalType":"uint256","name":"maxAmount_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DepositedERC1155","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"DepositedERC721","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"}],"name":"DepositedToken","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":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrewERC1155","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"WithdrewERC721","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"}],"name":"WithdrewToken","type":"event"},{"inputs":[{"internalType":"bool","name":"isErc721","type":"bool"},{"internalType":"address[]","name":"contractAddresses","type":"address[]"}],"name":"addAllowedContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"allowEmergencyAccess","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"newAddress","type":"address"}],"name":"changeDonationAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"donationAddress","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emergencyBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"targetAddress","type":"address"},{"internalType":"bytes","name":"targetCallData","type":"bytes"}],"name":"emergencyExecute","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emergencyMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isErc721","type":"bool"},{"internalType":"address[]","name":"contractAddresses","type":"address[]"}],"name":"emergencyRemoveAllowedContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isErc721","type":"bool"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"getAllowedContracts","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"isErc721","type":"bool"}],"name":"getAllowedContractsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTokensCreated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amountTokens","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requiredTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"requiredTokenAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"revokeEmergencyAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddressToSend","type":"address"},{"internalType":"uint256","name":"tokenIdToSend","type":"uint256"}],"name":"swapTokensForERC1155Art","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddressToSend","type":"address"},{"internalType":"uint256","name":"tokenIdToSend","type":"uint256"}],"name":"swapTokensForERC721Art","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawDonations","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c06040527f150b7a023d4804d13e8c85fb27262cb750cf6ba9f9dd3bb30d90f482ceeb4b1f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166080907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152507ff23a6e612e1ff4830e658fe43f4e3cb4a5f8170bd5d9e69fb5d7a7fa9e4fdf977bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191660a0907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250348015620000db57600080fd5b5060405162004cf138038062004cf183398181016040528101906200010191906200053d565b828281600390805190602001906200011b9291906200040d565b508060049080519060200190620001349291906200040d565b506012600560006101000a81548160ff021916908360ff16021790555050506200016b6301ffc9a760e01b6200030260201b60201c565b60006200017d620003db60201b60201c565b905080600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3506001600760146101000a81548160ff02191690831515021790555062000247620003e360201b60201c565b600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600a8190555080600b81905550620002f763bc197c8160e01b63f23a6e6160e01b186200030260201b60201c565b505050505062000769565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156200036e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003659062000633565b60405180910390fd5b600160066000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600033905090565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200045057805160ff191683800117855562000481565b8280016001018555821562000481579182015b828111156200048057825182559160200191906001019062000463565b5b50905062000490919062000494565b5090565b5b80821115620004af57600081600090555060010162000495565b5090565b600081519050620004c48162000735565b92915050565b600082601f830112620004dc57600080fd5b8151620004f3620004ed8262000683565b62000655565b915080825260208301602083018583830111156200051057600080fd5b6200051d838284620006ff565b50505092915050565b60008151905062000537816200074f565b92915050565b600080600080600060a086880312156200055657600080fd5b60006200056688828901620004b3565b9550506020620005798882890162000526565b945050604086015167ffffffffffffffff8111156200059757600080fd5b620005a588828901620004ca565b935050606086015167ffffffffffffffff811115620005c357600080fd5b620005d188828901620004ca565b9250506080620005e48882890162000526565b9150509295509295909350565b600062000600601c83620006b0565b91507f4552433136353a20696e76616c696420696e74657266616365206964000000006000830152602082019050919050565b600060208201905081810360008301526200064e81620005f1565b9050919050565b6000604051905081810181811067ffffffffffffffff821117156200067957600080fd5b8060405250919050565b600067ffffffffffffffff8211156200069b57600080fd5b601f19601f8301169050602081019050919050565b600082825260208201905092915050565b6000620006ce82620006d5565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b838110156200071f57808201518184015260208101905062000702565b838111156200072f576000848401525b50505050565b6200074081620006c1565b81146200074c57600080fd5b50565b6200075a81620006f5565b81146200076657600080fd5b50565b60805160e01c60e01b60a05160e01c60e01b6145586200079960003980611bb5525080610c3b52506145586000f3fe6080604052600436106102255760003560e01c806370a0823111610123578063ad589966116100ab578063dd62ed3e1161006f578063dd62ed3e14610815578063ec034bed14610852578063f23a6e611461087d578063f2fde38b146108ba578063f67a9218146108e357610225565b8063ad58996614610742578063b705f5f81461077f578063c151f0f1146107aa578063ce1b088a146107d3578063d5abeb01146107ea57610225565b806395d89b41116100f257806395d89b411461064957806398ae499f14610674578063a0321a531461068b578063a457c2d7146106c8578063a9059cbb1461070557610225565b806370a08231146105a1578063715018a6146105de57806379cc6790146105f55780638da5cb5b1461061e57610225565b8063313ce567116101b157806342be7aa71161017557806342be7aa7146104d057806343785dc9146104f95780635f48f39314610522578063641a8d751461054d5780636f264b2e1461057657610225565b8063313ce567146103e657806339509351146104115780633ed4c4a11461044e57806342264b3b1461046a57806342966c68146104a757610225565b8063150b7a02116101f8578063150b7a02146102eb57806318160ddd146103285780631e0d218e1461035357806323b872dd1461037e57806329d428ca146103bb57610225565b806301ffc9a71461022a5780630305001b1461026757806306fdde0314610283578063095ea7b3146102ae575b600080fd5b34801561023657600080fd5b50610251600480360381019061024c91906134b7565b61090c565b60405161025e9190613ee6565b60405180910390f35b610281600480360381019061027c91906133af565b610974565b005b34801561028f57600080fd5b506102986109d5565b6040516102a59190613f1c565b60405180910390f35b3480156102ba57600080fd5b506102d560048036038101906102d091906133af565b610a77565b6040516102e29190613ee6565b60405180910390f35b3480156102f757600080fd5b50610312600480360381019061030d9190613245565b610a95565b60405161031f9190613f01565b60405180910390f35b34801561033457600080fd5b5061033d610c67565b60405161034a91906141de565b60405180910390f35b34801561035f57600080fd5b50610368610c71565b6040516103759190613ee6565b60405180910390f35b34801561038a57600080fd5b506103a560048036038101906103a091906131f6565b610c84565b6040516103b29190613ee6565b60405180910390f35b3480156103c757600080fd5b506103d0610d5d565b6040516103dd91906141de565b60405180910390f35b3480156103f257600080fd5b506103fb610d63565b60405161040891906141f9565b60405180910390f35b34801561041d57600080fd5b50610438600480360381019061043391906133af565b610d7a565b6040516104459190613ee6565b60405180910390f35b610468600480360381019061046391906133af565b610e2d565b005b34801561047657600080fd5b50610491600480360381019061048c9190613468565b610e8e565b60405161049e9190613ec4565b60405180910390f35b3480156104b357600080fd5b506104ce60048036038101906104c991906134e0565b610f73565b005b3480156104dc57600080fd5b506104f760048036038101906104f29190613414565b610f87565b005b34801561050557600080fd5b50610520600480360381019061051b91906133af565b611075565b005b34801561052e57600080fd5b50610537611147565b60405161054491906141de565b60405180910390f35b34801561055957600080fd5b50610574600480360381019061056f9190613142565b61114d565b005b34801561058257600080fd5b5061058b611228565b6040516105989190613d76565b60405180910390f35b3480156105ad57600080fd5b506105c860048036038101906105c391906130f0565b61124e565b6040516105d591906141de565b60405180910390f35b3480156105ea57600080fd5b506105f3611296565b005b34801561060157600080fd5b5061061c600480360381019061061791906133af565b6113ee565b005b34801561062a57600080fd5b50610633611450565b6040516106409190613d76565b60405180910390f35b34801561065557600080fd5b5061065e61147a565b60405161066b9190613f1c565b60405180910390f35b34801561068057600080fd5b5061068961151c565b005b34801561069757600080fd5b506106b260048036038101906106ad9190613357565b6115d0565b6040516106bf9190613ee6565b60405180910390f35b3480156106d457600080fd5b506106ef60048036038101906106ea91906133af565b611710565b6040516106fc9190613ee6565b60405180910390f35b34801561071157600080fd5b5061072c600480360381019061072791906133af565b6117dd565b6040516107399190613ee6565b60405180910390f35b34801561074e57600080fd5b50610769600480360381019061076491906133eb565b6117fb565b60405161077691906141de565b60405180910390f35b34801561078b57600080fd5b50610794611820565b6040516107a19190613ee6565b60405180910390f35b3480156107b657600080fd5b506107d160048036038101906107cc91906133af565b611839565b005b3480156107df57600080fd5b506107e861190b565b005b3480156107f657600080fd5b506107ff611939565b60405161080c91906141de565b60405180910390f35b34801561082157600080fd5b5061083c600480360381019061083791906131ba565b611943565b60405161084991906141de565b60405180910390f35b34801561085e57600080fd5b506108676119ca565b6040516108749190613dac565b60405180910390f35b34801561088957600080fd5b506108a4600480360381019061089f91906132c5565b6119f0565b6040516108b19190613f01565b60405180910390f35b3480156108c657600080fd5b506108e160048036038101906108dc91906130f0565b611be3565b005b3480156108ef57600080fd5b5061090a60048036038101906109059190613414565b611daa565b005b600060066000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b61097d33611ec5565b7f9089118748848f35d2044622c8191c0581a5c78fbe3c37abad69704459cffed9336040516109ac9190613d91565b60405180910390a16109c633670de0b6b3a7640000612014565b6109d18282336121c2565b5050565b606060038054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a6d5780601f10610a4257610100808354040283529160200191610a6d565b820191906000526020600020905b815481529060010190602001808311610a5057829003601f168201915b5050505050905090565b6000610a8b610a8461234d565b8484612355565b6001905092915050565b6000610aa085611ec5565b60003390506000819050610abe82600c61252090919063ffffffff16565b610afd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af4906141be565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16636352211e886040518263ffffffff1660e01b8152600401610b4d91906141de565b60206040518083038186803b158015610b6557600080fd5b505afa158015610b79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9d9190613119565b73ffffffffffffffffffffffffffffffffffffffff1614610bf3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bea9061403e565b60405180910390fd5b7f816951017bbdb395e05a86d9ff716953c8ea003152bad3825fa891ce07646972878388604051610c2693929190613dc7565b60405180910390a1610c39878686612550565b7f00000000000000000000000000000000000000000000000000000000000000009250505095945050505050565b6000600254905090565b600760149054906101000a900460ff1681565b6000610c91848484612637565b610d5284610c9d61234d565b610d4d856040518060600160405280602881526020016144b260289139600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610d0361234d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546128cc9092919063ffffffff16565b612355565b600190509392505050565b600a5481565b6000600560009054906101000a900460ff16905090565b6000610e23610d8761234d565b84610e1e8560016000610d9861234d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461292790919063ffffffff16565b612355565b6001905092915050565b610e3633611ec5565b7f9089118748848f35d2044622c8191c0581a5c78fbe3c37abad69704459cffed933604051610e659190613d91565b60405180910390a1610e7f33670de0b6b3a7640000612014565b610e8a82823361297c565b5050565b6060600084610e9e57600e610ea1565b600c5b9050606084840367ffffffffffffffff81118015610ebe57600080fd5b50604051908082528060200260200182016040528015610eed5781602001602082028036833780820191505090505b50905060008590505b84811015610f6657610f118184612a3190919063ffffffff16565b8287830381518110610f1f57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508080600101915050610ef6565b5080925050509392505050565b610f84610f7e61234d565b82612014565b50565b610f8f61234d565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611015906140be565b60405180910390fd5b60008261102c57600e61102f565b600c5b905060005b825181101561106f5761106383828151811061104c57fe5b602002602001015183612a4b90919063ffffffff16565b50806001019050611034565b50505050565b61107d611450565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e190613ffe565b60405180910390fd5b600760149054906101000a900460ff16611139576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111309061415e565b60405180910390fd5b6111438282612a7b565b5050565b600b5481565b61115561234d565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146111e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111db906140be565b60405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61129e61234d565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461132d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611324906140be565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600061142d826040518060600160405280602481526020016144da6024913961141e8661141961234d565b611943565b6128cc9092919063ffffffff16565b90506114418361143b61234d565b83612355565b61144b8383612014565b505050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156115125780601f106114e757610100808354040283529160200191611512565b820191906000526020600020905b8154815290600101906020018083116114f557829003601f168201915b5050505050905090565b61152461234d565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146115b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115aa906140be565b60405180910390fd5b6000600760146101000a81548160ff021916908315150217905550565b60006115da611450565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611647576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161163e90613ffe565b60405180910390fd5b600760149054906101000a900460ff16611696576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168d9061415e565b60405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff1684846040516116bf929190613d48565b6000604051808303816000865af19150503d80600081146116fc576040519150601f19603f3d011682016040523d82523d6000602084013e611701565b606091505b50509050809150509392505050565b60006117d361171d61234d565b846117ce856040518060600160405280602581526020016144fe602591396001600061174761234d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546128cc9092919063ffffffff16565b612355565b6001905092915050565b60006117f16117ea61234d565b8484612637565b6001905092915050565b6000808261180a57600e61180d565b600c5b905061181881612c0f565b915050919050565b600061182a611939565b611832610c67565b1015905090565b611841611450565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146118ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118a590613ffe565b60405180910390fd5b600760149054906101000a900460ff166118fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118f49061415e565b60405180910390fd5b6119078282612014565b5050565b611937600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1647612c24565b565b6000600b54905090565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006119fb86611ec5565b60003390506000819050611a1982600e61252090919063ffffffff16565b611a58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a4f906141be565b60405180910390fd5b60008611611a9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9290613f7e565b60405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff1662fdd58e308a6040518363ffffffff1660e01b8152600401611ad7929190613e9b565b60206040518083038186803b158015611aef57600080fd5b505afa158015611b03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b279190613509565b9050868114611b6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b629061417e565b60405180910390fd5b7faa8ac49969d54ecc1663afbf95bbd6fcbca9397e87b9f860d130a42e67a59e9289848a8a604051611ba09493929190613dfe565b60405180910390a1611bb3898787612550565b7f000000000000000000000000000000000000000000000000000000000000000093505050509695505050505050565b611beb61234d565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611c7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c71906140be565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611cea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce190613f9e565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611db2611450565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e1690613ffe565b60405180910390fd5b600760149054906101000a900460ff16611e6e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e659061415e565b60405180910390fd5b600082611e7c57600e611e7f565b600c5b905060005b8251811015611ebf57611eb3838281518110611e9c57fe5b602002602001015183612d1890919063ffffffff16565b50806001019050611e84565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff16600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612011576000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b8152600401611f789190613d76565b60206040518083038186803b158015611f9057600080fd5b505afa158015611fa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fc89190613509565b905080600a54111561200f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120069061401e565b60405180910390fd5b505b50565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612084576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207b906140de565b60405180910390fd5b61209082600083612d48565b6120fb8160405180606001604052806022815260200161446a602291396000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546128cc9092919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061215281600254612d4d90919063ffffffff16565b600281905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516121b691906141de565b60405180910390a35050565b600083905060008173ffffffffffffffffffffffffffffffffffffffff1662fdd58e30866040518363ffffffff1660e01b8152600401612203929190613e9b565b60206040518083038186803b15801561221b57600080fd5b505afa15801561222f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122539190613509565b905060008111612298576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228f9061409e565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663f242432a308587856040518563ffffffff1660e01b81526004016122d79493929190613e43565b600060405180830381600087803b1580156122f157600080fd5b505af1158015612305573d6000803e3d6000fd5b505050507ff80ebeba7050b64dd3aeb554073ad10210323c4eed47159ff6587eacb9e8ecdc8386868460405161233e9493929190613dfe565b60405180910390a15050505050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156123c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123bc9061411e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612435576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161242c90613fbe565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258360405161251391906141de565b60405180910390a3505050565b6000612548836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612d97565b905092915050565b60008282905014156125f257612564611820565b156125a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161259b9061413e565b60405180910390fd5b6125b683670de0b6b3a7640000612a7b565b7f7e831c0f3b087e0d489853b765291ab7458a9d72dfb837ce1a5d84a22d4f2d02836040516125e59190613d76565b60405180910390a1612632565b60008060008484810190612606919061316b565b92509250925080156126225761261d8383886121c2565b61262e565b61262d83838861297c565b5b5050505b505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156126a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161269e906140fe565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161270e90613f5e565b60405180910390fd5b612722838383612d48565b61278d8160405180606001604052806026815260200161448c602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546128cc9092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612820816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461292790919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516128bf91906141de565b60405180910390a3505050565b6000838311158290612914576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161290b9190613f1c565b60405180910390fd5b5060008385039050809150509392505050565b600080828401905083811015612972576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161296990613fde565b60405180910390fd5b8091505092915050565b60008390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3084866040518463ffffffff1660e01b81526004016129be93929190613dc7565b600060405180830381600087803b1580156129d857600080fd5b505af11580156129ec573d6000803e3d6000fd5b505050507f760366092dec37cc9f0e5cfe45487dda85255614a6b7d143561d9ef106eb7993828585604051612a2393929190613dc7565b60405180910390a150505050565b6000612a408360000183612dba565b60001c905092915050565b6000612a73836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612e27565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612aeb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae29061419e565b60405180910390fd5b612af760008383612d48565b612b0c8160025461292790919063ffffffff16565b600281905550612b63816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461292790919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612c0391906141de565b60405180910390a35050565b6000612c1d82600001612e97565b9050919050565b80471015612c67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c5e9061407e565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff1682604051612c8d90613d61565b60006040518083038185875af1925050503d8060008114612cca576040519150601f19603f3d011682016040523d82523d6000602084013e612ccf565b606091505b5050905080612d13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d0a9061405e565b60405180910390fd5b505050565b6000612d40836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612ea8565b905092915050565b505050565b6000612d8f83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506128cc565b905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b600081836000018054905011612e05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dfc90613f3e565b60405180910390fd5b826000018281548110612e1457fe5b9060005260206000200154905092915050565b6000612e338383612d97565b612e8c578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612e91565b600090505b92915050565b600081600001805490509050919050565b60008083600101600084815260200190815260200160002054905060008114612f845760006001820390506000600186600001805490500390506000866000018281548110612ef357fe5b9060005260206000200154905080876000018481548110612f1057fe5b9060005260206000200181905550600183018760010160008381526020019081526020016000208190555086600001805480612f4857fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050612f8a565b60009150505b92915050565b600081359050612f9f816143f6565b92915050565b600081519050612fb4816143f6565b92915050565b600081359050612fc98161440d565b92915050565b600082601f830112612fe057600080fd5b8135612ff3612fee82614241565b614214565b9150818183526020840193506020810190508385602084028201111561301857600080fd5b60005b83811015613048578161302e8882612f90565b84526020840193506020830192505060018101905061301b565b5050505092915050565b60008135905061306181614424565b92915050565b6000813590506130768161443b565b92915050565b60008083601f84011261308e57600080fd5b8235905067ffffffffffffffff8111156130a757600080fd5b6020830191508360018202830111156130bf57600080fd5b9250929050565b6000813590506130d581614452565b92915050565b6000815190506130ea81614452565b92915050565b60006020828403121561310257600080fd5b600061311084828501612f90565b91505092915050565b60006020828403121561312b57600080fd5b600061313984828501612fa5565b91505092915050565b60006020828403121561315457600080fd5b600061316284828501612fba565b91505092915050565b60008060006060848603121561318057600080fd5b600061318e86828701612fba565b935050602061319f868287016130c6565b92505060406131b086828701613052565b9150509250925092565b600080604083850312156131cd57600080fd5b60006131db85828601612f90565b92505060206131ec85828601612f90565b9150509250929050565b60008060006060848603121561320b57600080fd5b600061321986828701612f90565b935050602061322a86828701612f90565b925050604061323b868287016130c6565b9150509250925092565b60008060008060006080868803121561325d57600080fd5b600061326b88828901612f90565b955050602061327c88828901612f90565b945050604061328d888289016130c6565b935050606086013567ffffffffffffffff8111156132aa57600080fd5b6132b68882890161307c565b92509250509295509295909350565b60008060008060008060a087890312156132de57600080fd5b60006132ec89828a01612f90565b96505060206132fd89828a01612f90565b955050604061330e89828a016130c6565b945050606061331f89828a016130c6565b935050608087013567ffffffffffffffff81111561333c57600080fd5b61334889828a0161307c565b92509250509295509295509295565b60008060006040848603121561336c57600080fd5b600061337a86828701612f90565b935050602084013567ffffffffffffffff81111561339757600080fd5b6133a38682870161307c565b92509250509250925092565b600080604083850312156133c257600080fd5b60006133d085828601612f90565b92505060206133e1858286016130c6565b9150509250929050565b6000602082840312156133fd57600080fd5b600061340b84828501613052565b91505092915050565b6000806040838503121561342757600080fd5b600061343585828601613052565b925050602083013567ffffffffffffffff81111561345257600080fd5b61345e85828601612fcf565b9150509250929050565b60008060006060848603121561347d57600080fd5b600061348b86828701613052565b935050602061349c868287016130c6565b92505060406134ad868287016130c6565b9150509250925092565b6000602082840312156134c957600080fd5b60006134d784828501613067565b91505092915050565b6000602082840312156134f257600080fd5b6000613500848285016130c6565b91505092915050565b60006020828403121561351b57600080fd5b6000613529848285016130db565b91505092915050565b600061353e8383613568565b60208301905092915050565b6135538161436d565b82525050565b613562816142ec565b82525050565b613571816142da565b82525050565b613580816142da565b82525050565b600061359182614279565b61359b818561429c565b93506135a683614269565b8060005b838110156135d75781516135be8882613532565b97506135c98361428f565b9250506001810190506135aa565b5085935050505092915050565b6135ed816142fe565b82525050565b6135fc8161430a565b82525050565b600061360e83856142be565b935061361b8385846143a3565b82840190509392505050565b600061363282614284565b61363c81856142c9565b935061364c8185602086016143b2565b613655816143e5565b840191505092915050565b600061366d6022836142c9565b91507f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006136d36023836142c9565b91507f45524332303a207472616e7366657220746f20746865207a65726f206164647260008301527f65737300000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613739601f836142c9565b91507f6d7573742068617665206e6f6e2d7a65726f20616d6f756e74546f6b656e73006000830152602082019050919050565b60006137796026836142c9565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006137df6022836142c9565b91507f45524332303a20617070726f766520746f20746865207a65726f20616464726560008301527f73730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613845601b836142c9565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b6000613885600d836142c9565b91507f6d757374206265206f776e6572000000000000000000000000000000000000006000830152602082019050919050565b60006138c56026836142c9565b91507f696e73756666696369656e742062616c616e6365206f6620726571756972656460008301527f20746f6b656e00000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061392b600f836142c9565b91507f646f6e74206f776e2065726337323100000000000000000000000000000000006000830152602082019050919050565b600061396b603a836142c9565b91507f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008301527f6563697069656e74206d617920686176652072657665727465640000000000006020830152604082019050919050565b60006139d1601d836142c9565b91507f416464726573733a20696e73756666696369656e742062616c616e63650000006000830152602082019050919050565b6000613a116017836142c9565b91507f646f65736e7420686f6c6420616e792062616c616e63650000000000000000006000830152602082019050919050565b6000613a516020836142c9565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000613a916021836142c9565b91507f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008301527f73000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613af76025836142c9565b91507f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008301527f64726573730000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613b5d6000836142ad565b9150600082019050919050565b6000613b776000836142be565b9150600082019050919050565b6000613b916024836142c9565b91507f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613bf76012836142c9565b91507f4d617820746f6b656e73206372656174656400000000000000000000000000006000830152602082019050919050565b6000613c37601c836142c9565b91507f656d657267656e637920616363657373206e6f7420616c6c6f776564000000006000830152602082019050919050565b6000613c776013836142c9565b91507f416c7265616479206861642045524331313535000000000000000000000000006000830152602082019050919050565b6000613cb7601f836142c9565b91507f45524332303a206d696e7420746f20746865207a65726f2061646472657373006000830152602082019050919050565b6000613cf76018836142c9565b91507f636f6e7472616374206e6f742077686974656c697374656400000000000000006000830152602082019050919050565b613d3381614356565b82525050565b613d4281614360565b82525050565b6000613d55828486613602565b91508190509392505050565b6000613d6c82613b6a565b9150819050919050565b6000602082019050613d8b6000830184613577565b92915050565b6000602082019050613da6600083018461354a565b92915050565b6000602082019050613dc16000830184613559565b92915050565b6000606082019050613ddc6000830186613577565b613de96020830185613577565b613df66040830184613d2a565b949350505050565b6000608082019050613e136000830187613577565b613e206020830186613577565b613e2d6040830185613d2a565b613e3a6060830184613d2a565b95945050505050565b600060a082019050613e586000830187613577565b613e656020830186613577565b613e726040830185613d2a565b613e7f6060830184613d2a565b8181036080830152613e9081613b50565b905095945050505050565b6000604082019050613eb06000830185613577565b613ebd6020830184613d2a565b9392505050565b60006020820190508181036000830152613ede8184613586565b905092915050565b6000602082019050613efb60008301846135e4565b92915050565b6000602082019050613f1660008301846135f3565b92915050565b60006020820190508181036000830152613f368184613627565b905092915050565b60006020820190508181036000830152613f5781613660565b9050919050565b60006020820190508181036000830152613f77816136c6565b9050919050565b60006020820190508181036000830152613f978161372c565b9050919050565b60006020820190508181036000830152613fb78161376c565b9050919050565b60006020820190508181036000830152613fd7816137d2565b9050919050565b60006020820190508181036000830152613ff781613838565b9050919050565b6000602082019050818103600083015261401781613878565b9050919050565b60006020820190508181036000830152614037816138b8565b9050919050565b600060208201905081810360008301526140578161391e565b9050919050565b600060208201905081810360008301526140778161395e565b9050919050565b60006020820190508181036000830152614097816139c4565b9050919050565b600060208201905081810360008301526140b781613a04565b9050919050565b600060208201905081810360008301526140d781613a44565b9050919050565b600060208201905081810360008301526140f781613a84565b9050919050565b6000602082019050818103600083015261411781613aea565b9050919050565b6000602082019050818103600083015261413781613b84565b9050919050565b6000602082019050818103600083015261415781613bea565b9050919050565b6000602082019050818103600083015261417781613c2a565b9050919050565b6000602082019050818103600083015261419781613c6a565b9050919050565b600060208201905081810360008301526141b781613caa565b9050919050565b600060208201905081810360008301526141d781613cea565b9050919050565b60006020820190506141f36000830184613d2a565b92915050565b600060208201905061420e6000830184613d39565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561423757600080fd5b8060405250919050565b600067ffffffffffffffff82111561425857600080fd5b602082029050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b60006142e582614336565b9050919050565b60006142f782614336565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60006143788261437f565b9050919050565b600061438a82614391565b9050919050565b600061439c82614336565b9050919050565b82818337600083830152505050565b60005b838110156143d05780820151818401526020810190506143b5565b838111156143df576000848401525b50505050565b6000601f19601f8301169050919050565b6143ff816142da565b811461440a57600080fd5b50565b614416816142ec565b811461442157600080fd5b50565b61442d816142fe565b811461443857600080fd5b50565b6144448161430a565b811461444f57600080fd5b50565b61445b81614356565b811461446657600080fd5b5056fe45524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e20616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220947b70cfbc59b728805502922039bb205ae10e55fd11ff4a8ee87f48542cd31f64736f6c634300060c003300000000000000000000000035bd01fc9d6d5d81ca9e055db88dc49aa2c699a800000000000000000000000000000000000000000000000340aad21b3b70000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000002086ac3510526000000000000000000000000000000000000000000000000000000000000000000010467269656e64732057697468204172740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034657410000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106102255760003560e01c806370a0823111610123578063ad589966116100ab578063dd62ed3e1161006f578063dd62ed3e14610815578063ec034bed14610852578063f23a6e611461087d578063f2fde38b146108ba578063f67a9218146108e357610225565b8063ad58996614610742578063b705f5f81461077f578063c151f0f1146107aa578063ce1b088a146107d3578063d5abeb01146107ea57610225565b806395d89b41116100f257806395d89b411461064957806398ae499f14610674578063a0321a531461068b578063a457c2d7146106c8578063a9059cbb1461070557610225565b806370a08231146105a1578063715018a6146105de57806379cc6790146105f55780638da5cb5b1461061e57610225565b8063313ce567116101b157806342be7aa71161017557806342be7aa7146104d057806343785dc9146104f95780635f48f39314610522578063641a8d751461054d5780636f264b2e1461057657610225565b8063313ce567146103e657806339509351146104115780633ed4c4a11461044e57806342264b3b1461046a57806342966c68146104a757610225565b8063150b7a02116101f8578063150b7a02146102eb57806318160ddd146103285780631e0d218e1461035357806323b872dd1461037e57806329d428ca146103bb57610225565b806301ffc9a71461022a5780630305001b1461026757806306fdde0314610283578063095ea7b3146102ae575b600080fd5b34801561023657600080fd5b50610251600480360381019061024c91906134b7565b61090c565b60405161025e9190613ee6565b60405180910390f35b610281600480360381019061027c91906133af565b610974565b005b34801561028f57600080fd5b506102986109d5565b6040516102a59190613f1c565b60405180910390f35b3480156102ba57600080fd5b506102d560048036038101906102d091906133af565b610a77565b6040516102e29190613ee6565b60405180910390f35b3480156102f757600080fd5b50610312600480360381019061030d9190613245565b610a95565b60405161031f9190613f01565b60405180910390f35b34801561033457600080fd5b5061033d610c67565b60405161034a91906141de565b60405180910390f35b34801561035f57600080fd5b50610368610c71565b6040516103759190613ee6565b60405180910390f35b34801561038a57600080fd5b506103a560048036038101906103a091906131f6565b610c84565b6040516103b29190613ee6565b60405180910390f35b3480156103c757600080fd5b506103d0610d5d565b6040516103dd91906141de565b60405180910390f35b3480156103f257600080fd5b506103fb610d63565b60405161040891906141f9565b60405180910390f35b34801561041d57600080fd5b50610438600480360381019061043391906133af565b610d7a565b6040516104459190613ee6565b60405180910390f35b610468600480360381019061046391906133af565b610e2d565b005b34801561047657600080fd5b50610491600480360381019061048c9190613468565b610e8e565b60405161049e9190613ec4565b60405180910390f35b3480156104b357600080fd5b506104ce60048036038101906104c991906134e0565b610f73565b005b3480156104dc57600080fd5b506104f760048036038101906104f29190613414565b610f87565b005b34801561050557600080fd5b50610520600480360381019061051b91906133af565b611075565b005b34801561052e57600080fd5b50610537611147565b60405161054491906141de565b60405180910390f35b34801561055957600080fd5b50610574600480360381019061056f9190613142565b61114d565b005b34801561058257600080fd5b5061058b611228565b6040516105989190613d76565b60405180910390f35b3480156105ad57600080fd5b506105c860048036038101906105c391906130f0565b61124e565b6040516105d591906141de565b60405180910390f35b3480156105ea57600080fd5b506105f3611296565b005b34801561060157600080fd5b5061061c600480360381019061061791906133af565b6113ee565b005b34801561062a57600080fd5b50610633611450565b6040516106409190613d76565b60405180910390f35b34801561065557600080fd5b5061065e61147a565b60405161066b9190613f1c565b60405180910390f35b34801561068057600080fd5b5061068961151c565b005b34801561069757600080fd5b506106b260048036038101906106ad9190613357565b6115d0565b6040516106bf9190613ee6565b60405180910390f35b3480156106d457600080fd5b506106ef60048036038101906106ea91906133af565b611710565b6040516106fc9190613ee6565b60405180910390f35b34801561071157600080fd5b5061072c600480360381019061072791906133af565b6117dd565b6040516107399190613ee6565b60405180910390f35b34801561074e57600080fd5b50610769600480360381019061076491906133eb565b6117fb565b60405161077691906141de565b60405180910390f35b34801561078b57600080fd5b50610794611820565b6040516107a19190613ee6565b60405180910390f35b3480156107b657600080fd5b506107d160048036038101906107cc91906133af565b611839565b005b3480156107df57600080fd5b506107e861190b565b005b3480156107f657600080fd5b506107ff611939565b60405161080c91906141de565b60405180910390f35b34801561082157600080fd5b5061083c600480360381019061083791906131ba565b611943565b60405161084991906141de565b60405180910390f35b34801561085e57600080fd5b506108676119ca565b6040516108749190613dac565b60405180910390f35b34801561088957600080fd5b506108a4600480360381019061089f91906132c5565b6119f0565b6040516108b19190613f01565b60405180910390f35b3480156108c657600080fd5b506108e160048036038101906108dc91906130f0565b611be3565b005b3480156108ef57600080fd5b5061090a60048036038101906109059190613414565b611daa565b005b600060066000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b61097d33611ec5565b7f9089118748848f35d2044622c8191c0581a5c78fbe3c37abad69704459cffed9336040516109ac9190613d91565b60405180910390a16109c633670de0b6b3a7640000612014565b6109d18282336121c2565b5050565b606060038054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a6d5780601f10610a4257610100808354040283529160200191610a6d565b820191906000526020600020905b815481529060010190602001808311610a5057829003601f168201915b5050505050905090565b6000610a8b610a8461234d565b8484612355565b6001905092915050565b6000610aa085611ec5565b60003390506000819050610abe82600c61252090919063ffffffff16565b610afd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af4906141be565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16636352211e886040518263ffffffff1660e01b8152600401610b4d91906141de565b60206040518083038186803b158015610b6557600080fd5b505afa158015610b79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9d9190613119565b73ffffffffffffffffffffffffffffffffffffffff1614610bf3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bea9061403e565b60405180910390fd5b7f816951017bbdb395e05a86d9ff716953c8ea003152bad3825fa891ce07646972878388604051610c2693929190613dc7565b60405180910390a1610c39878686612550565b7f150b7a02000000000000000000000000000000000000000000000000000000009250505095945050505050565b6000600254905090565b600760149054906101000a900460ff1681565b6000610c91848484612637565b610d5284610c9d61234d565b610d4d856040518060600160405280602881526020016144b260289139600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610d0361234d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546128cc9092919063ffffffff16565b612355565b600190509392505050565b600a5481565b6000600560009054906101000a900460ff16905090565b6000610e23610d8761234d565b84610e1e8560016000610d9861234d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461292790919063ffffffff16565b612355565b6001905092915050565b610e3633611ec5565b7f9089118748848f35d2044622c8191c0581a5c78fbe3c37abad69704459cffed933604051610e659190613d91565b60405180910390a1610e7f33670de0b6b3a7640000612014565b610e8a82823361297c565b5050565b6060600084610e9e57600e610ea1565b600c5b9050606084840367ffffffffffffffff81118015610ebe57600080fd5b50604051908082528060200260200182016040528015610eed5781602001602082028036833780820191505090505b50905060008590505b84811015610f6657610f118184612a3190919063ffffffff16565b8287830381518110610f1f57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508080600101915050610ef6565b5080925050509392505050565b610f84610f7e61234d565b82612014565b50565b610f8f61234d565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611015906140be565b60405180910390fd5b60008261102c57600e61102f565b600c5b905060005b825181101561106f5761106383828151811061104c57fe5b602002602001015183612a4b90919063ffffffff16565b50806001019050611034565b50505050565b61107d611450565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e190613ffe565b60405180910390fd5b600760149054906101000a900460ff16611139576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111309061415e565b60405180910390fd5b6111438282612a7b565b5050565b600b5481565b61115561234d565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146111e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111db906140be565b60405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61129e61234d565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461132d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611324906140be565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600061142d826040518060600160405280602481526020016144da6024913961141e8661141961234d565b611943565b6128cc9092919063ffffffff16565b90506114418361143b61234d565b83612355565b61144b8383612014565b505050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156115125780601f106114e757610100808354040283529160200191611512565b820191906000526020600020905b8154815290600101906020018083116114f557829003601f168201915b5050505050905090565b61152461234d565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146115b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115aa906140be565b60405180910390fd5b6000600760146101000a81548160ff021916908315150217905550565b60006115da611450565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611647576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161163e90613ffe565b60405180910390fd5b600760149054906101000a900460ff16611696576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168d9061415e565b60405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff1684846040516116bf929190613d48565b6000604051808303816000865af19150503d80600081146116fc576040519150601f19603f3d011682016040523d82523d6000602084013e611701565b606091505b50509050809150509392505050565b60006117d361171d61234d565b846117ce856040518060600160405280602581526020016144fe602591396001600061174761234d565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546128cc9092919063ffffffff16565b612355565b6001905092915050565b60006117f16117ea61234d565b8484612637565b6001905092915050565b6000808261180a57600e61180d565b600c5b905061181881612c0f565b915050919050565b600061182a611939565b611832610c67565b1015905090565b611841611450565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146118ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118a590613ffe565b60405180910390fd5b600760149054906101000a900460ff166118fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118f49061415e565b60405180910390fd5b6119078282612014565b5050565b611937600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1647612c24565b565b6000600b54905090565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006119fb86611ec5565b60003390506000819050611a1982600e61252090919063ffffffff16565b611a58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a4f906141be565b60405180910390fd5b60008611611a9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9290613f7e565b60405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff1662fdd58e308a6040518363ffffffff1660e01b8152600401611ad7929190613e9b565b60206040518083038186803b158015611aef57600080fd5b505afa158015611b03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b279190613509565b9050868114611b6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b629061417e565b60405180910390fd5b7faa8ac49969d54ecc1663afbf95bbd6fcbca9397e87b9f860d130a42e67a59e9289848a8a604051611ba09493929190613dfe565b60405180910390a1611bb3898787612550565b7ff23a6e610000000000000000000000000000000000000000000000000000000093505050509695505050505050565b611beb61234d565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611c7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c71906140be565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611cea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce190613f9e565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611db2611450565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e1690613ffe565b60405180910390fd5b600760149054906101000a900460ff16611e6e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e659061415e565b60405180910390fd5b600082611e7c57600e611e7f565b600c5b905060005b8251811015611ebf57611eb3838281518110611e9c57fe5b602002602001015183612d1890919063ffffffff16565b50806001019050611e84565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff16600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612011576000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b8152600401611f789190613d76565b60206040518083038186803b158015611f9057600080fd5b505afa158015611fa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fc89190613509565b905080600a54111561200f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120069061401e565b60405180910390fd5b505b50565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612084576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207b906140de565b60405180910390fd5b61209082600083612d48565b6120fb8160405180606001604052806022815260200161446a602291396000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546128cc9092919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061215281600254612d4d90919063ffffffff16565b600281905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516121b691906141de565b60405180910390a35050565b600083905060008173ffffffffffffffffffffffffffffffffffffffff1662fdd58e30866040518363ffffffff1660e01b8152600401612203929190613e9b565b60206040518083038186803b15801561221b57600080fd5b505afa15801561222f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122539190613509565b905060008111612298576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228f9061409e565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663f242432a308587856040518563ffffffff1660e01b81526004016122d79493929190613e43565b600060405180830381600087803b1580156122f157600080fd5b505af1158015612305573d6000803e3d6000fd5b505050507ff80ebeba7050b64dd3aeb554073ad10210323c4eed47159ff6587eacb9e8ecdc8386868460405161233e9493929190613dfe565b60405180910390a15050505050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156123c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123bc9061411e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612435576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161242c90613fbe565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258360405161251391906141de565b60405180910390a3505050565b6000612548836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612d97565b905092915050565b60008282905014156125f257612564611820565b156125a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161259b9061413e565b60405180910390fd5b6125b683670de0b6b3a7640000612a7b565b7f7e831c0f3b087e0d489853b765291ab7458a9d72dfb837ce1a5d84a22d4f2d02836040516125e59190613d76565b60405180910390a1612632565b60008060008484810190612606919061316b565b92509250925080156126225761261d8383886121c2565b61262e565b61262d83838861297c565b5b5050505b505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156126a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161269e906140fe565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161270e90613f5e565b60405180910390fd5b612722838383612d48565b61278d8160405180606001604052806026815260200161448c602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546128cc9092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612820816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461292790919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516128bf91906141de565b60405180910390a3505050565b6000838311158290612914576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161290b9190613f1c565b60405180910390fd5b5060008385039050809150509392505050565b600080828401905083811015612972576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161296990613fde565b60405180910390fd5b8091505092915050565b60008390508073ffffffffffffffffffffffffffffffffffffffff166342842e0e3084866040518463ffffffff1660e01b81526004016129be93929190613dc7565b600060405180830381600087803b1580156129d857600080fd5b505af11580156129ec573d6000803e3d6000fd5b505050507f760366092dec37cc9f0e5cfe45487dda85255614a6b7d143561d9ef106eb7993828585604051612a2393929190613dc7565b60405180910390a150505050565b6000612a408360000183612dba565b60001c905092915050565b6000612a73836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612e27565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612aeb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae29061419e565b60405180910390fd5b612af760008383612d48565b612b0c8160025461292790919063ffffffff16565b600281905550612b63816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461292790919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612c0391906141de565b60405180910390a35050565b6000612c1d82600001612e97565b9050919050565b80471015612c67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c5e9061407e565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff1682604051612c8d90613d61565b60006040518083038185875af1925050503d8060008114612cca576040519150601f19603f3d011682016040523d82523d6000602084013e612ccf565b606091505b5050905080612d13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d0a9061405e565b60405180910390fd5b505050565b6000612d40836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612ea8565b905092915050565b505050565b6000612d8f83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506128cc565b905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b600081836000018054905011612e05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dfc90613f3e565b60405180910390fd5b826000018281548110612e1457fe5b9060005260206000200154905092915050565b6000612e338383612d97565b612e8c578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612e91565b600090505b92915050565b600081600001805490509050919050565b60008083600101600084815260200190815260200160002054905060008114612f845760006001820390506000600186600001805490500390506000866000018281548110612ef357fe5b9060005260206000200154905080876000018481548110612f1057fe5b9060005260206000200181905550600183018760010160008381526020019081526020016000208190555086600001805480612f4857fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050612f8a565b60009150505b92915050565b600081359050612f9f816143f6565b92915050565b600081519050612fb4816143f6565b92915050565b600081359050612fc98161440d565b92915050565b600082601f830112612fe057600080fd5b8135612ff3612fee82614241565b614214565b9150818183526020840193506020810190508385602084028201111561301857600080fd5b60005b83811015613048578161302e8882612f90565b84526020840193506020830192505060018101905061301b565b5050505092915050565b60008135905061306181614424565b92915050565b6000813590506130768161443b565b92915050565b60008083601f84011261308e57600080fd5b8235905067ffffffffffffffff8111156130a757600080fd5b6020830191508360018202830111156130bf57600080fd5b9250929050565b6000813590506130d581614452565b92915050565b6000815190506130ea81614452565b92915050565b60006020828403121561310257600080fd5b600061311084828501612f90565b91505092915050565b60006020828403121561312b57600080fd5b600061313984828501612fa5565b91505092915050565b60006020828403121561315457600080fd5b600061316284828501612fba565b91505092915050565b60008060006060848603121561318057600080fd5b600061318e86828701612fba565b935050602061319f868287016130c6565b92505060406131b086828701613052565b9150509250925092565b600080604083850312156131cd57600080fd5b60006131db85828601612f90565b92505060206131ec85828601612f90565b9150509250929050565b60008060006060848603121561320b57600080fd5b600061321986828701612f90565b935050602061322a86828701612f90565b925050604061323b868287016130c6565b9150509250925092565b60008060008060006080868803121561325d57600080fd5b600061326b88828901612f90565b955050602061327c88828901612f90565b945050604061328d888289016130c6565b935050606086013567ffffffffffffffff8111156132aa57600080fd5b6132b68882890161307c565b92509250509295509295909350565b60008060008060008060a087890312156132de57600080fd5b60006132ec89828a01612f90565b96505060206132fd89828a01612f90565b955050604061330e89828a016130c6565b945050606061331f89828a016130c6565b935050608087013567ffffffffffffffff81111561333c57600080fd5b61334889828a0161307c565b92509250509295509295509295565b60008060006040848603121561336c57600080fd5b600061337a86828701612f90565b935050602084013567ffffffffffffffff81111561339757600080fd5b6133a38682870161307c565b92509250509250925092565b600080604083850312156133c257600080fd5b60006133d085828601612f90565b92505060206133e1858286016130c6565b9150509250929050565b6000602082840312156133fd57600080fd5b600061340b84828501613052565b91505092915050565b6000806040838503121561342757600080fd5b600061343585828601613052565b925050602083013567ffffffffffffffff81111561345257600080fd5b61345e85828601612fcf565b9150509250929050565b60008060006060848603121561347d57600080fd5b600061348b86828701613052565b935050602061349c868287016130c6565b92505060406134ad868287016130c6565b9150509250925092565b6000602082840312156134c957600080fd5b60006134d784828501613067565b91505092915050565b6000602082840312156134f257600080fd5b6000613500848285016130c6565b91505092915050565b60006020828403121561351b57600080fd5b6000613529848285016130db565b91505092915050565b600061353e8383613568565b60208301905092915050565b6135538161436d565b82525050565b613562816142ec565b82525050565b613571816142da565b82525050565b613580816142da565b82525050565b600061359182614279565b61359b818561429c565b93506135a683614269565b8060005b838110156135d75781516135be8882613532565b97506135c98361428f565b9250506001810190506135aa565b5085935050505092915050565b6135ed816142fe565b82525050565b6135fc8161430a565b82525050565b600061360e83856142be565b935061361b8385846143a3565b82840190509392505050565b600061363282614284565b61363c81856142c9565b935061364c8185602086016143b2565b613655816143e5565b840191505092915050565b600061366d6022836142c9565b91507f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006136d36023836142c9565b91507f45524332303a207472616e7366657220746f20746865207a65726f206164647260008301527f65737300000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613739601f836142c9565b91507f6d7573742068617665206e6f6e2d7a65726f20616d6f756e74546f6b656e73006000830152602082019050919050565b60006137796026836142c9565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006137df6022836142c9565b91507f45524332303a20617070726f766520746f20746865207a65726f20616464726560008301527f73730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613845601b836142c9565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b6000613885600d836142c9565b91507f6d757374206265206f776e6572000000000000000000000000000000000000006000830152602082019050919050565b60006138c56026836142c9565b91507f696e73756666696369656e742062616c616e6365206f6620726571756972656460008301527f20746f6b656e00000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061392b600f836142c9565b91507f646f6e74206f776e2065726337323100000000000000000000000000000000006000830152602082019050919050565b600061396b603a836142c9565b91507f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008301527f6563697069656e74206d617920686176652072657665727465640000000000006020830152604082019050919050565b60006139d1601d836142c9565b91507f416464726573733a20696e73756666696369656e742062616c616e63650000006000830152602082019050919050565b6000613a116017836142c9565b91507f646f65736e7420686f6c6420616e792062616c616e63650000000000000000006000830152602082019050919050565b6000613a516020836142c9565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000613a916021836142c9565b91507f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008301527f73000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613af76025836142c9565b91507f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008301527f64726573730000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613b5d6000836142ad565b9150600082019050919050565b6000613b776000836142be565b9150600082019050919050565b6000613b916024836142c9565b91507f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613bf76012836142c9565b91507f4d617820746f6b656e73206372656174656400000000000000000000000000006000830152602082019050919050565b6000613c37601c836142c9565b91507f656d657267656e637920616363657373206e6f7420616c6c6f776564000000006000830152602082019050919050565b6000613c776013836142c9565b91507f416c7265616479206861642045524331313535000000000000000000000000006000830152602082019050919050565b6000613cb7601f836142c9565b91507f45524332303a206d696e7420746f20746865207a65726f2061646472657373006000830152602082019050919050565b6000613cf76018836142c9565b91507f636f6e7472616374206e6f742077686974656c697374656400000000000000006000830152602082019050919050565b613d3381614356565b82525050565b613d4281614360565b82525050565b6000613d55828486613602565b91508190509392505050565b6000613d6c82613b6a565b9150819050919050565b6000602082019050613d8b6000830184613577565b92915050565b6000602082019050613da6600083018461354a565b92915050565b6000602082019050613dc16000830184613559565b92915050565b6000606082019050613ddc6000830186613577565b613de96020830185613577565b613df66040830184613d2a565b949350505050565b6000608082019050613e136000830187613577565b613e206020830186613577565b613e2d6040830185613d2a565b613e3a6060830184613d2a565b95945050505050565b600060a082019050613e586000830187613577565b613e656020830186613577565b613e726040830185613d2a565b613e7f6060830184613d2a565b8181036080830152613e9081613b50565b905095945050505050565b6000604082019050613eb06000830185613577565b613ebd6020830184613d2a565b9392505050565b60006020820190508181036000830152613ede8184613586565b905092915050565b6000602082019050613efb60008301846135e4565b92915050565b6000602082019050613f1660008301846135f3565b92915050565b60006020820190508181036000830152613f368184613627565b905092915050565b60006020820190508181036000830152613f5781613660565b9050919050565b60006020820190508181036000830152613f77816136c6565b9050919050565b60006020820190508181036000830152613f978161372c565b9050919050565b60006020820190508181036000830152613fb78161376c565b9050919050565b60006020820190508181036000830152613fd7816137d2565b9050919050565b60006020820190508181036000830152613ff781613838565b9050919050565b6000602082019050818103600083015261401781613878565b9050919050565b60006020820190508181036000830152614037816138b8565b9050919050565b600060208201905081810360008301526140578161391e565b9050919050565b600060208201905081810360008301526140778161395e565b9050919050565b60006020820190508181036000830152614097816139c4565b9050919050565b600060208201905081810360008301526140b781613a04565b9050919050565b600060208201905081810360008301526140d781613a44565b9050919050565b600060208201905081810360008301526140f781613a84565b9050919050565b6000602082019050818103600083015261411781613aea565b9050919050565b6000602082019050818103600083015261413781613b84565b9050919050565b6000602082019050818103600083015261415781613bea565b9050919050565b6000602082019050818103600083015261417781613c2a565b9050919050565b6000602082019050818103600083015261419781613c6a565b9050919050565b600060208201905081810360008301526141b781613caa565b9050919050565b600060208201905081810360008301526141d781613cea565b9050919050565b60006020820190506141f36000830184613d2a565b92915050565b600060208201905061420e6000830184613d39565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561423757600080fd5b8060405250919050565b600067ffffffffffffffff82111561425857600080fd5b602082029050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b60006142e582614336565b9050919050565b60006142f782614336565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60006143788261437f565b9050919050565b600061438a82614391565b9050919050565b600061439c82614336565b9050919050565b82818337600083830152505050565b60005b838110156143d05780820151818401526020810190506143b5565b838111156143df576000848401525b50505050565b6000601f19601f8301169050919050565b6143ff816142da565b811461440a57600080fd5b50565b614416816142ec565b811461442157600080fd5b50565b61442d816142fe565b811461443857600080fd5b50565b6144448161430a565b811461444f57600080fd5b50565b61445b81614356565b811461446657600080fd5b5056fe45524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e20616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220947b70cfbc59b728805502922039bb205ae10e55fd11ff4a8ee87f48542cd31f64736f6c634300060c0033

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

00000000000000000000000035bd01fc9d6d5d81ca9e055db88dc49aa2c699a800000000000000000000000000000000000000000000000340aad21b3b70000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000002086ac3510526000000000000000000000000000000000000000000000000000000000000000000010467269656e64732057697468204172740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034657410000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : requiredTokenAddress_ (address): 0x35bD01FC9d6D5D81CA9E055Db88Dc49aa2c699A8
Arg [1] : requiredTokenAmount_ (uint256): 60000000000000000000
Arg [2] : tokenName (string): Friends With Art
Arg [3] : tokenSymbol (string): FWA
Arg [4] : maxAmount_ (uint256): 600000000000000000000

-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 00000000000000000000000035bd01fc9d6d5d81ca9e055db88dc49aa2c699a8
Arg [1] : 00000000000000000000000000000000000000000000000340aad21b3b700000
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [4] : 00000000000000000000000000000000000000000000002086ac351052600000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000010
Arg [6] : 467269656e647320576974682041727400000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [8] : 4657410000000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

54252:10416:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32935:183;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59312:393;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;20402:83;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22599:210;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56744:944;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21477:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54375:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;23283:454;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54501:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21329:83;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24146:300;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58913:391;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;62743:480;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30342:91;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63231:399;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64111:147;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;54542:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56365:146;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;54459:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21640:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2782:148;;;;;;;;;;;;;:::i;:::-;;30752:357;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2140:79;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;20604:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56260:97;;;;;;;;;;;;;:::i;:::-;;64421:244;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24949:400;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21972:216;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62437:298;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59927:109;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64266:147;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;59713:112;;;;;;;;;;;;;:::i;:::-;;59833:86;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22251:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54414:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57696:1209;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3085:281;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63679:424;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;32935:183;33048:4;33077:20;:33;33098:11;33077:33;;;;;;;;;;;;;;;;;;;;;;;;;;;33070:40;;32935:183;;;:::o;59312:393::-;59452:32;59473:10;59452:20;:32::i;:::-;59535:26;59550:10;59535:26;;;;;;:::i;:::-;;;;;;;;59572;59578:10;59590:7;59572:5;:26::i;:::-;59632:65;59648:21;59671:13;59686:10;59632:15;:65::i;:::-;59312:393;;:::o;20402:83::-;20439:13;20472:5;20465:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20402:83;:::o;22599:210::-;22718:4;22740:39;22749:12;:10;:12::i;:::-;22763:7;22772:6;22740:8;:39::i;:::-;22797:4;22790:11;;22599:210;;;;:::o;56744:944::-;56901:6;56920:26;56941:4;56920:20;:26::i;:::-;56959:38;57000:10;56959:51;;57021:31;57076:30;57021:86;;57184:63;57216:30;57184:22;:31;;:63;;;;:::i;:::-;57162:137;;;;;;;;;;;;:::i;:::-;;;;;;;;;57419:4;57367:57;;:23;:31;;;57399:7;57367:40;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:57;;;57345:122;;;;;;;;;;;;:::i;:::-;;;;;;;;;57506:62;57522:4;57528:30;57560:7;57506:62;;;;;;;;:::i;:::-;;;;;;;;57603:35;57627:4;57633;;57603:23;:35::i;:::-;57656:24;57649:31;;;;56744:944;;;;;;;:::o;21477:100::-;21530:7;21557:12;;21550:19;;21477:100;:::o;54375:32::-;;;;;;;;;;;;;:::o;23283:454::-;23423:4;23440:36;23450:6;23458:9;23469:6;23440:9;:36::i;:::-;23487:220;23510:6;23531:12;:10;:12::i;:::-;23558:138;23614:6;23558:138;;;;;;;;;;;;;;;;;:11;:19;23570:6;23558:19;;;;;;;;;;;;;;;:33;23578:12;:10;:12::i;:::-;23558:33;;;;;;;;;;;;;;;;:37;;:138;;;;;:::i;:::-;23487:8;:220::i;:::-;23725:4;23718:11;;23283:454;;;;;:::o;54501:34::-;;;;:::o;21329:83::-;21370:5;21395:9;;;;;;;;;;;21388:16;;21329:83;:::o;24146:300::-;24261:4;24283:133;24306:12;:10;:12::i;:::-;24333:7;24355:50;24394:10;24355:11;:25;24367:12;:10;:12::i;:::-;24355:25;;;;;;;;;;;;;;;:34;24381:7;24355:34;;;;;;;;;;;;;;;;:38;;:50;;;;:::i;:::-;24283:8;:133::i;:::-;24434:4;24427:11;;24146:300;;;;:::o;58913:391::-;59052:32;59073:10;59052:20;:32::i;:::-;59135:26;59150:10;59135:26;;;;;;:::i;:::-;;;;;;;;59172;59178:10;59190:7;59172:5;:26::i;:::-;59232:64;59247:21;59270:13;59285:10;59232:14;:64::i;:::-;58913:391;;:::o;62743:480::-;62870:16;62899:49;62964:8;:59;;63000:23;62964:59;;;62975:22;62964:59;62899:124;;63034:19;63076:5;63070:3;:11;63056:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63034:48;;63098:9;63110:5;63098:17;;63093:103;63121:3;63117:1;:7;63093:103;;;63162:22;63182:1;63162:16;:19;;:22;;;;:::i;:::-;63146:2;63153:5;63149:1;:9;63146:13;;;;;;;;;;;;;:38;;;;;;;;;;;63126:3;;;;;;;63093:103;;;;63213:2;63206:9;;;;62743:480;;;;;:::o;30342:91::-;30398:27;30404:12;:10;:12::i;:::-;30418:6;30398:5;:27::i;:::-;30342:91;:::o;63231:399::-;2362:12;:10;:12::i;:::-;2352:22;;:6;;;;;;;;;;;:22;;;2344:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;63364:49:::1;63429:8;:59;;63465:23;63429:59;;;63440:22;63429:59;63364:124;;63504:9;63499:124;63523:17;:24;63519:1;:28;63499:124;;;63569:42;63590:17;63608:1;63590:20;;;;;;;;;;;;;;63569:16;:20;;:42;;;;:::i;:::-;;63549:3;;;;;63499:124;;;;2422:1;63231:399:::0;;:::o;64111:147::-;56583:7;:5;:7::i;:::-;56569:21;;:10;:21;;;56561:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;56627:20;;;;;;;;;;;56619:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;64228:22:::1;64234:7;64243:6;64228:5;:22::i;:::-;64111:147:::0;;:::o;54542:24::-;;;;:::o;56365:146::-;2362:12;:10;:12::i;:::-;2352:22;;:6;;;;;;;;;;;:22;;;2344:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;56493:10:::1;56475:15;;:28;;;;;;;;;;;;;;;;;;56365:146:::0;:::o;54459:35::-;;;;;;;;;;;;;:::o;21640:119::-;21706:7;21733:9;:18;21743:7;21733:18;;;;;;;;;;;;;;;;21726:25;;21640:119;;;:::o;2782:148::-;2362:12;:10;:12::i;:::-;2352:22;;:6;;;;;;;;;;;:22;;;2344:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;2889:1:::1;2852:40;;2873:6;;;;;;;;;;;2852:40;;;;;;;;;;;;2920:1;2903:6;;:19;;;;;;;;;;;;;;;;;;2782:148::o:0;30752:357::-;30829:26;30871:133;30926:6;30871:133;;;;;;;;;;;;;;;;;:32;30881:7;30890:12;:10;:12::i;:::-;30871:9;:32::i;:::-;:36;;:133;;;;;:::i;:::-;30829:175;;31017:51;31026:7;31035:12;:10;:12::i;:::-;31049:18;31017:8;:51::i;:::-;31079:22;31085:7;31094:6;31079:5;:22::i;:::-;30752:357;;;:::o;2140:79::-;2178:7;2205:6;;;;;;;;;;;2198:13;;2140:79;:::o;20604:87::-;20643:13;20676:7;20669:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20604:87;:::o;56260:97::-;2362:12;:10;:12::i;:::-;2352:22;;:6;;;;;;;;;;;:22;;;2344:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;56344:5:::1;56321:20;;:28;;;;;;;;;;;;;;;;;;56260:97::o:0;64421:244::-;64562:4;56583:7;:5;:7::i;:::-;56569:21;;:10;:21;;;56561:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;56627:20;;;;;;;;;;;56619:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;64580:12:::1;64598:13;:18;;64617:14;;64598:34;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64579:53;;;64650:7;64643:14;;;64421:244:::0;;;;;:::o;24949:400::-;25069:4;25091:228;25114:12;:10;:12::i;:::-;25141:7;25163:145;25220:15;25163:145;;;;;;;;;;;;;;;;;:11;:25;25175:12;:10;:12::i;:::-;25163:25;;;;;;;;;;;;;;;:34;25189:7;25163:34;;;;;;;;;;;;;;;;:38;;:145;;;;;:::i;:::-;25091:8;:228::i;:::-;25337:4;25330:11;;24949:400;;;;:::o;21972:216::-;22094:4;22116:42;22126:12;:10;:12::i;:::-;22140:9;22151:6;22116:9;:42::i;:::-;22176:4;22169:11;;21972:216;;;;:::o;62437:298::-;62535:7;62560:49;62625:8;:59;;62661:23;62625:59;;;62636:22;62625:59;62560:124;;62702:25;:16;:23;:25::i;:::-;62695:32;;;62437:298;;;:::o;59927:109::-;59976:4;60017:11;:9;:11::i;:::-;60000:13;:11;:13::i;:::-;:28;;59993:35;;59927:109;:::o;64266:147::-;56583:7;:5;:7::i;:::-;56569:21;;:10;:21;;;56561:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;56627:20;;;;;;;;;;;56619:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;64383:22:::1;64389:7;64398:6;64383:5;:22::i;:::-;64266:147:::0;;:::o;59713:112::-;59760:57;59778:15;;;;;;;;;;;59795:21;59760:17;:57::i;:::-;59713:112::o;59833:86::-;59875:7;59902:9;;59895:16;;59833:86;:::o;22251:201::-;22385:7;22417:11;:18;22429:5;22417:18;;;;;;;;;;;;;;;:27;22436:7;22417:27;;;;;;;;;;;;;;;;22410:34;;22251:201;;;;:::o;54414:38::-;;;;;;;;;;;;;:::o;57696:1209::-;57885:6;57904:26;57925:4;57904:20;:26::i;:::-;57943:39;57985:10;57943:52;;58006:33;58064:31;58006:90;;58171:65;58204:31;58171:23;:32;;:65;;;;:::i;:::-;58149:139;;;;;;;;;;;;:::i;:::-;;;;;;;;;58379:1;58364:12;:16;58356:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;58427:25;58468:24;:34;;;58511:4;58518:7;58468:58;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58427:99;;58566:12;58545:17;:33;58537:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;58643:141;58674:4;58693:31;58739:7;58761:12;58643:141;;;;;;;;;:::i;:::-;;;;;;;;58819:35;58843:4;58849;;58819:23;:35::i;:::-;58872:25;58865:32;;;;;57696:1209;;;;;;;;:::o;3085:281::-;2362:12;:10;:12::i;:::-;2352:22;;:6;;;;;;;;;;;:22;;;2344:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;3208:1:::1;3188:22;;:8;:22;;;;3166:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;3321:8;3292:38;;3313:6;;;;;;;;;;;3292:38;;;;;;;;;;;;3350:8;3341:6;;:17;;;;;;;;;;;;;;;;;;3085:281:::0;:::o;63679:424::-;56583:7;:5;:7::i;:::-;56569:21;;:10;:21;;;56561:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;56627:20;;;;;;;;;;;56619:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;63834:49:::1;63899:8;:59;;63935:23;63899:59;;;63910:22;63899:59;63834:124;;63974:9;63969:127;63993:17;:24;63989:1;:28;63969:127;;;64039:45;64063:17;64081:1;64063:20;;;;;;;;;;;;;;64039:16;:23;;:45;;;;:::i;:::-;;64019:3;;;;;63969:127;;;;56691:1;63679:424:::0;;:::o;62036:349::-;62140:1;62108:34;;:20;;;;;;;;;;;:34;;;62104:274;;62159:15;62184:20;;;;;;;;;;;62177:38;;;62216:4;62177:44;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62159:62;;62285:7;62262:19;;:30;;62236:130;;;;;;;;;;;;:::i;:::-;;;;;;;;;62104:274;;62036:349;:::o;27440:455::-;27543:1;27524:21;;:7;:21;;;;27516:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;27596:49;27617:7;27634:1;27638:6;27596:20;:49::i;:::-;27679:105;27716:6;27679:105;;;;;;;;;;;;;;;;;:9;:18;27689:7;27679:18;;;;;;;;;;;;;;;;:22;;:105;;;;;:::i;:::-;27658:9;:18;27668:7;27658:18;;;;;;;;;;;;;;;:126;;;;27810:24;27827:6;27810:12;;:16;;:24;;;;:::i;:::-;27795:12;:39;;;;27876:1;27850:37;;27859:7;27850:37;;;27880:6;27850:37;;;;;;:::i;:::-;;;;;;;;27440:455;;:::o;60493:722::-;60644:31;60687:21;60644:65;;60720:15;60751:22;:32;;;60792:4;60799:13;60751:62;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60720:93;;60842:1;60832:7;:11;60824:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;60884:22;:39;;;60946:4;60966:9;60990:13;61018:7;60884:169;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61071:136;61101:9;61125:21;61161:13;61189:7;61071:136;;;;;;;;;:::i;:::-;;;;;;;;60493:722;;;;;:::o;672:106::-;725:15;760:10;753:17;;672:106;:::o;28333:380::-;28486:1;28469:19;;:5;:19;;;;28461:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;28567:1;28548:21;;:7;:21;;;;28540:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;28651:6;28621:11;:18;28633:5;28621:18;;;;;;;;;;;;;;;:27;28640:7;28621:27;;;;;;;;;;;;;;;:36;;;;28689:7;28673:32;;28682:5;28673:32;;;28698:6;28673:32;;;;;;:::i;:::-;;;;;;;;28333:380;;;:::o;51522:190::-;51629:4;51658:46;51668:3;:10;;51696:5;51688:14;;51680:23;;51658:9;:46::i;:::-;51651:53;;51522:190;;;;:::o;61223:805::-;61343:1;61328:4;;:11;;:16;61324:697;;;61393:18;:16;:18::i;:::-;61389:87;;;61432:28;;;;;;;;;;:::i;:::-;;;;;;;;61389:87;61490:20;61496:4;61502:7;61490:5;:20::i;:::-;61530:19;61544:4;61530:19;;;;;;:::i;:::-;;;;;;;;61324:697;;;61625:29;61673:21;61713:14;61756:4;;61745:42;;;;;;;:::i;:::-;61606:181;;;;;;61806:9;61802:208;;;61836:59;61852:21;61875:13;61890:4;61836:15;:59::i;:::-;61802:208;;;61936:58;61951:21;61974:13;61989:4;61936:14;:58::i;:::-;61802:208;61324:697;;;;61223:805;;;:::o;25839:610::-;25997:1;25979:20;;:6;:20;;;;25971:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;26081:1;26060:23;;:9;:23;;;;26052:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;26136:47;26157:6;26165:9;26176:6;26136:20;:47::i;:::-;26216:108;26252:6;26216:108;;;;;;;;;;;;;;;;;:9;:17;26226:6;26216:17;;;;;;;;;;;;;;;;:21;;:108;;;;;:::i;:::-;26196:9;:17;26206:6;26196:17;;;;;;;;;;;;;;;:128;;;;26358:32;26383:6;26358:9;:20;26368:9;26358:20;;;;;;;;;;;;;;;;:24;;:32;;;;:::i;:::-;26335:9;:20;26345:9;26335:20;;;;;;;;;;;;;;;:55;;;;26423:9;26406:35;;26415:6;26406:35;;;26434:6;26406:35;;;;;;:::i;:::-;;;;;;;;25839:610;;;:::o;8109:226::-;8229:7;8262:1;8257;:6;;8265:12;8249:29;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;8289:9;8305:1;8301;:5;8289:17;;8326:1;8319:8;;;8109:226;;;;;:::o;7206:181::-;7264:7;7284:9;7300:1;7296;:5;7284:17;;7325:1;7320;:6;;7312:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;7378:1;7371:8;;;7206:181;;;;:::o;60044:441::-;60194:29;60234:21;60194:62;;60267:21;:38;;;60328:4;60348:9;60372:13;60267:129;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60414:63;60429:9;60440:21;60463:13;60414:63;;;;;;;;:::i;:::-;;;;;;;;60044:441;;;;:::o;52269:181::-;52370:7;52418:22;52422:3;:10;;52434:5;52418:3;:22::i;:::-;52410:31;;52395:47;;52269:181;;;;:::o;50922:166::-;51010:4;51039:41;51044:3;:10;;51072:5;51064:14;;51056:23;;51039:4;:41::i;:::-;51032:48;;50922:166;;;;:::o;26730:378::-;26833:1;26814:21;;:7;:21;;;;26806:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;26884:49;26913:1;26917:7;26926:6;26884:20;:49::i;:::-;26961:24;26978:6;26961:12;;:16;;:24;;;;:::i;:::-;26946:12;:39;;;;27017:30;27040:6;27017:9;:18;27027:7;27017:18;;;;;;;;;;;;;;;;:22;;:30;;;;:::i;:::-;26996:9;:18;27006:7;26996:18;;;;;;;;;;;;;;;:51;;;;27084:7;27063:37;;27080:1;27063:37;;;27093:6;27063:37;;;;;;:::i;:::-;;;;;;;;26730:378;;:::o;51798:117::-;51861:7;51888:19;51896:3;:10;;51888:7;:19::i;:::-;51881:26;;51798:117;;;:::o;13909:469::-;14038:6;14013:21;:31;;13991:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;14193:12;14211:9;:14;;14233:6;14211:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14192:52;;;14277:7;14255:115;;;;;;;;;;;;:::i;:::-;;;;;;;;;13909:469;;;:::o;51264:172::-;51355:4;51384:44;51392:3;:10;;51420:5;51412:14;;51404:23;;51384:7;:44::i;:::-;51377:51;;51264:172;;;;:::o;29738:125::-;;;;:::o;7670:136::-;7728:7;7755:43;7759:1;7762;7755:43;;;;;;;;;;;;;;;;;:3;:43::i;:::-;7748:50;;7670:136;;;;:::o;49685:161::-;49785:4;49837:1;49814:3;:12;;:19;49827:5;49814:19;;;;;;;;;;;;:24;;49807:31;;49685:161;;;;:::o;50395:273::-;50489:7;50557:5;50536:3;:11;;:18;;;;:26;50514:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;50642:3;:11;;50654:5;50642:18;;;;;;;;;;;;;;;;50635:25;;50395:273;;;;:::o;47452:414::-;47515:4;47537:21;47547:3;47552:5;47537:9;:21::i;:::-;47532:327;;47575:3;:11;;47592:5;47575:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47758:3;:11;;:18;;;;47736:3;:12;;:19;47749:5;47736:19;;;;;;;;;;;:40;;;;47798:4;47791:11;;;;47532:327;47842:5;47835:12;;47452:414;;;;;:::o;49932:109::-;49988:7;50015:3;:11;;:18;;;;50008:25;;49932:109;;;:::o;48042:1557::-;48108:4;48226:18;48247:3;:12;;:19;48260:5;48247:19;;;;;;;;;;;;48226:40;;48297:1;48283:10;:15;48279:1313;;48658:21;48695:1;48682:10;:14;48658:38;;48711:17;48752:1;48731:3;:11;;:18;;;;:22;48711:42;;48998:17;49018:3;:11;;49030:9;49018:22;;;;;;;;;;;;;;;;48998:42;;49164:9;49135:3;:11;;49147:13;49135:26;;;;;;;;;;;;;;;:38;;;;49283:1;49267:13;:17;49241:3;:12;;:23;49254:9;49241:23;;;;;;;;;;;:43;;;;49393:3;:11;;:17;;;;;;;;;;;;;;;;;;;;;;;;49488:3;:12;;:19;49501:5;49488:19;;;;;;;;;;;49481:26;;;49531:4;49524:11;;;;;;;;48279:1313;49575:5;49568:12;;;48042:1557;;;;;:::o;5:130:-1:-;;85:6;72:20;63:29;;97:33;124:5;97:33;:::i;:::-;57:78;;;;:::o;142:134::-;;226:6;220:13;211:22;;238:33;265:5;238:33;:::i;:::-;205:71;;;;:::o;283:146::-;;371:6;358:20;349:29;;383:41;418:5;383:41;:::i;:::-;343:86;;;;:::o;454:707::-;;571:3;564:4;556:6;552:17;548:27;538:2;;589:1;586;579:12;538:2;626:6;613:20;648:80;663:64;720:6;663:64;:::i;:::-;648:80;:::i;:::-;639:89;;745:5;770:6;763:5;756:21;800:4;792:6;788:17;778:27;;822:4;817:3;813:14;806:21;;875:6;922:3;914:4;906:6;902:17;897:3;893:27;890:36;887:2;;;939:1;936;929:12;887:2;964:1;949:206;974:6;971:1;968:13;949:206;;;1032:3;1054:37;1087:3;1075:10;1054:37;:::i;:::-;1049:3;1042:50;1115:4;1110:3;1106:14;1099:21;;1143:4;1138:3;1134:14;1127:21;;1006:149;996:1;993;989:9;984:14;;949:206;;;953:14;531:630;;;;;;;:::o;1169:124::-;;1246:6;1233:20;1224:29;;1258:30;1282:5;1258:30;:::i;:::-;1218:75;;;;:::o;1300:128::-;;1379:6;1366:20;1357:29;;1391:32;1417:5;1391:32;:::i;:::-;1351:77;;;;:::o;1449:336::-;;;1563:3;1556:4;1548:6;1544:17;1540:27;1530:2;;1581:1;1578;1571:12;1530:2;1614:6;1601:20;1591:30;;1641:18;1633:6;1630:30;1627:2;;;1673:1;1670;1663:12;1627:2;1707:4;1699:6;1695:17;1683:29;;1758:3;1750:4;1742:6;1738:17;1728:8;1724:32;1721:41;1718:2;;;1775:1;1772;1765:12;1718:2;1523:262;;;;;:::o;1793:130::-;;1873:6;1860:20;1851:29;;1885:33;1912:5;1885:33;:::i;:::-;1845:78;;;;:::o;1930:134::-;;2014:6;2008:13;1999:22;;2026:33;2053:5;2026:33;:::i;:::-;1993:71;;;;:::o;2071:241::-;;2175:2;2163:9;2154:7;2150:23;2146:32;2143:2;;;2191:1;2188;2181:12;2143:2;2226:1;2243:53;2288:7;2279:6;2268:9;2264:22;2243:53;:::i;:::-;2233:63;;2205:97;2137:175;;;;:::o;2319:263::-;;2434:2;2422:9;2413:7;2409:23;2405:32;2402:2;;;2450:1;2447;2440:12;2402:2;2485:1;2502:64;2558:7;2549:6;2538:9;2534:22;2502:64;:::i;:::-;2492:74;;2464:108;2396:186;;;;:::o;2589:257::-;;2701:2;2689:9;2680:7;2676:23;2672:32;2669:2;;;2717:1;2714;2707:12;2669:2;2752:1;2769:61;2822:7;2813:6;2802:9;2798:22;2769:61;:::i;:::-;2759:71;;2731:105;2663:183;;;;:::o;2853:501::-;;;;2996:2;2984:9;2975:7;2971:23;2967:32;2964:2;;;3012:1;3009;3002:12;2964:2;3047:1;3064:61;3117:7;3108:6;3097:9;3093:22;3064:61;:::i;:::-;3054:71;;3026:105;3162:2;3180:53;3225:7;3216:6;3205:9;3201:22;3180:53;:::i;:::-;3170:63;;3141:98;3270:2;3288:50;3330:7;3321:6;3310:9;3306:22;3288:50;:::i;:::-;3278:60;;3249:95;2958:396;;;;;:::o;3361:366::-;;;3482:2;3470:9;3461:7;3457:23;3453:32;3450:2;;;3498:1;3495;3488:12;3450:2;3533:1;3550:53;3595:7;3586:6;3575:9;3571:22;3550:53;:::i;:::-;3540:63;;3512:97;3640:2;3658:53;3703:7;3694:6;3683:9;3679:22;3658:53;:::i;:::-;3648:63;;3619:98;3444:283;;;;;:::o;3734:491::-;;;;3872:2;3860:9;3851:7;3847:23;3843:32;3840:2;;;3888:1;3885;3878:12;3840:2;3923:1;3940:53;3985:7;3976:6;3965:9;3961:22;3940:53;:::i;:::-;3930:63;;3902:97;4030:2;4048:53;4093:7;4084:6;4073:9;4069:22;4048:53;:::i;:::-;4038:63;;4009:98;4138:2;4156:53;4201:7;4192:6;4181:9;4177:22;4156:53;:::i;:::-;4146:63;;4117:98;3834:391;;;;;:::o;4232:741::-;;;;;;4406:3;4394:9;4385:7;4381:23;4377:33;4374:2;;;4423:1;4420;4413:12;4374:2;4458:1;4475:53;4520:7;4511:6;4500:9;4496:22;4475:53;:::i;:::-;4465:63;;4437:97;4565:2;4583:53;4628:7;4619:6;4608:9;4604:22;4583:53;:::i;:::-;4573:63;;4544:98;4673:2;4691:53;4736:7;4727:6;4716:9;4712:22;4691:53;:::i;:::-;4681:63;;4652:98;4809:2;4798:9;4794:18;4781:32;4833:18;4825:6;4822:30;4819:2;;;4865:1;4862;4855:12;4819:2;4893:64;4949:7;4940:6;4929:9;4925:22;4893:64;:::i;:::-;4875:82;;;;4760:203;4368:605;;;;;;;;:::o;4980:867::-;;;;;;;5171:3;5159:9;5150:7;5146:23;5142:33;5139:2;;;5188:1;5185;5178:12;5139:2;5223:1;5240:53;5285:7;5276:6;5265:9;5261:22;5240:53;:::i;:::-;5230:63;;5202:97;5330:2;5348:53;5393:7;5384:6;5373:9;5369:22;5348:53;:::i;:::-;5338:63;;5309:98;5438:2;5456:53;5501:7;5492:6;5481:9;5477:22;5456:53;:::i;:::-;5446:63;;5417:98;5546:2;5564:53;5609:7;5600:6;5589:9;5585:22;5564:53;:::i;:::-;5554:63;;5525:98;5682:3;5671:9;5667:19;5654:33;5707:18;5699:6;5696:30;5693:2;;;5739:1;5736;5729:12;5693:2;5767:64;5823:7;5814:6;5803:9;5799:22;5767:64;:::i;:::-;5749:82;;;;5633:204;5133:714;;;;;;;;:::o;5854:490::-;;;;5994:2;5982:9;5973:7;5969:23;5965:32;5962:2;;;6010:1;6007;6000:12;5962:2;6045:1;6062:53;6107:7;6098:6;6087:9;6083:22;6062:53;:::i;:::-;6052:63;;6024:97;6180:2;6169:9;6165:18;6152:32;6204:18;6196:6;6193:30;6190:2;;;6236:1;6233;6226:12;6190:2;6264:64;6320:7;6311:6;6300:9;6296:22;6264:64;:::i;:::-;6246:82;;;;6131:203;5956:388;;;;;:::o;6351:366::-;;;6472:2;6460:9;6451:7;6447:23;6443:32;6440:2;;;6488:1;6485;6478:12;6440:2;6523:1;6540:53;6585:7;6576:6;6565:9;6561:22;6540:53;:::i;:::-;6530:63;;6502:97;6630:2;6648:53;6693:7;6684:6;6673:9;6669:22;6648:53;:::i;:::-;6638:63;;6609:98;6434:283;;;;;:::o;6724:235::-;;6825:2;6813:9;6804:7;6800:23;6796:32;6793:2;;;6841:1;6838;6831:12;6793:2;6876:1;6893:50;6935:7;6926:6;6915:9;6911:22;6893:50;:::i;:::-;6883:60;;6855:94;6787:172;;;;:::o;6966:496::-;;;7109:2;7097:9;7088:7;7084:23;7080:32;7077:2;;;7125:1;7122;7115:12;7077:2;7160:1;7177:50;7219:7;7210:6;7199:9;7195:22;7177:50;:::i;:::-;7167:60;;7139:94;7292:2;7281:9;7277:18;7264:32;7316:18;7308:6;7305:30;7302:2;;;7348:1;7345;7338:12;7302:2;7368:78;7438:7;7429:6;7418:9;7414:22;7368:78;:::i;:::-;7358:88;;7243:209;7071:391;;;;;:::o;7469:485::-;;;;7604:2;7592:9;7583:7;7579:23;7575:32;7572:2;;;7620:1;7617;7610:12;7572:2;7655:1;7672:50;7714:7;7705:6;7694:9;7690:22;7672:50;:::i;:::-;7662:60;;7634:94;7759:2;7777:53;7822:7;7813:6;7802:9;7798:22;7777:53;:::i;:::-;7767:63;;7738:98;7867:2;7885:53;7930:7;7921:6;7910:9;7906:22;7885:53;:::i;:::-;7875:63;;7846:98;7566:388;;;;;:::o;7961:239::-;;8064:2;8052:9;8043:7;8039:23;8035:32;8032:2;;;8080:1;8077;8070:12;8032:2;8115:1;8132:52;8176:7;8167:6;8156:9;8152:22;8132:52;:::i;:::-;8122:62;;8094:96;8026:174;;;;:::o;8207:241::-;;8311:2;8299:9;8290:7;8286:23;8282:32;8279:2;;;8327:1;8324;8317:12;8279:2;8362:1;8379:53;8424:7;8415:6;8404:9;8400:22;8379:53;:::i;:::-;8369:63;;8341:97;8273:175;;;;:::o;8455:263::-;;8570:2;8558:9;8549:7;8545:23;8541:32;8538:2;;;8586:1;8583;8576:12;8538:2;8621:1;8638:64;8694:7;8685:6;8674:9;8670:22;8638:64;:::i;:::-;8628:74;;8600:108;8532:186;;;;:::o;8726:173::-;;8813:46;8855:3;8847:6;8813:46;:::i;:::-;8888:4;8883:3;8879:14;8865:28;;8806:93;;;;:::o;8907:142::-;8998:45;9037:5;8998:45;:::i;:::-;8993:3;8986:58;8980:69;;:::o;9056:137::-;9155:32;9181:5;9155:32;:::i;:::-;9150:3;9143:45;9137:56;;:::o;9200:103::-;9273:24;9291:5;9273:24;:::i;:::-;9268:3;9261:37;9255:48;;:::o;9310:113::-;9393:24;9411:5;9393:24;:::i;:::-;9388:3;9381:37;9375:48;;:::o;9461:690::-;;9606:54;9654:5;9606:54;:::i;:::-;9673:86;9752:6;9747:3;9673:86;:::i;:::-;9666:93;;9780:56;9830:5;9780:56;:::i;:::-;9856:7;9884:1;9869:260;9894:6;9891:1;9888:13;9869:260;;;9961:6;9955:13;9982:63;10041:3;10026:13;9982:63;:::i;:::-;9975:70;;10062:60;10115:6;10062:60;:::i;:::-;10052:70;;9926:203;9916:1;9913;9909:9;9904:14;;9869:260;;;9873:14;10142:3;10135:10;;9585:566;;;;;;;:::o;10159:104::-;10236:21;10251:5;10236:21;:::i;:::-;10231:3;10224:34;10218:45;;:::o;10270:110::-;10351:23;10368:5;10351:23;:::i;:::-;10346:3;10339:36;10333:47;;:::o;10410:310::-;;10542:88;10623:6;10618:3;10542:88;:::i;:::-;10535:95;;10642:43;10678:6;10673:3;10666:5;10642:43;:::i;:::-;10707:6;10702:3;10698:16;10691:23;;10528:192;;;;;:::o;10728:347::-;;10840:39;10873:5;10840:39;:::i;:::-;10891:71;10955:6;10950:3;10891:71;:::i;:::-;10884:78;;10967:52;11012:6;11007:3;11000:4;10993:5;10989:16;10967:52;:::i;:::-;11040:29;11062:6;11040:29;:::i;:::-;11035:3;11031:39;11024:46;;10820:255;;;;;:::o;11083:371::-;;11243:67;11307:2;11302:3;11243:67;:::i;:::-;11236:74;;11343:34;11339:1;11334:3;11330:11;11323:55;11412:4;11407:2;11402:3;11398:12;11391:26;11445:2;11440:3;11436:12;11429:19;;11229:225;;;:::o;11463:372::-;;11623:67;11687:2;11682:3;11623:67;:::i;:::-;11616:74;;11723:34;11719:1;11714:3;11710:11;11703:55;11792:5;11787:2;11782:3;11778:12;11771:27;11826:2;11821:3;11817:12;11810:19;;11609:226;;;:::o;11844:331::-;;12004:67;12068:2;12063:3;12004:67;:::i;:::-;11997:74;;12104:33;12100:1;12095:3;12091:11;12084:54;12166:2;12161:3;12157:12;12150:19;;11990:185;;;:::o;12184:375::-;;12344:67;12408:2;12403:3;12344:67;:::i;:::-;12337:74;;12444:34;12440:1;12435:3;12431:11;12424:55;12513:8;12508:2;12503:3;12499:12;12492:30;12550:2;12545:3;12541:12;12534:19;;12330:229;;;:::o;12568:371::-;;12728:67;12792:2;12787:3;12728:67;:::i;:::-;12721:74;;12828:34;12824:1;12819:3;12815:11;12808:55;12897:4;12892:2;12887:3;12883:12;12876:26;12930:2;12925:3;12921:12;12914:19;;12714:225;;;:::o;12948:327::-;;13108:67;13172:2;13167:3;13108:67;:::i;:::-;13101:74;;13208:29;13204:1;13199:3;13195:11;13188:50;13266:2;13261:3;13257:12;13250:19;;13094:181;;;:::o;13284:313::-;;13444:67;13508:2;13503:3;13444:67;:::i;:::-;13437:74;;13544:15;13540:1;13535:3;13531:11;13524:36;13588:2;13583:3;13579:12;13572:19;;13430:167;;;:::o;13606:375::-;;13766:67;13830:2;13825:3;13766:67;:::i;:::-;13759:74;;13866:34;13862:1;13857:3;13853:11;13846:55;13935:8;13930:2;13925:3;13921:12;13914:30;13972:2;13967:3;13963:12;13956:19;;13752:229;;;:::o;13990:315::-;;14150:67;14214:2;14209:3;14150:67;:::i;:::-;14143:74;;14250:17;14246:1;14241:3;14237:11;14230:38;14296:2;14291:3;14287:12;14280:19;;14136:169;;;:::o;14314:395::-;;14474:67;14538:2;14533:3;14474:67;:::i;:::-;14467:74;;14574:34;14570:1;14565:3;14561:11;14554:55;14643:28;14638:2;14633:3;14629:12;14622:50;14700:2;14695:3;14691:12;14684:19;;14460:249;;;:::o;14718:329::-;;14878:67;14942:2;14937:3;14878:67;:::i;:::-;14871:74;;14978:31;14974:1;14969:3;14965:11;14958:52;15038:2;15033:3;15029:12;15022:19;;14864:183;;;:::o;15056:323::-;;15216:67;15280:2;15275:3;15216:67;:::i;:::-;15209:74;;15316:25;15312:1;15307:3;15303:11;15296:46;15370:2;15365:3;15361:12;15354:19;;15202:177;;;:::o;15388:332::-;;15548:67;15612:2;15607:3;15548:67;:::i;:::-;15541:74;;15648:34;15644:1;15639:3;15635:11;15628:55;15711:2;15706:3;15702:12;15695:19;;15534:186;;;:::o;15729:370::-;;15889:67;15953:2;15948:3;15889:67;:::i;:::-;15882:74;;15989:34;15985:1;15980:3;15976:11;15969:55;16058:3;16053:2;16048:3;16044:12;16037:25;16090:2;16085:3;16081:12;16074:19;;15875:224;;;:::o;16108:374::-;;16268:67;16332:2;16327:3;16268:67;:::i;:::-;16261:74;;16368:34;16364:1;16359:3;16355:11;16348:55;16437:7;16432:2;16427:3;16423:12;16416:29;16473:2;16468:3;16464:12;16457:19;;16254:228;;;:::o;16491:260::-;;16650:65;16713:1;16708:3;16650:65;:::i;:::-;16643:72;;16743:1;16738:3;16734:11;16727:18;;16636:115;;;:::o;16760:296::-;;16937:83;17018:1;17013:3;16937:83;:::i;:::-;16930:90;;17048:1;17043:3;17039:11;17032:18;;16923:133;;;:::o;17065:373::-;;17225:67;17289:2;17284:3;17225:67;:::i;:::-;17218:74;;17325:34;17321:1;17316:3;17312:11;17305:55;17394:6;17389:2;17384:3;17380:12;17373:28;17429:2;17424:3;17420:12;17413:19;;17211:227;;;:::o;17447:318::-;;17607:67;17671:2;17666:3;17607:67;:::i;:::-;17600:74;;17707:20;17703:1;17698:3;17694:11;17687:41;17756:2;17751:3;17747:12;17740:19;;17593:172;;;:::o;17774:328::-;;17934:67;17998:2;17993:3;17934:67;:::i;:::-;17927:74;;18034:30;18030:1;18025:3;18021:11;18014:51;18093:2;18088:3;18084:12;18077:19;;17920:182;;;:::o;18111:319::-;;18271:67;18335:2;18330:3;18271:67;:::i;:::-;18264:74;;18371:21;18367:1;18362:3;18358:11;18351:42;18421:2;18416:3;18412:12;18405:19;;18257:173;;;:::o;18439:331::-;;18599:67;18663:2;18658:3;18599:67;:::i;:::-;18592:74;;18699:33;18695:1;18690:3;18686:11;18679:54;18761:2;18756:3;18752:12;18745:19;;18585:185;;;:::o;18779:324::-;;18939:67;19003:2;18998:3;18939:67;:::i;:::-;18932:74;;19039:26;19035:1;19030:3;19026:11;19019:47;19094:2;19089:3;19085:12;19078:19;;18925:178;;;:::o;19111:113::-;19194:24;19212:5;19194:24;:::i;:::-;19189:3;19182:37;19176:48;;:::o;19231:107::-;19310:22;19326:5;19310:22;:::i;:::-;19305:3;19298:35;19292:46;;:::o;19345:291::-;;19508:103;19607:3;19598:6;19590;19508:103;:::i;:::-;19501:110;;19628:3;19621:10;;19489:147;;;;;:::o;19643:379::-;;19850:147;19993:3;19850:147;:::i;:::-;19843:154;;20014:3;20007:10;;19831:191;;;:::o;20029:222::-;;20156:2;20145:9;20141:18;20133:26;;20170:71;20238:1;20227:9;20223:17;20214:6;20170:71;:::i;:::-;20127:124;;;;:::o;20258:238::-;;20393:2;20382:9;20378:18;20370:26;;20407:79;20483:1;20472:9;20468:17;20459:6;20407:79;:::i;:::-;20364:132;;;;:::o;20503:254::-;;20646:2;20635:9;20631:18;20623:26;;20660:87;20744:1;20733:9;20729:17;20720:6;20660:87;:::i;:::-;20617:140;;;;:::o;20764:444::-;;20947:2;20936:9;20932:18;20924:26;;20961:71;21029:1;21018:9;21014:17;21005:6;20961:71;:::i;:::-;21043:72;21111:2;21100:9;21096:18;21087:6;21043:72;:::i;:::-;21126;21194:2;21183:9;21179:18;21170:6;21126:72;:::i;:::-;20918:290;;;;;;:::o;21215:556::-;;21426:3;21415:9;21411:19;21403:27;;21441:71;21509:1;21498:9;21494:17;21485:6;21441:71;:::i;:::-;21523:72;21591:2;21580:9;21576:18;21567:6;21523:72;:::i;:::-;21606;21674:2;21663:9;21659:18;21650:6;21606:72;:::i;:::-;21689;21757:2;21746:9;21742:18;21733:6;21689:72;:::i;:::-;21397:374;;;;;;;:::o;21778:860::-;;22089:3;22078:9;22074:19;22066:27;;22104:71;22172:1;22161:9;22157:17;22148:6;22104:71;:::i;:::-;22186:72;22254:2;22243:9;22239:18;22230:6;22186:72;:::i;:::-;22269;22337:2;22326:9;22322:18;22313:6;22269:72;:::i;:::-;22352;22420:2;22409:9;22405:18;22396:6;22352:72;:::i;:::-;22473:9;22467:4;22463:20;22457:3;22446:9;22442:19;22435:49;22498:130;22623:4;22498:130;:::i;:::-;22490:138;;22060:578;;;;;;;:::o;22645:333::-;;22800:2;22789:9;22785:18;22777:26;;22814:71;22882:1;22871:9;22867:17;22858:6;22814:71;:::i;:::-;22896:72;22964:2;22953:9;22949:18;22940:6;22896:72;:::i;:::-;22771:207;;;;;:::o;22985:370::-;;23162:2;23151:9;23147:18;23139:26;;23212:9;23206:4;23202:20;23198:1;23187:9;23183:17;23176:47;23237:108;23340:4;23331:6;23237:108;:::i;:::-;23229:116;;23133:222;;;;:::o;23362:210::-;;23483:2;23472:9;23468:18;23460:26;;23497:65;23559:1;23548:9;23544:17;23535:6;23497:65;:::i;:::-;23454:118;;;;:::o;23579:218::-;;23704:2;23693:9;23689:18;23681:26;;23718:69;23784:1;23773:9;23769:17;23760:6;23718:69;:::i;:::-;23675:122;;;;:::o;23804:310::-;;23951:2;23940:9;23936:18;23928:26;;24001:9;23995:4;23991:20;23987:1;23976:9;23972:17;23965:47;24026:78;24099:4;24090:6;24026:78;:::i;:::-;24018:86;;23922:192;;;;:::o;24121:416::-;;24321:2;24310:9;24306:18;24298:26;;24371:9;24365:4;24361:20;24357:1;24346:9;24342:17;24335:47;24396:131;24522:4;24396:131;:::i;:::-;24388:139;;24292:245;;;:::o;24544:416::-;;24744:2;24733:9;24729:18;24721:26;;24794:9;24788:4;24784:20;24780:1;24769:9;24765:17;24758:47;24819:131;24945:4;24819:131;:::i;:::-;24811:139;;24715:245;;;:::o;24967:416::-;;25167:2;25156:9;25152:18;25144:26;;25217:9;25211:4;25207:20;25203:1;25192:9;25188:17;25181:47;25242:131;25368:4;25242:131;:::i;:::-;25234:139;;25138:245;;;:::o;25390:416::-;;25590:2;25579:9;25575:18;25567:26;;25640:9;25634:4;25630:20;25626:1;25615:9;25611:17;25604:47;25665:131;25791:4;25665:131;:::i;:::-;25657:139;;25561:245;;;:::o;25813:416::-;;26013:2;26002:9;25998:18;25990:26;;26063:9;26057:4;26053:20;26049:1;26038:9;26034:17;26027:47;26088:131;26214:4;26088:131;:::i;:::-;26080:139;;25984:245;;;:::o;26236:416::-;;26436:2;26425:9;26421:18;26413:26;;26486:9;26480:4;26476:20;26472:1;26461:9;26457:17;26450:47;26511:131;26637:4;26511:131;:::i;:::-;26503:139;;26407:245;;;:::o;26659:416::-;;26859:2;26848:9;26844:18;26836:26;;26909:9;26903:4;26899:20;26895:1;26884:9;26880:17;26873:47;26934:131;27060:4;26934:131;:::i;:::-;26926:139;;26830:245;;;:::o;27082:416::-;;27282:2;27271:9;27267:18;27259:26;;27332:9;27326:4;27322:20;27318:1;27307:9;27303:17;27296:47;27357:131;27483:4;27357:131;:::i;:::-;27349:139;;27253:245;;;:::o;27505:416::-;;27705:2;27694:9;27690:18;27682:26;;27755:9;27749:4;27745:20;27741:1;27730:9;27726:17;27719:47;27780:131;27906:4;27780:131;:::i;:::-;27772:139;;27676:245;;;:::o;27928:416::-;;28128:2;28117:9;28113:18;28105:26;;28178:9;28172:4;28168:20;28164:1;28153:9;28149:17;28142:47;28203:131;28329:4;28203:131;:::i;:::-;28195:139;;28099:245;;;:::o;28351:416::-;;28551:2;28540:9;28536:18;28528:26;;28601:9;28595:4;28591:20;28587:1;28576:9;28572:17;28565:47;28626:131;28752:4;28626:131;:::i;:::-;28618:139;;28522:245;;;:::o;28774:416::-;;28974:2;28963:9;28959:18;28951:26;;29024:9;29018:4;29014:20;29010:1;28999:9;28995:17;28988:47;29049:131;29175:4;29049:131;:::i;:::-;29041:139;;28945:245;;;:::o;29197:416::-;;29397:2;29386:9;29382:18;29374:26;;29447:9;29441:4;29437:20;29433:1;29422:9;29418:17;29411:47;29472:131;29598:4;29472:131;:::i;:::-;29464:139;;29368:245;;;:::o;29620:416::-;;29820:2;29809:9;29805:18;29797:26;;29870:9;29864:4;29860:20;29856:1;29845:9;29841:17;29834:47;29895:131;30021:4;29895:131;:::i;:::-;29887:139;;29791:245;;;:::o;30043:416::-;;30243:2;30232:9;30228:18;30220:26;;30293:9;30287:4;30283:20;30279:1;30268:9;30264:17;30257:47;30318:131;30444:4;30318:131;:::i;:::-;30310:139;;30214:245;;;:::o;30466:416::-;;30666:2;30655:9;30651:18;30643:26;;30716:9;30710:4;30706:20;30702:1;30691:9;30687:17;30680:47;30741:131;30867:4;30741:131;:::i;:::-;30733:139;;30637:245;;;:::o;30889:416::-;;31089:2;31078:9;31074:18;31066:26;;31139:9;31133:4;31129:20;31125:1;31114:9;31110:17;31103:47;31164:131;31290:4;31164:131;:::i;:::-;31156:139;;31060:245;;;:::o;31312:416::-;;31512:2;31501:9;31497:18;31489:26;;31562:9;31556:4;31552:20;31548:1;31537:9;31533:17;31526:47;31587:131;31713:4;31587:131;:::i;:::-;31579:139;;31483:245;;;:::o;31735:416::-;;31935:2;31924:9;31920:18;31912:26;;31985:9;31979:4;31975:20;31971:1;31960:9;31956:17;31949:47;32010:131;32136:4;32010:131;:::i;:::-;32002:139;;31906:245;;;:::o;32158:416::-;;32358:2;32347:9;32343:18;32335:26;;32408:9;32402:4;32398:20;32394:1;32383:9;32379:17;32372:47;32433:131;32559:4;32433:131;:::i;:::-;32425:139;;32329:245;;;:::o;32581:416::-;;32781:2;32770:9;32766:18;32758:26;;32831:9;32825:4;32821:20;32817:1;32806:9;32802:17;32795:47;32856:131;32982:4;32856:131;:::i;:::-;32848:139;;32752:245;;;:::o;33004:222::-;;33131:2;33120:9;33116:18;33108:26;;33145:71;33213:1;33202:9;33198:17;33189:6;33145:71;:::i;:::-;33102:124;;;;:::o;33233:214::-;;33356:2;33345:9;33341:18;33333:26;;33370:67;33434:1;33423:9;33419:17;33410:6;33370:67;:::i;:::-;33327:120;;;;:::o;33454:256::-;;33516:2;33510:9;33500:19;;33554:4;33546:6;33542:17;33653:6;33641:10;33638:22;33617:18;33605:10;33602:34;33599:62;33596:2;;;33674:1;33671;33664:12;33596:2;33694:10;33690:2;33683:22;33494:216;;;;:::o;33717:304::-;;33876:18;33868:6;33865:30;33862:2;;;33908:1;33905;33898:12;33862:2;33943:4;33935:6;33931:17;33923:25;;34006:4;34000;33996:15;33988:23;;33799:222;;;:::o;34028:151::-;;34114:3;34106:11;;34152:4;34147:3;34143:14;34135:22;;34100:79;;;:::o;34186:137::-;;34295:5;34289:12;34279:22;;34260:63;;;:::o;34330:122::-;;34424:5;34418:12;34408:22;;34389:63;;;:::o;34459:108::-;;34557:4;34552:3;34548:14;34540:22;;34534:33;;;:::o;34575:178::-;;34705:6;34700:3;34693:19;34742:4;34737:3;34733:14;34718:29;;34686:67;;;;:::o;34762:162::-;;34876:6;34871:3;34864:19;34913:4;34908:3;34904:14;34889:29;;34857:67;;;;:::o;34933:144::-;;35068:3;35053:18;;35046:31;;;;:::o;35086:163::-;;35201:6;35196:3;35189:19;35238:4;35233:3;35229:14;35214:29;;35182:67;;;;:::o;35257:91::-;;35319:24;35337:5;35319:24;:::i;:::-;35308:35;;35302:46;;;:::o;35355:99::-;;35425:24;35443:5;35425:24;:::i;:::-;35414:35;;35408:46;;;:::o;35461:85::-;;35534:5;35527:13;35520:21;35509:32;;35503:43;;;:::o;35553:144::-;;35625:66;35618:5;35614:78;35603:89;;35597:100;;;:::o;35704:121::-;;35777:42;35770:5;35766:54;35755:65;;35749:76;;;:::o;35832:72::-;;35894:5;35883:16;;35877:27;;;:::o;35911:81::-;;35982:4;35975:5;35971:16;35960:27;;35954:38;;;:::o;35999:129::-;;36086:37;36117:5;36086:37;:::i;:::-;36073:50;;36067:61;;;:::o;36135:121::-;;36214:37;36245:5;36214:37;:::i;:::-;36201:50;;36195:61;;;:::o;36263:108::-;;36342:24;36360:5;36342:24;:::i;:::-;36329:37;;36323:48;;;:::o;36379:145::-;36460:6;36455:3;36450;36437:30;36516:1;36507:6;36502:3;36498:16;36491:27;36430:94;;;:::o;36533:268::-;36598:1;36605:101;36619:6;36616:1;36613:13;36605:101;;;36695:1;36690:3;36686:11;36680:18;36676:1;36671:3;36667:11;36660:39;36641:2;36638:1;36634:10;36629:15;;36605:101;;;36721:6;36718:1;36715:13;36712:2;;;36786:1;36777:6;36772:3;36768:16;36761:27;36712:2;36582:219;;;;:::o;36809:97::-;;36897:2;36893:7;36888:2;36881:5;36877:14;36873:28;36863:38;;36857:49;;;:::o;36914:117::-;36983:24;37001:5;36983:24;:::i;:::-;36976:5;36973:35;36963:2;;37022:1;37019;37012:12;36963:2;36957:74;:::o;37038:133::-;37115:32;37141:5;37115:32;:::i;:::-;37108:5;37105:43;37095:2;;37162:1;37159;37152:12;37095:2;37089:82;:::o;37178:111::-;37244:21;37259:5;37244:21;:::i;:::-;37237:5;37234:32;37224:2;;37280:1;37277;37270:12;37224:2;37218:71;:::o;37296:115::-;37364:23;37381:5;37364:23;:::i;:::-;37357:5;37354:34;37344:2;;37402:1;37399;37392:12;37344:2;37338:73;:::o;37418:117::-;37487:24;37505:5;37487:24;:::i;:::-;37480:5;37477:35;37467:2;;37526:1;37523;37516:12;37467:2;37461:74;:::o

Swarm Source

ipfs://947b70cfbc59b728805502922039bb205ae10e55fd11ff4a8ee87f48542cd31f
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ 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.