Token Maniatic

 

Overview

TokenID:
2

Transfers:
-

 
Loading
[ Download CSV Export  ] 
Loading
Loading

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

Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0x6c95EE9e37ce4a208d4061ec28FE0baf6f9672A8

Contract Name:
ERC721Matcha

Compiler Version
v0.5.7+commit.6da8b019

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

// File: contracts/Flattened-NFTMatcha-v0.5.7.sol

/**

MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMWWWWWWWWWWWWWWWMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMWWNXXKKKKKKKXXXXKKKKKKXXNWWMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMWNXKKKKXXNWWWWMMWWWWMWWWWNXXXKKKXNWMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMWNXKKKXNWMMMMMMMMMNOdxKWMMMMMMMMWNXKKKXNWMMMMMMMMMMMMMM
MMMMMMMMMMMMMWXKKKNWMMMMMMMMMMMMNx:;;l0WMMMMMMMMMMMWNK0KXWMMMMMMMMMMMM
MMMMMMMMMMMWXKKXWMMMMMMMMMMMMMMXd:;;;;cOWMMMMMMMMMMMMMWXKKXWMMMMMMMMMM
MMMMMMMMMWNKKXWMMMMMMMMMMMMMMWKo;;col:;:kNMMMMMMMMMMMMMMWX0KNWMMMMMMMM
MMMMMMMMWX0XWMMMMMMMMMMMMMMMWOl;;oKWXkc;:dXMMMMMMMMMMMMMMMWX0XWMMMMMMM
MMMMMMMNKKNWMMMMMMMMMMMMMMMNkc;:dXMMMWOc;;oKWMMMMMMMMMMMMMMWNKKNMMMMMM
MMMMMMNKKNMMMMMMMMMMMMMMMMNx:;:xNMMMMMW0l;;l0WMMMMMMMWMMMMMMMNKKNMMMMM
MMMMMNKKNMMMMMMMMMMMMMMMMXd:;ckNMMMMMMMMKo:;cOWMMMMXkxkXWMMMMMNKKNMMMM
MMMMWK0NMMMMMMMMMMMMMMMWKo;;l0WMMMMMMMMMMXx:;:xNMMW0lccxXMMMMMMN0KWMMM
MMMMX0XWMMMMMMWWMMMMMMWOl;;oKWMMMMMMMMMMMMNkc;:dXMMNklcoKMMMMMMMX0XMMM
MMMWKKNMMWK0OkkkkkkKWNkc;:dXMMMMMMMMMMMMMMMWOl;;oKWMXdcxNMMMMMMMNKKWMM
MMMN0XWMMWNXX0OdlccdKOc;:xNMMMWXKKXNWNNNNWWMW0o;;l0WNkdKWMMMMMMMWX0NMM
MMMX0XMMMMMMMMMN0dlcdOxoONMMMMW0xdddddodxk0KNWXd:;l0Kx0WMMMMMMMMMX0XMM
MMMX0NMMMMMMMMMMWXxlcoOXWMMMMWKkolclodkKNNNNWWMNxcxOkKWMMMMMMMMMMX0XMM
MMMX0XMMMMMMMMMMMMNklclkNMMWXklccodxdodKWMMMMMMMNKOkKWMMMMMMMMMMMX0XMM
MMMN0XWMMMMMMMMMMMMNOoclxXN0occcdKX0xlco0WMMMMMMNOOXMMMMMMMMMMMMMX0NMM
MMMWKKWMMMMMMMMMMMMMW0dccoxocccdKWMWNklclONMMMMXOONMMMMMMMMMMMMMWKKWMM
MMMMX0XMMMMMMMMMMMMMMWKdcccccco0WMMMMNOoclkNWWKk0NMMMMMMMMMMMMMMX0XWMM
MMMMWKKNMMMMMMMMMMMMMMMXxlcccckNMMMMMMW0oclxK0kKWMMMMMMMMMMMMMMNKKWMMM
MMMMMN0KWMMMMMMMMMMMMMMMNklccoKWMMMMMMMWKdlcoxKWMMMMMMMMMMMMMMWK0NMMMM
MMMMMMN0KWMMMMMMMMMMMMMMMNOod0KXWMMMMMMNK0xoxXWMMMMMMMMMMMMMMWK0NMMMMM
MMMMMMMN0KNMMMMMMMMMMMMMMMWXKkll0WMMMMXdcoOKNMMMMMMMMMMMMMMMNK0NMMMMMM
MMMMMMMMNK0XWMMMMMMMMMMMMMMMNd:;cOWMWKo:;c0WMMMMMMMMMMMMMMWX0KNMMMMMMM
MMMMMMMMMWXKKNWMMMMMMMMMMMMMMXd:;cx0kl;;l0WMMMMMMMMMMMMMWNKKXWMMMMMMMM
MMMMMMMMMMMWX0KNWMMMMMMMMMMMMMNkc;;::;:oKWMMMMMMMMMMMMWNK0XWMMMMMMMMMM
MMMMMMMMMMMMMNXKKXNWMMMMMMMMMMMWOc;;;:dXMMMMMMMMMMMWNXKKXWMMMMMMMMMMMM
MMMMMMMMMMMMMMMWNKKKXNWMMMMMMMMMW0l:ckNMMMMMMMMMWNXKKKNWMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMWNXKKKXXNWWWMMMMX0KWMMMWWWNXXKKKXNWMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMWWNXXKKKKKXXXXXXXXXXKKKKXXNWWMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMWWNNNNNNNNNNNNWWWMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM


---------------------- [ WPSmartContracts.com ] ----------------------

                       [ Blockchain Made Easy ]


    |
    |  ERC-721 NFT Marketplace
    |
    |----------------------------
    |
    |  Flavors
    |
    |  >  Matcha: Fully featured ERC-721 Token, with Buy, 
    |     Sell and Auction NFT Marketplace
    |


*/

pragma solidity ^0.5.7;

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

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
contract IERC721 is IERC165 {
    event Transfer(
        address indexed from,
        address indexed to,
        uint256 indexed tokenId
    );
    event Approval(
        address indexed owner,
        address indexed approved,
        uint256 indexed tokenId
    );
    event ApprovalForAll(
        address indexed owner,
        address indexed operator,
        bool approved
    );

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

    /**
     * @dev Returns the owner of the NFT specified by `tokenId`.
     */
    function ownerOf(uint256 tokenId) public view returns (address owner);

    /**
     * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
     * another (`to`).
     *
     *
     *
     * Requirements:
     * - `from`, `to` cannot be zero.
     * - `tokenId` must be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this
     * NFT by either {approve} or {setApproveForAll}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public;

    /**
     * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
     * another (`to`).
     *
     * Requirements:
     * - If the caller is not `from`, it must be approved to move this NFT by
     * either {approve} or {setApproveForAll}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public;

    function approve(address to, uint256 tokenId) public;

    function getApproved(uint256 tokenId)
        public
        view
        returns (address operator);

    function setApprovalForAll(address operator, bool _approved) public;

    function isApprovedForAll(address owner, address operator)
        public
        view
        returns (bool);

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) public;
}

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
contract IERC721Receiver {
    /**
     * @notice Handle the receipt of an NFT
     * @dev The ERC721 smart contract calls this function on the recipient
     * after a {IERC721-safeTransfer}. This function MUST return the function selector,
     * otherwise the caller will revert the transaction. The selector to be
     * returned can be obtained as `this.onERC721Received.selector`. This
     * function MAY throw to revert and reject the transfer.
     * Note: the ERC721 contract address is always the message sender.
     * @param operator The address which called `safeTransferFrom` function
     * @param from The address which previously owned the token
     * @param tokenId The NFT identifier which is being transferred
     * @param data Additional data with no specified format
     * @return bytes4 `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes memory data
    ) public returns (bytes4);
}

/**
 * @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) {
        require(b <= a, "SafeMath: subtraction overflow");
        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-solidity/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) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, "SafeMath: division by zero");
        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) {
        require(b != 0, "SafeMath: modulo by zero");
        return a % b;
    }
}

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

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

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

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}
 * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never
 * directly accessed.
 */
library Counters {
    using SafeMath for uint256;

    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

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

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

    function decrement(Counter storage counter) internal {
        counter._value = counter._value.sub(1);
    }
}

/**
 * @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)
        external
        view
        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 {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

/**
 * @title ERC721 Non-Fungible Token Standard basic implementation
 * @dev see https://eips.ethereum.org/EIPS/eip-721
 */
contract ERC721 is ERC165, IERC721 {
    using SafeMath for uint256;
    using Address for address;
    using Counters for Counters.Counter;

    // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
    bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;

    // Mapping from token ID to owner
    mapping(uint256 => address) private _tokenOwner;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to number of owned token
    mapping(address => Counters.Counter) private _ownedTokensCount;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    /*
     *     bytes4(keccak256('balanceOf(address)')) == 0x70a08231
     *     bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
     *     bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
     *     bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
     *     bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
     *
     *     => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
     *        0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
     */
    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;

    constructor() public {
        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721);
    }

    /**
     * @dev Gets the balance of the specified address.
     * @param owner address to query the balance of
     * @return uint256 representing the amount owned by the passed address
     */
    function balanceOf(address owner) public view returns (uint256) {
        require(
            owner != address(0),
            "ERC721: balance query for the zero address"
        );

        return _ownedTokensCount[owner].current();
    }

    /**
     * @dev Gets the owner of the specified token ID.
     * @param tokenId uint256 ID of the token to query the owner of
     * @return address currently marked as the owner of the given token ID
     */
    function ownerOf(uint256 tokenId) public view returns (address) {
        address owner = _tokenOwner[tokenId];
        require(
            owner != address(0),
            "ERC721: owner query for nonexistent token"
        );

        return owner;
    }

    /**
     * @dev Approves another address to transfer the given token ID
     * The zero address indicates there is no approved address.
     * There can only be one approved address per token at a given time.
     * Can only be called by the token owner or an approved operator.
     * @param to address to be approved for the given token ID
     * @param tokenId uint256 ID of the token to be approved
     */
    function approve(address to, uint256 tokenId) public {
        address owner = ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            msg.sender == owner || isApprovedForAll(owner, msg.sender),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev Gets the approved address for a token ID, or zero if no address set
     * Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token to query the approval of
     * @return address currently approved for the given token ID
     */
    function getApproved(uint256 tokenId) public view returns (address) {
        require(
            _exists(tokenId),
            "ERC721: approved query for nonexistent token"
        );

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev Sets or unsets the approval of a given operator
     * An operator is allowed to transfer all tokens of the sender on their behalf.
     * @param to operator address to set the approval
     * @param approved representing the status of the approval to be set
     */
    function setApprovalForAll(address to, bool approved) public {
        require(to != msg.sender, "ERC721: approve to caller");

        _operatorApprovals[msg.sender][to] = approved;
        emit ApprovalForAll(msg.sender, to, approved);
    }

    /**
     * @dev Tells whether an operator is approved by a given owner.
     * @param owner owner address which you want to query the approval of
     * @param operator operator address which you want to query the approval of
     * @return bool whether the given operator is approved by the given owner
     */
    function isApprovedForAll(address owner, address operator)
        public
        view
        returns (bool)
    {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev Transfers the ownership of a given token ID to another address.
     * Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     * Requires the msg.sender to be the owner, approved, or operator.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public {
        //solhint-disable-next-line max-line-length
        require(
            _isApprovedOrOwner(msg.sender, tokenId),
            "ERC721: transfer caller is not owner nor approved"
        );

        _transferFrom(from, to, tokenId);
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement {IERC721Receiver-onERC721Received},
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the msg.sender to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement {IERC721Receiver-onERC721Received},
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the msg.sender to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes data to send along with a safe transfer check
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public {
        transferFrom(from, to, tokenId);
        require(
            _checkOnERC721Received(from, to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Returns whether the specified token exists.
     * @param tokenId uint256 ID of the token to query the existence of
     * @return bool whether the token exists
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        address owner = _tokenOwner[tokenId];
        return owner != address(0);
    }

    /**
     * @dev Returns whether the given spender can transfer a given token ID.
     * @param spender address of the spender to query
     * @param tokenId uint256 ID of the token to be transferred
     * @return bool whether the msg.sender is approved for the given token ID,
     * is an operator of the owner, or is the owner of the token
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId)
        internal
        view
        returns (bool)
    {
        require(
            _exists(tokenId),
            "ERC721: operator query for nonexistent token"
        );
        address owner = ownerOf(tokenId);
        return (spender == owner ||
            getApproved(tokenId) == spender ||
            isApprovedForAll(owner, spender));
    }

    /**
     * @dev Internal function to mint a new token.
     * Reverts if the given token ID already exists.
     * @param to The address that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     */
    function _mint(address to, uint256 tokenId) internal {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _tokenOwner[tokenId] = to;
        _ownedTokensCount[to].increment();

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Internal function to transfer ownership of a given token ID to another address.
     * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) internal {
        require(
            ownerOf(tokenId) == from,
            "ERC721: transfer of token that is not own"
        );
        require(to != address(0), "ERC721: transfer to the zero address");

        _clearApproval(tokenId);

        _ownedTokensCount[from].decrement();
        _ownedTokensCount[to].increment();

        _tokenOwner[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * This function is deprecated.
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal returns (bool) {
        if (!to.isContract()) {
            return true;
        }

        bytes4 retval =
            IERC721Receiver(to).onERC721Received(
                msg.sender,
                from,
                tokenId,
                _data
            );
        return (retval == _ERC721_RECEIVED);
    }

    /**
     * @dev Private function to clear current approval of a given token ID.
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _clearApproval(uint256 tokenId) private {
        if (_tokenApprovals[tokenId] != address(0)) {
            _tokenApprovals[tokenId] = address(0);
        }
    }
}

/**
 * @title Roles
 * @dev Library for managing addresses assigned to a Role.
 */
library Roles {
    struct Role {
        mapping(address => bool) bearer;
    }

    /**
     * @dev Give an account access to this role.
     */
    function add(Role storage role, address account) internal {
        require(!has(role, account), "Roles: account already has role");
        role.bearer[account] = true;
    }

    /**
     * @dev Remove an account's access to this role.
     */
    function remove(Role storage role, address account) internal {
        require(has(role, account), "Roles: account does not have role");
        role.bearer[account] = false;
    }

    /**
     * @dev Check if an account has this role.
     * @return bool
     */
    function has(Role storage role, address account)
        internal
        view
        returns (bool)
    {
        require(account != address(0), "Roles: account is the zero address");
        return role.bearer[account];
    }
}

contract MinterRole {
    using Roles for Roles.Role;

    event MinterAdded(address indexed account);
    event MinterRemoved(address indexed account);

    Roles.Role private _minters;

    constructor() internal {
        _addMinter(msg.sender);
    }

    modifier onlyMinter() {
        require(
            isMinter(msg.sender),
            "MinterRole: caller does not have the Minter role"
        );
        _;
    }

    function isMinter(address account) public view returns (bool) {
        return _minters.has(account);
    }

    function addMinter(address account) public onlyMinter {
        _addMinter(account);
    }

    function renounceMinter() public {
        _removeMinter(msg.sender);
    }

    function _addMinter(address account) internal {
        _minters.add(account);
        emit MinterAdded(account);
    }

    function _removeMinter(address account) internal {
        _minters.remove(account);
        emit MinterRemoved(account);
    }
}

/**
 * @title ERC721Mintable
 * @dev ERC721 minting logic.
 */
contract ERC721Mintable is ERC721, MinterRole {

    bool public anyoneCanMint;
    
    /**
     * @dev Options to activate or deactivate mint ability
     */

    function _setMintableOption(bool _anyoneCanMint) internal {
        anyoneCanMint = _anyoneCanMint;
    }

    /**
     * @dev Function to mint tokens.
     * @param to The address that will receive the minted tokens.
     * @param tokenId The token id to mint.
     * @return A boolean that indicates if the operation was successful.
     */
    function mint(address to, uint256 tokenId)
        public
        onlyMinter
        returns (bool)
    {
        _mint(to, tokenId);
        return true;
    }

    function canIMint() public view returns (bool) {
        return anyoneCanMint || isMinter(msg.sender);
    }

    /**
     * Open modifier to anyone can mint possibility
     */
    modifier onlyMinter() {
        string memory mensaje;
        require(
            canIMint(),
            "MinterRole: caller does not have the Minter role"
        );
        _;
    }

}

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
contract IERC721Enumerable is IERC721 {
    function totalSupply() public view returns (uint256);
    function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256 tokenId);

    function tokenByIndex(uint256 index) public view returns (uint256);
}

/**
 * @title ERC-721 Non-Fungible Token with optional enumeration extension logic
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
contract ERC721Enumerable is ERC165, ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => uint256[]) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

    /*
     *     bytes4(keccak256('totalSupply()')) == 0x18160ddd
     *     bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
     *     bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
     *
     *     => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
     */
    bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;

    /**
     * @dev Constructor function.
     */
    constructor () public {
        // register the supported interface to conform to ERC721Enumerable via ERC165
        _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
    }

    /**
     * @dev Gets the token ID at a given index of the tokens list of the requested owner.
     * @param owner address owning the tokens list to be accessed
     * @param index uint256 representing the index to be accessed of the requested tokens list
     * @return uint256 token ID at the given index of the tokens list owned by the requested address
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) {
        require(index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev Gets the total amount of tokens stored by the contract.
     * @return uint256 representing the total amount of tokens
     */
    function totalSupply() public view returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev Gets the token ID at a given index of all the tokens in this contract
     * Reverts if the index is greater or equal to the total number of tokens.
     * @param index uint256 representing the index to be accessed of the tokens list
     * @return uint256 token ID at the given index of the tokens list
     */
    function tokenByIndex(uint256 index) public view returns (uint256) {
        require(index < totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @dev Internal function to transfer ownership of a given token ID to another address.
     * As opposed to transferFrom, this imposes no restrictions on msg.sender.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _transferFrom(address from, address to, uint256 tokenId) internal {
        super._transferFrom(from, to, tokenId);

        _removeTokenFromOwnerEnumeration(from, tokenId);

        _addTokenToOwnerEnumeration(to, tokenId);
    }

    /**
     * @dev Internal function to mint a new token.
     * Reverts if the given token ID already exists.
     * @param to address the beneficiary that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     */
    function _mint(address to, uint256 tokenId) internal {
        super._mint(to, tokenId);

        _addTokenToOwnerEnumeration(to, tokenId);

        _addTokenToAllTokensEnumeration(tokenId);
    }

    /**
     * @dev Gets the list of token IDs of the requested owner.
     * @param owner address owning the tokens
     * @return uint256[] List of token IDs owned by the requested address
     */
    function _tokensOfOwner(address owner) internal view returns (uint256[] storage) {
        return _ownedTokens[owner];
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        _ownedTokensIndex[tokenId] = _ownedTokens[to].length;
        _ownedTokens[to].push(tokenId);
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _ownedTokens[from].length.sub(1);
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        _ownedTokens[from].length--;

        // Note that _ownedTokensIndex[tokenId] hasn't been cleared: it still points to the old slot (now occupied by
        // lastTokenId, or just over the end of the array if the token was the last one).
    }

}

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
contract IERC721Metadata is IERC721 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

contract ERC721Metadata is ERC165, ERC721, IERC721Metadata {
    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

    /*
     *     bytes4(keccak256('name()')) == 0x06fdde03
     *     bytes4(keccak256('symbol()')) == 0x95d89b41
     *     bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
     *
     *     => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
     */
    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;

    /**
     * @dev Constructor function
     */
    constructor (string memory name, string memory symbol) public {
        _name = name;
        _symbol = symbol;

        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721_METADATA);
    }

    /**
     * @dev Gets the token name.
     * @return string representing the token name
     */
    function name() external view returns (string memory) {
        return _name;
    }

    /**
     * @dev Gets the token symbol.
     * @return string representing the token symbol
     */
    function symbol() external view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns an URI for a given token ID.
     * Throws if the token ID does not exist. May return an empty string.
     * @param tokenId uint256 ID of the token to query
     */
    function tokenURI(uint256 tokenId) external view returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
        return _tokenURIs[tokenId];
    }

    /**
     * @dev Internal function to set the token URI for a given token.
     * Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token to set its URI
     * @param uri string URI to assign
     */
    function _setTokenURI(uint256 tokenId, string memory uri) internal {
        require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
        _tokenURIs[tokenId] = uri;
    }

}

/**
 * @title ERC721MetadataMintable
 * @dev ERC721 minting logic with metadata.
 */
contract ERC721MetadataMintable is ERC721, ERC721Metadata, MinterRole {
    /**
     * @dev Function to mint tokens.
     * @param to The address that will receive the minted tokens.
     * @param tokenId The token id to mint.
     * @param tokenURI The token URI of the minted token.
     * @return A boolean that indicates if the operation was successful.
     */
    function mintWithTokenURI(address to, uint256 tokenId, string memory tokenURI) public onlyMinter returns (bool) {
        _mint(to, tokenId);
        _setTokenURI(tokenId, tokenURI);
        return true;
    }
}

/**
 * @title ERC721
 * Full ERC-721 Token with automint function
 */

contract ERC721Full is ERC721, ERC721Enumerable, ERC721Metadata, ERC721Mintable, ERC721MetadataMintable {

    uint256 autoTokenId;
    constructor (string memory name, string memory symbol, bool _anyoneCanMint) public 
        ERC721Mintable() 
        ERC721Metadata(name, symbol) {
        // solhint-disable-previous-line no-empty-blocks

        _setMintableOption(_anyoneCanMint);

    }

    function exists(uint256 tokenId) public view returns (bool) {
        return _exists(tokenId);
    }

    function tokensOfOwner(address owner) public view returns (uint256[] memory) {
        return _tokensOfOwner(owner);
    }

    function setTokenURI(uint256 tokenId, string memory uri) public {
        _setTokenURI(tokenId, uri);
    }

    /**
     * @dev Function to mint tokens with automatic ID
     * @param to The address that will receive the minted tokens.
     * @return A boolean that indicates if the operation was successful.
     */
    function autoMint(string memory tokenURI, address to) public onlyMinter returns (bool) {
        do {
            autoTokenId++;
        } while(_exists(autoTokenId));
        _mint(to, autoTokenId);
        _setTokenURI(autoTokenId, tokenURI);
        return true;
    }

    /**
     * @dev Function to transfer tokens
     * @param to The address that will receive the minted tokens.
     * @param tokenId the token ID
     */
    function transfer(
        address to,
        uint256 tokenId
    ) public {
        _transferFrom(msg.sender, to, tokenId);
    }

}

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be aplied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 */
contract ReentrancyGuard {
    // counter to allow mutex lock with only one SSTORE operation
    uint256 private _guardCounter;

    constructor () internal {
        // The counter starts at one to prevent changing it from zero to a non-zero
        // value, which is a more expensive operation.
        _guardCounter = 1;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _guardCounter += 1;
        uint256 localCounter = _guardCounter;
        _;
        require(localCounter == _guardCounter, "ReentrancyGuard: reentrant call");
    }
}

/**
 * @title ERC721Matcha
 * ERC-721 Marketplace
 */

contract ERC721Matcha is ERC721Full, ReentrancyGuard {

    using SafeMath for uint256;

    using Address for address payable;

    // admin address, the owner of the marketplace
    address payable admin;

    address public contract_owner;

    // commission rate is a value from 0 to 100
    uint256 commissionRate;

    // last price sold or auctioned
    mapping(uint256 => uint256) public soldFor;
    
    // Mapping from token ID to sell price in Ether or to bid price, depending if it is an auction or not
    mapping(uint256 => uint256) public sellBidPrice;

    // Mapping payment address for tokenId 
    mapping(uint256 => address payable) private _wallets;

    event Sale(uint256 indexed tokenId, address indexed from, address indexed to, uint256 value);
    event Commission(uint256 indexed tokenId, address indexed to, uint256 value, uint256 rate, uint256 total);

    /*

    index   _isAuction  _sellBidPrice   Meaning
    0       true        0               Item 0 is on auction and no bids so far
    1       true        10              Item 1 is on auction and the last bid is for 10 Ethers
    2       false       0               Item 2 is not on auction nor for sell
    3       false       10              Item 3 is on sale for 10 Ethers

    */

    // Auction data
    struct Auction {

        // Parameters of the auction. Times are either
        // absolute unix timestamps (seconds since 1970-01-01)
        // or time periods in seconds.
        address payable beneficiary;
        uint auctionEnd;

        // Current state of the auction.
        address payable highestBidder;
        uint highestBid;

        // Set to true at the end, disallows any change
        bool open;

        // minimum reserve price in wei
        uint256 reserve;

    }

    // mapping auctions for each tokenId
    mapping(uint256 => Auction) public auctions;

    // Events that will be fired on changes.
    event Refund(address bidder, uint amount);
    event HighestBidIncreased(address indexed bidder, uint amount, uint256 tokenId);
    event AuctionEnded(address winner, uint amount);

    event LimitSell(address indexed from, address indexed to, uint256 amount);
    event LimitBuy(address indexed from, address indexed to, uint256 amount);
    event MarketSell(address indexed from, address indexed to, uint256 amount);
    event MarketBuy(address indexed from, address indexed to, uint256 amount);


    constructor(address _owner, address payable _admin, uint256 _commissionRate, string memory name, string memory symbol, bool _anyoneCanMint) public 
        ERC721Full(name, symbol, _anyoneCanMint) {
        admin = _admin;
        contract_owner = _owner;
        require(_commissionRate<=100, "ERC721Matcha: Commission rate has to be between 0 and 100");
        commissionRate = _commissionRate;
    }

    function canSell(uint256 tokenId) public view returns (bool) {
        return (ownerOf(tokenId)==msg.sender && !auctions[tokenId].open);
    }

    // Sell option for a fixed price
    function sell(uint256 tokenId, uint256 price, address payable wallet) public {

        // onlyOwner
        require(ownerOf(tokenId)==msg.sender, "ERC721Matcha: Only owner can sell this item");

        // cannot set a price if auction is activated
        require(!auctions[tokenId].open, "ERC721Matcha: Cannot sell an item which has an active auction");

        // set sell price for index
        sellBidPrice[tokenId] = price;

        // If price is zero, means not for sale
        if (price>0) {

            // approve the Index to the current contract
            approve(address(this), tokenId);
            
            // set wallet payment
            _wallets[tokenId] = wallet;
            
        }

    }

    // simple function to return the price of a tokenId
    // returns: sell price, bid price, sold price, only one can be non zero
    function getPrice(uint256 tokenId) public view returns (uint256, uint256, uint256) {
        if (sellBidPrice[tokenId]>0) return (sellBidPrice[tokenId], 0, 0);
        if (auctions[tokenId].highestBid>0) return (0, auctions[tokenId].highestBid, 0);
        return (0, 0, soldFor[tokenId]);
    }

    function canBuy(uint256 tokenId) public view returns (uint256) {
        if (!auctions[tokenId].open && sellBidPrice[tokenId]>0 && sellBidPrice[tokenId]>0 && getApproved(tokenId) == address(this)) {
            return sellBidPrice[tokenId];
        } else {
            return 0;
        }
    }

    // Buy option
    function buy(uint256 tokenId) public payable nonReentrant {

        // is on sale
        require(!auctions[tokenId].open && sellBidPrice[tokenId]>0, "ERC721Matcha: The collectible is not for sale");

        // transfer funds
        require(msg.value >= sellBidPrice[tokenId], "ERC721Matcha: Not enough funds");

        // transfer ownership
        address owner = ownerOf(tokenId);

        require(msg.sender!=owner, "ERC721Matcha: The seller cannot buy his own collectible");

        // we need to call a transferFrom from this contract, which is the one with permission to sell the NFT
        callOptionalReturn(this, abi.encodeWithSelector(this.transferFrom.selector, owner, msg.sender, tokenId));

        // calculate amounts
        uint256 amount4admin = msg.value.mul(commissionRate).div(100);
        uint256 amount4owner = msg.value.sub(amount4admin);

        // to owner
        (bool success, ) = _wallets[tokenId].call.value(amount4owner)("");
        require(success, "Transfer failed.");

        // to admin
        (bool success2, ) = admin.call.value(amount4admin)("");
        require(success2, "Transfer failed.");

        // close the sell
        sellBidPrice[tokenId] = 0;
        _wallets[tokenId] = address(0);

        soldFor[tokenId] = msg.value;

        emit Sale(tokenId, owner, msg.sender, msg.value);
        emit Commission(tokenId, owner, msg.value, commissionRate, amount4admin);

    }

    function canAuction(uint256 tokenId) public view returns (bool) {
        return (ownerOf(tokenId)==msg.sender && !auctions[tokenId].open && sellBidPrice[tokenId]==0);
    }

    // Instantiate an auction contract for a tokenId
    function createAuction(uint256 tokenId, uint _closingTime, address payable _beneficiary, uint256 _reservePrice) public {

        require(sellBidPrice[tokenId]==0, "ERC721Matcha: The selected NFT is open for sale, cannot be auctioned");
        require(!auctions[tokenId].open, "ERC721Matcha: The selected NFT already has an auction");
        require(ownerOf(tokenId)==msg.sender, "ERC721Matcha: Only owner can auction this item");

        auctions[tokenId].beneficiary = _beneficiary;
        auctions[tokenId].auctionEnd = _closingTime;
        auctions[tokenId].reserve = _reservePrice;
        auctions[tokenId].open = true;

        // approve the Index to the current contract
        approve(address(this), tokenId);

    }

    function canBid(uint256 tokenId) public view returns (bool) {
        if (!msg.sender.isContract() &&
            auctions[tokenId].open &&
            now <= auctions[tokenId].auctionEnd &&
            msg.sender != ownerOf(tokenId) &&
            getApproved(tokenId) == address(this)
        ) {
            return true;
        } else {
            return false;
        }
    }

    /// Bid on the auction with the value sent
    /// together with this transaction.
    /// The value will only be refunded if the
    /// auction is not won.
    function bid(uint256 tokenId) public payable nonReentrant {
        // No arguments are necessary, all
        // information is already part of
        // the transaction. The keyword payable
        // is required for the function to
        // be able to receive Ether.

        // Contracts cannot bid, because they can block the auction with a reentrant attack
        require(!msg.sender.isContract(), "No script kiddies");

        // auction has to be opened
        require(auctions[tokenId].open, "No opened auction found");

        // approve was lost
        require(getApproved(tokenId) == address(this), "Cannot complete the auction");

        // Revert the call if the bidding
        // period is over.
        require(
            now <= auctions[tokenId].auctionEnd,
            "Auction already ended."
        );

        // If the bid is not higher, send the
        // money back.
        require(
            msg.value > auctions[tokenId].highestBid,
            "There already is a higher bid."
        );

        address owner = ownerOf(tokenId);
        require(msg.sender!=owner, "ERC721Matcha: The owner cannot bid his own collectible");

        // return the funds to the previous bidder, if there is one
        if (auctions[tokenId].highestBid>0) {
            (bool success, ) = auctions[tokenId].highestBidder.call.value(auctions[tokenId].highestBid)("");
            require(success, "Transfer failed.");
            emit Refund(auctions[tokenId].highestBidder, auctions[tokenId].highestBid);
        }

        // now store the bid data
        auctions[tokenId].highestBidder = msg.sender;
        auctions[tokenId].highestBid = msg.value;
        emit HighestBidIncreased(msg.sender, msg.value, tokenId);

    }

    // anyone can execute withdraw if auction is opened and 
    // the bid time expired and the reserve was not met
    // or
    // the auction is openen but the contract is unable to transfer
    function canWithdraw(uint256 tokenId) public view returns (bool) {
        if (auctions[tokenId].open && 
            (
                (
                    now >= auctions[tokenId].auctionEnd &&
                    auctions[tokenId].highestBid > 0 &&
                    auctions[tokenId].highestBid<auctions[tokenId].reserve
                ) || 
                getApproved(tokenId) != address(this)
            )
        ) {
            return true;
        } else {
            return false;
        }
    }

    /// Withdraw a bid when the auction is not finalized
    function withdraw(uint256 tokenId) public nonReentrant returns (bool) {

        require(canWithdraw(tokenId), "Conditions to withdraw are not met");

        // transfer funds to highest bidder always
        if (auctions[tokenId].highestBid > 0) {
            (bool success, ) = auctions[tokenId].highestBidder.call.value(auctions[tokenId].highestBid)("");
            require(success, "Transfer failed.");
        }

        // finalize the auction
        delete auctions[tokenId];

    }

    function canFinalize(uint256 tokenId) public view returns (bool) {
        if (auctions[tokenId].open && 
            now >= auctions[tokenId].auctionEnd &&
            (
                auctions[tokenId].highestBid>=auctions[tokenId].reserve || 
                auctions[tokenId].highestBid==0
            )
        ) {
            return true;
        } else {
            return false;
        }
    }

    // implement the auctionFinalize including the NFT transfer logic
    function auctionFinalize(uint256 tokenId) public nonReentrant {

        require(canFinalize(tokenId), "Cannot finalize");

        if (auctions[tokenId].highestBid>0) {

            // transfer the ownership of token to the highest bidder
            address payable highestBidder = auctions[tokenId].highestBidder;

            // calculate payment amounts
            uint256 amount4admin = auctions[tokenId].highestBid.mul(commissionRate).div(100);
            uint256 amount4owner = auctions[tokenId].highestBid.sub(amount4admin);

            // to owner
            (bool success, ) = auctions[tokenId].beneficiary.call.value(amount4owner)("");
            require(success, "Transfer failed.");

            // to admin
            (bool success2, ) = admin.call.value(amount4admin)("");
            require(success2, "Transfer failed.");

            emit Sale(tokenId, auctions[tokenId].beneficiary, highestBidder, auctions[tokenId].highestBid);
            emit Commission(tokenId, auctions[tokenId].beneficiary, auctions[tokenId].highestBid, commissionRate, amount4admin);

            // transfer ownership
            address owner = ownerOf(tokenId);

            // we need to call a transferFrom from this contract, which is the one with permission to sell the NFT
            // transfer the NFT to the auction's highest bidder
            callOptionalReturn(this, abi.encodeWithSelector(this.transferFrom.selector, owner, highestBidder, tokenId));

            soldFor[tokenId] = auctions[tokenId].highestBid;

        }

        emit AuctionEnded(auctions[tokenId].highestBidder, auctions[tokenId].highestBid);

        // finalize the auction
        delete auctions[tokenId];

    }

    // Bid query functions
    function highestBidder(uint256 tokenId) public view returns (address payable) {
        return auctions[tokenId].highestBidder;
    }

    function highestBid(uint256 tokenId) public view returns (uint256) {
        return auctions[tokenId].highestBid;
    }

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

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

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

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

    // update contract fields
    function updateAdmin(address payable _admin, uint256 _commissionRate, bool _anyoneCanMint) public {
        require(msg.sender==contract_owner, "Only contract owner can do this");
        admin=_admin;
        commissionRate=_commissionRate;
        anyoneCanMint=_anyoneCanMint;
    }

}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[{"name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"tokenId","type":"uint256"},{"name":"uri","type":"string"}],"name":"setTokenURI","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"sellBidPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"canAuction","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_admin","type":"address"},{"name":"_commissionRate","type":"uint256"},{"name":"_anyoneCanMint","type":"bool"}],"name":"updateAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"withdraw","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"contract_owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"canBuy","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"mint","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"highestBidder","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"bid","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"tokenURI","type":"string"}],"name":"mintWithTokenURI","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"auctions","outputs":[{"name":"beneficiary","type":"address"},{"name":"auctionEnd","type":"uint256"},{"name":"highestBidder","type":"address"},{"name":"highestBid","type":"uint256"},{"name":"open","type":"bool"},{"name":"reserve","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"tokenURI","type":"string"},{"name":"to","type":"address"}],"name":"autoMint","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"canBid","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"}],"name":"addMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"soldFor","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"isMinter","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"anyoneCanMint","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"highestBid","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"tokenId","type":"uint256"},{"name":"_closingTime","type":"uint256"},{"name":"_beneficiary","type":"address"},{"name":"_reservePrice","type":"uint256"}],"name":"createAuction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"canSell","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"tokenId","type":"uint256"},{"name":"price","type":"uint256"},{"name":"wallet","type":"address"}],"name":"sell","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"buy","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"auctionFinalize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"canFinalize","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"getPrice","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"canIMint","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"canWithdraw","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_owner","type":"address"},{"name":"_admin","type":"address"},{"name":"_commissionRate","type":"uint256"},{"name":"name","type":"string"},{"name":"symbol","type":"string"},{"name":"_anyoneCanMint","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"tokenId","type":"uint256"},{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Sale","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"tokenId","type":"uint256"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"rate","type":"uint256"},{"indexed":false,"name":"total","type":"uint256"}],"name":"Commission","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"bidder","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Refund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"bidder","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"tokenId","type":"uint256"}],"name":"HighestBidIncreased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"winner","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"AuctionEnded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"LimitSell","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"LimitBuy","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"MarketSell","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"MarketBuy","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"MinterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"MinterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":true,"name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"approved","type":"address"},{"indexed":true,"name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"operator","type":"address"},{"indexed":false,"name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"}]

60806040523480156200001157600080fd5b506040516200453338038062004533833981018060405260c08110156200003757600080fd5b81516020830151604084015160608501805193959294919391830192916401000000008111156200006757600080fd5b820160208101848111156200007b57600080fd5b81516401000000008111828201871017156200009657600080fd5b50509291906020018051640100000000811115620000b357600080fd5b82016020810184811115620000c757600080fd5b8151640100000000811182820187101715620000e257600080fd5b50506020918201519093509150839083908390839083906200012a907f01ffc9a7000000000000000000000000000000000000000000000000000000009062000265811b901c565b620001426380ac58cd60e01b6200026560201b60201c565b6200015a63780e9d6360e01b6200026560201b60201c565b81516200016f906009906020850190620004c0565b5080516200018590600a906020840190620004c0565b506200019e635b5e139f60e01b6200026560201b60201c565b5050620001b1336200033460201b60201c565b620001c2816200038660201b60201c565b50506001600f5550601080546001600160a01b038088166001600160a01b0319928316179092556011805492891692909116919091179055606484111562000256576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180620044d86039913960400191505060405180910390fd5b50505060125550620005659050565b7fffffffff000000000000000000000000000000000000000000000000000000008082161415620002f757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152602081905260409020805460ff19166001179055565b6200034f81600c6200039960201b620038031790919060201c565b6040516001600160a01b038216907f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f690600090a250565b600d805460ff1916911515919091179055565b620003ab82826200043d60201b60201c565b156200041857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60006001600160a01b038216620004a0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180620045116022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200050357805160ff191683800117855562000533565b8280016001018555821562000533579182015b828111156200053357825182559160200191906001019062000516565b506200054192915062000545565b5090565b6200056291905b808211156200054157600081556001016200054c565b90565b613f6380620005756000396000f3fe6080604052600436106102935760003560e01c806370a082311161015a578063b1cb48ef116100c1578063dc16bd431161007a578063dc16bd4314610d88578063e4e2bfe414610db2578063e757223014610ddc578063e985e9c514610e24578063ee1b59e414610e5f578063fbe85f0614610e7457610293565b8063b1cb48ef14610bc2578063b2ecfad414610c07578063b88d4fde14610c31578063c87b56dd14610d02578063d04c698314610d2c578063d96a094a14610d6b57610293565b8063a22cb46511610113578063a22cb46514610ab2578063a36b146214610aed578063a9059cbb14610b17578063aa271e1a14610b50578063b13fbe9614610b83578063b14c63c514610b9857610293565b806370a08231146109755780638462151c146109a857806389f4c0b114610a2b57806395d89b4114610a55578063983b2d5614610a6a5780639865027514610a9d57610293565b8063384f58eb116101fe5780634f558e79116101b75780634f558e79146107075780634f6ccce71461073157806350bb4e7f1461075b578063571a26a01461082157806361a09c971461088f5780636352211e1461094b57610293565b8063384f58eb146106055780633ca88a2f1461061a57806340c10f191461064457806342842e0e1461067d578063451df52e146106c0578063454a2ab3146106ea57610293565b806318160ddd1161025057806318160ddd146104df5780631ac70f6f146104f457806323b872dd1461051e578063263f5877146105615780632e1a7d4d146105a25780632f745c59146105cc57610293565b806301ffc9a71461029857806306fdde03146102e0578063081812fc1461036a578063095ea7b3146103b0578063162094c4146103eb578063172b099d146104a3575b600080fd5b3480156102a457600080fd5b506102cc600480360360208110156102bb57600080fd5b50356001600160e01b031916610e9e565b604080519115158252519081900360200190f35b3480156102ec57600080fd5b506102f5610ec1565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561032f578181015183820152602001610317565b50505050905090810190601f16801561035c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561037657600080fd5b506103946004803603602081101561038d57600080fd5b5035610f58565b604080516001600160a01b039092168252519081900360200190f35b3480156103bc57600080fd5b506103e9600480360360408110156103d357600080fd5b506001600160a01b038135169060200135610fbd565b005b3480156103f757600080fd5b506103e96004803603604081101561040e57600080fd5b81359190810190604081016020820135600160201b81111561042f57600080fd5b82018360208201111561044157600080fd5b803590602001918460018302840111600160201b8311171561046257600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506110d4945050505050565b3480156104af57600080fd5b506104cd600480360360208110156104c657600080fd5b50356110e2565b60408051918252519081900360200190f35b3480156104eb57600080fd5b506104cd6110f4565b34801561050057600080fd5b506102cc6004803603602081101561051757600080fd5b50356110fa565b34801561052a57600080fd5b506103e96004803603606081101561054157600080fd5b506001600160a01b0381358116916020810135909116906040013561114c565b34801561056d57600080fd5b506103e96004803603606081101561058457600080fd5b506001600160a01b03813516906020810135906040013515156111a4565b3480156105ae57600080fd5b506102cc600480360360208110156105c557600080fd5b503561123d565b3480156105d857600080fd5b506104cd600480360360408110156105ef57600080fd5b506001600160a01b0381351690602001356113f4565b34801561061157600080fd5b50610394611476565b34801561062657600080fd5b506104cd6004803603602081101561063d57600080fd5b5035611485565b34801561065057600080fd5b506102cc6004803603604081101561066757600080fd5b506001600160a01b03813516906020013561150b565b34801561068957600080fd5b506103e9600480360360608110156106a057600080fd5b506001600160a01b03813581169160208101359091169060400135611569565b3480156106cc57600080fd5b50610394600480360360208110156106e357600080fd5b5035611584565b6103e96004803603602081101561070057600080fd5b50356115a2565b34801561071357600080fd5b506102cc6004803603602081101561072a57600080fd5b50356119e5565b34801561073d57600080fd5b506104cd6004803603602081101561075457600080fd5b50356119f0565b34801561076757600080fd5b506102cc6004803603606081101561077e57600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b8111156107ad57600080fd5b8201836020820111156107bf57600080fd5b803590602001918460018302840111600160201b831117156107e057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611a59945050505050565b34801561082d57600080fd5b5061084b6004803603602081101561084457600080fd5b5035611ac2565b604080516001600160a01b0397881681526020810196909652939095168484015260608401919091521515608083015260a082019290925290519081900360c00190f35b34801561089b57600080fd5b506102cc600480360360408110156108b257600080fd5b810190602081018135600160201b8111156108cc57600080fd5b8201836020820111156108de57600080fd5b803590602001918460018302840111600160201b831117156108ff57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550505090356001600160a01b03169150611b099050565b34801561095757600080fd5b506103946004803603602081101561096e57600080fd5b5035611b83565b34801561098157600080fd5b506104cd6004803603602081101561099857600080fd5b50356001600160a01b0316611bda565b3480156109b457600080fd5b506109db600480360360208110156109cb57600080fd5b50356001600160a01b0316611c45565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610a175781810151838201526020016109ff565b505050509050019250505060405180910390f35b348015610a3757600080fd5b506102cc60048036036020811015610a4e57600080fd5b5035611ca6565b348015610a6157600080fd5b506102f5611d3b565b348015610a7657600080fd5b506103e960048036036020811015610a8d57600080fd5b50356001600160a01b0316611d9c565b348015610aa957600080fd5b506103e9611ded565b348015610abe57600080fd5b506103e960048036036040811015610ad557600080fd5b506001600160a01b0381351690602001351515611df8565b348015610af957600080fd5b506104cd60048036036020811015610b1057600080fd5b5035611ec7565b348015610b2357600080fd5b506103e960048036036040811015610b3a57600080fd5b506001600160a01b038135169060200135611ed9565b348015610b5c57600080fd5b506102cc60048036036020811015610b7357600080fd5b50356001600160a01b0316611ee4565b348015610b8f57600080fd5b506102cc611ef7565b348015610ba457600080fd5b506104cd60048036036020811015610bbb57600080fd5b5035611f00565b348015610bce57600080fd5b506103e960048036036080811015610be557600080fd5b508035906020810135906001600160a01b036040820135169060600135611f15565b348015610c1357600080fd5b506102cc60048036036020811015610c2a57600080fd5b503561205f565b348015610c3d57600080fd5b506103e960048036036080811015610c5457600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610c8e57600080fd5b820183602082011115610ca057600080fd5b803590602001918460018302840111600160201b83111715610cc157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612096945050505050565b348015610d0e57600080fd5b506102f560048036036020811015610d2557600080fd5b50356120eb565b348015610d3857600080fd5b506103e960048036036060811015610d4f57600080fd5b50803590602081013590604001356001600160a01b03166121c9565b6103e960048036036020811015610d8157600080fd5b50356122be565b348015610d9457600080fd5b506103e960048036036020811015610dab57600080fd5b50356126ef565b348015610dbe57600080fd5b506102cc60048036036020811015610dd557600080fd5b5035612b6b565b348015610de857600080fd5b50610e0660048036036020811015610dff57600080fd5b5035612be3565b60408051938452602084019290925282820152519081900360600190f35b348015610e3057600080fd5b506102cc60048036036040811015610e4757600080fd5b506001600160a01b0381358116916020013516612c62565b348015610e6b57600080fd5b506102cc612c90565b348015610e8057600080fd5b506102cc60048036036020811015610e9757600080fd5b5035612cad565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60098054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610f4d5780601f10610f2257610100808354040283529160200191610f4d565b820191906000526020600020905b815481529060010190602001808311610f3057829003601f168201915b505050505090505b90565b6000610f6382612d42565b610fa157604051600160e51b62461bcd02815260040180806020018281038252602c815260200180613cb7602c913960400191505060405180910390fd5b506000908152600260205260409020546001600160a01b031690565b6000610fc882611b83565b9050806001600160a01b0316836001600160a01b0316141561101e57604051600160e51b62461bcd028152600401808060200182810382526021815260200180613dcd6021913960400191505060405180910390fd5b336001600160a01b038216148061103a575061103a8133612c62565b61107857604051600160e51b62461bcd028152600401808060200182810382526038815260200180613b996038913960400191505060405180910390fd5b60008281526002602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6110de8282612d5f565b5050565b60146020526000908152604090205481565b60075490565b60003361110683611b83565b6001600160a01b031614801561112e575060008281526016602052604090206004015460ff16155b80156111465750600082815260146020526040902054155b92915050565b6111563382612dc5565b61119457604051600160e51b62461bcd028152600401808060200182810382526031815260200180613e1b6031913960400191505060405180910390fd5b61119f838383612e6c565b505050565b6011546001600160a01b031633146112065760408051600160e51b62461bcd02815260206004820152601f60248201527f4f6e6c7920636f6e7472616374206f776e65722063616e20646f207468697300604482015290519081900360640190fd5b601080546001600160a01b0319166001600160a01b039490941693909317909255601255600d805460ff1916911515919091179055565b600f80546001019081905560009061125483612cad565b61129257604051600160e51b62461bcd028152600401808060200182810382526022815260200180613ee06022913960400191505060405180910390fd5b6000838152601660205260409020600301541561136057600083815260166020526040808220600281015460039091015491516001600160a01b0390911691908381818185875af1925050503d806000811461130a576040519150601f19603f3d011682016040523d82523d6000602084013e61130f565b606091505b505090508061135e5760408051600160e51b62461bcd0281526020600482015260106024820152600160811b6f2a3930b739b332b9103330b4b632b21702604482015290519081900360640190fd5b505b600083815260166020526040812080546001600160a01b031990811682556001820183905560028201805490911690556003810182905560048101805460ff1916905560050155600f5481146113ee5760408051600160e51b62461bcd02815260206004820152601f6024820152600080516020613a3c833981519152604482015290519081900360640190fd5b50919050565b60006113ff83611bda565b821061143f57604051600160e51b62461bcd02815260040180806020018281038252602b815260200180613a8a602b913960400191505060405180910390fd5b6001600160a01b038316600090815260056020526040902080548390811061146357fe5b9060005260206000200154905092915050565b6011546001600160a01b031681565b60008181526016602052604081206004015460ff161580156114b4575060008281526014602052604090205415155b80156114cd575060008281526014602052604090205415155b80156114e95750306114de83610f58565b6001600160a01b0316145b156115035750600081815260146020526040902054610ebc565b506000610ebc565b60006060611517612c90565b61155557604051600160e51b62461bcd028152600401808060200182810382526030815260200180613c456030913960400191505060405180910390fd5b61155f8484612e8b565b5060019392505050565b61119f83838360405180602001604052806000815250612096565b6000908152601660205260409020600201546001600160a01b031690565b600f8054600101908190556115b633612ea8565b1561160b5760408051600160e51b62461bcd02815260206004820152601160248201527f4e6f20736372697074206b696464696573000000000000000000000000000000604482015290519081900360640190fd5b60008281526016602052604090206004015460ff166116745760408051600160e51b62461bcd02815260206004820152601760248201527f4e6f206f70656e65642061756374696f6e20666f756e64000000000000000000604482015290519081900360640190fd5b3061167e83610f58565b6001600160a01b0316146116dc5760408051600160e51b62461bcd02815260206004820152601b60248201527f43616e6e6f7420636f6d706c657465207468652061756374696f6e0000000000604482015290519081900360640190fd5b6000828152601660205260409020600101544211156117455760408051600160e51b62461bcd02815260206004820152601660248201527f41756374696f6e20616c726561647920656e6465642e00000000000000000000604482015290519081900360640190fd5b60008281526016602052604090206003015434116117ad5760408051600160e51b62461bcd02815260206004820152601e60248201527f546865726520616c7265616479206973206120686967686572206269642e0000604482015290519081900360640190fd5b60006117b883611b83565b9050336001600160a01b038216141561180557604051600160e51b62461bcd028152600401808060200182810382526036815260200180613f026036913960400191505060405180910390fd5b6000838152601660205260409020600301541561193357600083815260166020526040808220600281015460039091015491516001600160a01b0390911691908381818185875af1925050503d806000811461187d576040519150601f19603f3d011682016040523d82523d6000602084013e611882565b606091505b50509050806118d15760408051600160e51b62461bcd0281526020600482015260106024820152600160811b6f2a3930b739b332b9103330b4b632b21702604482015290519081900360640190fd5b600084815260166020908152604091829020600281015460039091015483516001600160a01b0390921682529181019190915281517fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d929181900390910190a1505b6000838152601660209081526040918290206002810180546001600160a01b031916339081179091553460039092018290558351918252918101869052825191927fdafc4a123c6bb3b49dd38a0cba299808581a0126a37248a5f1102d5e5fa0633792918290030190a250600f5481146110de5760408051600160e51b62461bcd02815260206004820152601f6024820152600080516020613a3c833981519152604482015290519081900360640190fd5b600061114682612d42565b60006119fa6110f4565b8210611a3a57604051600160e51b62461bcd02815260040180806020018281038252602c815260200180613e4c602c913960400191505060405180910390fd5b60078281548110611a4757fe5b90600052602060002001549050919050565b60006060611a65612c90565b611aa357604051600160e51b62461bcd028152600401808060200182810382526030815260200180613c456030913960400191505060405180910390fd5b611aad8585612e8b565b611ab78484612d5f565b506001949350505050565b6016602052600090815260409020805460018201546002830154600384015460048501546005909501546001600160a01b0394851695939490921692909160ff9091169086565b60006060611b15612c90565b611b5357604051600160e51b62461bcd028152600401808060200182810382526030815260200180613c456030913960400191505060405180910390fd5b600e805460010190819055611b6790612d42565b611b5357611b7783600e54612e8b565b61155f600e5485612d5f565b6000818152600160205260408120546001600160a01b03168061114657604051600160e51b62461bcd028152600401808060200182810382526029815260200180613bfb6029913960400191505060405180910390fd5b60006001600160a01b038216611c2457604051600160e51b62461bcd02815260040180806020018281038252602a815260200180613bd1602a913960400191505060405180910390fd5b6001600160a01b038216600090815260036020526040902061114690612edf565b6060611c5082612ee3565b805480602002602001604051908101604052809291908181526020018280548015611c9a57602002820191906000526020600020905b815481526020019060010190808311611c86575b50505050509050919050565b6000611cb133612ea8565b158015611ccf575060008281526016602052604090206004015460ff165b8015611cec57506000828152601660205260409020600101544211155b8015611d125750611cfc82611b83565b6001600160a01b0316336001600160a01b031614155b8015611d2e575030611d2383610f58565b6001600160a01b0316145b1561150357506001610ebc565b600a8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610f4d5780601f10610f2257610100808354040283529160200191610f4d565b6060611da6612c90565b611de457604051600160e51b62461bcd028152600401808060200182810382526030815260200180613c456030913960400191505060405180910390fd5b6110de82612efd565b611df633612f45565b565b6001600160a01b038216331415611e595760408051600160e51b62461bcd02815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b3360008181526004602090815260408083206001600160a01b03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b60136020526000908152604090205481565b6110de338383612e6c565b6000611146600c8363ffffffff612f8d16565b600d5460ff1681565b60009081526016602052604090206003015490565b60008481526014602052604090205415611f6357604051600160e51b62461bcd028152600401808060200182810382526044815260200180613d896044913960600191505060405180910390fd5b60008481526016602052604090206004015460ff1615611fb757604051600160e51b62461bcd028152600401808060200182810382526035815260200180613a076035913960400191505060405180910390fd5b33611fc185611b83565b6001600160a01b03161461200957604051600160e51b62461bcd02815260040180806020018281038252602e815260200180613a5c602e913960400191505060405180910390fd5b600084815260166020526040902080546001600160a01b0319166001600160a01b0384161781556001808201859055600582018390556004909101805460ff191690911790556120593085610fbd565b50505050565b60003361206b83611b83565b6001600160a01b031614801561114657505060009081526016602052604090206004015460ff161590565b6120a184848461114c565b6120ad84848484612ff7565b61205957604051600160e51b62461bcd028152600401808060200182810382526032815260200180613ab56032913960400191505060405180910390fd5b60606120f682612d42565b61213457604051600160e51b62461bcd02815260040180806020018281038252602f815260200180613d5a602f913960400191505060405180910390fd5b6000828152600b602090815260409182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084529091830182828015611c9a5780601f1061219c57610100808354040283529160200191611c9a565b820191906000526020600020905b8154815290600101906020018083116121aa5750939695505050505050565b336121d384611b83565b6001600160a01b03161461221b57604051600160e51b62461bcd02815260040180806020018281038252602b815260200180613ae7602b913960400191505060405180910390fd5b60008381526016602052604090206004015460ff161561226f57604051600160e51b62461bcd02815260040180806020018281038252603d815260200180613ea3603d913960400191505060405180910390fd5b6000838152601460205260409020829055811561119f576122903084610fbd565b600083815260156020526040902080546001600160a01b0383166001600160a01b0319909116179055505050565b600f80546001019081905560008281526016602052604090206004015460ff161580156122f8575060008281526014602052604090205415155b61233657604051600160e51b62461bcd02815260040180806020018281038252602d815260200180613dee602d913960400191505060405180910390fd5b60008281526014602052604090205434101561239c5760408051600160e51b62461bcd02815260206004820152601e60248201527f4552433732314d61746368613a204e6f7420656e6f7567682066756e64730000604482015290519081900360640190fd5b60006123a783611b83565b9050336001600160a01b03821614156123f457604051600160e51b62461bcd028152600401808060200182810382526037815260200180613b366037913960400191505060405180910390fd5b604080516001600160a01b038316602482015233604482015260648082018690528251808303909101815260849091019091526020810180516001600160e01b0316600160e01b6323b872dd0217905261244f903090613130565b6000612477606461246b601254346132db90919063ffffffff16565b9063ffffffff61333e16565b9050600061248b348363ffffffff6133ab16565b60008681526015602052604080822054905192935090916001600160a01b039091169083908381818185875af1925050503d80600081146124e8576040519150601f19603f3d011682016040523d82523d6000602084013e6124ed565b606091505b505090508061253c5760408051600160e51b62461bcd0281526020600482015260106024820152600160811b6f2a3930b739b332b9103330b4b632b21702604482015290519081900360640190fd5b6010546040516000916001600160a01b03169085908381818185875af1925050503d8060008114612589576040519150601f19603f3d011682016040523d82523d6000602084013e61258e565b606091505b50509050806125dd5760408051600160e51b62461bcd0281526020600482015260106024820152600160811b6f2a3930b739b332b9103330b4b632b21702604482015290519081900360640190fd5b60008781526014602090815260408083208390556015825280832080546001600160a01b0319169055601382529182902034908190558251908152915133926001600160a01b038916928b927f88863d5e20f64464b554931394e2e4b6f09c10015147215bf26b3ba5070acebe9281900390910190a4601254604080513481526020810192909252818101869052516001600160a01b0387169189917fef7a63d352d8b0f42e35d7f8bd277ba75ba2ff721a50eaad4c62f1ee6561d5eb9181900360600190a35050505050600f5481146110de5760408051600160e51b62461bcd02815260206004820152601f6024820152600080516020613a3c833981519152604482015290519081900360640190fd5b600f80546001019081905561270382612b6b565b6127575760408051600160e51b62461bcd02815260206004820152600f60248201527f43616e6e6f742066696e616c697a650000000000000000000000000000000000604482015290519081900360640190fd5b60008281526016602052604090206003015415612a7d57600082815260166020526040812060028101546012546003909201546001600160a01b0390911692916127ae9160649161246b919063ffffffff6132db16565b600085815260166020526040812060030154919250906127d4908363ffffffff6133ab16565b60008681526016602052604080822054905192935090916001600160a01b039091169083908381818185875af1925050503d8060008114612831576040519150601f19603f3d011682016040523d82523d6000602084013e612836565b606091505b50509050806128855760408051600160e51b62461bcd0281526020600482015260106024820152600160811b6f2a3930b739b332b9103330b4b632b21702604482015290519081900360640190fd5b6010546040516000916001600160a01b03169085908381818185875af1925050503d80600081146128d2576040519150601f19603f3d011682016040523d82523d6000602084013e6128d7565b606091505b50509050806129265760408051600160e51b62461bcd0281526020600482015260106024820152600160811b6f2a3930b739b332b9103330b4b632b21702604482015290519081900360640190fd5b6000878152601660209081526040918290208054600390910154835190815292516001600160a01b03808a16949216928b927f88863d5e20f64464b554931394e2e4b6f09c10015147215bf26b3ba5070acebe929081900390910190a4600087815260166020908152604091829020805460039091015460125484519182529281019290925281830187905291516001600160a01b039092169189917fef7a63d352d8b0f42e35d7f8bd277ba75ba2ff721a50eaad4c62f1ee6561d5eb919081900360600190a360006129f888611b83565b604080516001600160a01b0380841660248301528916604482015260648082018c90528251808303909101815260849091019091526020810180516001600160e01b0316600160e01b6323b872dd02179052909150612a58903090613130565b5050506000858152601660209081526040808320600301546013909252909120555050505b600082815260166020908152604091829020600281015460039091015483516001600160a01b0390921682529181019190915281517fdaec4582d5d9595688c8c98545fdd1c696d41c6aeaeb636737e84ed2f5c00eda929181900390910190a1600082815260166020526040812080546001600160a01b031990811682556001820183905560028201805490911690556003810182905560048101805460ff1916905560050155600f5481146110de5760408051600160e51b62461bcd02815260206004820152601f6024820152600080516020613a3c833981519152604482015290519081900360640190fd5b60008181526016602052604081206004015460ff168015612b9d57506000828152601660205260409020600101544210155b8015611d2e575060008281526016602052604090206005810154600390910154101580611d2e575060008281526016602052604090206003015461150357506001610ebc565b6000818152601460205260408120548190819015612c14575050506000818152601460205260408120549080612c5b565b60008481526016602052604090206003015415612c465750505060008181526016602052604081206003015481612c5b565b50505060008181526013602052604081205481905b9193909250565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205460ff1690565b600d5460009060ff1680612ca85750612ca833611ee4565b905090565b60008181526016602052604081206004015460ff168015611d2e57506000828152601660205260409020600101544210801590612cfa575060008281526016602052604090206003015415155b8015612d1c575060008281526016602052604090206005810154600390910154105b80611d2e575030612d2c83610f58565b6001600160a01b03161461150357506001610ebc565b6000908152600160205260409020546001600160a01b0316151590565b612d6882612d42565b612da657604051600160e51b62461bcd02815260040180806020018281038252602c815260200180613ce3602c913960400191505060405180910390fd5b6000828152600b60209081526040909120825161119f9284019061394e565b6000612dd082612d42565b612e0e57604051600160e51b62461bcd02815260040180806020018281038252602c815260200180613b6d602c913960400191505060405180910390fd5b6000612e1983611b83565b9050806001600160a01b0316846001600160a01b03161480612e545750836001600160a01b0316612e4984610f58565b6001600160a01b0316145b80612e645750612e648185612c62565b949350505050565b612e7783838361340b565b612e818382613555565b61119f828261364a565b612e958282613688565b612e9f828261364a565b6110de816137bf565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708115801590612e645750141592915050565b5490565b6001600160a01b0316600090815260056020526040902090565b612f0e600c8263ffffffff61380316565b6040516001600160a01b038216907f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f690600090a250565b612f56600c8263ffffffff61388716565b6040516001600160a01b038216907fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb6669290600090a250565b60006001600160a01b038216612fd757604051600160e51b62461bcd028152600401808060200182810382526022815260200180613d0f6022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b600061300b846001600160a01b0316612ea8565b61301757506001612e64565b604051600160e11b630a85bd0102815233600482018181526001600160a01b03888116602485015260448401879052608060648501908152865160848601528651600095928a169463150b7a029490938c938b938b939260a4019060208501908083838e5b8381101561309457818101518382015260200161307c565b50505050905090810190601f1680156130c15780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b1580156130e357600080fd5b505af11580156130f7573d6000803e3d6000fd5b505050506040513d602081101561310d57600080fd5b50516001600160e01b031916600160e11b630a85bd010214915050949350505050565b613142826001600160a01b0316612ea8565b6131965760408051600160e51b62461bcd02815260206004820181905260248201527f536166654552433732313a2063616c6c20746f206e6f6e2d636f6e7472616374604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106131d45780518252601f1990920191602091820191016131b5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613236576040519150601f19603f3d011682016040523d82523d6000602084013e61323b565b606091505b50915091508161327f57604051600160e51b62461bcd028152600401808060200182810382526021815260200180613c246021913960400191505060405180910390fd5b8051156120595780806020019051602081101561329b57600080fd5b505161205957604051600160e51b62461bcd02815260040180806020018281038252602b815260200180613e78602b913960400191505060405180910390fd5b6000826132ea57506000611146565b828202828482816132f757fe5b041461333757604051600160e51b62461bcd028152600401808060200182810382526021815260200180613c966021913960400191505060405180910390fd5b9392505050565b60008082116133975760408051600160e51b62461bcd02815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b60008284816133a257fe5b04949350505050565b6000828211156134055760408051600160e51b62461bcd02815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b826001600160a01b031661341e82611b83565b6001600160a01b03161461346657604051600160e51b62461bcd028152600401808060200182810382526029815260200180613d316029913960400191505060405180910390fd5b6001600160a01b0382166134ae57604051600160e51b62461bcd028152600401808060200182810382526024815260200180613b126024913960400191505060405180910390fd5b6134b7816138f1565b6001600160a01b03831660009081526003602052604090206134d89061392e565b6001600160a01b03821660009081526003602052604090206134f990613945565b60008181526001602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b03821660009081526005602052604081205461357f90600163ffffffff6133ab16565b60008381526006602052604090205490915080821461361a576001600160a01b03841660009081526005602052604081208054849081106135bc57fe5b906000526020600020015490508060056000876001600160a01b03166001600160a01b0316815260200190815260200160002083815481106135fa57fe5b600091825260208083209091019290925591825260069052604090208190555b6001600160a01b03841660009081526005602052604090208054906136439060001983016139cc565b5050505050565b6001600160a01b0390911660009081526005602081815260408084208054868652600684529185208290559282526001810183559183529091200155565b6001600160a01b0382166136e65760408051600160e51b62461bcd02815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b6136ef81612d42565b156137445760408051600160e51b62461bcd02815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b600081815260016020908152604080832080546001600160a01b0319166001600160a01b03871690811790915583526003909152902061378390613945565b60405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600780546000838152600860205260408120829055600182018355919091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880155565b61380d8282612f8d565b156138625760408051600160e51b62461bcd02815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6138918282612f8d565b6138cf57604051600160e51b62461bcd028152600401808060200182810382526021815260200180613c756021913960400191505060405180910390fd5b6001600160a01b0316600090815260209190915260409020805460ff19169055565b6000818152600260205260409020546001600160a01b03161561392b57600081815260026020526040902080546001600160a01b03191690555b50565b805461394190600163ffffffff6133ab16565b9055565b80546001019055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061398f57805160ff19168380011785556139bc565b828001600101855582156139bc579182015b828111156139bc5782518255916020019190600101906139a1565b506139c89291506139ec565b5090565b81548183558181111561119f5760008381526020902061119f9181019083015b610f5591905b808211156139c857600081556001016139f256fe4552433732314d61746368613a205468652073656c6563746564204e465420616c72656164792068617320616e2061756374696f6e5265656e7472616e637947756172643a207265656e7472616e742063616c6c004552433732314d61746368613a204f6e6c79206f776e65722063616e2061756374696f6e2074686973206974656d455243373231456e756d657261626c653a206f776e657220696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732314d61746368613a204f6e6c79206f776e65722063616e2073656c6c2074686973206974656d4552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732314d61746368613a205468652073656c6c65722063616e6e6f742062757920686973206f776e20636f6c6c65637469626c654552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e536166654552433732313a206c6f772d6c6576656c2063616c6c206661696c65644d696e746572526f6c653a2063616c6c657220646f6573206e6f74206861766520746865204d696e74657220726f6c65526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c65536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732314d657461646174613a2055524920736574206f66206e6f6e6578697374656e7420746f6b656e526f6c65733a206163636f756e7420697320746865207a65726f20616464726573734552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732314d61746368613a205468652073656c6563746564204e4654206973206f70656e20666f722073616c652c2063616e6e6f742062652061756374696f6e65644552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732314d61746368613a2054686520636f6c6c65637469626c65206973206e6f7420666f722073616c654552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564455243373231456e756d657261626c653a20676c6f62616c20696e646578206f7574206f6620626f756e6473536166654552433732313a204552433230206f7065726174696f6e20646964206e6f7420737563636565644552433732314d61746368613a2043616e6e6f742073656c6c20616e206974656d2077686963682068617320616e206163746976652061756374696f6e436f6e646974696f6e7320746f20776974686472617720617265206e6f74206d65744552433732314d61746368613a20546865206f776e65722063616e6e6f742062696420686973206f776e20636f6c6c65637469626c65a165627a7a72305820d3217b6ed168ce6b7ca5300deebd80a96402daffd563ff2fd72587dbe10a806700294552433732314d61746368613a20436f6d6d697373696f6e20726174652068617320746f206265206265747765656e203020616e6420313030526f6c65733a206163636f756e7420697320746865207a65726f2061646472657373000000000000000000000000df0d65cece2eb2d50d2242fa86ee8fb4e7136fa4000000000000000000000000df0d65cece2eb2d50d2242fa86ee8fb4e7136fa4000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c6d6174636861206d61746963000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024d4d000000000000000000000000000000000000000000000000000000000000

Deployed ByteCode Sourcemap

44684:15163:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14778:167;;8:9:-1;5:2;;;30:1;27;20:12;5:2;14778:167:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;14778:167:0;-1:-1:-1;;;;;;14778:167:0;;:::i;:::-;;;;;;;;;;;;;;;;;;39656:85;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39656:85:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;39656:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19740:241;;8:9:-1;5:2;;;30:1;27;20:12;5:2;19740:241:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;19740:241:0;;:::i;:::-;;;;-1:-1:-1;;;;;19740:241:0;;;;;;;;;;;;;;19012:435;;8:9:-1;5:2;;;30:1;27;20:12;5:2;19012:435:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;19012:435:0;;;;;;;;:::i;:::-;;42224:109;;8:9:-1;5:2;;;30:1;27;20:12;5:2;42224:109:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;42224:109:0;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;42224:109:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;42224:109:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;42224:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;42224:109:0;;-1:-1:-1;42224:109:0;;-1:-1:-1;;;;;42224:109:0:i;45222:47::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;45222:47:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;45222:47:0;;:::i;:::-;;;;;;;;;;;;;;;;33538:96;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33538:96:0;;;:::i;50797:175::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50797:175:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;50797:175:0;;:::i;21486:361::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21486:361:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;21486:361:0;;;;;;;;;;;;;;;;;:::i;59552:290::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59552:290:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;59552:290:0;;;;;;;;;;;;;;;:::i;54953:505::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54953:505:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54953:505:0;;:::i;33147:232::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33147:232:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;33147:232:0;;;;;;;;:::i;44905:29::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;44905:29:0;;;:::i;48991:301::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48991:301:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;48991:301:0;;:::i;30493:167::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;30493:167:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;30493:167:0;;;;;;;;:::i;22509:168::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22509:168:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;22509:168:0;;;;;;;;;;;;;;;;;:::i;57740:135::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57740:135:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57740:135:0;;:::i;52355:1797::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;52355:1797:0;;:::i;41982:102::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41982:102:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;41982:102:0;;:::i;33980:199::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33980:199:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;33980:199:0;;:::i;41275:213::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41275:213:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;41275:213:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;41275:213:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;41275:213:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;41275:213:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;41275:213:0;;-1:-1:-1;41275:213:0;;-1:-1:-1;;;;;41275:213:0:i;46577:43::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;46577:43:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;46577:43:0;;:::i;:::-;;;;-1:-1:-1;;;;;46577:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42555:278;;8:9:-1;5:2;;;30:1;27;20:12;5:2;42555:278:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;42555:278:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;42555:278:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;42555:278:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;42555:278:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;42555:278:0;;-1:-1:-1;;;42555:278:0;;-1:-1:-1;;;;;42555:278:0;;-1:-1:-1;42555:278:0;;-1:-1:-1;42555:278:0:i;18316:265::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;18316:265:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;18316:265:0;;:::i;17842:248::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;17842:248:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;17842:248:0;-1:-1:-1;;;;;17842:248:0;;:::i;42092:124::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;42092:124:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;42092:124:0;-1:-1:-1;;;;;42092:124:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;42092:124:0;;;;;;;;;;;;;;;;;51788:393;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51788:393:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51788:393:0;;:::i;39856:89::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39856:89:0;;;:::i;29444:92::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;29444:92:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;29444:92:0;-1:-1:-1;;;;;29444:92:0;;:::i;29544:77::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;29544:77:0;;;:::i;20282:248::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20282:248:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;20282:248:0;;;;;;;;;;:::i;45060:42::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;45060:42:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;45060:42:0;;:::i;43003:136::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;43003:136:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;43003:136:0;;;;;;;;:::i;29327:109::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;29327:109:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;29327:109:0;-1:-1:-1;;;;;29327:109:0;;:::i;30018:25::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;30018:25:0;;;:::i;57883:121::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57883:121:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57883:121:0;;:::i;51034:746::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51034:746:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;51034:746:0;;;;;;;;-1:-1:-1;;;;;51034:746:0;;;;;;;;;;:::i;47606:144::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;47606:144:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;47606:144:0;;:::i;23412:348::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;23412:348:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;23412:348:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;23412:348:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;23412:348:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;23412:348:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;23412:348:0;;-1:-1:-1;23412:348:0;;-1:-1:-1;;;;;23412:348:0:i;40152:205::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40152:205:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;40152:205:0;;:::i;47796:746::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;47796:746:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;47796:746:0;;;;;;;;;;;-1:-1:-1;;;;;47796:746:0;;:::i;49319:1470::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;49319:1470:0;;:::i;55961:1743::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55961:1743:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;55961:1743:0;;:::i;55466:416::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55466:416:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;55466:416:0;;:::i;48684:299::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48684:299:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;48684:299:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;20860:179;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20860:179:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;20860:179:0;;;;;;;;;;:::i;30668:110::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;30668:110:0;;;:::i;54359:528::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;54359:528:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54359:528:0;;:::i;14778:167::-;-1:-1:-1;;;;;;14904:33:0;;14875:4;14904:33;;;;;;;;;;;;;14778:167;;;;:::o;39656:85::-;39728:5;39721:12;;;;;;;;-1:-1:-1;;39721:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39695:13;;39721:12;;39728:5;;39721:12;;39728:5;39721:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39656:85;;:::o;19740:241::-;19799:7;19841:16;19849:7;19841;:16::i;:::-;19819:110;;;;-1:-1:-1;;;;;19819:110:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19949:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;19949:24:0;;19740:241::o;19012:435::-;19076:13;19092:16;19100:7;19092;:16::i;:::-;19076:32;;19133:5;-1:-1:-1;;;;;19127:11:0;:2;-1:-1:-1;;;;;19127:11:0;;;19119:57;;;;-1:-1:-1;;;;;19119:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19211:10;-1:-1:-1;;;;;19211:19:0;;;;:58;;;19234:35;19251:5;19258:10;19234:16;:35::i;:::-;19189:164;;;;-1:-1:-1;;;;;19189:164:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19366:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;19366:29:0;-1:-1:-1;;;;;19366:29:0;;;;;;;;;19411:28;;19366:24;;19411:28;;;;;;;19012:435;;;:::o;42224:109::-;42299:26;42312:7;42321:3;42299:12;:26::i;:::-;42224:109;;:::o;45222:47::-;;;;;;;;;;;;;:::o;33538:96::-;33609:10;:17;33538:96;:::o;50797:175::-;50855:4;50898:10;50880:16;50888:7;50880;:16::i;:::-;-1:-1:-1;;;;;50880:28:0;;:55;;;;-1:-1:-1;50913:17:0;;;;:8;:17;;;;;:22;;;;;50912:23;50880:55;:83;;;;-1:-1:-1;50939:21:0;;;;:12;:21;;;;;;:24;50880:83;50872:92;50797:175;-1:-1:-1;;50797:175:0:o;21486:361::-;21678:39;21697:10;21709:7;21678:18;:39::i;:::-;21656:138;;;;-1:-1:-1;;;;;21656:138:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21807:32;21821:4;21827:2;21831:7;21807:13;:32::i;:::-;21486:361;;;:::o;59552:290::-;59681:14;;-1:-1:-1;;;;;59681:14:0;59669:10;:26;59661:70;;;;;-1:-1:-1;;;;;59661:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;59742:5;:12;;-1:-1:-1;;;;;;59742:12:0;-1:-1:-1;;;;;59742:12:0;;;;;;;;;;;59765:14;:30;59806:13;:28;;-1:-1:-1;;59806:28:0;;;;;;;;;;59552:290::o;54953:505::-;44448:13;:18;;44465:1;44448:18;;;;;55017:4;;55044:20;55056:7;55044:11;:20::i;:::-;55036:67;;;;-1:-1:-1;;;;;55036:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55203:1;55172:17;;;:8;:17;;;;;:28;;;:32;55168:211;;55222:12;55240:17;;;:8;:17;;;;;;:31;;;;55283:28;;;;;55240:76;;-1:-1:-1;;;;;55240:31:0;;;;55283:28;55222:12;55240:76;55222:12;55240:76;55283:28;55240:31;:76;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;55221:95:0;;;55339:7;55331:36;;;;;-1:-1:-1;;;;;55331:36:0;;;;;;;;;;;;-1:-1:-1;;;;;55331:36:0;;;;;;;;;;;;;;;55168:211;;55431:17;;;;:8;:17;;;;;55424:24;;-1:-1:-1;;;;;;55424:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;55424:24:0;;;;;;44560:13;;44544:29;;44536:73;;;;;-1:-1:-1;;;;;44536:73:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;44536:73:0;;;;;;;;;;;;;;;54953:505;;;;:::o;33147:232::-;33227:7;33263:16;33273:5;33263:9;:16::i;:::-;33255:5;:24;33247:80;;;;-1:-1:-1;;;;;33247:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33345:19:0;;;;;;:12;:19;;;;;:26;;33365:5;;33345:26;;;;;;;;;;;;;;33338:33;;33147:232;;;;:::o;44905:29::-;;;-1:-1:-1;;;;;44905:29:0;;:::o;48991:301::-;49045:7;49070:17;;;:8;:17;;;;;:22;;;;;49069:23;:50;;;;-1:-1:-1;49118:1:0;49096:21;;;:12;:21;;;;;;:23;;49069:50;:77;;;;-1:-1:-1;49145:1:0;49123:21;;;:12;:21;;;;;;:23;;49069:77;:118;;;;-1:-1:-1;49182:4:0;49150:20;49162:7;49150:11;:20::i;:::-;-1:-1:-1;;;;;49150:37:0;;49069:118;49065:220;;;-1:-1:-1;49211:21:0;;;;:12;:21;;;;;;49204:28;;49065:220;-1:-1:-1;49272:1:0;49265:8;;30493:167;30590:4;30890:21;30944:10;:8;:10::i;:::-;30922:108;;;;-1:-1:-1;;;;;30922:108:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30612:18;30618:2;30622:7;30612:5;:18::i;:::-;-1:-1:-1;30648:4:0;;30493:167;-1:-1:-1;;;30493:167:0:o;22509:168::-;22630:39;22647:4;22653:2;22657:7;22630:39;;;;;;;;;;;;:16;:39::i;57740:135::-;57801:15;57836:17;;;:8;:17;;;;;:31;;;-1:-1:-1;;;;;57836:31:0;;57740:135::o;52355:1797::-;44448:13;:18;;44465:1;44448:18;;;;;52746:23;:10;:21;:23::i;:::-;52745:24;52737:54;;;;;-1:-1:-1;;;;;52737:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;52849:17;;;;:8;:17;;;;;:22;;;;;52841:58;;;;;-1:-1:-1;;;;;52841:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;52981:4;52949:20;52961:7;52949:11;:20::i;:::-;-1:-1:-1;;;;;52949:37:0;;52941:77;;;;;-1:-1:-1;;;;;52941:77:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;53131:17;;;;:8;:17;;;;;:28;;;53124:3;:35;;53102:107;;;;;-1:-1:-1;;;;;53102:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;53327:17;;;;:8;:17;;;;;:28;;;53315:9;:40;53293:120;;;;;-1:-1:-1;;;;;53293:120:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;53426:13;53442:16;53450:7;53442;:16::i;:::-;53426:32;-1:-1:-1;53477:10:0;-1:-1:-1;;;;;53477:17:0;;;;53469:84;;;;-1:-1:-1;;;;;53469:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53668:1;53639:17;;;:8;:17;;;;;:28;;;:30;53635:298;;53687:12;53705:17;;;:8;:17;;;;;;:31;;;;53748:28;;;;;53705:76;;-1:-1:-1;;;;;53705:31:0;;;;53748:28;53687:12;53705:76;53687:12;53705:76;53748:28;53705:31;:76;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;53686:95:0;;;53804:7;53796:36;;;;;-1:-1:-1;;;;;53796:36:0;;;;;;;;;;;;-1:-1:-1;;;;;53796:36:0;;;;;;;;;;;;;;;53859:17;;;;:8;:17;;;;;;;;;:31;;;;53892:28;;;;;53852:69;;-1:-1:-1;;;;;53859:31:0;;;53852:69;;;;;;;;;;;;;;;;;;;;;;53635:298;;53980:17;;;;:8;:17;;;;;;;;;:31;;;:44;;-1:-1:-1;;;;;;53980:44:0;54014:10;53980:44;;;;;;54066:9;54035:28;;;;:40;;;54091:51;;;;;;;;;;;;;54014:10;;54091:51;;;;;;;;;44524:1;44560:13;;44544:12;:29;44536:73;;;;;-1:-1:-1;;;;;44536:73:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;44536:73:0;;;;;;;;;;;;;;41982:102;42036:4;42060:16;42068:7;42060;:16::i;33980:199::-;34038:7;34074:13;:11;:13::i;:::-;34066:5;:21;34058:78;;;;-1:-1:-1;;;;;34058:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34154:10;34165:5;34154:17;;;;;;;;;;;;;;;;34147:24;;33980:199;;;:::o;41275:213::-;41381:4;30890:21;30944:10;:8;:10::i;:::-;30922:108;;;;-1:-1:-1;;;;;30922:108:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41398:18;41404:2;41408:7;41398:5;:18::i;:::-;41427:31;41440:7;41449:8;41427:12;:31::i;:::-;-1:-1:-1;41476:4:0;;41275:213;-1:-1:-1;;;;41275:213:0:o;46577:43::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;46577:43:0;;;;;;;;;;;;;;;;;;:::o;42555:278::-;42636:4;30890:21;30944:10;:8;:10::i;:::-;30922:108;;;;-1:-1:-1;;;;;30922:108:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42671:11;:13;;;;;;;;42703:20;;:7;:20::i;:::-;42653:72;;42735:22;42741:2;42745:11;;42735:5;:22::i;:::-;42768:35;42781:11;;42794:8;42768:12;:35::i;18316:265::-;18371:7;18407:20;;;:11;:20;;;;;;-1:-1:-1;;;;;18407:20:0;18460:19;18438:110;;;;-1:-1:-1;;;;;18438:110:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17842:248;17897:7;-1:-1:-1;;;;;17939:19:0;;17917:111;;;;-1:-1:-1;;;;;17917:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;18048:24:0;;;;;;:17;:24;;;;;:34;;:32;:34::i;42092:124::-;42151:16;42187:21;42202:5;42187:14;:21::i;:::-;42180:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42092:124;;;:::o;51788:393::-;51842:4;51864:23;:10;:21;:23::i;:::-;51863:24;:63;;;;-1:-1:-1;51904:17:0;;;;:8;:17;;;;;:22;;;;;51863:63;:115;;;;-1:-1:-1;51950:17:0;;;;:8;:17;;;;;:28;;;51943:3;:35;;51863:115;:162;;;;;52009:16;52017:7;52009;:16::i;:::-;-1:-1:-1;;;;;51995:30:0;:10;-1:-1:-1;;;;;51995:30:0;;;51863:162;:216;;;;-1:-1:-1;52074:4:0;52042:20;52054:7;52042:11;:20::i;:::-;-1:-1:-1;;;;;52042:37:0;;51863:216;51859:315;;;-1:-1:-1;52113:4:0;52106:11;;39856:89;39930:7;39923:14;;;;;;;;-1:-1:-1;;39923:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39897:13;;39923:14;;39930:7;;39923:14;;39930:7;39923:14;;;;;;;;;;;;;;;;;;;;;;;;29444:92;30890:21;30944:10;:8;:10::i;:::-;30922:108;;;;-1:-1:-1;;;;;30922:108:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29509:19;29520:7;29509:10;:19::i;29544:77::-;29588:25;29602:10;29588:13;:25::i;:::-;29544:77::o;20282:248::-;-1:-1:-1;;;;;20362:16:0;;20368:10;20362:16;;20354:54;;;;;-1:-1:-1;;;;;20354:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;20440:10;20421:30;;;;:18;:30;;;;;;;;-1:-1:-1;;;;;20421:34:0;;;;;;;;;;;;:45;;-1:-1:-1;;20421:45:0;;;;;;;;;;20482:40;;;;;;;20421:34;;20440:10;20482:40;;;;;;;;;;;20282:248;;:::o;45060:42::-;;;;;;;;;;;;;:::o;43003:136::-;43093:38;43107:10;43119:2;43123:7;43093:13;:38::i;29327:109::-;29383:4;29407:21;:8;29420:7;29407:21;:12;:21;:::i;30018:25::-;;;;;;:::o;57883:121::-;57941:7;57968:17;;;:8;:17;;;;;:28;;;;57883:121::o;51034:746::-;51174:21;;;;:12;:21;;;;;;:24;51166:105;;;;-1:-1:-1;;;;;51166:105:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51291:17;;;;:8;:17;;;;;:22;;;;;51290:23;51282:89;;;;-1:-1:-1;;;;;51282:89:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51408:10;51390:16;51398:7;51390;:16::i;:::-;-1:-1:-1;;;;;51390:28:0;;51382:87;;;;-1:-1:-1;;;;;51382:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51482:17;;;;:8;:17;;;;;:44;;-1:-1:-1;;;;;;51482:44:0;-1:-1:-1;;;;;51482:44:0;;;;;-1:-1:-1;51537:28:0;;;:43;;;51591:25;;;:41;;;51643:22;;;;:29;;-1:-1:-1;;51643:29:0;;;;;;51739:31;51755:4;51482:17;51739:7;:31::i;:::-;51034:746;;;;:::o;47606:144::-;47661:4;47704:10;47686:16;47694:7;47686;:16::i;:::-;-1:-1:-1;;;;;47686:28:0;;:55;;;;-1:-1:-1;;47719:17:0;;;;:8;:17;;;;;:22;;;;;47718:23;;47606:144::o;23412:348::-;23562:31;23575:4;23581:2;23585:7;23562:12;:31::i;:::-;23626:48;23649:4;23655:2;23659:7;23668:5;23626:22;:48::i;:::-;23604:148;;;;-1:-1:-1;;;;;23604:148:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40152:205;40210:13;40244:16;40252:7;40244;:16::i;:::-;40236:76;;;;-1:-1:-1;;;;;40236:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40330:19;;;;:10;:19;;;;;;;;;40323:26;;;;;;-1:-1:-1;;40323:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40330:19;;40323:26;;40330:19;40323:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40323:26:0;;40152:205;-1:-1:-1;;;;;;40152:205:0:o;47796:746::-;47934:10;47916:16;47924:7;47916;:16::i;:::-;-1:-1:-1;;;;;47916:28:0;;47908:84;;;;-1:-1:-1;;;;;47908:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48069:17;;;;:8;:17;;;;;:22;;;;;48068:23;48060:97;;;;-1:-1:-1;;;;;48060:97:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48207:21;;;;:12;:21;;;;;:29;;;48302:7;;48298:235;;48386:31;48402:4;48409:7;48386;:31::i;:::-;48481:17;;;;:8;:17;;;;;:26;;-1:-1:-1;;;;;48481:26:0;;-1:-1:-1;;;;;;48481:26:0;;;;;;47796:746;;;:::o;49319:1470::-;44448:13;:18;;44465:1;44448:18;;;;;:13;49422:17;;;:8;:17;;;;;:22;;;;;49421:23;:50;;;;-1:-1:-1;49470:1:0;49448:21;;;:12;:21;;;;;;:23;;49421:50;49413:108;;;;-1:-1:-1;;;;;49413:108:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49582:21;;;;:12;:21;;;;;;49569:9;:34;;49561:77;;;;;-1:-1:-1;;;;;49561:77:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;49682:13;49698:16;49706:7;49698;:16::i;:::-;49682:32;-1:-1:-1;49735:10:0;-1:-1:-1;;;;;49735:17:0;;;;49727:85;;;;-1:-1:-1;;;;;49727:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49962:78;;;-1:-1:-1;;;;;49962:78:0;;;;;;50020:10;49962:78;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;49962:78:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;179:29;160:49;;49937:104:0;;49956:4;;49937:18;:104::i;:::-;50084:20;50107:38;50141:3;50107:29;50121:14;;50107:9;:13;;:29;;;;:::i;:::-;:33;:38;:33;:38;:::i;:::-;50084:61;-1:-1:-1;50156:20:0;50179:27;:9;50084:61;50179:27;:13;:27;:::i;:::-;50241:12;50259:17;;;:8;:17;;;;;;;:46;;50156:50;;-1:-1:-1;50241:12:0;;-1:-1:-1;;;;;50259:17:0;;;;50156:50;;50241:12;50259:46;50241:12;50259:46;50156:50;50259:17;:46;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;50240:65:0;;;50324:7;50316:36;;;;;-1:-1:-1;;;;;50316:36:0;;;;;;;;;;;;-1:-1:-1;;;;;50316:36:0;;;;;;;;;;;;;;;50406:5;;:34;;50387:13;;-1:-1:-1;;;;;50406:5:0;;50423:12;;50387:13;50406:34;50387:13;50406:34;50423:12;50406:5;:34;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;50386:54:0;;;50459:8;50451:37;;;;;-1:-1:-1;;;;;50451:37:0;;;;;;;;;;;;-1:-1:-1;;;;;50451:37:0;;;;;;;;;;;;;;;50552:1;50528:21;;;:12;:21;;;;;;;;:25;;;50564:8;:17;;;;;:30;;-1:-1:-1;;;;;;50564:30:0;;;50607:7;:16;;;;;;50626:9;50607:28;;;;50653:43;;;;;;;50674:10;;-1:-1:-1;;;;;50653:43:0;;;50541:7;;50653:43;;;;;;;;;;50750:14;;50712:67;;;50739:9;50712:67;;;;;;;;;;;;;;;;-1:-1:-1;;;;;50712:67:0;;;50723:7;;50712:67;;;;;;;;;44524:1;;;;;44560:13;;44544:12;:29;44536:73;;;;;-1:-1:-1;;;;;44536:73:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;44536:73:0;;;;;;;;;;;;;;55961:1743;44448:13;:18;;44465:1;44448:18;;;;;56044:20;56056:7;56044:11;:20::i;:::-;56036:48;;;;;-1:-1:-1;;;;;56036:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;56130:1;56101:17;;;:8;:17;;;;;:28;;;:30;56097:1435;;56220:29;56252:17;;;:8;:17;;;;;:31;;;;56398:14;;56365:28;;;;;-1:-1:-1;;;;;56252:31:0;;;;56220:29;56365:57;;56418:3;;56365:48;;:28;:48;:32;:48;:::i;:57::-;56437:20;56460:17;;;:8;:17;;;;;:28;;;56342:80;;-1:-1:-1;56437:20:0;56460:46;;56342:80;56460:46;:32;:46;:::i;:::-;56549:12;56567:17;;;:8;:17;;;;;;:29;:58;;56437:69;;-1:-1:-1;56549:12:0;;-1:-1:-1;;;;;56567:29:0;;;;56437:69;;56549:12;56567:58;56549:12;56567:58;56437:69;56567:29;:58;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;56548:77:0;;;56648:7;56640:36;;;;;-1:-1:-1;;;;;56640:36:0;;;;;;;;;;;;-1:-1:-1;;;;;56640:36:0;;;;;;;;;;;;;;;56738:5;;:34;;56719:13;;-1:-1:-1;;;;;56738:5:0;;56755:12;;56719:13;56738:34;56719:13;56738:34;56755:12;56738:5;:34;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;56718:54:0;;;56795:8;56787:37;;;;;-1:-1:-1;;;;;56787:37:0;;;;;;;;;;;;-1:-1:-1;;;;;56787:37:0;;;;;;;;;;;;;;;56860:17;;;;:8;:17;;;;;;;;;:29;;56906:28;;;;;56846:89;;;;;;;-1:-1:-1;;;;;56846:89:0;;;;56860:29;;;56869:7;;56846:89;;;;;;;;;;;56975:17;;;;:8;:17;;;;;;;;;:29;;57006:28;;;;;57036:14;;56955:110;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;56975:29:0;;;;56984:7;;56955:110;;;;;;;;;;57117:13;57133:16;57141:7;57133;:16::i;:::-;57372:81;;;-1:-1:-1;;;;;57372:81:0;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;57372:81:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;179:29;160:49;;57117:32:0;;-1:-1:-1;57347:107:0;;57366:4;;57347:18;:107::i;:::-;-1:-1:-1;;;57490:17:0;;;;:8;:17;;;;;;;;:28;;;57471:7;:16;;;;;;:47;-1:-1:-1;;;56097:1435:0;57562:17;;;;:8;:17;;;;;;;;;:31;;;;57595:28;;;;;57549:75;;-1:-1:-1;;;;;57562:31:0;;;57549:75;;;;;;;;;;;;;;;;;;;;;;57677:17;;;;:8;:17;;;;;57670:24;;-1:-1:-1;;;;;;57670:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;57670:24:0;;;;;;44560:13;;44544:29;;44536:73;;;;;-1:-1:-1;;;;;44536:73:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;44536:73:0;;;;;;;;;;;;;;55466:416;55525:4;55546:17;;;:8;:17;;;;;:22;;;;;:75;;;;-1:-1:-1;55593:17:0;;;;:8;:17;;;;;:28;;;55586:3;:35;;55546:75;:234;;;;-1:-1:-1;55687:17:0;;;;:8;:17;;;;;:25;;;;55657:28;;;;;:55;;;:108;;-1:-1:-1;55734:17:0;;;;:8;:17;;;;;:28;;;55542:333;;-1:-1:-1;55814:4:0;55807:11;;48684:299;48740:7;48782:21;;;:12;:21;;;;;;48740:7;;;;48782:23;48778:65;;-1:-1:-1;;;48815:21:0;;;;:12;:21;;;;;;;;48807:36;;48778:65;48887:1;48858:17;;;:8;:17;;;;;:28;;;:30;48854:79;;-1:-1:-1;;;48898:1:0;48901:17;;;:8;:17;;;;;:28;;;48898:1;48890:43;;48854:79;-1:-1:-1;;;48952:1:0;48958:16;;;:7;:16;;;;;;48952:1;;48684:299;;;;;;:::o;20860:179::-;-1:-1:-1;;;;;20996:25:0;;;20967:4;20996:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;20860:179::o;30668:110::-;30733:13;;30709:4;;30733:13;;;:37;;;30750:20;30759:10;30750:8;:20::i;:::-;30726:44;;30668:110;:::o;54359:528::-;54418:4;54439:17;;;:8;:17;;;;;:22;;;;;:346;;;;-1:-1:-1;54528:17:0;;;;:8;:17;;;;;:28;;;54521:3;:35;;;;:92;;-1:-1:-1;54612:1:0;54581:17;;;:8;:17;;;;;:28;;;:32;;54521:92;:171;;;;-1:-1:-1;54667:17:0;;;;:8;:17;;;;;:25;;;;54638:28;;;;;:54;54521:171;54498:272;;;-1:-1:-1;54765:4:0;54733:20;54745:7;54733:11;:20::i;:::-;-1:-1:-1;;;;;54733:37:0;;54435:445;;-1:-1:-1;54819:4:0;54812:11;;23962:155;24019:4;24052:20;;;:11;:20;;;;;;-1:-1:-1;;;;;24052:20:0;24090:19;;;23962:155::o;40604:195::-;40690:16;40698:7;40690;:16::i;:::-;40682:73;;;;-1:-1:-1;;;;;40682:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40766:19;;;;:10;:19;;;;;;;;:25;;;;;;;;:::i;24487:428::-;24599:4;24643:16;24651:7;24643;:16::i;:::-;24621:110;;;;-1:-1:-1;;;;;24621:110:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24742:13;24758:16;24766:7;24758;:16::i;:::-;24742:32;;24804:5;-1:-1:-1;;;;;24793:16:0;:7;-1:-1:-1;;;;;24793:16:0;;:64;;;;24850:7;-1:-1:-1;;;;;24826:31:0;:20;24838:7;24826:11;:20::i;:::-;-1:-1:-1;;;;;24826:31:0;;24793:64;:113;;;;24874:32;24891:5;24898:7;24874:16;:32::i;:::-;24785:122;24487:428;-1:-1:-1;;;;24487:428:0:o;34563:245::-;34649:38;34669:4;34675:2;34679:7;34649:19;:38::i;:::-;34700:47;34733:4;34739:7;34700:32;:47::i;:::-;34760:40;34788:2;34792:7;34760:27;:40::i;35073:202::-;35137:24;35149:2;35153:7;35137:11;:24::i;:::-;35174:40;35202:2;35206:7;35174:27;:40::i;:::-;35227;35259:7;35227:31;:40::i;11333:845::-;11393:4;12078:20;;11908:66;12127:15;;;;;:42;;-1:-1:-1;12146:23:0;;;12119:51;-1:-1:-1;;11333:845:0:o;13548:114::-;13640:14;;13548:114::o;35487:126::-;-1:-1:-1;;;;;35586:19:0;35549:17;35586:19;;;:12;:19;;;;;;35487:126::o;29629:122::-;29686:21;:8;29699:7;29686:21;:12;:21;:::i;:::-;29723:20;;-1:-1:-1;;;;;29723:20:0;;;;;;;;29629:122;:::o;29759:130::-;29819:24;:8;29835:7;29819:24;:15;:24;:::i;:::-;29859:22;;-1:-1:-1;;;;;29859:22:0;;;;;;;;29759:130;:::o;28634:235::-;28733:4;-1:-1:-1;;;;;28763:21:0;;28755:68;;;;-1:-1:-1;;;;;28755:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;28841:20:0;:11;:20;;;;;;;;;;;;;;;28634:235::o;27021:481::-;27177:4;27199:15;:2;-1:-1:-1;;;;;27199:13:0;;:15::i;:::-;27194:60;;-1:-1:-1;27238:4:0;27231:11;;27194:60;27295:153;;-1:-1:-1;;;;;27295:153:0;;27350:10;27295:153;;;;;;-1:-1:-1;;;;;27295:153:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;27266:13;;27295:36;;;;;;27350:10;;27379:4;;27402:7;;27428:5;;27295:153;;;;;;;;;;;27266:13;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;27295:153:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;27295:153:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;27295:153:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;27295:153:0;-1:-1:-1;;;;;;27467:26:0;-1:-1:-1;;;;;27467:26:0;;-1:-1:-1;;27021:481:0;;;;;;:::o;58395:1118::-;59000:27;59008:5;-1:-1:-1;;;;;59000:25:0;;:27::i;:::-;58992:72;;;;;-1:-1:-1;;;;;58992:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59138:12;59152:23;59187:5;-1:-1:-1;;;;;59179:19:0;59199:4;59179:25;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;59179:25:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;59137:67:0;;;;59223:7;59215:53;;;;-1:-1:-1;;;;;59215:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59285:17;;:21;59281:225;;59427:10;59416:30;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59416:30:0;59408:86;;;;-1:-1:-1;;;;;59408:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8899:470;8957:7;9201:6;9197:47;;-1:-1:-1;9231:1:0;9224:8;;9197:47;9268:5;;;9272:1;9268;:5;:1;9292:5;;;;;:10;9284:56;;;;-1:-1:-1;;;;;9284:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9360:1;8899:470;-1:-1:-1;;;8899:470:0:o;9837:333::-;9895:7;9994:1;9990;:5;9982:44;;;;;-1:-1:-1;;;;;9982:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;10037:9;10053:1;10049;:5;;;;;;;9837:333;-1:-1:-1;;;;9837:333:0:o;8464:184::-;8522:7;8555:1;8550;:6;;8542:49;;;;;-1:-1:-1;;;;;8542:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8614:5:0;;;8464:184::o;25889:530::-;26051:4;-1:-1:-1;;;;;26031:24:0;:16;26039:7;26031;:16::i;:::-;-1:-1:-1;;;;;26031:24:0;;26009:115;;;;-1:-1:-1;;;;;26009:115:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;26143:16:0;;26135:65;;;;-1:-1:-1;;;;;26135:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26213:23;26228:7;26213:14;:23::i;:::-;-1:-1:-1;;;;;26249:23:0;;;;;;:17;:23;;;;;:35;;:33;:35::i;:::-;-1:-1:-1;;;;;26295:21:0;;;;;;:17;:21;;;;;:33;;:31;:33::i;:::-;26341:20;;;;:11;:20;;;;;;:25;;-1:-1:-1;;;;;;26341:25:0;-1:-1:-1;;;;;26341:25:0;;;;;;;;;26384:27;;26341:20;;26384:27;;;;;;;25889:530;;;:::o;37092:1148::-;-1:-1:-1;;;;;37383:18:0;;37358:22;37383:18;;;:12;:18;;;;;:25;:32;;37413:1;37383:32;:29;:32;:::i;:::-;37426:18;37447:26;;;:17;:26;;;;;;37358:57;;-1:-1:-1;37580:28:0;;;37576:328;;-1:-1:-1;;;;;37647:18:0;;37625:19;37647:18;;;:12;:18;;;;;:34;;37666:14;;37647:34;;;;;;;;;;;;;;37625:56;;37731:11;37698:12;:18;37711:4;-1:-1:-1;;;;;37698:18:0;-1:-1:-1;;;;;37698:18:0;;;;;;;;;;;;37717:10;37698:30;;;;;;;;;;;;;;;;;;;:44;;;;37815:30;;;:17;:30;;;;;:43;;;37576:328;-1:-1:-1;;;;;37993:18:0;;;;;;:12;:18;;;;;:27;;;;;-1:-1:-1;;37993:27:0;;;:::i;:::-;;37092:1148;;;;:::o;35914:186::-;-1:-1:-1;;;;;36028:16:0;;;;;;;:12;:16;;;;;;;;:23;;35999:26;;;:17;:26;;;;;:52;;;36062:16;;;39:1:-1;23:18;;45:23;;36062:30:0;;;;;;;;35914:186::o;25168:335::-;-1:-1:-1;;;;;25240:16:0;;25232:61;;;;;-1:-1:-1;;;;;25232:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25313:16;25321:7;25313;:16::i;:::-;25312:17;25304:58;;;;;-1:-1:-1;;;;;25304:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;25375:20;;;;:11;:20;;;;;;;;:25;;-1:-1:-1;;;;;;25375:25:0;-1:-1:-1;;;;;25375:25:0;;;;;;;;25411:21;;:17;:21;;;;;:33;;:31;:33::i;:::-;25462;;25487:7;;-1:-1:-1;;;;;25462:33:0;;;25479:1;;25462:33;;25479:1;;25462:33;25168:335;;:::o;36301:164::-;36405:10;:17;;36378:24;;;;:15;:24;;;;;:44;;;39:1:-1;23:18;;45:23;;36433:24:0;;;;;;;36301:164::o;28098:178::-;28176:18;28180:4;28186:7;28176:3;:18::i;:::-;28175:19;28167:63;;;;;-1:-1:-1;;;;;28167:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;28241:20:0;:11;:20;;;;;;;;;;;:27;;-1:-1:-1;;28241:27:0;28264:4;28241:27;;;28098:178::o;28356:183::-;28436:18;28440:4;28446:7;28436:3;:18::i;:::-;28428:64;;;;-1:-1:-1;;;;;28428:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;28503:20:0;28526:5;28503:20;;;;;;;;;;;:28;;-1:-1:-1;;28503:28:0;;;28356:183::o;27670:175::-;27770:1;27734:24;;;:15;:24;;;;;;-1:-1:-1;;;;;27734:24:0;:38;27730:108;;27824:1;27789:24;;;:15;:24;;;;;:37;;-1:-1:-1;;;;;;27789:37:0;;;27730:108;27670:175;:::o;13769:110::-;13850:14;;:21;;13869:1;13850:21;:18;:21;:::i;:::-;13833:38;;13769:110::o;13670:91::-;13734:19;;13752:1;13734:19;;;13670:91::o;44684:15163::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44684:15163:0;;;-1:-1:-1;44684:15163:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Swarm Source

bzzr://d3217b6ed168ce6b7ca5300deebd80a96402daffd563ff2fd72587dbe10a8067
Loading