Token Fantomon Trainers Gen1 on FTM

 

Overview ERC-721

Total Supply:
10,000 FTG1

Holders:
1,246 addresses

Transfers:
-

Loading
[ Download CSV Export  ] 
Loading
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
FantomonTrainer

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 15000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

/*
░██╗░░░░░░░██╗░█████╗░████████╗███████╗██████╗░██╗░░██╗██████╗░░█████╗░██████╗░
░██║░░██╗░░██║██╔══██╗╚══██╔══╝██╔════╝██╔══██╗██║░░██║╚════██╗██╔══██╗╚════██╗
░╚██╗████╗██╔╝███████║░░░██║░░░█████╗░░██████╔╝███████║░░███╔═╝██║░░██║░█████╔╝
░░████╔═████║░██╔══██║░░░██║░░░██╔══╝░░██╔══██╗██╔══██║██╔══╝░░██║░░██║░╚═══██╗
░░╚██╔╝░╚██╔╝░██║░░██║░░░██║░░░███████╗██║░░██║██║░░██║███████╗╚█████╔╝██████╔╝
░░░╚═╝░░░╚═╝░░╚═╝░░╚═╝░░░╚═╝░░░╚══════╝╚═╝░░╚═╝╚═╝░░╚═╝╚══════╝░╚════╝░╚═════╝░

░█████╗░███╗░░██╗██████╗░  ██╗░░░░░░█████╗░██████╗░██╗░░██╗██╗███╗░░██╗
██╔══██╗████╗░██║██╔══██╗  ██║░░░░░██╔══██╗██╔══██╗██║░██╔╝██║████╗░██║
███████║██╔██╗██║██║░░██║  ██║░░░░░███████║██████╔╝█████═╝░██║██╔██╗██║
██╔══██║██║╚████║██║░░██║  ██║░░░░░██╔══██║██╔══██╗██╔═██╗░██║██║╚████║
██║░░██║██║░╚███║██████╔╝  ███████╗██║░░██║██║░░██║██║░╚██╗██║██║░╚███║
╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░  ╚══════╝╚═╝░░╚═╝╚═╝░░╚═╝╚═╝░░╚═╝╚═╝╚═╝░░╚══╝
*/
// Sources flattened with hardhat v2.6.7 https://hardhat.org

// File @openzeppelin/contracts/utils/introspection/[email protected]

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.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);
}


// File @openzeppelin/contracts/token/ERC721/[email protected]





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

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

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

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

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

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

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

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

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

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

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

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


// File @openzeppelin/contracts/token/ERC721/[email protected]





/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}


// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]





/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}


// File @openzeppelin/contracts/utils/[email protected]





/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


// File @openzeppelin/contracts/utils/[email protected]





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

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


// File @openzeppelin/contracts/utils/[email protected]





/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

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

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

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

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


// File @openzeppelin/contracts/utils/introspection/[email protected]





/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}


// File @openzeppelin/contracts/token/ERC721/[email protected]











/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

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

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

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

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

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

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

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

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

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), 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.
     *
     * @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
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

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


// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]





/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}


// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]






/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => 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;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
        return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

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

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

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

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @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 {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @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 = ERC721.balanceOf(from) - 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
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the 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 = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}


// File @openzeppelin/contracts/security/[email protected]





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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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


// File @openzeppelin/contracts/access/[email protected]





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

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

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

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

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

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

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

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}


// File contracts/IFantomonTrainer.sol





interface IFantomonTrainer {

    /**************************************************************************
     * Stats and attributes for all trainers
     **************************************************************************/
    function getKinship(uint256 _tokenId) external view returns (uint256);
    function getFlare(uint256 _tokenId) external view returns (uint256);
    function getCourage(uint256 _tokenId) external view returns (uint256);
    function getWins(uint256 _tokenId) external view returns (uint256);
    function getLosses(uint256 _tokenId) external view returns (uint256);
    /* Stats and attributes for all trainers
     **************************************************************************/

    /**************************************************************************
     * Getters
     **************************************************************************/
    function getStatus(uint256 _tokenId) external view returns (uint8);
    function getRarity(uint256 _tokenId) external view returns (uint8);
    function getClass(uint256 _tokenId) external view returns (uint8);
    function getFace(uint256 _tokenId) external view returns (uint8);
    function getHomeworld(uint256 _tokenId) external view returns (uint8);
    function getTrainerName(uint256 _tokenId) external view returns (string memory);
    function getHealing(uint256 _tokenId) external view returns (uint256);
    /* End getters
     **************************************************************************/

}


// File contracts/FantomonTrainerGraphics.sol

/*
░██╗░░░░░░░██╗░█████╗░████████╗███████╗██████╗░██╗░░██╗██████╗░░█████╗░██████╗░
░██║░░██╗░░██║██╔══██╗╚══██╔══╝██╔════╝██╔══██╗██║░░██║╚════██╗██╔══██╗╚════██╗
░╚██╗████╗██╔╝███████║░░░██║░░░█████╗░░██████╔╝███████║░░███╔═╝██║░░██║░█████╔╝
░░████╔═████║░██╔══██║░░░██║░░░██╔══╝░░██╔══██╗██╔══██║██╔══╝░░██║░░██║░╚═══██╗
░░╚██╔╝░╚██╔╝░██║░░██║░░░██║░░░███████╗██║░░██║██║░░██║███████╗╚█████╔╝██████╔╝
░░░╚═╝░░░╚═╝░░╚═╝░░╚═╝░░░╚═╝░░░╚══════╝╚═╝░░╚═╝╚═╝░░╚═╝╚══════╝░╚════╝░╚═════╝░

░█████╗░███╗░░██╗██████╗░  ██╗░░░░░░█████╗░██████╗░██╗░░██╗██╗███╗░░██╗
██╔══██╗████╗░██║██╔══██╗  ██║░░░░░██╔══██╗██╔══██╗██║░██╔╝██║████╗░██║
███████║██╔██╗██║██║░░██║  ██║░░░░░███████║██████╔╝█████═╝░██║██╔██╗██║
██╔══██║██║╚████║██║░░██║  ██║░░░░░██╔══██║██╔══██╗██╔═██╗░██║██║╚████║
██║░░██║██║░╚███║██████╔╝  ███████╗██║░░██║██║░░██║██║░╚██╗██║██║░╚███║
╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░  ╚══════╝╚═╝░░╚═╝╚═╝░░╚═╝╚═╝░░╚═╝╚═╝╚═╝░░╚══╝
*/





contract FantomonTrainerGraphics is Ownable {

    bool private IMAGE_EMBED = false;

    //string private _baseURIextended = "ipfs://bafybeib3qdfhsed43gsoj3l6lckwvbqgb7svficyyyxp53lxzn6lcouwmu/"
    string private _baseURIextended = "http://ipfs.io/ipfs/bafybeib3qdfhsed43gsoj3l6lckwvbqgb7svficyyyxp53lxzn6lcouwmu/";

    string[5] private STATUSES = ["WATCHING ANIME", "PREPARING FOR BATTLE", "BATTLING", "TREATING WOUNDS", "LOST"];

    uint8 constant private RESTING   = 0;
    uint8 constant private PREPARING = 1;
    uint8 constant private BATTLING  = 2;
    uint8 constant private HEALING   = 3;
    uint8 constant private LOST      = 4;

    string[4] private RARITIES = ["Common", "Rare", "Epic", "Legendary"];

    string constant private COMMON_CARD    = '#708155"/><stop offset="95%" stop-color="#daddc3"/></linearGradient></defs><rect x="2" y="2" width="242" height="444" style="fill:#daddc3;';
    string constant private RARE_CARD      = '#daddc3"/><stop offset="95%" stop-color="#a17a71"/></linearGradient></defs><rect x="2" y="2" width="242" height="444" style="fill:#a17a71;';
    string constant private EPIC_CARD      = '#ffdda2"/><stop offset="95%" stop-color="#c1e6e6"/></linearGradient></defs><rect x="2" y="2" width="242" height="444" style="fill:#c1e6e6;';
    string constant private LEGENDARY_CARD = '#181211"/><stop offset="95%" stop-color="#ffba6a"/></linearGradient></defs><rect x="2" y="2" width="242" height="444" style="fill:#ffba6a;';

    string[16] private CLASSES = [
        // 60%
        "Botanist",
        "Zoologist",
        "Hydrologist",
        "Entomologist",

        // 30%
        "Biochemist",
        "Microbiologist",
        "Biotechnologist",
        "Biomedical Engineer",

        // 9%
        "Geneticist",
        "Astrophysicist",
        "String Theorist",
        "Quantum Physicist",

        // 1%
        "Ent Mystic",
        "Ent Theorist",
        "Cosmic Explorer",
        "Ancient Ent Master"
    ];

    string[7] private FACES = ["1", "2", "3", "4", "5", "6", "7"];

    string[13] private WORLDS = [
        // 60%
        "Gunka",
        "Sha'afta",
        "Jiego ",
        "Beck S68",
        "Gem Z32",

        // 30%
        "Junapla",
        "Strigah",
        "Mastazu",

        // 9%
        "Clyve R24",
        "Larukin",
        "H-203",

        // 1%
        "Ancient Territories",
        "Relics Rock"
    ];

    // Setters
    function setBaseURI(string memory baseURI_) external onlyOwner {
        _baseURIextended = baseURI_;
    }
    function toggleEmbed() external onlyOwner {
        IMAGE_EMBED = !IMAGE_EMBED;
    }

    // Getters
    function getTrainerName(uint256 _tokenId, IFantomonTrainer _trainers) public view returns (string memory) {
        return _trainers.getTrainerName(_tokenId);
    }
    function getKinship(uint256 _tokenId, IFantomonTrainer _trainers) public view returns (string memory) {
        return toString(_trainers.getKinship(_tokenId));
    }
    function getFlare(uint256 _tokenId, IFantomonTrainer _trainers) public view returns (string memory) {
        return toString(_trainers.getFlare(_tokenId));
    }
    function getHealing(uint256 _tokenId, IFantomonTrainer _trainers) public view returns (string memory) {
        return toString(_trainers.getHealing(_tokenId));
    }
    function getCourage(uint256 _tokenId, IFantomonTrainer _trainers) public view returns (string memory) {
        return toString(_trainers.getCourage(_tokenId));
    }
    function getWins(uint256 _tokenId, IFantomonTrainer _trainers) public view returns (string memory) {
        return toString(_trainers.getWins(_tokenId));
    }
    function getLosses(uint256 _tokenId, IFantomonTrainer _trainers) public view returns (string memory) {
        return toString(_trainers.getLosses(_tokenId));
    }
    function getClass(uint256 _tokenId, IFantomonTrainer _trainers) public view returns (string memory) {
        return CLASSES[_trainers.getClass(_tokenId)];
    }
    function getFace(uint256 _tokenId, IFantomonTrainer _trainers) public view returns (string memory) {
        return FACES[_trainers.getFace(_tokenId)];
    }
    function getHomeworld(uint256 _tokenId, IFantomonTrainer _trainers) public view returns (string memory) {
        return WORLDS[_trainers.getHomeworld(_tokenId)];
    }
    function getRarity(uint256 _tokenId, IFantomonTrainer _trainers) public view returns (string memory) {
        return RARITIES[_trainers.getRarity(_tokenId)];
    }
    function getStatus(uint256 _tokenId, IFantomonTrainer _trainers) public view returns (string memory) {
        return STATUSES[_trainers.getStatus(_tokenId)];
    }
    function getImageURI(uint256 _tokenId, IFantomonTrainer _trainers) public view returns (string memory) {
        return string(abi.encodePacked(_baseURIextended, getRarity(_tokenId, _trainers), getFace(_tokenId, _trainers)));
    }

    // Visualizations
    function tokenURI(uint256 _tokenId, IFantomonTrainer _trainers) external view returns (string memory) {
        return tokenURIEmbeddable(_tokenId, _trainers, IMAGE_EMBED);
    }
    function tokenURIEmbeddable(uint256 _tokenId, IFantomonTrainer _trainers, bool _embed) public view returns (string memory) {
        string[34] memory parts;
        parts[0]  = '<svg preserveaspectratio="xMinYMin meet" style="width: 100%; height: 100%; transform: translate3d(0px, 0px, 0px);" viewbox="0 0 246 448" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.header { fill: black; font-family: Courier; font-size: 16px; }</style><style>.base { fill: black; font-family: Courier; font-size: 16px; }</style><style>.trailer { fill: white; font-family: Courier; font-size: 12px; }</style><style>.trailerGen { fill: gold; font-family: Courier; font-size: 12px; }</style>';
        if (_embed) {
            parts[1]  = '<image x="0" y="0" width="246" height="448" xlink:href="';
            parts[2]  =     getImageURI(_tokenId, _trainers);
            parts[3]  = '"/>'
                        '<text x="123" y="25" text-anchor="middle" font-weight="bold" class="base">';
        } else {
            parts[1]  = '<defs> <linearGradient id="myGradient" gradientTransform="rotate(90)"><stop offset="5%" stop-color="';
            if (_trainers.getRarity(_tokenId) == 0) {
                parts[2]  =     COMMON_CARD;
            } else if (_trainers.getRarity(_tokenId) == 1) {
                parts[2]  =     RARE_CARD;
            } else if (_trainers.getRarity(_tokenId) == 2) {
                parts[2]  =     EPIC_CARD;
            } else {  // if _trainers.getRarity(_tokenId) == 3) {
                parts[2]  =     LEGENDARY_CARD;
            }
            parts[3]  = 'stroke:#120f16;stroke-width:4;fill-opacity:1.0"/><rect x="7" y="8" width="232" height="23" style="stroke:#120f16;stroke-width:1.5;fill-opacity:0.0"/><rect x="7" y="30" width="232" height="192" style="fill:url(#myGradient);stroke:#120f16;stroke-width:1.5;fill-opacity:1"/><rect x="7" y="222" width="232" height="128" style="stroke:#120f16;stroke-width:1.5;fill-opacity:0.0"/><rect x="11" y="226" width="224" height="120" style="stroke:#120f16;stroke-width:1.5;fill-opacity:0.0"/><rect x="7" y="351" width="232" height="90" style="stroke:#120f16;stroke-width:1.5;fill-opacity:1"/><text x="123" y="100" text-anchor="middle" font-weight="bold" class="base">Fantomon</text><text x="123" y="120" text-anchor="middle" font-weight="bold" class="base">Trainer</text><text x="123" y="140" text-anchor="middle" font-weight="bold" class="base">#';
            parts[4]  =     toString(_tokenId);
            parts[5]  = '</text><text x="123" y="160" text-anchor="middle" font-weight="bold" class="base">Avatar ';
            parts[6]  = getFace(_tokenId, _trainers);
            parts[7]  = '</text>'
                        '<text x="123" y="25" text-anchor="middle" font-weight="bold" class="base">';
        }
        parts[8]  =     getTrainerName(_tokenId, _trainers);
        parts[9]  = '</text>'
                    '<text x="14" y="243" font-weight="bold" class="base">'
                        'Kinship: ';
        parts[10]  =     getKinship(_tokenId, _trainers);
        parts[11]  = '</text>'
                    '<text x="14" y="262" font-weight="bold" class="base">'
                        'Flare: ';
        parts[12]  =    getFlare(_tokenId, _trainers);
        parts[13]  = '</text>'
                    '<text x="14" y="281" font-weight="bold" class="base">'
                        'Healing: ';
        parts[14] =     getHealing(_tokenId, _trainers);
        parts[15] = '</text>'
                    '<text x="14" y="300" font-weight="bold" class="base">'
                        'Courage: ';
        parts[16]  =    getCourage(_tokenId, _trainers);
        parts[17] = '</text>'
                    '<text x="14" y="319" class="base">'
                        'Wins: ';
        parts[18] =     getWins(_tokenId, _trainers);
        parts[19] = '</text>'
                    '<text x="14" y="338" class="base">'
                        'Losses: ';
        parts[20] =     getLosses(_tokenId, _trainers);
        parts[21] = '</text>'
                    '<text x="14" y="365" class="trailer">'
                        'Class: ';
        parts[22] =     getClass(_tokenId, _trainers);
        parts[23] = '</text>'
                    '<text x="15" y="380" class="trailer">'
                        'Homeworld: ';
        parts[24] =     getHomeworld(_tokenId, _trainers);
        parts[25] = '</text>'
                    '<text x="14" y="395" class="trailer">'
                        'Rarity: ';
        parts[26] =     getRarity(_tokenId, _trainers);
        parts[27] = '</text>'
                    '<text x="14" y="416" class="trailer">'
                        'Status: ';
        parts[28] =     getStatus(_tokenId, _trainers);
        if (_trainers.getStatus(_tokenId) == RESTING) {  // if RESTING, green box
            parts[29] = '</text><rect x="10" y="403" width="166" height="17" style="fill:lime;stroke:lime;stroke-width:2;fill-opacity:0.1;stroke-opacity:0.9" />';
        } else if (_trainers.getStatus(_tokenId) == PREPARING) {  // if PREPARING, yellow box
            parts[29] = '</text><rect x="10" y="403" width="210" height="17" style="fill:yellow;stroke:yellow;stroke-width:2;fill-opacity:0.1;stroke-opacity:0.9" />';
        } else if (_trainers.getStatus(_tokenId) == BATTLING) {  // if BATTLING, blue box
            parts[29] = '</text><rect x="10" y="403" width="123" height="17" style="fill:cyan;stroke:cyan;stroke-width:2;fill-opacity:0.1;stroke-opacity:0.9" />';
        } else if (_trainers.getStatus(_tokenId) == HEALING) {  // if HEALING, red box
            parts[29] = '</text><rect x="10" y="403" width="173" height="17" style="fill:red;stroke:red;stroke-width:2;fill-opacity:0.1;stroke-opacity:0.9" />';
        } else {  // if (_trainers.getStatus(_tokenId) == LOST) {  // if LOST, magenta box
            parts[29] = '</text><rect x="10" y="403" width="94" height="17" style="fill:magenta;stroke:magenta;stroke-width:2;fill-opacity:0.1;stroke-opacity:0.9" />';
        }
        parts[30] = '<text x="14" y="435" font-weight="bold" class="trailerGen">'
                        'Generation 1'
                    '</text>'
                    '<text x="232" y="435" text-anchor="end" class="trailer">#';
        parts[31] =     toString(_tokenId);
        parts[32] = '</text>';
        parts[33] = '</svg>';

        string memory output = string(abi.encodePacked(parts[0], parts[1],  parts[2],  parts[3],  parts[4],  parts[5],  parts[6],  parts[7],  parts[8]));
        output =               string(abi.encodePacked(output,   parts[9],  parts[10], parts[11], parts[12], parts[13], parts[14], parts[15], parts[16]));
        output =               string(abi.encodePacked(output,   parts[17], parts[18], parts[19], parts[20], parts[21], parts[22], parts[23], parts[24]));
        output =               string(abi.encodePacked(output,   parts[25], parts[26], parts[27], parts[28], parts[29], parts[30], parts[31], parts[32]));
        output =               string(abi.encodePacked(output,   parts[33]));

        parts[0]  = '{"name":"';
        parts[1]  = getTrainerName(_tokenId, _trainers);
        parts[2]  = '", "trainerId":"';
        parts[3]  = toString(_tokenId);
        parts[4]  = '", "avatar":"';
        parts[5]  = getFace(_tokenId, _trainers);
        parts[6]  = '", "kinship": "';
        parts[7]  = getKinship(_tokenId, _trainers);
        parts[8]  = '", "flare": "';
        parts[9]  = getFlare(_tokenId, _trainers);
        parts[10]  = '", "healing": "';
        parts[11]  = getHealing(_tokenId, _trainers);
        parts[12] = '", "courage": "';
        parts[13] = getCourage(_tokenId, _trainers);
        parts[14] = '", "wins": "';
        parts[15] = getWins(_tokenId, _trainers);
        parts[16] = '", "losses": "';
        parts[17] = getLosses(_tokenId, _trainers);
        parts[18] = '", "class": "';
        parts[19] = getClass(_tokenId, _trainers);
        parts[20] = '", "homeworld": "';
        parts[21] = getHomeworld(_tokenId, _trainers);
        parts[22] = '", "rarity": "';
        parts[23] = getRarity(_tokenId, _trainers);
        parts[24] = '", "status":"';
        parts[25] = getStatus(_tokenId, _trainers);
        parts[26] = '", "generation": "1", ';

        string memory json = string(abi.encodePacked(parts[0], parts[1],  parts[2],  parts[3],  parts[4],  parts[5],  parts[6],  parts[7],  parts[8]));
        json =               string(abi.encodePacked(json,   parts[9],  parts[10], parts[11], parts[12], parts[13], parts[14], parts[15], parts[16]));
        json =               string(abi.encodePacked(json,   parts[17], parts[18], parts[19], parts[20], parts[21], parts[22], parts[23], parts[24]));
        json =               string(abi.encodePacked(json,   parts[25], parts[26]));  //, parts[27], parts[28], parts[29], parts[30], parts[31]));
        json = Base64.encode(bytes(string(abi.encodePacked(json, '"description": "Fantomon Trainers are player profiles for the Fantomons Play-to-Earn game. Attributes (class, homeworld, rarity, and avatar#) are randomly chosen and stored on-chain. Stats are initialized to 1, wins and losses to 0, and can be increased via interactions in the Fantomon universe. Start playing at Fantomon.net", "image": "data:image/svg+xml;base64,', Base64.encode(bytes(output)), '"}'))));
        output = string(abi.encodePacked('data:application/json;base64,', json));

        return output;
    }

    function toString(uint256 value) internal pure returns (string memory) {
    // Inspired by OraclizeAPI's implementation - MIT license
    // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

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

/// [MIT License]
/// @title Base64
/// @notice Provides a function for encoding some bytes in base64
/// @author Brecht Devos <[email protected]>
library Base64 {
    bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /// @notice Encodes some bytes to the base64 representation
    function encode(bytes memory data) internal pure returns (string memory) {
        uint256 len = data.length;
        if (len == 0) return "";

        // multiply by 4/3 rounded up
        uint256 encodedLen = 4 * ((len + 2) / 3);

        // Add some extra buffer at the end
        bytes memory result = new bytes(encodedLen + 32);

        bytes memory table = TABLE;

        assembly {
            let tablePtr := add(table, 1)
            let resultPtr := add(result, 32)

            for {
                let i := 0
            } lt(i, len) {

            } {
                i := add(i, 3)
                let input := and(mload(add(data, i)), 0xffffff)

                let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF))
                out := shl(224, out)

                mstore(resultPtr, out)

                resultPtr := add(resultPtr, 4)
            }

            switch mod(len, 3)
            case 1 {
                mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
            }
            case 2 {
                mstore(sub(resultPtr, 1), shl(248, 0x3d))
            }

            mstore(result, encodedLen)
        }

        return string(result);
    }
}


// File contracts/IFantomon.sol





/**
 * @dev Interface for a Fantomon Location contract
 */
interface IFantomon {
    /**
     * @dev Called with the tokenId of a trainer and its fantomon to interact with that fantomon
     * @param _trainer  - the trainer ID interacting
     * @param _fantomon - the fantomon ID being interacted with
     * @param _args     - miscellaneous other arguments (placeholder to be interpreted by Fantomon contracts)
     * Note: msg.sender here should be the FantomonTrainer contract to which _trainer belongs
     */
    function interact(uint256 _trainer, uint256 _fantomon, uint256[] calldata _args) external;
}


// File contracts/IFantomonLocation.sol





/**
 * @dev Interface for a Fantomon Location contract
 */
interface IFantomonLocation {
    /**
     * @dev Called with the tokenId of a trainer to enter that trainer into a new location
     * @param _tokenId - the trainer ID entering this location
     * @param _args    - miscellaneous other arguments (placeholder to be interpreted by location contracts)
     */
    function enter(uint256 _tokenId, uint256[] calldata _args) external;
    /**
     * @dev Called with the tokenId of a trainer to flee from a location
     * @param _tokenId - the trainer ID being entered into arena
     */
    function flee(uint256 _tokenId) external;
}


// File contracts/FantomonTrainer.sol

/*
░██╗░░░░░░░██╗░█████╗░████████╗███████╗██████╗░██╗░░██╗██████╗░░█████╗░██████╗░
░██║░░██╗░░██║██╔══██╗╚══██╔══╝██╔════╝██╔══██╗██║░░██║╚════██╗██╔══██╗╚════██╗
░╚██╗████╗██╔╝███████║░░░██║░░░█████╗░░██████╔╝███████║░░███╔═╝██║░░██║░█████╔╝
░░████╔═████║░██╔══██║░░░██║░░░██╔══╝░░██╔══██╗██╔══██║██╔══╝░░██║░░██║░╚═══██╗
░░╚██╔╝░╚██╔╝░██║░░██║░░░██║░░░███████╗██║░░██║██║░░██║███████╗╚█████╔╝██████╔╝
░░░╚═╝░░░╚═╝░░╚═╝░░╚═╝░░░╚═╝░░░╚══════╝╚═╝░░╚═╝╚═╝░░╚═╝╚══════╝░╚════╝░╚═════╝░

░█████╗░███╗░░██╗██████╗░  ██╗░░░░░░█████╗░██████╗░██╗░░██╗██╗███╗░░██╗
██╔══██╗████╗░██║██╔══██╗  ██║░░░░░██╔══██╗██╔══██╗██║░██╔╝██║████╗░██║
███████║██╔██╗██║██║░░██║  ██║░░░░░███████║██████╔╝█████═╝░██║██╔██╗██║
██╔══██║██║╚████║██║░░██║  ██║░░░░░██╔══██║██╔══██╗██╔═██╗░██║██║╚████║
██║░░██║██║░╚███║██████╔╝  ███████╗██║░░██║██║░░██║██║░╚██╗██║██║░╚███║
╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░  ╚══════╝╚═╝░░╚═╝╚═╝░░╚═╝╚═╝░░╚═╝╚═╝╚═╝░░╚══╝
*/








contract FantomonTrainer is IFantomonTrainer, ERC721Enumerable, ReentrancyGuard, Ownable {

    //using SafeMath for uint;
    //using SafeMath for uint256;

    // Contract containing visualization logic for Fantomon Trainers
    FantomonTrainerGraphics graphics_;

    /**************************************************************************
     * High-level constants
     **************************************************************************/
    uint256 constant private PRICE = 10 ether;
    uint256 constant private MAX_MINT = 10;
    uint256 constant private SUPPLY_CAP = 10000;
    /* End high-level constants
     **************************************************************************/

    /**************************************************************************
    * Addresses, team, whiteli
     **************************************************************************/
    address private LARKIN = 0x14E8F54f35eE42Cdf436A19086659B34dA6D9D47;
    address private WATER  = 0x692b54A541eE5590F551E002b0967b7981fF36F5;
    mapping(address => bool) private isTeam_;
    mapping(address => bool) public isOnWhiteList_;
    /* End addresses, team, whiteli
     **************************************************************************/

    /**************************************************************************
     * Stats and attributes for all trainers
     **************************************************************************/
    mapping (uint256 => address) public location_;    // per tokenId
    mapping (uint256 => bool)    private named_;       // per tokenId
    mapping (string => bool)     public  nameTaken_;
    mapping (uint256 => string)  private trainerName_; // per tokenId

    mapping (uint256 => uint256) private kinship_;      // per tokenId
    mapping (uint256 => uint256) private flare_;        // per tokenId
    mapping (uint256 => uint256) private timeHealing_;  // per tokenId
    mapping (uint256 => uint256) private courage_;      // per tokenId

    mapping (uint256 => uint256) private wins_;         // per tokenId
    mapping (uint256 => uint256) private losses_;       // per tokenId

    mapping (uint256 => uint256) private timeLastInteraction_;  // per tokenId - what time did you last interact with a Fantomon
    mapping (uint256 => uint256) private timeEnteredRift_;      // per tokenId - what time did you last enter a HealingRift
    mapping (uint256 => uint256) private timeLastJourney_;      // per tokenId - what time did you last journey


    uint8 constant private RESTING   = 0;
    uint8 constant private PREPARING = 1;
    uint8 constant private BATTLING  = 2;
    uint8 constant private HEALING   = 3;
    uint8 constant private LOST      = 4;

    mapping (uint256 => uint8) private status_;      // per tokenId

    mapping (uint256 => uint8) private rarity_;      // per tokenId

    uint8 constant private NUM_TRAINER_CLASSES = 16;
    mapping (uint256 => uint8) private class_;  // per tokenId

    uint8 constant private NUM_TRAINER_FACES = 7;
    mapping (uint256 => uint8) private face_;  // per tokenId

    uint8 constant private NUM_WORLDS = 13;
    mapping (uint256 => uint8) private homeworld_;  // per tokenId
    /* Stats and attributes for all trainers
     **************************************************************************/

    /**************************************************************************
     * External enabled contracts
     **************************************************************************/
    mapping (address => bool) public fantomonsEnabled_;
    mapping (address => bool) public arenasEnabled_;
    mapping (address => bool) public healingRiftsEnabled_;
    /* End external enabled contracts
     **************************************************************************/


    /**************************************************************************
     * Modifiers
     **************************************************************************/
    modifier onlyOwnerOf(uint _tokenId) {
      require(msg.sender == ownerOf(_tokenId), "Only owner of that tokenId can do that");
      _;
    }
    modifier onlyTeam() {
        require(msg.sender == owner() || msg.sender == LARKIN || msg.sender == WATER, "Can't do that, you are not part of the team");
        _;
    }
    modifier onlyCurrentLocation(uint256 _tokenId) {
        require(location_[_tokenId] == msg.sender, "Only this trainer's current location can do this");
        _;
    }
    /* End modifiers
     **************************************************************************/

    /**************************************************************************
     * Getters
     **************************************************************************/
    // Simple getters for interface
    function getKinship(uint256 _tokenId) external view override returns (uint256) {
        return kinship_[_tokenId];
    }
    function getFlare(uint256 _tokenId) external view override returns (uint256) {
        return flare_[_tokenId];
    }
    function getCourage(uint256 _tokenId) external view override returns (uint256) {
        return courage_[_tokenId];
    }
    function getWins(uint256 _tokenId) external view override returns (uint256) {
        return wins_[_tokenId];
    }
    function getLosses(uint256 _tokenId) external view override returns (uint256) {
        return losses_[_tokenId];
    }
    function getStatus(uint256 _tokenId) external view override returns (uint8) {
        return status_[_tokenId];
    }
    function getRarity(uint256 _tokenId) external view override returns (uint8) {
        return rarity_[_tokenId];
    }
    function getClass(uint256 _tokenId) external view override returns (uint8) {
        return class_[_tokenId];
    }
    function getFace(uint256 _tokenId) external view override returns (uint8) {
        return face_[_tokenId];
    }
    function getHomeworld(uint256 _tokenId) external view override returns (uint8) {
        return homeworld_[_tokenId];
    }
    function getTrainerName(uint256 _tokenId) external view override returns (string memory) {
        if (named_[_tokenId]) {
            return trainerName_[_tokenId];
        } else {
            return "UNKNOWN TRAINER";
        }
    }
    // if not healing, return timehealing
    // if healing, return timehealing + timesinceenter
    function getFullTimeHealing(uint256 _tokenId) public view returns (uint256) {
        if (status_[_tokenId] == HEALING && healingRiftsEnabled_[location_[_tokenId]]) {
            return timeHealing_[_tokenId] + block.timestamp - timeEnteredRift_[_tokenId];
        } else {
            return timeHealing_[_tokenId];
        }
    }
    function getHealing(uint256 _tokenId) external view override returns (uint256) {
        require(_tokenId <= totalSupply(), "That tokenId has not yet been claimed");
        return 1 + (getFullTimeHealing(_tokenId) / 1 days);
    }
    /* End getters
     **************************************************************************/

    /**************************************************************************
     * Token URI: image and metadata construction
     **************************************************************************/
    function tokenURI(uint256 _tokenId) public view override returns (string memory) {
        return graphics_.tokenURI(_tokenId, IFantomonTrainer(this));
    }
    /* End token URI: image and metadata construction
     **************************************************************************/

    /**************************************************************************
     * Setters
     **************************************************************************/
    // onlyOwner setters
    function toggleTeam(address _addr) external onlyOwner {
        isTeam_[_addr] = !isTeam_[_addr];
    }
    // onlyTeam setters
    function toggleFantomons(address _addr) external onlyTeam {
        fantomonsEnabled_[_addr] = !fantomonsEnabled_[_addr];
    }
    function toggleArena(address _addr) external onlyTeam {
        arenasEnabled_[_addr] = !arenasEnabled_[_addr];
    }
    function toggleHealingRift(address _addr) external onlyTeam {
        healingRiftsEnabled_[_addr] = !healingRiftsEnabled_[_addr];
    }
    function setManyWhiteList(address[] memory _addr) external onlyTeam {
        for(uint i = 0; i < _addr.length; i++){
            isOnWhiteList_[_addr[i]] = true;
        }
    }

    // onlyOwnerOf(_tokenId) setters
    function setTrainerName(uint256 _tokenId, string memory _name) external onlyOwnerOf(_tokenId) {
        require(!nameTaken_[_name], "Name already taken, choose another");
        require(bytes(_name).length > 0 && bytes(_name).length <= 24, "Name empty or too long");
        require(keccak256(abi.encodePacked(_name)) != keccak256(abi.encodePacked("UNKNOWN TRAINER")), "Invalid name");
        trainerName_[_tokenId] = _name;
        nameTaken_[_name] = true;
        named_[_tokenId] = true;
    }
    /* End getters
     **************************************************************************/

    /**************************************************************************
     * Initialization functions
     **************************************************************************/
    function _initRarity(uint256 _tokenId) internal {
        uint256 rand = random("RARITY", _tokenId);
        uint256 randMod100 = rand % 100;
        if (randMod100 < 52) {
            rarity_[_tokenId] = 0;
        } else if (randMod100 < 85) {
            rarity_[_tokenId] = 1;
        } else if (randMod100 < 99) {
            rarity_[_tokenId] = 2;
        } else { //} else if (randMod100 > 99) {
            rarity_[_tokenId] = 3;
        }
    }
    function _initFace(uint256 _tokenId) internal {
        uint256 rand = random("FACE", _tokenId);
        face_[_tokenId] = uint8(rand % NUM_TRAINER_FACES);
    }
    function _initClass(uint256 _tokenId) internal {
        uint256 rand = random("CLASS", _tokenId);
        uint256 randMod10000 = rand % 10000;
        if (       randMod10000 < 1500) {
            class_[_tokenId] = 0;
        } else if (randMod10000 < 3000) {
            class_[_tokenId] = 1;
        } else if (randMod10000 < 4500) {
            class_[_tokenId] = 2;
        } else if (randMod10000 < 6000) {
            class_[_tokenId] = 3;
        } else if (randMod10000 < 6750) {
            class_[_tokenId] = 4;
        } else if (randMod10000 < 7500) {
            class_[_tokenId] = 5;
        } else if (randMod10000 < 8250) {
            class_[_tokenId] = 6;
        } else if (randMod10000 < 9000) {
            class_[_tokenId] = 7;
        } else if (randMod10000 < 9225) {
            class_[_tokenId] = 8;
        } else if (randMod10000 < 9450) {
            class_[_tokenId] = 9;
        } else if (randMod10000 < 9675) {
            class_[_tokenId] = 10;
        } else if (randMod10000 < 9900) {
            class_[_tokenId] = 11;
        } else if (randMod10000 < 9925) {
            class_[_tokenId] = 12;
        } else if (randMod10000 < 9950) {
            class_[_tokenId] = 13;
        } else if (randMod10000 < 9975) {
            class_[_tokenId] = 14;
        } else {
            class_[_tokenId] = 15;
        }
    }
    function _initHomeworld(uint256 _tokenId) internal {
        uint256 rand = random("HOMEWORLD", _tokenId);
        uint256 randMod1000 = rand % 1000;
        if (       randMod1000 < 120) {
            homeworld_[_tokenId] = 0;
        } else if (randMod1000 < 240) {
            homeworld_[_tokenId] = 1;
        } else if (randMod1000 < 360) {
            homeworld_[_tokenId] = 2;
        } else if (randMod1000 < 480) {
            homeworld_[_tokenId] = 3;
        } else if (randMod1000 < 600) {
            homeworld_[_tokenId] = 4;
        } else if (randMod1000 < 700) {
            homeworld_[_tokenId] = 5;
        } else if (randMod1000 < 800) {
            homeworld_[_tokenId] = 6;
        } else if (randMod1000 < 900) {
            homeworld_[_tokenId] = 7;
        } else if (randMod1000 < 930) {
            homeworld_[_tokenId] = 8;
        } else if (randMod1000 < 960) {
            homeworld_[_tokenId] = 9;
        } else if (randMod1000 < 990) {
            homeworld_[_tokenId] = 10;
        } else if (randMod1000 < 995) {
            homeworld_[_tokenId] = 11;
        } else {
            homeworld_[_tokenId] = 12;
        }
    }
    /* End initialization functions
     **************************************************************************/


    /**************************************************************************
     * Mint
     **************************************************************************/
    function mint(uint8 _amount) external nonReentrant payable {
        require(_amount > 0 && _amount <= MAX_MINT, "Invalid mint amount");
        require(totalSupply() + _amount <= SUPPLY_CAP, "Cant mint past 10K supply cap");
        uint8 paidAmount = _amount;
        if (isOnWhiteList_[msg.sender]) {
            paidAmount--;
        }
        require(msg.value == PRICE * paidAmount, "Wrong amount of FTM sent with mint");

        isOnWhiteList_[msg.sender] = false;

        for (uint8 i = 0; i < _amount; i++) {
            uint256 tokenId = totalSupply() + 1;

            kinship_[tokenId] = 1;
            flare_[tokenId]   = 1;
            courage_[tokenId] = 1;
            status_[tokenId] = RESTING;  // start at rest

            _initRarity(tokenId);
            _initFace(tokenId);
            _initClass(tokenId);
            _initHomeworld(tokenId);

            _safeMint(_msgSender(), tokenId);
        }
    }
    /* End mint
     **************************************************************************/

    /**************************************************************************
     * Trainer actions - performed by owner
     **************************************************************************/
    // Fantomon interactions
    function pet(uint256 _trainer, uint256 _fantomon, address _fantomonContract) external onlyOwnerOf(_trainer) nonReentrant {
        require(status_[_trainer] == RESTING, "Trainer busy");
        require(fantomonsEnabled_[_fantomonContract], "Can only interact with an enabled Fantomon contract");
        require(block.timestamp > timeLastInteraction_[_trainer] + 1 hours, "Can only interact with a fantomon once per hour");

        uint256[] memory petArgs = new uint256[](1);
        petArgs[0] = 0;  // pet
        IFantomon(_fantomonContract).interact(_trainer, _fantomon, petArgs);
        kinship_[_trainer]++;
        timeLastInteraction_[_trainer] = block.timestamp;
    }
    function play(uint256 _trainer, uint256 _fantomon, address _fantomonContract) external onlyOwnerOf(_trainer) nonReentrant {
        require(status_[_trainer] == RESTING, "Trainer busy");
        require(fantomonsEnabled_[_fantomonContract], "Can only interact with an enabled Fantomon contract");
        require(block.timestamp > timeLastInteraction_[_trainer] + 1 hours, "Can only interact with a fantomon once per hour");

        uint256[] memory playArgs = new uint256[](1);
        playArgs[0] = 1;  // play
        IFantomon(_fantomonContract).interact(_trainer, _fantomon, playArgs);
        kinship_[_trainer]++;
        timeLastInteraction_[_trainer] = block.timestamp;
    }
    function sing(uint256 _trainer, uint256 _fantomon, address _fantomonContract) external onlyOwnerOf(_trainer) nonReentrant {
        require(status_[_trainer] == RESTING, "Trainer busy");
        require(fantomonsEnabled_[_fantomonContract], "Can only interact with an enabled Fantomon contract");
        require(block.timestamp > timeLastInteraction_[_trainer] + 1 hours, "Can only interact with a fantomon once per hour");

        uint256[] memory singArgs = new uint256[](1);
        singArgs[0] = 2;  // sing
        IFantomon(_fantomonContract).interact(_trainer, _fantomon, singArgs);
        flare_[_trainer]++;
        timeLastInteraction_[_trainer] = block.timestamp;
    }

    // Travel - Arenas, HealingRifts, Journeys
    function enterArena(uint256 _tokenId, address _arena, uint256[] calldata _args) external onlyOwnerOf(_tokenId) nonReentrant {
        require(status_[_tokenId] == RESTING, "Trainer busy");

        status_[_tokenId] = PREPARING;  // preparing for battle

        location_[_tokenId] = _arena;
        IFantomonLocation(_arena).enter(_tokenId, _args);
    }
    function enterHealingRift(uint256 _tokenId, address _rifts, uint256[] calldata _args) external onlyOwnerOf(_tokenId) nonReentrant {
        require(status_[_tokenId] == RESTING, "Trainer busy");

        status_[_tokenId] = HEALING;  // treating wounds
        timeEnteredRift_[_tokenId] = block.timestamp;

        location_[_tokenId] = _rifts;
        IFantomonLocation(_rifts).enter(_tokenId, _args);
    }
    function enterJourney(uint256 _tokenId, address _journey, uint256[] calldata _args) external onlyOwnerOf(_tokenId) nonReentrant {
        require(status_[_tokenId] == RESTING, "Trainer busy");
        require(block.timestamp > timeLastJourney_[_tokenId] + 12 hours, "Can only journey once every 12 hours");

        status_[_tokenId] = LOST;  // treating wounds

        timeLastJourney_[_tokenId] = block.timestamp;
        location_[_tokenId] = _journey;
        IFantomonLocation(_journey).enter(_tokenId, _args);
    }

    function flee(uint256 _tokenId) external onlyOwnerOf(_tokenId) nonReentrant {
        if (status_[_tokenId] == BATTLING && arenasEnabled_[location_[_tokenId]]) {
            // If emergency flee during battle, loss
            losses_[_tokenId]++;
        } else if (status_[_tokenId] == HEALING && healingRiftsEnabled_[location_[_tokenId]]) {
            timeHealing_[_tokenId] += block.timestamp - timeEnteredRift_[_tokenId];
        }
        // call flee in location's contract, but allow it to fail, and proceed with cleanup
        IFantomonLocation(location_[_tokenId]).flee(_tokenId);

        status_[_tokenId] = RESTING;  // resting
        location_[_tokenId] = address(0);
    }
    function emergencyFlee(uint256 _tokenId) external onlyOwnerOf(_tokenId) {
        if (status_[_tokenId] == BATTLING && arenasEnabled_[location_[_tokenId]]) {
            // If emergency flee during battle, loss
            losses_[_tokenId]++;
        } else if (status_[_tokenId] == HEALING && healingRiftsEnabled_[location_[_tokenId]]) {
            timeHealing_[_tokenId] += block.timestamp - timeEnteredRift_[_tokenId];
        }
        status_[_tokenId] = RESTING;  // resting
        location_[_tokenId] = address(0);
        emit EmergencyFlee(_tokenId);
    }
    /* End trainer actions - performed by owner
     **************************************************************************/

    /**************************************************************************
     * Trainer actions - performed by location contract
     **************************************************************************/
    function _enterBattle(uint256 _tokenId) external onlyCurrentLocation(_tokenId) {
        require(status_[_tokenId] != BATTLING, "Already battling");
        status_[_tokenId] = BATTLING;  // in battle
    }
    // To be called by a location contract to cleanly leave after an action/event is complete
    function _leaveArena(uint256 _tokenId, bool _won) external onlyCurrentLocation(_tokenId) {
        require(status_[_tokenId] == PREPARING || status_[_tokenId] == BATTLING, "Can only do this if currently at an arena");
        if (status_[_tokenId] == BATTLING && arenasEnabled_[location_[_tokenId]]) {
            if (_won) {
                wins_[_tokenId]++;
            } else {
                losses_[_tokenId]++;
            }
        }
        status_[_tokenId] = RESTING;  // resting
        location_[_tokenId] = address(0);
    }
    function _leaveHealingRift(uint256 _tokenId) external onlyCurrentLocation(_tokenId) {
        require(status_[_tokenId] == HEALING, "Can only do this if currently treating wounds");
        if (healingRiftsEnabled_[location_[_tokenId]]) {
            timeHealing_[_tokenId] += block.timestamp - timeEnteredRift_[_tokenId];
        }
        status_[_tokenId] = RESTING;  // resting
        location_[_tokenId] = address(0);
    }
    function _leaveJourney(uint256 _tokenId) external onlyCurrentLocation(_tokenId) {
        require(status_[_tokenId] == LOST, "Can only do this if currently lost");
        courage_[_tokenId]++;
        status_[_tokenId] = RESTING;  // resting
        location_[_tokenId] = address(0);
    }
    // Called by an arena or journey to leave without updating stats (an arena tie, failed journey)
    function _leave(uint256 _tokenId) external onlyCurrentLocation(_tokenId) {
        require(status_[_tokenId] != HEALING, "Cannot leave via _leave() while healing");
        status_[_tokenId] = RESTING;  // resting
        location_[_tokenId] = address(0);
    }
    /* Trainer actions - performed by location contract
     **************************************************************************/


    /**************************************************************************
     * Payments
     **************************************************************************/
    function withdraw() external onlyTeam {
        uint256 halfBal = address(this).balance / 2;

        Address.sendValue(payable(LARKIN), halfBal);
        Address.sendValue(payable(WATER),  halfBal);
    }
    /* End payments
     **************************************************************************/


    /**************************************************************************
     * Helper functions
     **************************************************************************/
    function random(string memory _tag, uint256 _int0) internal view returns (uint256) {
        return uint256(keccak256(abi.encodePacked(_tag, toString(_int0), toString(block.timestamp), msg.sender)));
    }

    function toString(uint256 value) internal pure returns (string memory) {
    // Inspired by OraclizeAPI's implementation - MIT license
    // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

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

    // Constructor
    constructor(FantomonTrainerGraphics _graphics) ERC721("Fantomon Trainers Gen1 on FTM", "FTG1") Ownable() {
        graphics_ = _graphics;
        isTeam_[LARKIN] = true;
        isTeam_[WATER]  = true;
    }

    // Events
    event EmergencyFlee(uint256 tokenId);
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract FantomonTrainerGraphics","name":"_graphics","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"EmergencyFlee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"_enterBattle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"_leave","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_won","type":"bool"}],"name":"_leaveArena","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"_leaveHealingRift","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"_leaveJourney","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"arenasEnabled_","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"emergencyFlee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_arena","type":"address"},{"internalType":"uint256[]","name":"_args","type":"uint256[]"}],"name":"enterArena","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_rifts","type":"address"},{"internalType":"uint256[]","name":"_args","type":"uint256[]"}],"name":"enterHealingRift","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_journey","type":"address"},{"internalType":"uint256[]","name":"_args","type":"uint256[]"}],"name":"enterJourney","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"fantomonsEnabled_","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"flee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getClass","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getCourage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getFace","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getFlare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getFullTimeHealing","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getHealing","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getHomeworld","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getKinship","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getLosses","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getRarity","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getStatus","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getTrainerName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getWins","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"healingRiftsEnabled_","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isOnWhiteList_","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"location_","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_amount","type":"uint8"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"nameTaken_","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_trainer","type":"uint256"},{"internalType":"uint256","name":"_fantomon","type":"uint256"},{"internalType":"address","name":"_fantomonContract","type":"address"}],"name":"pet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_trainer","type":"uint256"},{"internalType":"uint256","name":"_fantomon","type":"uint256"},{"internalType":"address","name":"_fantomonContract","type":"address"}],"name":"play","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addr","type":"address[]"}],"name":"setManyWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"string","name":"_name","type":"string"}],"name":"setTrainerName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_trainer","type":"uint256"},{"internalType":"uint256","name":"_fantomon","type":"uint256"},{"internalType":"address","name":"_fantomonContract","type":"address"}],"name":"sing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"toggleArena","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"toggleFantomons","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"toggleHealingRift","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"toggleTeam","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052600d80546001600160a01b03199081167314e8f54f35ee42cdf436a19086659b34da6d9d4717909155600e805490911673692b54a541ee5590f551e002b0967b7981ff36f51790553480156200005957600080fd5b5060405162005f7f38038062005f7f8339810160408190526200007c9162000256565b604080518082018252601d81527f46616e746f6d6f6e20547261696e6572732047656e31206f6e2046544d0000006020808301918252835180850190945260048452634654473160e01b908401528151919291620000dd91600091620001b0565b508051620000f3906001906020840190620001b0565b50506001600a555062000106336200015e565b600c80546001600160a01b0319166001600160a01b03928316179055600d5481166000908152600f6020526040808220805460ff199081166001908117909255600e54909416835291208054909216179055620002c5565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620001be9062000288565b90600052602060002090601f016020900481019282620001e257600085556200022d565b82601f10620001fd57805160ff19168380011785556200022d565b828001600101855582156200022d579182015b828111156200022d57825182559160200191906001019062000210565b506200023b9291506200023f565b5090565b5b808211156200023b576000815560010162000240565b6000602082840312156200026957600080fd5b81516001600160a01b03811681146200028157600080fd5b9392505050565b600181811c908216806200029d57607f821691505b60208210811415620002bf57634e487b7160e01b600052602260045260246000fd5b50919050565b615caa80620002d56000396000f3fe60806040526004361061038b5760003560e01c80636ecd2306116101dc578063aade6e4211610102578063cb4c20f6116100a0578063e23aff0f1161006f578063e23aff0f14610b66578063e985e9c514610b93578063f2fde38b14610bdc578063f92f844b14610bfc57600080fd5b8063cb4c20f614610ae6578063cd6516ac14610b06578063d297315314610b26578063d6f792ed14610b4657600080fd5b8063be85bf1e116100dc578063be85bf1e14610a59578063bf962ba414610a79578063c2e4ff2114610a99578063c87b56dd14610ac657600080fd5b8063aade6e42146109dc578063b88d4fde14610a09578063bae404d214610a2957600080fd5b80637f40711e1161017a5780639d39958f116101495780639d39958f1461095c578063a106d7711461097c578063a22cb4651461099c578063a95a036b146109bc57600080fd5b80637f40711e146108e957806384cb37ea146109095780638da5cb5b1461092957806395d89b411461094757600080fd5b806372136828116101b657806372136828146108595780637bee2c50146108895780637c66ae22146108a95780637ed75068146108c957600080fd5b80636ecd23061461081157806370a0823114610824578063715018a61461084457600080fd5b80632f745c59116102c1578063538026021161025f57806367c5f7201161022e57806367c5f7201461077b5780636bc80c661461079b5780636d3ff596146107d15780636d449371146107f157600080fd5b806353802602146106db5780635c622a0e146106fb5780636275e9f21461072b5780636352211e1461075b57600080fd5b806342842e0e1161029b57806342842e0e1461062a578063487586971461064a5780634f6ccce71461068c578063512d62df146106ac57600080fd5b80632f745c59146105c85780632fd333c4146105e85780633ccfd60b1461061557600080fd5b806318160ddd1161032e57806323b872dd1161030857806323b872dd1461052b57806325bd9e351461054b57806326e22e5f146105785780632c22642c146105a857600080fd5b806318160ddd146104b15780631a77392b146104d057806321742e2d1461050b57600080fd5b806306fdde031161036a57806306fdde0314610417578063081812fc14610439578063095ea7b3146104715780630c8beff71461049157600080fd5b80621c07661461039057806301ffc9a7146103d5578063055a2082146103f5575b600080fd5b34801561039c57600080fd5b506103c06103ab3660046152ed565b60256020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b3480156103e157600080fd5b506103c06103f03660046154fb565b610c2c565b34801561040157600080fd5b506104156104103660046156ee565b610c88565b005b34801561042357600080fd5b5061042c610fea565b6040516103cc919061585a565b34801561044557600080fd5b506104596104543660046155e1565b61107c565b6040516001600160a01b0390911681526020016103cc565b34801561047d57600080fd5b5061041561048c36600461541d565b611122565b34801561049d57600080fd5b506104156104ac3660046155e1565b611254565b3480156104bd57600080fd5b506008545b6040519081526020016103cc565b3480156104dc57600080fd5b506103c06104eb366004615535565b805160208183018101805160138252928201919093012091525460ff1681565b34801561051757600080fd5b50610415610526366004615684565b611454565b34801561053757600080fd5b5061041561054636600461533b565b611663565b34801561055757600080fd5b506104c26105663660046155e1565b60009081526015602052604090205490565b34801561058457600080fd5b506103c06105933660046152ed565b60236020526000908152604090205460ff1681565b3480156105b457600080fd5b506104156105c3366004615447565b6116ea565b3480156105d457600080fd5b506104c26105e336600461541d565b611800565b3480156105f457600080fd5b506104c26106033660046155e1565b6000908152601a602052604090205490565b34801561062157600080fd5b506104156118a8565b34801561063657600080fd5b5061041561064536600461533b565b611991565b34801561065657600080fd5b5061067a6106653660046155e1565b6000908152601f602052604090205460ff1690565b60405160ff90911681526020016103cc565b34801561069857600080fd5b506104c26106a73660046155e1565b6119ac565b3480156106b857600080fd5b5061067a6106c73660046155e1565b600090815260208052604090205460ff1690565b3480156106e757600080fd5b506104156106f63660046155fa565b611a50565b34801561070757600080fd5b5061067a6107163660046155e1565b6000908152601e602052604090205460ff1690565b34801561073757600080fd5b5061067a6107463660046155e1565b60009081526021602052604090205460ff1690565b34801561076757600080fd5b506104596107763660046155e1565b611c6c565b34801561078757600080fd5b506104156107963660046155fa565b611cf7565b3480156107a757600080fd5b506104596107b63660046155e1565b6011602052600090815260409020546001600160a01b031681565b3480156107dd57600080fd5b506104156107ec3660046155e1565b611f6e565b3480156107fd57600080fd5b5061041561080c3660046156a7565b612136565b61041561081f366004615723565b6123e1565b34801561083057600080fd5b506104c261083f3660046152ed565b612675565b34801561085057600080fd5b5061041561270f565b34801561086557600080fd5b5061067a6108743660046155e1565b60009081526022602052604090205460ff1690565b34801561089557600080fd5b506104c26108a43660046155e1565b612775565b3480156108b557600080fd5b506104156108c43660046156ee565b612807565b3480156108d557600080fd5b506104156108e43660046155e1565b612aa2565b3480156108f557600080fd5b506104156109043660046152ed565b612bd1565b34801561091557600080fd5b506104156109243660046155e1565b612ca4565b34801561093557600080fd5b50600b546001600160a01b0316610459565b34801561095357600080fd5b5061042c612f53565b34801561096857600080fd5b506104156109773660046156ee565b612f62565b34801561098857600080fd5b506104156109973660046155e1565b61329e565b3480156109a857600080fd5b506104156109b73660046153f3565b6133aa565b3480156109c857600080fd5b5061042c6109d73660046155e1565b61346f565b3480156109e857600080fd5b506104c26109f73660046155e1565b60009081526019602052604090205490565b348015610a1557600080fd5b50610415610a24366004615377565b613560565b348015610a3557600080fd5b506103c0610a443660046152ed565b60106020526000908152604090205460ff1681565b348015610a6557600080fd5b50610415610a743660046152ed565b6135ee565b348015610a8557600080fd5b50610415610a943660046152ed565b6136c1565b348015610aa557600080fd5b506104c2610ab43660046155e1565b60009081526018602052604090205490565b348015610ad257600080fd5b5061042c610ae13660046155e1565b613744565b348015610af257600080fd5b50610415610b013660046152ed565b613802565b348015610b1257600080fd5b50610415610b213660046155fa565b6138d5565b348015610b3257600080fd5b506104c2610b413660046155e1565b613abd565b348015610b5257600080fd5b50610415610b613660046155e1565b613b5f565b348015610b7257600080fd5b506104c2610b813660046155e1565b60009081526016602052604090205490565b348015610b9f57600080fd5b506103c0610bae366004615308565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610be857600080fd5b50610415610bf73660046152ed565b613c75565b348015610c0857600080fd5b506103c0610c173660046152ed565b60246020526000908152604090205460ff1681565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d63000000000000000000000000000000000000000000000000000000001480610c825750610c8282613d54565b92915050565b82610c9281611c6c565b6001600160a01b0316336001600160a01b031614610d1d5760405162461bcd60e51b815260206004820152602660248201527f4f6e6c79206f776e6572206f66207468617420746f6b656e49642063616e206460448201527f6f2074686174000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6002600a541415610d705760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610d14565b6002600a556000848152601e602052604090205460ff1615610dd45760405162461bcd60e51b815260206004820152600c60248201527f547261696e6572206275737900000000000000000000000000000000000000006044820152606401610d14565b6001600160a01b03821660009081526023602052604090205460ff16610e625760405162461bcd60e51b815260206004820152603360248201527f43616e206f6e6c7920696e746572616374207769746820616e20656e61626c6560448201527f642046616e746f6d6f6e20636f6e7472616374000000000000000000000000006064820152608401610d14565b6000848152601b6020526040902054610e7d90610e106159b3565b4211610ef15760405162461bcd60e51b815260206004820152602f60248201527f43616e206f6e6c7920696e746572616374207769746820612066616e746f6d6f60448201527f6e206f6e63652070657220686f757200000000000000000000000000000000006064820152608401610d14565b60408051600180825281830190925260009160208083019080368337019050509050600081600081518110610f2857610f28615be8565b60209081029190910101526040517ffcfd05d20000000000000000000000000000000000000000000000000000000081526001600160a01b0384169063fcfd05d290610f7c908890889086906004016158c9565b600060405180830381600087803b158015610f9657600080fd5b505af1158015610faa573d6000803e3d6000fd5b50505060008681526015602052604081208054925090610fc983615aee565b90915550505060009384525050601b60205250604090204290556001600a55565b606060008054610ff990615a9a565b80601f016020809104026020016040519081016040528092919081815260200182805461102590615a9a565b80156110725780601f1061104757610100808354040283529160200191611072565b820191906000526020600020905b81548152906001019060200180831161105557829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166111065760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e00000000000000000000000000000000000000006064820152608401610d14565b506000908152600460205260409020546001600160a01b031690565b600061112d82611c6c565b9050806001600160a01b0316836001600160a01b031614156111b75760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610d14565b336001600160a01b03821614806111d357506111d38133610bae565b6112455760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610d14565b61124f8383613e37565b505050565b8061125e81611c6c565b6001600160a01b0316336001600160a01b0316146112e45760405162461bcd60e51b815260206004820152602660248201527f4f6e6c79206f776e6572206f66207468617420746f6b656e49642063616e206460448201527f6f207468617400000000000000000000000000000000000000000000000000006064820152608401610d14565b6000828152601e602052604090205460ff16600214801561132957506000828152601160209081526040808320546001600160a01b03168352602490915290205460ff165b15611352576000828152601a6020526040812080549161134883615aee565b91905055506113d9565b6000828152601e602052604090205460ff16600314801561139757506000828152601160209081526040808320546001600160a01b03168352602590915290205460ff165b156113d9576000828152601c60205260409020546113b59042615a1c565b600083815260176020526040812080549091906113d39084906159b3565b90915550505b6000828152601e60209081526040808320805460ff19169055601182529182902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590518381527fde6cab0f84985f9aa0e287ac4ceee232005dead876e761f43aa225510cb8923b910160405180910390a15050565b60008281526011602052604090205482906001600160a01b031633146114e25760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79207468697320747261696e657227732063757272656e74206c6f636160448201527f74696f6e2063616e20646f2074686973000000000000000000000000000000006064820152608401610d14565b6000838152601e602052604090205460ff166001148061151357506000838152601e602052604090205460ff166002145b6115855760405162461bcd60e51b815260206004820152602960248201527f43616e206f6e6c7920646f20746869732069662063757272656e746c7920617460448201527f20616e206172656e6100000000000000000000000000000000000000000000006064820152608401610d14565b6000838152601e602052604090205460ff1660021480156115ca57506000838152601160209081526040808320546001600160a01b03168352602490915290205460ff165b156116195781156115f95760008381526019602052604081208054916115ef83615aee565b9190505550611619565b6000838152601a6020526040812080549161161383615aee565b91905055505b50506000908152601e60209081526040808320805460ff191690556011909152902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b61166d3382613ebd565b6116df5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610d14565b61124f838383613fc5565b600b546001600160a01b031633148061170d5750600d546001600160a01b031633145b806117225750600e546001600160a01b031633145b6117945760405162461bcd60e51b815260206004820152602b60248201527f43616e277420646f20746861742c20796f7520617265206e6f7420706172742060448201527f6f6620746865207465616d0000000000000000000000000000000000000000006064820152608401610d14565b60005b81518110156117fc576001601060008484815181106117b8576117b8615be8565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055806117f481615aee565b915050611797565b5050565b600061180b83612675565b821061187f5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e64730000000000000000000000000000000000000000006064820152608401610d14565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600b546001600160a01b03163314806118cb5750600d546001600160a01b031633145b806118e05750600e546001600160a01b031633145b6119525760405162461bcd60e51b815260206004820152602b60248201527f43616e277420646f20746861742c20796f7520617265206e6f7420706172742060448201527f6f6620746865207465616d0000000000000000000000000000000000000000006064820152608401610d14565b600061195f6002476159cb565b600d54909150611978906001600160a01b0316826141b5565b600e5461198e906001600160a01b0316826141b5565b50565b61124f83838360405180602001604052806000815250613560565b60006119b760085490565b8210611a2b5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e647300000000000000000000000000000000000000006064820152608401610d14565b60088281548110611a3e57611a3e615be8565b90600052602060002001549050919050565b83611a5a81611c6c565b6001600160a01b0316336001600160a01b031614611ae05760405162461bcd60e51b815260206004820152602660248201527f4f6e6c79206f776e6572206f66207468617420746f6b656e49642063616e206460448201527f6f207468617400000000000000000000000000000000000000000000000000006064820152608401610d14565b6002600a541415611b335760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610d14565b6002600a556000858152601e602052604090205460ff1615611b975760405162461bcd60e51b815260206004820152600c60248201527f547261696e6572206275737900000000000000000000000000000000000000006044820152606401610d14565b6000858152601e60209081526040808320805460ff1916600117905560119091529081902080546001600160a01b0387167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116811790915590517f9caac016000000000000000000000000000000000000000000000000000000008152639caac01690611c2e9088908790879060040161586d565b600060405180830381600087803b158015611c4857600080fd5b505af1158015611c5c573d6000803e3d6000fd5b50506001600a5550505050505050565b6000818152600260205260408120546001600160a01b031680610c825760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e00000000000000000000000000000000000000000000006064820152608401610d14565b83611d0181611c6c565b6001600160a01b0316336001600160a01b031614611d875760405162461bcd60e51b815260206004820152602660248201527f4f6e6c79206f776e6572206f66207468617420746f6b656e49642063616e206460448201527f6f207468617400000000000000000000000000000000000000000000000000006064820152608401610d14565b6002600a541415611dda5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610d14565b6002600a556000858152601e602052604090205460ff1615611e3e5760405162461bcd60e51b815260206004820152600c60248201527f547261696e6572206275737900000000000000000000000000000000000000006044820152606401610d14565b6000858152601d6020526040902054611e599061a8c06159b3565b4211611ecc5760405162461bcd60e51b8152602060048201526024808201527f43616e206f6e6c79206a6f75726e6579206f6e6365206576657279203132206860448201527f6f757273000000000000000000000000000000000000000000000000000000006064820152608401610d14565b6000858152601e60209081526040808320805460ff19166004908117909155601d835281842042905560119092529182902080546001600160a01b0388167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116811790915591517f9caac016000000000000000000000000000000000000000000000000000000008152639caac01691611c2e918991889188910161586d565b60008181526011602052604090205481906001600160a01b03163314611ffc5760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79207468697320747261696e657227732063757272656e74206c6f636160448201527f74696f6e2063616e20646f2074686973000000000000000000000000000000006064820152608401610d14565b6000828152601e602052604090205460ff166003146120835760405162461bcd60e51b815260206004820152602d60248201527f43616e206f6e6c7920646f20746869732069662063757272656e746c7920747260448201527f656174696e6720776f756e6473000000000000000000000000000000000000006064820152608401610d14565b6000828152601160209081526040808320546001600160a01b03168352602590915290205460ff16156120ed576000828152601c60205260409020546120c99042615a1c565b600083815260176020526040812080549091906120e79084906159b3565b90915550505b506000908152601e60209081526040808320805460ff191690556011909152902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b8161214081611c6c565b6001600160a01b0316336001600160a01b0316146121c65760405162461bcd60e51b815260206004820152602660248201527f4f6e6c79206f776e6572206f66207468617420746f6b656e49642063616e206460448201527f6f207468617400000000000000000000000000000000000000000000000000006064820152608401610d14565b6013826040516121d69190615790565b9081526040519081900360200190205460ff161561225c5760405162461bcd60e51b815260206004820152602260248201527f4e616d6520616c72656164792074616b656e2c2063686f6f736520616e6f746860448201527f65720000000000000000000000000000000000000000000000000000000000006064820152608401610d14565b6000825111801561226f57506018825111155b6122bb5760405162461bcd60e51b815260206004820152601660248201527f4e616d6520656d707479206f7220746f6f206c6f6e67000000000000000000006044820152606401610d14565b6040517f554e4b4e4f574e20545241494e455200000000000000000000000000000000006020820152602f01604051602081830303815290604052805190602001208260405160200161230e9190615790565b6040516020818303038152906040528051906020012014156123725760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e616d6500000000000000000000000000000000000000006044820152606401610d14565b60008381526014602090815260409091208351612391928501906151c8565b5060016013836040516123a49190615790565b90815260408051918290036020908101909220805493151560ff199485161790556000958652601290915290932080549093166001179092555050565b6002600a5414156124345760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610d14565b6002600a5560ff81161580159061244f5750600a8160ff1611155b61249b5760405162461bcd60e51b815260206004820152601360248201527f496e76616c6964206d696e7420616d6f756e74000000000000000000000000006044820152606401610d14565b6127108160ff166124ab60085490565b6124b591906159b3565b11156125035760405162461bcd60e51b815260206004820152601d60248201527f43616e74206d696e7420706173742031304b20737570706c79206361700000006044820152606401610d14565b33600090815260106020526040902054819060ff161561252b578061252781615a5f565b9150505b61254060ff8216678ac7230489e800006159df565b34146125b45760405162461bcd60e51b815260206004820152602260248201527f57726f6e6720616d6f756e74206f662046544d2073656e742077697468206d6960448201527f6e740000000000000000000000000000000000000000000000000000000000006064820152608401610d14565b336000908152601060205260408120805460ff191690555b8260ff168160ff16101561266b5760006125e560085490565b6125f09060016159b3565b6000818152601560209081526040808320600190819055601683528184208190556018835281842055601e9091529020805460ff191690559050612633816142ce565b61263c816143af565b61264581614421565b61264e816146d6565b6126583382614921565b508061266381615b27565b9150506125cc565b50506001600a5550565b60006001600160a01b0382166126f35760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f2061646472657373000000000000000000000000000000000000000000006064820152608401610d14565b506001600160a01b031660009081526003602052604090205490565b600b546001600160a01b031633146127695760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d14565b612773600061493b565b565b6000818152601e602052604081205460ff1660031480156127ba57506000828152601160209081526040808320546001600160a01b03168352602590915290205460ff165b156127ef576000828152601c60209081526040808320546017909252909120546127e59042906159b3565b610c829190615a1c565b5060009081526017602052604090205490565b919050565b8261281181611c6c565b6001600160a01b0316336001600160a01b0316146128975760405162461bcd60e51b815260206004820152602660248201527f4f6e6c79206f776e6572206f66207468617420746f6b656e49642063616e206460448201527f6f207468617400000000000000000000000000000000000000000000000000006064820152608401610d14565b6002600a5414156128ea5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610d14565b6002600a556000848152601e602052604090205460ff161561294e5760405162461bcd60e51b815260206004820152600c60248201527f547261696e6572206275737900000000000000000000000000000000000000006044820152606401610d14565b6001600160a01b03821660009081526023602052604090205460ff166129dc5760405162461bcd60e51b815260206004820152603360248201527f43616e206f6e6c7920696e746572616374207769746820616e20656e61626c6560448201527f642046616e746f6d6f6e20636f6e7472616374000000000000000000000000006064820152608401610d14565b6000848152601b60205260409020546129f790610e106159b3565b4211612a6b5760405162461bcd60e51b815260206004820152602f60248201527f43616e206f6e6c7920696e746572616374207769746820612066616e746f6d6f60448201527f6e206f6e63652070657220686f757200000000000000000000000000000000006064820152608401610d14565b60408051600180825281830190925260009160208083019080368337019050509050600181600081518110610f2857610f28615be8565b60008181526011602052604090205481906001600160a01b03163314612b305760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79207468697320747261696e657227732063757272656e74206c6f636160448201527f74696f6e2063616e20646f2074686973000000000000000000000000000000006064820152608401610d14565b6000828152601e602052604090205460ff16600414612bb75760405162461bcd60e51b815260206004820152602260248201527f43616e206f6e6c7920646f20746869732069662063757272656e746c79206c6f60448201527f73740000000000000000000000000000000000000000000000000000000000006064820152608401610d14565b60008281526018602052604081208054916120e783615aee565b600b546001600160a01b0316331480612bf45750600d546001600160a01b031633145b80612c095750600e546001600160a01b031633145b612c7b5760405162461bcd60e51b815260206004820152602b60248201527f43616e277420646f20746861742c20796f7520617265206e6f7420706172742060448201527f6f6620746865207465616d0000000000000000000000000000000000000000006064820152608401610d14565b6001600160a01b03166000908152602360205260409020805460ff19811660ff90911615179055565b80612cae81611c6c565b6001600160a01b0316336001600160a01b031614612d345760405162461bcd60e51b815260206004820152602660248201527f4f6e6c79206f776e6572206f66207468617420746f6b656e49642063616e206460448201527f6f207468617400000000000000000000000000000000000000000000000000006064820152608401610d14565b6002600a541415612d875760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610d14565b6002600a8190556000838152601e602052604090205460ff16148015612dd157506000828152601160209081526040808320546001600160a01b03168352602490915290205460ff165b15612dfa576000828152601a60205260408120805491612df083615aee565b9190505550612e81565b6000828152601e602052604090205460ff166003148015612e3f57506000828152601160209081526040808320546001600160a01b03168352602590915290205460ff165b15612e81576000828152601c6020526040902054612e5d9042615a1c565b60008381526017602052604081208054909190612e7b9084906159b3565b90915550505b600082815260116020526040908190205490517f84cb37ea000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b03909116906384cb37ea90602401600060405180830381600087803b158015612eed57600080fd5b505af1158015612f01573d6000803e3d6000fd5b50505060009283525050601e60209081526040808320805460ff191690556011909152902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556001600a55565b606060018054610ff990615a9a565b82612f6c81611c6c565b6001600160a01b0316336001600160a01b031614612ff25760405162461bcd60e51b815260206004820152602660248201527f4f6e6c79206f776e6572206f66207468617420746f6b656e49642063616e206460448201527f6f207468617400000000000000000000000000000000000000000000000000006064820152608401610d14565b6002600a5414156130455760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610d14565b6002600a556000848152601e602052604090205460ff16156130a95760405162461bcd60e51b815260206004820152600c60248201527f547261696e6572206275737900000000000000000000000000000000000000006044820152606401610d14565b6001600160a01b03821660009081526023602052604090205460ff166131375760405162461bcd60e51b815260206004820152603360248201527f43616e206f6e6c7920696e746572616374207769746820616e20656e61626c6560448201527f642046616e746f6d6f6e20636f6e7472616374000000000000000000000000006064820152608401610d14565b6000848152601b602052604090205461315290610e106159b3565b42116131c65760405162461bcd60e51b815260206004820152602f60248201527f43616e206f6e6c7920696e746572616374207769746820612066616e746f6d6f60448201527f6e206f6e63652070657220686f757200000000000000000000000000000000006064820152608401610d14565b604080516001808252818301909252600091602080830190803683370190505090506002816000815181106131fd576131fd615be8565b60209081029190910101526040517ffcfd05d20000000000000000000000000000000000000000000000000000000081526001600160a01b0384169063fcfd05d290613251908890889086906004016158c9565b600060405180830381600087803b15801561326b57600080fd5b505af115801561327f573d6000803e3d6000fd5b50505060008681526016602052604081208054925090610fc983615aee565b60008181526011602052604090205481906001600160a01b0316331461332c5760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79207468697320747261696e657227732063757272656e74206c6f636160448201527f74696f6e2063616e20646f2074686973000000000000000000000000000000006064820152608401610d14565b6000828152601e602052604090205460ff166002141561338e5760405162461bcd60e51b815260206004820152601060248201527f416c726561647920626174746c696e67000000000000000000000000000000006044820152606401610d14565b506000908152601e60205260409020805460ff19166002179055565b6001600160a01b0382163314156134035760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610d14565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60008181526012602052604090205460609060ff161561352757600082815260146020526040902080546134a290615a9a565b80601f01602080910402602001604051908101604052809291908181526020018280546134ce90615a9a565b801561351b5780601f106134f05761010080835404028352916020019161351b565b820191906000526020600020905b8154815290600101906020018083116134fe57829003601f168201915b50505050509050919050565b505060408051808201909152600f81527f554e4b4e4f574e20545241494e45520000000000000000000000000000000000602082015290565b61356a3383613ebd565b6135dc5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610d14565b6135e8848484846149a5565b50505050565b600b546001600160a01b03163314806136115750600d546001600160a01b031633145b806136265750600e546001600160a01b031633145b6136985760405162461bcd60e51b815260206004820152602b60248201527f43616e277420646f20746861742c20796f7520617265206e6f7420706172742060448201527f6f6620746865207465616d0000000000000000000000000000000000000000006064820152608401610d14565b6001600160a01b03166000908152602460205260409020805460ff19811660ff90911615179055565b600b546001600160a01b0316331461371b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d14565b6001600160a01b03166000908152600f60205260409020805460ff19811660ff90911615179055565b600c546040517f8c4c1b2f000000000000000000000000000000000000000000000000000000008152600481018390523060248201526060916001600160a01b031690638c4c1b2f9060440160006040518083038186803b1580156137a857600080fd5b505afa1580156137bc573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c82919081019061556a565b600b546001600160a01b03163314806138255750600d546001600160a01b031633145b8061383a5750600e546001600160a01b031633145b6138ac5760405162461bcd60e51b815260206004820152602b60248201527f43616e277420646f20746861742c20796f7520617265206e6f7420706172742060448201527f6f6620746865207465616d0000000000000000000000000000000000000000006064820152608401610d14565b6001600160a01b03166000908152602560205260409020805460ff19811660ff90911615179055565b836138df81611c6c565b6001600160a01b0316336001600160a01b0316146139655760405162461bcd60e51b815260206004820152602660248201527f4f6e6c79206f776e6572206f66207468617420746f6b656e49642063616e206460448201527f6f207468617400000000000000000000000000000000000000000000000000006064820152608401610d14565b6002600a5414156139b85760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610d14565b6002600a556000858152601e602052604090205460ff1615613a1c5760405162461bcd60e51b815260206004820152600c60248201527f547261696e6572206275737900000000000000000000000000000000000000006044820152606401610d14565b6000858152601e60209081526040808320805460ff19166003179055601c825280832042905560119091529081902080546001600160a01b0387167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116811790915590517f9caac016000000000000000000000000000000000000000000000000000000008152639caac01690611c2e9088908790879060040161586d565b6000613ac860085490565b821115613b3d5760405162461bcd60e51b815260206004820152602560248201527f5468617420746f6b656e496420686173206e6f7420796574206265656e20636c60448201527f61696d65640000000000000000000000000000000000000000000000000000006064820152608401610d14565b62015180613b4a83612775565b613b5491906159cb565b610c829060016159b3565b60008181526011602052604090205481906001600160a01b03163314613bed5760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79207468697320747261696e657227732063757272656e74206c6f636160448201527f74696f6e2063616e20646f2074686973000000000000000000000000000000006064820152608401610d14565b6000828152601e602052604090205460ff16600314156120ed5760405162461bcd60e51b815260206004820152602760248201527f43616e6e6f74206c6561766520766961205f6c656176652829207768696c652060448201527f6865616c696e67000000000000000000000000000000000000000000000000006064820152608401610d14565b600b546001600160a01b03163314613ccf5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d14565b6001600160a01b038116613d4b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610d14565b61198e8161493b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd000000000000000000000000000000000000000000000000000000001480613de757507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610c8257507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610c82565b600081815260046020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384169081179091558190613e8482611c6c565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600260205260408120546001600160a01b0316613f475760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e00000000000000000000000000000000000000006064820152608401610d14565b6000613f5283611c6c565b9050806001600160a01b0316846001600160a01b03161480613f8d5750836001600160a01b0316613f828461107c565b6001600160a01b0316145b80613fbd57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316613fd882611c6c565b6001600160a01b0316146140545760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e00000000000000000000000000000000000000000000006064820152608401610d14565b6001600160a01b0382166140cf5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610d14565b6140da838383614a2e565b6140e5600082613e37565b6001600160a01b038316600090815260036020526040812080546001929061410e908490615a1c565b90915550506001600160a01b038216600090815260036020526040812080546001929061413c9084906159b3565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b804710156142055760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610d14565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114614252576040519150601f19603f3d011682016040523d82523d6000602084013e614257565b606091505b505090508061124f5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610d14565b600061430f6040518060400160405280600681526020017f524152495459000000000000000000000000000000000000000000000000000081525083614ae6565b9050600061431e606483615b47565b905060348110156143435750506000908152601f60205260409020805460ff19169055565b605581101561436a576000838152601f60205260409020805460ff19166001179055505050565b6063811015614391576000838152601f60205260409020805460ff19166002179055505050565b6000838152601f60205260409020805460ff19166003179055505050565b60006143f06040518060400160405280600481526020017f464143450000000000000000000000000000000000000000000000000000000081525083614ae6565b90506143fd600782615b47565b600092835260216020526040909220805460ff191660ff9093169290921790915550565b60006144626040518060400160405280600581526020017f434c41535300000000000000000000000000000000000000000000000000000081525083614ae6565b9050600061447261271083615b47565b90506105dc81101561449757505060009081526020805260409020805460ff19169055565b610bb88110156144be5760008381526020805260409020805460ff19166001179055505050565b6111948110156144e55760008381526020805260409020805460ff19166002179055505050565b61177081101561450c5760008381526020805260409020805460ff19166003179055505050565b611a5e8110156145335760008381526020805260409020805460ff19166004179055505050565b611d4c81101561455a5760008381526020805260409020805460ff19166005179055505050565b61203a8110156145815760008381526020805260409020805460ff19166006179055505050565b6123288110156145a85760008381526020805260409020805460ff19166007179055505050565b6124098110156145cf5760008381526020805260409020805460ff19166008179055505050565b6124ea8110156145f65760008381526020805260409020805460ff19166009179055505050565b6125cb81101561461d5760008381526020805260409020805460ff1916600a179055505050565b6126ac8110156146445760008381526020805260409020805460ff1916600b179055505050565b6126c581101561466b5760008381526020805260409020805460ff1916600c179055505050565b6126de8110156146925760008381526020805260409020805460ff1916600d179055505050565b6126f78110156146b95760008381526020805260409020805460ff1916600e179055505050565b60008381526020805260409020805460ff1916600f179055505050565b60006147176040518060400160405280600981526020017f484f4d45574f524c44000000000000000000000000000000000000000000000081525083614ae6565b905060006147276103e883615b47565b9050607881101561474c5750506000908152602260205260409020805460ff19169055565b60f0811015614773576000838152602260205260409020805460ff19166001179055505050565b61016881101561479b576000838152602260205260409020805460ff19166002179055505050565b6101e08110156147c3576000838152602260205260409020805460ff19166003179055505050565b6102588110156147eb576000838152602260205260409020805460ff19166004179055505050565b6102bc811015614813576000838152602260205260409020805460ff19166005179055505050565b61032081101561483b576000838152602260205260409020805460ff19166006179055505050565b610384811015614863576000838152602260205260409020805460ff19166007179055505050565b6103a281101561488b576000838152602260205260409020805460ff19166008179055505050565b6103c08110156148b3576000838152602260205260409020805460ff19166009179055505050565b6103de8110156148db576000838152602260205260409020805460ff1916600a179055505050565b6103e3811015614903576000838152602260205260409020805460ff1916600b179055505050565b6000838152602260205260409020805460ff1916600c179055505050565b6117fc828260405180602001604052806000815250614b4c565b600b80546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6149b0848484613fc5565b6149bc84848484614bd5565b6135e85760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610d14565b6001600160a01b038316614a8957614a8481600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b614aac565b816001600160a01b0316836001600160a01b031614614aac57614aac8382614da0565b6001600160a01b038216614ac35761124f81614e3d565b826001600160a01b0316826001600160a01b03161461124f5761124f8282614eec565b600082614af283614f30565b614afb42614f30565b33604051602001614b0f94939291906157ac565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209392505050565b614b568383615062565b614b636000848484614bd5565b61124f5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610d14565b60006001600160a01b0384163b15614d95576040517f150b7a020000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063150b7a0290614c3290339089908890889060040161581e565b602060405180830381600087803b158015614c4c57600080fd5b505af1925050508015614c9a575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252614c9791810190615518565b60015b614d4a573d808015614cc8576040519150601f19603f3d011682016040523d82523d6000602084013e614ccd565b606091505b508051614d425760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610d14565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050613fbd565b506001949350505050565b60006001614dad84612675565b614db79190615a1c565b600083815260076020526040902054909150808214614e0a576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090614e4f90600190615a1c565b60008381526009602052604081205460088054939450909284908110614e7757614e77615be8565b906000526020600020015490508060088381548110614e9857614e98615be8565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480614ed057614ed0615bb9565b6001900381819060005260206000200160009055905550505050565b6000614ef783612675565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b606081614f7057505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115614f9a5780614f8481615aee565b9150614f939050600a836159cb565b9150614f74565b60008167ffffffffffffffff811115614fb557614fb5615c17565b6040519080825280601f01601f191660200182016040528015614fdf576020820181803683370190505b5090505b8415613fbd57614ff4600183615a1c565b9150615001600a86615b47565b61500c9060306159b3565b60f81b81838151811061502157615021615be8565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061505b600a866159cb565b9450614fe3565b6001600160a01b0382166150b85760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610d14565b6000818152600260205260409020546001600160a01b03161561511d5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610d14565b61512960008383614a2e565b6001600160a01b03821660009081526003602052604081208054600192906151529084906159b3565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b8280546151d490615a9a565b90600052602060002090601f0160209004810192826151f6576000855561523c565b82601f1061520f57805160ff191683800117855561523c565b8280016001018555821561523c579182015b8281111561523c578251825591602001919060010190615221565b5061524892915061524c565b5090565b5b80821115615248576000815560010161524d565b600061527461526f8461596d565b61591e565b905082815283838301111561528857600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b038116811461280257600080fd5b8035801515811461280257600080fd5b600082601f8301126152d757600080fd5b6152e683833560208501615261565b9392505050565b6000602082840312156152ff57600080fd5b6152e68261529f565b6000806040838503121561531b57600080fd5b6153248361529f565b91506153326020840161529f565b90509250929050565b60008060006060848603121561535057600080fd5b6153598461529f565b92506153676020850161529f565b9150604084013590509250925092565b6000806000806080858703121561538d57600080fd5b6153968561529f565b93506153a46020860161529f565b925060408501359150606085013567ffffffffffffffff8111156153c757600080fd5b8501601f810187136153d857600080fd5b6153e787823560208401615261565b91505092959194509250565b6000806040838503121561540657600080fd5b61540f8361529f565b9150615332602084016152b6565b6000806040838503121561543057600080fd5b6154398361529f565b946020939093013593505050565b6000602080838503121561545a57600080fd5b823567ffffffffffffffff8082111561547257600080fd5b818501915085601f83011261548657600080fd5b81358181111561549857615498615c17565b8060051b91506154a984830161591e565b8181528481019084860184860187018a10156154c457600080fd5b600095505b838610156154ee576154da8161529f565b8352600195909501949186019186016154c9565b5098975050505050505050565b60006020828403121561550d57600080fd5b81356152e681615c46565b60006020828403121561552a57600080fd5b81516152e681615c46565b60006020828403121561554757600080fd5b813567ffffffffffffffff81111561555e57600080fd5b613fbd848285016152c6565b60006020828403121561557c57600080fd5b815167ffffffffffffffff81111561559357600080fd5b8201601f810184136155a457600080fd5b80516155b261526f8261596d565b8181528560208385010111156155c757600080fd5b6155d8826020830160208601615a33565b95945050505050565b6000602082840312156155f357600080fd5b5035919050565b6000806000806060858703121561561057600080fd5b843593506156206020860161529f565b9250604085013567ffffffffffffffff8082111561563d57600080fd5b818701915087601f83011261565157600080fd5b81358181111561566057600080fd5b8860208260051b850101111561567557600080fd5b95989497505060200194505050565b6000806040838503121561569757600080fd5b82359150615332602084016152b6565b600080604083850312156156ba57600080fd5b82359150602083013567ffffffffffffffff8111156156d857600080fd5b6156e4858286016152c6565b9150509250929050565b60008060006060848603121561570357600080fd5b833592506020840135915061571a6040850161529f565b90509250925092565b60006020828403121561573557600080fd5b813560ff811681146152e657600080fd5b6000815180845261575e816020860160208601615a33565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082516157a2818460208701615a33565b9190910192915050565b600085516157be818460208a01615a33565b8551908301906157d2818360208a01615a33565b85519101906157e5818360208901615a33565b60609490941b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016930192835250506014019392505050565b60006001600160a01b038087168352808616602084015250836040830152608060608301526158506080830184615746565b9695505050505050565b6020815260006152e66020830184615746565b8381526040602082015281604082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156158ac57600080fd5b8260051b8085606085013760009201606001918252509392505050565b6000606082018583526020858185015260606040850152818551808452608086019150828701935060005b81811015615910578451835293830193918301916001016158f4565b509098975050505050505050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561596557615965615c17565b604052919050565b600067ffffffffffffffff82111561598757615987615c17565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082198211156159c6576159c6615b5b565b500190565b6000826159da576159da615b8a565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615a1757615a17615b5b565b500290565b600082821015615a2e57615a2e615b5b565b500390565b60005b83811015615a4e578181015183820152602001615a36565b838111156135e85750506000910152565b600060ff821680615a7257615a72615b5b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b600181811c90821680615aae57607f821691505b60208210811415615ae8577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415615b2057615b20615b5b565b5060010190565b600060ff821660ff811415615b3e57615b3e615b5b565b60010192915050565b600082615b5657615b56615b8a565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7fffffffff000000000000000000000000000000000000000000000000000000008116811461198e57600080fdfea264697066735822122017b7bf2668beda9087288055b1730da19237c9d3bbb5e70e857dd3af1a56b37064736f6c63430008070033000000000000000000000000406e0a6d2dfd526c2b44628990ebf98535890606

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

000000000000000000000000406e0a6d2dfd526c2b44628990ebf98535890606

-----Decoded View---------------
Arg [0] : _graphics (address): 0x406e0a6d2dfd526c2b44628990ebf98535890606

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000406e0a6d2dfd526c2b44628990ebf98535890606


Deployed ByteCode Sourcemap

74485:23636:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78212:53;;;;;;;;;;-1:-1:-1;78212:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;10400:14:1;;10393:22;10375:41;;10363:2;10348:18;78212:53:0;;;;;;;;37338:224;;;;;;;;;;-1:-1:-1;37338:224:0;;;;;:::i;:::-;;:::i;88841:690::-;;;;;;;;;;-1:-1:-1;88841:690:0;;;;;:::i;:::-;;:::i;:::-;;24273:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;25832:221::-;;;;;;;;;;-1:-1:-1;25832:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;9652:55:1;;;9634:74;;9622:2;9607:18;25832:221:0;9488:226:1;25355:411:0;;;;;;;;;;-1:-1:-1;25355:411:0;;;;;:::i;:::-;;:::i;93026:578::-;;;;;;;;;;-1:-1:-1;93026:578:0;;;;;:::i;:::-;;:::i;37978:113::-;;;;;;;;;;-1:-1:-1;38066:10:0;:17;37978:113;;;26141:25:1;;;26129:2;26114:18;37978:113:0;25995:177:1;76130:47:0;;;;;;;;;;-1:-1:-1;76130:47:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94273:550;;;;;;;;;;-1:-1:-1;94273:550:0;;;;;:::i;:::-;;:::i;26722:339::-;;;;;;;;;;-1:-1:-1;26722:339:0;;;;;:::i;:::-;;:::i;79410:123::-;;;;;;;;;;-1:-1:-1;79410:123:0;;;;;:::i;:::-;79480:7;79507:18;;;:8;:18;;;;;;;79410:123;78101:50;;;;;;;;;;-1:-1:-1;78101:50:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;82965:182;;;;;;;;;;-1:-1:-1;82965:182:0;;;;;:::i;:::-;;:::i;37646:256::-;;;;;;;;;;-1:-1:-1;37646:256:0;;;;;:::i;:::-;;:::i;79916:121::-;;;;;;;;;;-1:-1:-1;79916:121:0;;;;;:::i;:::-;79985:7;80012:17;;;:7;:17;;;;;;;79916:121;96267:210;;;;;;;;;;;;;:::i;27132:185::-;;;;;;;;;;-1:-1:-1;27132:185:0;;;;;:::i;:::-;;:::i;80168:119::-;;;;;;;;;;-1:-1:-1;80168:119:0;;;;;:::i;:::-;80237:5;80262:17;;;:7;:17;;;;;;;;;80168:119;;;;28065:4:1;28053:17;;;28035:36;;28023:2;28008:18;80168:119:0;27893:184:1;38168:233:0;;;;;;;;;;-1:-1:-1;38168:233:0;;;;;:::i;:::-;;:::i;80293:117::-;;;;;;;;;;-1:-1:-1;80293:117:0;;;;;:::i;:::-;80361:5;80386:16;;;:6;:16;;;;;;;;;80293:117;90987:363;;;;;;;;;;-1:-1:-1;90987:363:0;;;;;:::i;:::-;;:::i;80043:119::-;;;;;;;;;;-1:-1:-1;80043:119:0;;;;;:::i;:::-;80112:5;80137:17;;;:7;:17;;;;;;;;;80043:119;80416:115;;;;;;;;;;-1:-1:-1;80416:115:0;;;;;:::i;:::-;80483:5;80508:15;;;:5;:15;;;;;;;;;80416:115;23967:239;;;;;;;;;;-1:-1:-1;23967:239:0;;;;;:::i;:::-;;:::i;91779:531::-;;;;;;;;;;-1:-1:-1;91779:531:0;;;;;:::i;:::-;;:::i;75989:45::-;;;;;;;;;;-1:-1:-1;75989:45:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;75989:45:0;;;94829:436;;;;;;;;;;-1:-1:-1;94829:436:0;;;;;:::i;:::-;;:::i;83193:506::-;;;;;;;;;;-1:-1:-1;83193:506:0;;;;;:::i;:::-;;:::i;87538:958::-;;;;;;:::i;:::-;;:::i;23697:208::-;;;;;;;;;;-1:-1:-1;23697:208:0;;;;;:::i;:::-;;:::i;47795:94::-;;;;;;;;;;;;;:::i;80537:125::-;;;;;;;;;;-1:-1:-1;80537:125:0;;;;;:::i;:::-;80609:5;80634:20;;;:10;:20;;;;;;;;;80537:125;81015:338;;;;;;;;;;-1:-1:-1;81015:338:0;;;;;:::i;:::-;;:::i;89537:695::-;;;;;;;;;;-1:-1:-1;89537:695:0;;;;;:::i;:::-;;:::i;95271:295::-;;;;;;;;;;-1:-1:-1;95271:295:0;;;;;:::i;:::-;;:::i;82562:129::-;;;;;;;;;;-1:-1:-1;82562:129:0;;;;;:::i;:::-;;:::i;92318:702::-;;;;;;;;;;-1:-1:-1;92318:702:0;;;;;:::i;:::-;;:::i;47144:87::-;;;;;;;;;;-1:-1:-1;47217:6:0;;-1:-1:-1;;;;;47217:6:0;47144:87;;24442:104;;;;;;;;;;;;;:::i;90238:693::-;;;;;;;;;;-1:-1:-1;90238:693:0;;;;;:::i;:::-;;:::i;93963:209::-;;;;;;;;;;-1:-1:-1;93963:209:0;;;;;:::i;:::-;;:::i;26125:295::-;;;;;;;;;;-1:-1:-1;26125:295:0;;;;;:::i;:::-;;:::i;80668:242::-;;;;;;;;;;-1:-1:-1;80668:242:0;;;;;:::i;:::-;;:::i;79793:117::-;;;;;;;;;;-1:-1:-1;79793:117:0;;;;;:::i;:::-;79860:7;79887:15;;;:5;:15;;;;;;;79793:117;27388:328;;;;;;;;;;-1:-1:-1;27388:328:0;;;;;:::i;:::-;;:::i;75606:46::-;;;;;;;;;;-1:-1:-1;75606:46:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;82697:119;;;;;;;;;;-1:-1:-1;82697:119:0;;;;;:::i;:::-;;:::i;82426:105::-;;;;;;;;;;-1:-1:-1;82426:105:0;;;;;:::i;:::-;;:::i;79664:123::-;;;;;;;;;;-1:-1:-1;79664:123:0;;;;;:::i;:::-;79734:7;79761:18;;;:8;:18;;;;;;;79664:123;81917:159;;;;;;;;;;-1:-1:-1;81917:159:0;;;;;:::i;:::-;;:::i;82822:137::-;;;;;;;;;;-1:-1:-1;82822:137:0;;;;;:::i;:::-;;:::i;91356:417::-;;;;;;;;;;-1:-1:-1;91356:417:0;;;;;:::i;:::-;;:::i;81359:234::-;;;;;;;;;;-1:-1:-1;81359:234:0;;;;;:::i;:::-;;:::i;95673:265::-;;;;;;;;;;-1:-1:-1;95673:265:0;;;;;:::i;:::-;;:::i;79539:119::-;;;;;;;;;;-1:-1:-1;79539:119:0;;;;;:::i;:::-;79607:7;79634:16;;;:6;:16;;;;;;;79539:119;26491:164;;;;;;;;;;-1:-1:-1;26491:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;26612:25:0;;;26588:4;26612:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;26491:164;48044:192;;;;;;;;;;-1:-1:-1;48044:192:0;;;;;:::i;:::-;;:::i;78158:47::-;;;;;;;;;;-1:-1:-1;78158:47:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;37338:224;37440:4;37464:50;;;37479:35;37464:50;;:90;;;37518:36;37542:11;37518:23;:36::i;:::-;37457:97;37338:224;-1:-1:-1;;37338:224:0:o;88841:690::-;88939:8;78645:17;78653:8;78645:7;:17::i;:::-;-1:-1:-1;;;;;78631:31:0;:10;-1:-1:-1;;;;;78631:31:0;;78623:82;;;;-1:-1:-1;;;78623:82:0;;14011:2:1;78623:82:0;;;13993:21:1;14050:2;14030:18;;;14023:30;14089:34;14069:18;;;14062:62;14160:8;14140:18;;;14133:36;14186:19;;78623:82:0;;;;;;;;;45218:1:::1;45814:7;;:19;;45806:63;;;::::0;-1:-1:-1;;;45806:63:0;;25432:2:1;45806:63:0::1;::::0;::::1;25414:21:1::0;25471:2;25451:18;;;25444:30;25510:33;25490:18;;;25483:61;25561:18;;45806:63:0::1;25230:355:1::0;45806:63:0::1;45218:1;45947:7;:18:::0;77100:1:::2;88981:17:::0;;;:7:::2;:17;::::0;;;;;:28:::2;:17;:28:::0;88973:53:::2;;;::::0;-1:-1:-1;;;88973:53:0;;25091:2:1;88973:53:0::2;::::0;::::2;25073:21:1::0;25130:2;25110:18;;;25103:30;25169:14;25149:18;;;25142:42;25201:18;;88973:53:0::2;24889:336:1::0;88973:53:0::2;-1:-1:-1::0;;;;;89045:36:0;::::2;;::::0;;;:17:::2;:36;::::0;;;;;::::2;;89037:100;;;::::0;-1:-1:-1;;;89037:100:0;;19198:2:1;89037:100:0::2;::::0;::::2;19180:21:1::0;19237:2;19217:18;;;19210:30;19276:34;19256:18;;;19249:62;19347:21;19327:18;;;19320:49;19386:19;;89037:100:0::2;18996:415:1::0;89037:100:0::2;89174:30;::::0;;;:20:::2;:30;::::0;;;;;:40:::2;::::0;89207:7:::2;89174:40;:::i;:::-;89156:15;:58;89148:118;;;::::0;-1:-1:-1;;;89148:118:0;;10853:2:1;89148:118:0::2;::::0;::::2;10835:21:1::0;10892:2;10872:18;;;10865:30;10931:34;10911:18;;;10904:62;11002:17;10982:18;;;10975:45;11037:19;;89148:118:0::2;10651:411:1::0;89148:118:0::2;89306:16;::::0;;89320:1:::2;89306:16:::0;;;;;::::2;::::0;;;89279:24:::2;::::0;89306:16:::2;::::0;;::::2;::::0;;::::2;::::0;::::2;;::::0;-1:-1:-1;89306:16:0::2;89279:43;;89346:1;89333:7;89341:1;89333:10;;;;;;;;:::i;:::-;;::::0;;::::2;::::0;;;;;:14;89366:67:::2;::::0;;;;-1:-1:-1;;;;;89366:37:0;::::2;::::0;::::2;::::0;:67:::2;::::0;89404:8;;89414:9;;89425:7;;89366:67:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;;89444:18:0::2;::::0;;;:8:::2;:18;::::0;;;;:20;;;-1:-1:-1;89444:18:0;:20:::2;::::0;::::2;:::i;:::-;::::0;;;-1:-1:-1;;;89475:30:0::2;::::0;;;-1:-1:-1;;89475:20:0::2;:30;::::0;-1:-1:-1;89475:30:0;;;89508:15:::2;89475:48:::0;;45174:1:::1;46126:7;:22:::0;88841:690::o;24273:100::-;24327:13;24360:5;24353:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24273:100;:::o;25832:221::-;25908:7;29315:16;;;:7;:16;;;;;;-1:-1:-1;;;;;29315:16:0;25928:73;;;;-1:-1:-1;;;25928:73:0;;19979:2:1;25928:73:0;;;19961:21:1;20018:2;19998:18;;;19991:30;20057:34;20037:18;;;20030:62;20128:14;20108:18;;;20101:42;20160:19;;25928:73:0;19777:408:1;25928:73:0;-1:-1:-1;26021:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;26021:24:0;;25832:221::o;25355:411::-;25436:13;25452:23;25467:7;25452:14;:23::i;:::-;25436:39;;25500:5;-1:-1:-1;;;;;25494:11:0;:2;-1:-1:-1;;;;;25494:11:0;;;25486:57;;;;-1:-1:-1;;;25486:57:0;;22807:2:1;25486:57:0;;;22789:21:1;22846:2;22826:18;;;22819:30;22885:34;22865:18;;;22858:62;22956:3;22936:18;;;22929:31;22977:19;;25486:57:0;22605:397:1;25486:57:0;18879:10;-1:-1:-1;;;;;25578:21:0;;;;:62;;-1:-1:-1;25603:37:0;25620:5;18879:10;26491:164;:::i;25603:37::-;25556:168;;;;-1:-1:-1;;;25556:168:0;;17952:2:1;25556:168:0;;;17934:21:1;17991:2;17971:18;;;17964:30;18030:34;18010:18;;;18003:62;18101:26;18081:18;;;18074:54;18145:19;;25556:168:0;17750:420:1;25556:168:0;25737:21;25746:2;25750:7;25737:8;:21::i;:::-;25425:341;25355:411;;:::o;93026:578::-;93088:8;78645:17;78653:8;78645:7;:17::i;:::-;-1:-1:-1;;;;;78631:31:0;:10;-1:-1:-1;;;;;78631:31:0;;78623:82;;;;-1:-1:-1;;;78623:82:0;;14011:2:1;78623:82:0;;;13993:21:1;14050:2;14030:18;;;14023:30;14089:34;14069:18;;;14062:62;14160:8;14140:18;;;14133:36;14186:19;;78623:82:0;13809:402:1;78623:82:0;93113:17:::1;::::0;;;:7:::1;:17;::::0;;;;;:29:::1;:17;77186:1;93113:29;:68:::0;::::1;;;-1:-1:-1::0;93146:35:0::1;93161:19:::0;;;:9:::1;:19;::::0;;;;;;;;-1:-1:-1;;;;;93161:19:0::1;93146:35:::0;;:14:::1;:35:::0;;;;;;::::1;;93113:68;93109:356;;;93252:17;::::0;;;:7:::1;:17;::::0;;;;:19;;;::::1;::::0;::::1;:::i;:::-;;;;;;93109:356;;;93293:17;::::0;;;:7:::1;:17;::::0;;;;;:28:::1;:17;77229:1;93293:28;:73:::0;::::1;;;-1:-1:-1::0;93325:41:0::1;93346:19:::0;;;:9:::1;:19;::::0;;;;;;;;-1:-1:-1;;;;;93346:19:0::1;93325:41:::0;;:20:::1;:41:::0;;;;;;::::1;;93293:73;93289:176;;;93427:26;::::0;;;:16:::1;:26;::::0;;;;;93409:44:::1;::::0;:15:::1;:44;:::i;:::-;93383:22;::::0;;;:12:::1;:22;::::0;;;;:70;;:22;;;:70:::1;::::0;;;::::1;:::i;:::-;::::0;;;-1:-1:-1;;93289:176:0::1;77100:1;93475:17:::0;;;:7:::1;:17;::::0;;;;;;;:27;;-1:-1:-1;;93475:27:0::1;::::0;;93525:9:::1;:19:::0;;;;;;:32;;;::::1;::::0;;93573:23;;26141:25:1;;;93573:23:0::1;::::0;26114:18:1;93573:23:0::1;;;;;;;93026:578:::0;;:::o;94273:550::-;78976:19;;;;:9;:19;;;;;;94352:8;;-1:-1:-1;;;;;78976:19:0;78999:10;78976:33;78968:94;;;;-1:-1:-1;;;78968:94:0;;21987:2:1;78968:94:0;;;21969:21:1;22026:2;22006:18;;;21999:30;22065:34;22045:18;;;22038:62;22136:18;22116;;;22109:46;22172:19;;78968:94:0;21785:412:1;78968:94:0;94381:17:::1;::::0;;;:7:::1;:17;::::0;;;;;:30:::1;:17;77143:1;94381:30;::::0;:63:::1;;-1:-1:-1::0;94415:17:0::1;::::0;;;:7:::1;:17;::::0;;;;;:29:::1;:17;77186:1;94415:29;94381:63;94373:117;;;::::0;-1:-1:-1;;;94373:117:0;;21577:2:1;94373:117:0::1;::::0;::::1;21559:21:1::0;21616:2;21596:18;;;21589:30;21655:34;21635:18;;;21628:62;21726:11;21706:18;;;21699:39;21755:19;;94373:117:0::1;21375:405:1::0;94373:117:0::1;94505:17;::::0;;;:7:::1;:17;::::0;;;;;:29:::1;:17;77186:1;94505:29;:68:::0;::::1;;;-1:-1:-1::0;94538:35:0::1;94553:19:::0;;;:9:::1;:19;::::0;;;;;;;;-1:-1:-1;;;;;94553:19:0::1;94538:35:::0;;:14:::1;:35:::0;;;;;;::::1;;94505:68;94501:222;;;94594:4;94590:122;;;94619:15;::::0;;;:5:::1;:15;::::0;;;;:17;;;::::1;::::0;::::1;:::i;:::-;;;;;;94590:122;;;94677:17;::::0;;;:7:::1;:17;::::0;;;;:19;;;::::1;::::0;::::1;:::i;:::-;;;;;;94590:122;-1:-1:-1::0;;77100:1:0::1;94733:17:::0;;;:7:::1;:17;::::0;;;;;;;:27;;-1:-1:-1;;94733:27:0::1;::::0;;94783:9:::1;:19:::0;;;;;:32;;;::::1;::::0;;94273:550::o;26722:339::-;26917:41;18879:10;26950:7;26917:18;:41::i;:::-;26909:103;;;;-1:-1:-1;;;26909:103:0;;23209:2:1;26909:103:0;;;23191:21:1;23248:2;23228:18;;;23221:30;23287:34;23267:18;;;23260:62;23358:19;23338:18;;;23331:47;23395:19;;26909:103:0;23007:413:1;26909:103:0;27025:28;27035:4;27041:2;27045:7;27025:9;:28::i;82965:182::-;47217:6;;-1:-1:-1;;;;;47217:6:0;78768:10;:21;;:45;;-1:-1:-1;78807:6:0;;-1:-1:-1;;;;;78807:6:0;78793:10;:20;78768:45;:68;;;-1:-1:-1;78831:5:0;;-1:-1:-1;;;;;78831:5:0;78817:10;:19;78768:68;78760:124;;;;-1:-1:-1;;;78760:124:0;;14418:2:1;78760:124:0;;;14400:21:1;14457:2;14437:18;;;14430:30;14496:34;14476:18;;;14469:62;14567:13;14547:18;;;14540:41;14598:19;;78760:124:0;14216:407:1;78760:124:0;83048:6:::1;83044:96;83064:5;:12;83060:1;:16;83044:96;;;83124:4;83097:14;:24;83112:5;83118:1;83112:8;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;;;83097:24:0::1;::::0;;;::::1;::::0;;;;;;-1:-1:-1;83097:24:0;:31;;-1:-1:-1;;83097:31:0::1;::::0;::::1;;::::0;;;::::1;::::0;;83078:3;::::1;::::0;::::1;:::i;:::-;;;;83044:96;;;;82965:182:::0;:::o;37646:256::-;37743:7;37779:23;37796:5;37779:16;:23::i;:::-;37771:5;:31;37763:87;;;;-1:-1:-1;;;37763:87:0;;11610:2:1;37763:87:0;;;11592:21:1;11649:2;11629:18;;;11622:30;11688:34;11668:18;;;11661:62;11759:13;11739:18;;;11732:41;11790:19;;37763:87:0;11408:407:1;37763:87:0;-1:-1:-1;;;;;;37868:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;37646:256::o;96267:210::-;47217:6;;-1:-1:-1;;;;;47217:6:0;78768:10;:21;;:45;;-1:-1:-1;78807:6:0;;-1:-1:-1;;;;;78807:6:0;78793:10;:20;78768:45;:68;;;-1:-1:-1;78831:5:0;;-1:-1:-1;;;;;78831:5:0;78817:10;:19;78768:68;78760:124;;;;-1:-1:-1;;;78760:124:0;;14418:2:1;78760:124:0;;;14400:21:1;14457:2;14437:18;;;14430:30;14496:34;14476:18;;;14469:62;14567:13;14547:18;;;14540:41;14598:19;;78760:124:0;14216:407:1;78760:124:0;96316:15:::1;96334:25;96358:1;96334:21;:25;:::i;:::-;96398:6;::::0;96316:43;;-1:-1:-1;96372:43:0::1;::::0;-1:-1:-1;;;;;96398:6:0::1;96316:43:::0;96372:17:::1;:43::i;:::-;96452:5;::::0;96426:43:::1;::::0;-1:-1:-1;;;;;96452:5:0::1;96461:7:::0;96426:17:::1;:43::i;:::-;96305:172;96267:210::o:0;27132:185::-;27270:39;27287:4;27293:2;27297:7;27270:39;;;;;;;;;;;;:16;:39::i;38168:233::-;38243:7;38279:30;38066:10;:17;;37978:113;38279:30;38271:5;:38;38263:95;;;;-1:-1:-1;;;38263:95:0;;23975:2:1;38263:95:0;;;23957:21:1;24014:2;23994:18;;;23987:30;24053:34;24033:18;;;24026:62;24124:14;24104:18;;;24097:42;24156:19;;38263:95:0;23773:408:1;38263:95:0;38376:10;38387:5;38376:17;;;;;;;;:::i;:::-;;;;;;;;;38369:24;;38168:233;;;:::o;90987:363::-;91088:8;78645:17;78653:8;78645:7;:17::i;:::-;-1:-1:-1;;;;;78631:31:0;:10;-1:-1:-1;;;;;78631:31:0;;78623:82;;;;-1:-1:-1;;;78623:82:0;;14011:2:1;78623:82:0;;;13993:21:1;14050:2;14030:18;;;14023:30;14089:34;14069:18;;;14062:62;14160:8;14140:18;;;14133:36;14186:19;;78623:82:0;13809:402:1;78623:82:0;45218:1:::1;45814:7;;:19;;45806:63;;;::::0;-1:-1:-1;;;45806:63:0;;25432:2:1;45806:63:0::1;::::0;::::1;25414:21:1::0;25471:2;25451:18;;;25444:30;25510:33;25490:18;;;25483:61;25561:18;;45806:63:0::1;25230:355:1::0;45806:63:0::1;45218:1;45947:7;:18:::0;77100:1:::2;91130:17:::0;;;:7:::2;:17;::::0;;;;;:28:::2;:17;:28:::0;91122:53:::2;;;::::0;-1:-1:-1;;;91122:53:0;;25091:2:1;91122:53:0::2;::::0;::::2;25073:21:1::0;25130:2;25110:18;;;25103:30;25169:14;25149:18;;;25142:42;25201:18;;91122:53:0::2;24889:336:1::0;91122:53:0::2;91188:17;::::0;;;:7:::2;:17;::::0;;;;;;;:29;;-1:-1:-1;;91188:29:0::2;77143:1;91188:29;::::0;;91255:9:::2;:19:::0;;;;;;;:28;;-1:-1:-1;;;;;91255:28:0;::::2;::::0;;;::::2;::::0;::::2;::::0;;;91294:48;;;;;:31:::2;::::0;:48:::2;::::0;91196:8;;91336:5;;;;91294:48:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;45174:1:0::1;46126:7;:22:::0;-1:-1:-1;;;;;;;90987:363:0:o;23967:239::-;24039:7;24075:16;;;:7;:16;;;;;;-1:-1:-1;;;;;24075:16:0;24110:19;24102:73;;;;-1:-1:-1;;;24102:73:0;;18788:2:1;24102:73:0;;;18770:21:1;18827:2;18807:18;;;18800:30;18866:34;18846:18;;;18839:62;18937:11;18917:18;;;18910:39;18966:19;;24102:73:0;18586:405:1;91779:531:0;91884:8;78645:17;78653:8;78645:7;:17::i;:::-;-1:-1:-1;;;;;78631:31:0;:10;-1:-1:-1;;;;;78631:31:0;;78623:82;;;;-1:-1:-1;;;78623:82:0;;14011:2:1;78623:82:0;;;13993:21:1;14050:2;14030:18;;;14023:30;14089:34;14069:18;;;14062:62;14160:8;14140:18;;;14133:36;14186:19;;78623:82:0;13809:402:1;78623:82:0;45218:1:::1;45814:7;;:19;;45806:63;;;::::0;-1:-1:-1;;;45806:63:0;;25432:2:1;45806:63:0::1;::::0;::::1;25414:21:1::0;25471:2;25451:18;;;25444:30;25510:33;25490:18;;;25483:61;25561:18;;45806:63:0::1;25230:355:1::0;45806:63:0::1;45218:1;45947:7;:18:::0;77100:1:::2;91926:17:::0;;;:7:::2;:17;::::0;;;;;:28:::2;:17;:28:::0;91918:53:::2;;;::::0;-1:-1:-1;;;91918:53:0;;25091:2:1;91918:53:0::2;::::0;::::2;25073:21:1::0;25130:2;25110:18;;;25103:30;25169:14;25149:18;;;25142:42;25201:18;;91918:53:0::2;24889:336:1::0;91918:53:0::2;92008:26;::::0;;;:16:::2;:26;::::0;;;;;:37:::2;::::0;92037:8:::2;92008:37;:::i;:::-;91990:15;:55;91982:104;;;::::0;-1:-1:-1;;;91982:104:0;;25792:2:1;91982:104:0::2;::::0;::::2;25774:21:1::0;25831:2;25811:18;;;25804:30;25870:34;25850:18;;;25843:62;25941:6;25921:18;;;25914:34;25965:19;;91982:104:0::2;25590:400:1::0;91982:104:0::2;92099:17;::::0;;;:7:::2;:17;::::0;;;;;;;:24;;-1:-1:-1;;92099:24:0::2;77272:1;92099:24:::0;;::::2;::::0;;;92156:16:::2;:26:::0;;;;;92185:15:::2;92156:44:::0;;92211:9:::2;:19:::0;;;;;;;:30;;-1:-1:-1;;;;;92211:30:0;::::2;::::0;;;::::2;::::0;::::2;::::0;;;92252:50;;;;;:33:::2;::::0;:50:::2;::::0;92107:8;;92296:5;;;;92252:50:::2;;:::i;94829:436::-:0;78976:19;;;;:9;:19;;;;;;94903:8;;-1:-1:-1;;;;;78976:19:0;78999:10;78976:33;78968:94;;;;-1:-1:-1;;;78968:94:0;;21987:2:1;78968:94:0;;;21969:21:1;22026:2;22006:18;;;21999:30;22065:34;22045:18;;;22038:62;22136:18;22116;;;22109:46;22172:19;;78968:94:0;21785:412:1;78968:94:0;94932:17:::1;::::0;;;:7:::1;:17;::::0;;;;;:28:::1;:17;77229:1;94932:28;94924:86;;;::::0;-1:-1:-1;;;94924:86:0;;20392:2:1;94924:86:0::1;::::0;::::1;20374:21:1::0;20431:2;20411:18;;;20404:30;20470:34;20450:18;;;20443:62;20541:15;20521:18;;;20514:43;20574:19;;94924:86:0::1;20190:409:1::0;94924:86:0::1;95025:41;95046:19:::0;;;:9:::1;:19;::::0;;;;;;;;-1:-1:-1;;;;;95046:19:0::1;95025:41:::0;;:20:::1;:41:::0;;;;;;::::1;;95021:144;;;95127:26;::::0;;;:16:::1;:26;::::0;;;;;95109:44:::1;::::0;:15:::1;:44;:::i;:::-;95083:22;::::0;;;:12:::1;:22;::::0;;;;:70;;:22;;;:70:::1;::::0;;;::::1;:::i;:::-;::::0;;;-1:-1:-1;;95021:144:0::1;-1:-1:-1::0;77100:1:0::1;95175:17:::0;;;:7:::1;:17;::::0;;;;;;;:27;;-1:-1:-1;;95175:27:0::1;::::0;;95225:9:::1;:19:::0;;;;;:32;;;::::1;::::0;;94829:436::o;83193:506::-;83277:8;78645:17;78653:8;78645:7;:17::i;:::-;-1:-1:-1;;;;;78631:31:0;:10;-1:-1:-1;;;;;78631:31:0;;78623:82;;;;-1:-1:-1;;;78623:82:0;;14011:2:1;78623:82:0;;;13993:21:1;14050:2;14030:18;;;14023:30;14089:34;14069:18;;;14062:62;14160:8;14140:18;;;14133:36;14186:19;;78623:82:0;13809:402:1;78623:82:0;83307:10:::1;83318:5;83307:17;;;;;;:::i;:::-;::::0;;;::::1;::::0;;;;;::::1;::::0;;;;::::1;;83306:18;83298:65;;;::::0;-1:-1:-1;;;83298:65:0;;12848:2:1;83298:65:0::1;::::0;::::1;12830:21:1::0;12887:2;12867:18;;;12860:30;12926:34;12906:18;;;12899:62;12997:4;12977:18;;;12970:32;13019:19;;83298:65:0::1;12646:398:1::0;83298:65:0::1;83404:1;83388:5;83382:19;:23;:52;;;;;83432:2;83415:5;83409:19;:25;;83382:52;83374:87;;;::::0;-1:-1:-1;;;83374:87:0;;17195:2:1;83374:87:0::1;::::0;::::1;17177:21:1::0;17234:2;17214:18;;;17207:30;17273:24;17253:18;;;17246:52;17315:18;;83374:87:0::1;16993:346:1::0;83374:87:0::1;83528:35;::::0;9221:17:1;83528:35:0::1;::::0;::::1;9209:30:1::0;9255:12;;83528:35:0::1;;;;;;;;;;;;83518:46;;;;;;83507:5;83490:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;83480:34;;;;;;:84;;83472:109;;;::::0;-1:-1:-1;;;83472:109:0;;11269:2:1;83472:109:0::1;::::0;::::1;11251:21:1::0;11308:2;11288:18;;;11281:30;11347:14;11327:18;;;11320:42;11379:18;;83472:109:0::1;11067:336:1::0;83472:109:0::1;83592:22;::::0;;;:12:::1;:22;::::0;;;;;;;:30;;::::1;::::0;;::::1;::::0;::::1;:::i;:::-;;83653:4;83633:10;83644:5;83633:17;;;;;;:::i;:::-;::::0;;;::::1;::::0;;;;;;::::1;::::0;;;;;;:24;;;::::1;;-1:-1:-1::0;;83633:24:0;;::::1;;::::0;;:17:::1;83668:16:::0;;;:6:::1;:16:::0;;;;;;:23;;;;::::1;83633:24:::0;83668:23:::1;::::0;;;-1:-1:-1;;83193:506:0:o;87538:958::-;45218:1;45814:7;;:19;;45806:63;;;;-1:-1:-1;;;45806:63:0;;25432:2:1;45806:63:0;;;25414:21:1;25471:2;25451:18;;;25444:30;25510:33;25490:18;;;25483:61;25561:18;;45806:63:0;25230:355:1;45806:63:0;45218:1;45947:7;:18;87616:11:::1;::::0;::::1;::::0;;;;:34:::1;;;75040:2;87631:7;:19;;;;87616:34;87608:66;;;::::0;-1:-1:-1;;;87608:66:0;;23627:2:1;87608:66:0::1;::::0;::::1;23609:21:1::0;23666:2;23646:18;;;23639:30;23705:21;23685:18;;;23678:49;23744:18;;87608:66:0::1;23425:343:1::0;87608:66:0::1;75087:5;87709:7;87693:23;;:13;38066:10:::0;:17;;37978:113;87693:13:::1;:23;;;;:::i;:::-;:37;;87685:79;;;::::0;-1:-1:-1;;;87685:79:0;;24388:2:1;87685:79:0::1;::::0;::::1;24370:21:1::0;24427:2;24407:18;;;24400:30;24466:31;24446:18;;;24439:59;24515:18;;87685:79:0::1;24186:353:1::0;87685:79:0::1;87831:10;87775:16;87816:26:::0;;;:14:::1;:26;::::0;;;;;87794:7;;87816:26:::1;;87812:71;;;87859:12:::0;::::1;::::0;::::1;:::i;:::-;;;;87812:71;87914:18;;::::0;::::1;74989:8;87914:18;:::i;:::-;87901:9;:31;87893:78;;;::::0;-1:-1:-1;;;87893:78:0;;13608:2:1;87893:78:0::1;::::0;::::1;13590:21:1::0;13647:2;13627:18;;;13620:30;13686:34;13666:18;;;13659:62;13757:4;13737:18;;;13730:32;13779:19;;87893:78:0::1;13406:398:1::0;87893:78:0::1;87999:10;88013:5;87984:26:::0;;;:14:::1;:26;::::0;;;;:34;;-1:-1:-1;;87984:34:0::1;::::0;;88031:458:::1;88053:7;88049:11;;:1;:11;;;88031:458;;;88082:15;88100:13;38066:10:::0;:17;;37978:113;88100:13:::1;:17;::::0;88116:1:::1;88100:17;:::i;:::-;88134;::::0;;;:8:::1;:17;::::0;;;;;;;88154:1:::1;88134:21:::0;;;;88170:6:::1;:15:::0;;;;;:21;;;88206:8:::1;:17:::0;;;;;:21;88242:7:::1;:16:::0;;;;;:26;;-1:-1:-1;;88242:26:0::1;::::0;;88082:35;-1:-1:-1;88303:20:0::1;88082:35:::0;88303:11:::1;:20::i;:::-;88338:18;88348:7;88338:9;:18::i;:::-;88371:19;88382:7;88371:10;:19::i;:::-;88405:23;88420:7;88405:14;:23::i;:::-;88445:32;18879:10:::0;88469:7:::1;88445:9;:32::i;:::-;-1:-1:-1::0;88062:3:0;::::1;::::0;::::1;:::i;:::-;;;;88031:458;;;-1:-1:-1::0;;45174:1:0;46126:7;:22;-1:-1:-1;87538:958:0:o;23697:208::-;23769:7;-1:-1:-1;;;;;23797:19:0;;23789:74;;;;-1:-1:-1;;;23789:74:0;;18377:2:1;23789:74:0;;;18359:21:1;18416:2;18396:18;;;18389:30;18455:34;18435:18;;;18428:62;18526:12;18506:18;;;18499:40;18556:19;;23789:74:0;18175:406:1;23789:74:0;-1:-1:-1;;;;;;23881:16:0;;;;;:9;:16;;;;;;;23697:208::o;47795:94::-;47217:6;;-1:-1:-1;;;;;47217:6:0;18879:10;47364:23;47356:68;;;;-1:-1:-1;;;47356:68:0;;20806:2:1;47356:68:0;;;20788:21:1;;;20825:18;;;20818:30;20884:34;20864:18;;;20857:62;20936:18;;47356:68:0;20604:356:1;47356:68:0;47860:21:::1;47878:1;47860:9;:21::i;:::-;47795:94::o:0;81015:338::-;81082:7;81106:17;;;:7;:17;;;;;;:28;:17;77229:1;81106:28;:73;;;;-1:-1:-1;81138:41:0;81159:19;;;:9;:19;;;;;;;;;-1:-1:-1;;;;;81159:19:0;81138:41;;:20;:41;;;;;;;;81106:73;81102:244;;;81246:26;;;;:16;:26;;;;;;;;;81203:12;:22;;;;;;;:40;;81228:15;;81203:40;:::i;:::-;:69;;;;:::i;81102:244::-;-1:-1:-1;81312:22:0;;;;:12;:22;;;;;;;81015:338::o;81102:244::-;81015:338;;;:::o;89537:695::-;89636:8;78645:17;78653:8;78645:7;:17::i;:::-;-1:-1:-1;;;;;78631:31:0;:10;-1:-1:-1;;;;;78631:31:0;;78623:82;;;;-1:-1:-1;;;78623:82:0;;14011:2:1;78623:82:0;;;13993:21:1;14050:2;14030:18;;;14023:30;14089:34;14069:18;;;14062:62;14160:8;14140:18;;;14133:36;14186:19;;78623:82:0;13809:402:1;78623:82:0;45218:1:::1;45814:7;;:19;;45806:63;;;::::0;-1:-1:-1;;;45806:63:0;;25432:2:1;45806:63:0::1;::::0;::::1;25414:21:1::0;25471:2;25451:18;;;25444:30;25510:33;25490:18;;;25483:61;25561:18;;45806:63:0::1;25230:355:1::0;45806:63:0::1;45218:1;45947:7;:18:::0;77100:1:::2;89678:17:::0;;;:7:::2;:17;::::0;;;;;:28:::2;:17;:28:::0;89670:53:::2;;;::::0;-1:-1:-1;;;89670:53:0;;25091:2:1;89670:53:0::2;::::0;::::2;25073:21:1::0;25130:2;25110:18;;;25103:30;25169:14;25149:18;;;25142:42;25201:18;;89670:53:0::2;24889:336:1::0;89670:53:0::2;-1:-1:-1::0;;;;;89742:36:0;::::2;;::::0;;;:17:::2;:36;::::0;;;;;::::2;;89734:100;;;::::0;-1:-1:-1;;;89734:100:0;;19198:2:1;89734:100:0::2;::::0;::::2;19180:21:1::0;19237:2;19217:18;;;19210:30;19276:34;19256:18;;;19249:62;19347:21;19327:18;;;19320:49;19386:19;;89734:100:0::2;18996:415:1::0;89734:100:0::2;89871:30;::::0;;;:20:::2;:30;::::0;;;;;:40:::2;::::0;89904:7:::2;89871:40;:::i;:::-;89853:15;:58;89845:118;;;::::0;-1:-1:-1;;;89845:118:0;;10853:2:1;89845:118:0::2;::::0;::::2;10835:21:1::0;10892:2;10872:18;;;10865:30;10931:34;10911:18;;;10904:62;11002:17;10982:18;;;10975:45;11037:19;;89845:118:0::2;10651:411:1::0;89845:118:0::2;90004:16;::::0;;90018:1:::2;90004:16:::0;;;;;::::2;::::0;;;89976:25:::2;::::0;90004:16:::2;::::0;;::::2;::::0;;::::2;::::0;::::2;;::::0;-1:-1:-1;90004:16:0::2;89976:44;;90045:1;90031:8;90040:1;90031:11;;;;;;;;:::i;95271:295::-:0;78976:19;;;;:9;:19;;;;;;95341:8;;-1:-1:-1;;;;;78976:19:0;78999:10;78976:33;78968:94;;;;-1:-1:-1;;;78968:94:0;;21987:2:1;78968:94:0;;;21969:21:1;22026:2;22006:18;;;21999:30;22065:34;22045:18;;;22038:62;22136:18;22116;;;22109:46;22172:19;;78968:94:0;21785:412:1;78968:94:0;95370:17:::1;::::0;;;:7:::1;:17;::::0;;;;;:25:::1;:17;77272:1;95370:25;95362:72;;;::::0;-1:-1:-1;;;95362:72:0;;22404:2:1;95362:72:0::1;::::0;::::1;22386:21:1::0;22443:2;22423:18;;;22416:30;22482:34;22462:18;;;22455:62;22553:4;22533:18;;;22526:32;22575:19;;95362:72:0::1;22202:398:1::0;95362:72:0::1;95445:18;::::0;;;:8:::1;:18;::::0;;;;:20;;;::::1;::::0;::::1;:::i;82562:129::-:0;47217:6;;-1:-1:-1;;;;;47217:6:0;78768:10;:21;;:45;;-1:-1:-1;78807:6:0;;-1:-1:-1;;;;;78807:6:0;78793:10;:20;78768:45;:68;;;-1:-1:-1;78831:5:0;;-1:-1:-1;;;;;78831:5:0;78817:10;:19;78768:68;78760:124;;;;-1:-1:-1;;;78760:124:0;;14418:2:1;78760:124:0;;;14400:21:1;14457:2;14437:18;;;14430:30;14496:34;14476:18;;;14469:62;14567:13;14547:18;;;14540:41;14598:19;;78760:124:0;14216:407:1;78760:124:0;-1:-1:-1;;;;;82659:24:0::1;;::::0;;;:17:::1;:24;::::0;;;;;;-1:-1:-1;;82631:52:0;::::1;82659:24;::::0;;::::1;82658:25;82631:52;::::0;;82562:129::o;92318:702::-;92371:8;78645:17;78653:8;78645:7;:17::i;:::-;-1:-1:-1;;;;;78631:31:0;:10;-1:-1:-1;;;;;78631:31:0;;78623:82;;;;-1:-1:-1;;;78623:82:0;;14011:2:1;78623:82:0;;;13993:21:1;14050:2;14030:18;;;14023:30;14089:34;14069:18;;;14062:62;14160:8;14140:18;;;14133:36;14186:19;;78623:82:0;13809:402:1;78623:82:0;45218:1:::1;45814:7;;:19;;45806:63;;;::::0;-1:-1:-1;;;45806:63:0;;25432:2:1;45806:63:0::1;::::0;::::1;25414:21:1::0;25471:2;25451:18;;;25444:30;25510:33;25490:18;;;25483:61;25561:18;;45806:63:0::1;25230:355:1::0;45806:63:0::1;45218:1;45947:7;:18:::0;;;92409:17:::2;::::0;;;:7:::2;:17;::::0;;;;;:29:::2;:17;:29;:68:::0;::::2;;;-1:-1:-1::0;92442:35:0::2;92457:19:::0;;;:9:::2;:19;::::0;;;;;;;;-1:-1:-1;;;;;92457:19:0::2;92442:35:::0;;:14:::2;:35:::0;;;;;;::::2;;92409:68;92405:356;;;92548:17;::::0;;;:7:::2;:17;::::0;;;;:19;;;::::2;::::0;::::2;:::i;:::-;;;;;;92405:356;;;92589:17;::::0;;;:7:::2;:17;::::0;;;;;:28:::2;:17;77229:1;92589:28;:73:::0;::::2;;;-1:-1:-1::0;92621:41:0::2;92642:19:::0;;;:9:::2;:19;::::0;;;;;;;;-1:-1:-1;;;;;92642:19:0::2;92621:41:::0;;:20:::2;:41:::0;;;;;;::::2;;92589:73;92585:176;;;92723:26;::::0;;;:16:::2;:26;::::0;;;;;92705:44:::2;::::0;:15:::2;:44;:::i;:::-;92679:22;::::0;;;:12:::2;:22;::::0;;;;:70;;:22;;;:70:::2;::::0;;;::::2;:::i;:::-;::::0;;;-1:-1:-1;;92585:176:0::2;92882:19;::::0;;;:9:::2;:19;::::0;;;;;;;92864:53;;;;;::::2;::::0;::::2;26141:25:1::0;;;-1:-1:-1;;;;;92882:19:0;;::::2;::::0;92864:43:::2;::::0;26114:18:1;;92864:53:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;;77100:1:0::2;92930:17:::0;;;-1:-1:-1;;92930:7:0::2;:17;::::0;;;;;;;:27;;-1:-1:-1;;92930:27:0::2;::::0;;92980:9:::2;:19:::0;;;;;:32;;;::::2;::::0;;92930:27;46126:7:::1;:22:::0;92318:702::o;24442:104::-;24498:13;24531:7;24524:14;;;;;:::i;90238:693::-;90337:8;78645:17;78653:8;78645:7;:17::i;:::-;-1:-1:-1;;;;;78631:31:0;:10;-1:-1:-1;;;;;78631:31:0;;78623:82;;;;-1:-1:-1;;;78623:82:0;;14011:2:1;78623:82:0;;;13993:21:1;14050:2;14030:18;;;14023:30;14089:34;14069:18;;;14062:62;14160:8;14140:18;;;14133:36;14186:19;;78623:82:0;13809:402:1;78623:82:0;45218:1:::1;45814:7;;:19;;45806:63;;;::::0;-1:-1:-1;;;45806:63:0;;25432:2:1;45806:63:0::1;::::0;::::1;25414:21:1::0;25471:2;25451:18;;;25444:30;25510:33;25490:18;;;25483:61;25561:18;;45806:63:0::1;25230:355:1::0;45806:63:0::1;45218:1;45947:7;:18:::0;77100:1:::2;90379:17:::0;;;:7:::2;:17;::::0;;;;;:28:::2;:17;:28:::0;90371:53:::2;;;::::0;-1:-1:-1;;;90371:53:0;;25091:2:1;90371:53:0::2;::::0;::::2;25073:21:1::0;25130:2;25110:18;;;25103:30;25169:14;25149:18;;;25142:42;25201:18;;90371:53:0::2;24889:336:1::0;90371:53:0::2;-1:-1:-1::0;;;;;90443:36:0;::::2;;::::0;;;:17:::2;:36;::::0;;;;;::::2;;90435:100;;;::::0;-1:-1:-1;;;90435:100:0;;19198:2:1;90435:100:0::2;::::0;::::2;19180:21:1::0;19237:2;19217:18;;;19210:30;19276:34;19256:18;;;19249:62;19347:21;19327:18;;;19320:49;19386:19;;90435:100:0::2;18996:415:1::0;90435:100:0::2;90572:30;::::0;;;:20:::2;:30;::::0;;;;;:40:::2;::::0;90605:7:::2;90572:40;:::i;:::-;90554:15;:58;90546:118;;;::::0;-1:-1:-1;;;90546:118:0;;10853:2:1;90546:118:0::2;::::0;::::2;10835:21:1::0;10892:2;10872:18;;;10865:30;10931:34;10911:18;;;10904:62;11002:17;10982:18;;;10975:45;11037:19;;90546:118:0::2;10651:411:1::0;90546:118:0::2;90705:16;::::0;;90719:1:::2;90705:16:::0;;;;;::::2;::::0;;;90677:25:::2;::::0;90705:16:::2;::::0;;::::2;::::0;;::::2;::::0;::::2;;::::0;-1:-1:-1;90705:16:0::2;90677:44;;90746:1;90732:8;90741:1;90732:11;;;;;;;;:::i;:::-;;::::0;;::::2;::::0;;;;;:15;90767:68:::2;::::0;;;;-1:-1:-1;;;;;90767:37:0;::::2;::::0;::::2;::::0;:68:::2;::::0;90805:8;;90815:9;;90826:8;;90767:68:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;;90846:16:0::2;::::0;;;:6:::2;:16;::::0;;;;:18;;;-1:-1:-1;90846:16:0;:18:::2;::::0;::::2;:::i;93963:209::-:0;78976:19;;;;:9;:19;;;;;;94032:8;;-1:-1:-1;;;;;78976:19:0;78999:10;78976:33;78968:94;;;;-1:-1:-1;;;78968:94:0;;21987:2:1;78968:94:0;;;21969:21:1;22026:2;22006:18;;;21999:30;22065:34;22045:18;;;22038:62;22136:18;22116;;;22109:46;22172:19;;78968:94:0;21785:412:1;78968:94:0;94061:17:::1;::::0;;;:7:::1;:17;::::0;;;;;:29:::1;:17;77186:1;94061:29;;94053:58;;;::::0;-1:-1:-1;;;94053:58:0;;24746:2:1;94053:58:0::1;::::0;::::1;24728:21:1::0;24785:2;24765:18;;;24758:30;24824:18;24804;;;24797:46;24860:18;;94053:58:0::1;24544:340:1::0;94053:58:0::1;-1:-1:-1::0;94122:17:0::1;::::0;;;:7:::1;:17;::::0;;;;:28;;-1:-1:-1;;94122:28:0::1;77186:1;94122:28;::::0;;93963:209::o;26125:295::-;-1:-1:-1;;;;;26228:24:0;;18879:10;26228:24;;26220:62;;;;-1:-1:-1;;;26220:62:0;;15235:2:1;26220:62:0;;;15217:21:1;15274:2;15254:18;;;15247:30;15313:27;15293:18;;;15286:55;15358:18;;26220:62:0;15033:349:1;26220:62:0;18879:10;26295:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;26295:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;26295:53:0;;;;;;;;;;26364:48;;10375:41:1;;;26295:42:0;;18879:10;26364:48;;10348:18:1;26364:48:0;;;;;;;26125:295;;:::o;80668:242::-;80772:16;;;;:6;:16;;;;;;80742:13;;80772:16;;80768:135;;;80812:22;;;;:12;:22;;;;;80805:29;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80668:242;;;:::o;80768:135::-;-1:-1:-1;;80867:24:0;;;;;;;;;;;;;;;;;;80668:242::o;27388:328::-;27563:41;18879:10;27596:7;27563:18;:41::i;:::-;27555:103;;;;-1:-1:-1;;;27555:103:0;;23209:2:1;27555:103:0;;;23191:21:1;23248:2;23228:18;;;23221:30;23287:34;23267:18;;;23260:62;23358:19;23338:18;;;23331:47;23395:19;;27555:103:0;23007:413:1;27555:103:0;27669:39;27683:4;27689:2;27693:7;27702:5;27669:13;:39::i;:::-;27388:328;;;;:::o;82697:119::-;47217:6;;-1:-1:-1;;;;;47217:6:0;78768:10;:21;;:45;;-1:-1:-1;78807:6:0;;-1:-1:-1;;;;;78807:6:0;78793:10;:20;78768:45;:68;;;-1:-1:-1;78831:5:0;;-1:-1:-1;;;;;78831:5:0;78817:10;:19;78768:68;78760:124;;;;-1:-1:-1;;;78760:124:0;;14418:2:1;78760:124:0;;;14400:21:1;14457:2;14437:18;;;14430:30;14496:34;14476:18;;;14469:62;14567:13;14547:18;;;14540:41;14598:19;;78760:124:0;14216:407:1;78760:124:0;-1:-1:-1;;;;;82787:21:0::1;;::::0;;;:14:::1;:21;::::0;;;;;;-1:-1:-1;;82762:46:0;::::1;82787:21;::::0;;::::1;82786:22;82762:46;::::0;;82697:119::o;82426:105::-;47217:6;;-1:-1:-1;;;;;47217:6:0;18879:10;47364:23;47356:68;;;;-1:-1:-1;;;47356:68:0;;20806:2:1;47356:68:0;;;20788:21:1;;;20825:18;;;20818:30;20884:34;20864:18;;;20857:62;20936:18;;47356:68:0;20604:356:1;47356:68:0;-1:-1:-1;;;;;82509:14:0::1;;::::0;;;:7:::1;:14;::::0;;;;;;-1:-1:-1;;82491:32:0;::::1;82509:14;::::0;;::::1;82508:15;82491:32;::::0;;82426:105::o;81917:159::-;82016:9;;:52;;;;;;;;26985:25:1;;;82062:4:0;27026:18:1;;;27019:83;81983:13:0;;-1:-1:-1;;;;;82016:9:0;;:18;;26958::1;;82016:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;82822:137::-;47217:6;;-1:-1:-1;;;;;47217:6:0;78768:10;:21;;:45;;-1:-1:-1;78807:6:0;;-1:-1:-1;;;;;78807:6:0;78793:10;:20;78768:45;:68;;;-1:-1:-1;78831:5:0;;-1:-1:-1;;;;;78831:5:0;78817:10;:19;78768:68;78760:124;;;;-1:-1:-1;;;78760:124:0;;14418:2:1;78760:124:0;;;14400:21:1;14457:2;14437:18;;;14430:30;14496:34;14476:18;;;14469:62;14567:13;14547:18;;;14540:41;14598:19;;78760:124:0;14216:407:1;78760:124:0;-1:-1:-1;;;;;82924:27:0::1;;::::0;;;:20:::1;:27;::::0;;;;;;-1:-1:-1;;82893:58:0;::::1;82924:27;::::0;;::::1;82923:28;82893:58;::::0;;82822:137::o;91356:417::-;91463:8;78645:17;78653:8;78645:7;:17::i;:::-;-1:-1:-1;;;;;78631:31:0;:10;-1:-1:-1;;;;;78631:31:0;;78623:82;;;;-1:-1:-1;;;78623:82:0;;14011:2:1;78623:82:0;;;13993:21:1;14050:2;14030:18;;;14023:30;14089:34;14069:18;;;14062:62;14160:8;14140:18;;;14133:36;14186:19;;78623:82:0;13809:402:1;78623:82:0;45218:1:::1;45814:7;;:19;;45806:63;;;::::0;-1:-1:-1;;;45806:63:0;;25432:2:1;45806:63:0::1;::::0;::::1;25414:21:1::0;25471:2;25451:18;;;25444:30;25510:33;25490:18;;;25483:61;25561:18;;45806:63:0::1;25230:355:1::0;45806:63:0::1;45218:1;45947:7;:18:::0;77100:1:::2;91505:17:::0;;;:7:::2;:17;::::0;;;;;:28:::2;:17;:28:::0;91497:53:::2;;;::::0;-1:-1:-1;;;91497:53:0;;25091:2:1;91497:53:0::2;::::0;::::2;25073:21:1::0;25130:2;25110:18;;;25103:30;25169:14;25149:18;;;25142:42;25201:18;;91497:53:0::2;24889:336:1::0;91497:53:0::2;91563:17;::::0;;;:7:::2;:17;::::0;;;;;;;:27;;-1:-1:-1;;91563:27:0::2;77229:1;91563:27;::::0;;91621:16:::2;:26:::0;;;;;91650:15:::2;91621:44:::0;;91678:9:::2;:19:::0;;;;;;;:28;;-1:-1:-1;;;;;91678:28:0;::::2;::::0;;;::::2;::::0;::::2;::::0;;;91717:48;;;;;:31:::2;::::0;:48:::2;::::0;91571:8;;91759:5;;;;91717:48:::2;;;:::i;81359:234::-:0;81429:7;81469:13;38066:10;:17;;37978:113;81469:13;81457:8;:25;;81449:75;;;;-1:-1:-1;;;81449:75:0;;17546:2:1;81449:75:0;;;17528:21:1;17585:2;17565:18;;;17558:30;17624:34;17604:18;;;17597:62;17695:7;17675:18;;;17668:35;17720:19;;81449:75:0;17344:401:1;81449:75:0;81578:6;81547:28;81566:8;81547:18;:28::i;:::-;:37;;;;:::i;:::-;81542:43;;:1;:43;:::i;95673:265::-;78976:19;;;;:9;:19;;;;;;95736:8;;-1:-1:-1;;;;;78976:19:0;78999:10;78976:33;78968:94;;;;-1:-1:-1;;;78968:94:0;;21987:2:1;78968:94:0;;;21969:21:1;22026:2;22006:18;;;21999:30;22065:34;22045:18;;;22038:62;22136:18;22116;;;22109:46;22172:19;;78968:94:0;21785:412:1;78968:94:0;95765:17:::1;::::0;;;:7:::1;:17;::::0;;;;;:28:::1;:17;77229:1;95765:28;;95757:80;;;::::0;-1:-1:-1;;;95757:80:0;;16787:2:1;95757:80:0::1;::::0;::::1;16769:21:1::0;16826:2;16806:18;;;16799:30;16865:34;16845:18;;;16838:62;16936:9;16916:18;;;16909:37;16963:19;;95757:80:0::1;16585:403:1::0;48044:192:0;47217:6;;-1:-1:-1;;;;;47217:6:0;18879:10;47364:23;47356:68;;;;-1:-1:-1;;;47356:68:0;;20806:2:1;47356:68:0;;;20788:21:1;;;20825:18;;;20818:30;20884:34;20864:18;;;20857:62;20936:18;;47356:68:0;20604:356:1;47356:68:0;-1:-1:-1;;;;;48133:22:0;::::1;48125:73;;;::::0;-1:-1:-1;;;48125:73:0;;12441:2:1;48125:73:0::1;::::0;::::1;12423:21:1::0;12480:2;12460:18;;;12453:30;12519:34;12499:18;;;12492:62;12590:8;12570:18;;;12563:36;12616:19;;48125:73:0::1;12239:402:1::0;48125:73:0::1;48209:19;48219:8;48209:9;:19::i;23328:305::-:0;23430:4;23467:40;;;23482:25;23467:40;;:105;;-1:-1:-1;23524:48:0;;;23539:33;23524:48;23467:105;:158;;;-1:-1:-1;21973:25:0;21958:40;;;;23589:36;21849:157;33208:174;33283:24;;;;:15;:24;;;;;:29;;;;-1:-1:-1;;;;;33283:29:0;;;;;;;;:24;;33337:23;33283:24;33337:14;:23::i;:::-;-1:-1:-1;;;;;33328:46:0;;;;;;;;;;;33208:174;;:::o;29520:348::-;29613:4;29315:16;;;:7;:16;;;;;;-1:-1:-1;;;;;29315:16:0;29630:73;;;;-1:-1:-1;;;29630:73:0;;16374:2:1;29630:73:0;;;16356:21:1;16413:2;16393:18;;;16386:30;16452:34;16432:18;;;16425:62;16523:14;16503:18;;;16496:42;16555:19;;29630:73:0;16172:408:1;29630:73:0;29714:13;29730:23;29745:7;29730:14;:23::i;:::-;29714:39;;29783:5;-1:-1:-1;;;;;29772:16:0;:7;-1:-1:-1;;;;;29772:16:0;;:51;;;;29816:7;-1:-1:-1;;;;;29792:31:0;:20;29804:7;29792:11;:20::i;:::-;-1:-1:-1;;;;;29792:31:0;;29772:51;:87;;;-1:-1:-1;;;;;;26612:25:0;;;26588:4;26612:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;29827:32;29764:96;29520:348;-1:-1:-1;;;;29520:348:0:o;32512:578::-;32671:4;-1:-1:-1;;;;;32644:31:0;:23;32659:7;32644:14;:23::i;:::-;-1:-1:-1;;;;;32644:31:0;;32636:85;;;;-1:-1:-1;;;32636:85:0;;21167:2:1;32636:85:0;;;21149:21:1;21206:2;21186:18;;;21179:30;21245:34;21225:18;;;21218:62;21316:11;21296:18;;;21289:39;21345:19;;32636:85:0;20965:405:1;32636:85:0;-1:-1:-1;;;;;32740:16:0;;32732:65;;;;-1:-1:-1;;;32732:65:0;;14830:2:1;32732:65:0;;;14812:21:1;14869:2;14849:18;;;14842:30;14908:34;14888:18;;;14881:62;14979:6;14959:18;;;14952:34;15003:19;;32732:65:0;14628:400:1;32732:65:0;32810:39;32831:4;32837:2;32841:7;32810:20;:39::i;:::-;32914:29;32931:1;32935:7;32914:8;:29::i;:::-;-1:-1:-1;;;;;32956:15:0;;;;;;:9;:15;;;;;:20;;32975:1;;32956:15;:20;;32975:1;;32956:20;:::i;:::-;;;;-1:-1:-1;;;;;;;32987:13:0;;;;;;:9;:13;;;;;:18;;33004:1;;32987:13;:18;;33004:1;;32987:18;:::i;:::-;;;;-1:-1:-1;;33016:16:0;;;;:7;:16;;;;;;:21;;;;-1:-1:-1;;;;;33016:21:0;;;;;;;;;33055:27;;33016:16;;33055:27;;;;;;;32512:578;;;:::o;12180:317::-;12295:6;12270:21;:31;;12262:73;;;;-1:-1:-1;;;12262:73:0;;16016:2:1;12262:73:0;;;15998:21:1;16055:2;16035:18;;;16028:30;16094:31;16074:18;;;16067:59;16143:18;;12262:73:0;15814:353:1;12262:73:0;12349:12;12367:9;-1:-1:-1;;;;;12367:14:0;12389:6;12367:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12348:52;;;12419:7;12411:78;;;;-1:-1:-1;;;12411:78:0;;15589:2:1;12411:78:0;;;15571:21:1;15628:2;15608:18;;;15601:30;15667:34;15647:18;;;15640:62;15738:28;15718:18;;;15711:56;15784:19;;12411:78:0;15387:422:1;84005:465:0;84064:12;84079:26;;;;;;;;;;;;;;;;;;84096:8;84079:6;:26::i;:::-;84064:41;-1:-1:-1;84116:18:0;84137:10;84144:3;84064:41;84137:10;:::i;:::-;84116:31;;84175:2;84162:10;:15;84158:305;;;-1:-1:-1;;84214:1:0;84194:17;;;:7;:17;;;;;:21;;-1:-1:-1;;84194:21:0;;;25355:411::o;84158:305::-;84250:2;84237:10;:15;84233:230;;;84269:17;;;;:7;:17;;;;;:21;;-1:-1:-1;;84269:21:0;84289:1;84269:21;;;25425:341;25355:411;;:::o;84233:230::-;84325:2;84312:10;:15;84308:155;;;84344:17;;;;:7;:17;;;;;:21;;-1:-1:-1;;84344:21:0;84364:1;84344:21;;;25425:341;25355:411;;:::o;84308:155::-;84430:17;;;;:7;:17;;;;;:21;;-1:-1:-1;;84430:21:0;84450:1;84430:21;;;84053:417;;84005:465;:::o;84476:164::-;84533:12;84548:24;;;;;;;;;;;;;;;;;;84563:8;84548:6;:24::i;:::-;84533:39;-1:-1:-1;84607:24:0;77587:1;84533:39;84607:24;:::i;:::-;84583:15;;;;:5;:15;;;;;;:49;;-1:-1:-1;;84583:49:0;;;;;;;;;;;;-1:-1:-1;84476:164:0:o;84646:1392::-;84704:12;84719:25;;;;;;;;;;;;;;;;;;84735:8;84719:6;:25::i;:::-;84704:40;-1:-1:-1;84755:20:0;84778:12;84785:5;84704:40;84778:12;:::i;:::-;84755:35;;84827:4;84812:12;:19;84801:1230;;;-1:-1:-1;;84867:1:0;84848:16;;;:6;:16;;;;;:20;;-1:-1:-1;;84848:20:0;;;25355:411::o;84801:1230::-;84905:4;84890:12;:19;84886:1145;;;84926:16;;;;:6;:16;;;;;:20;;-1:-1:-1;;84926:20:0;84945:1;84926:20;;;25425:341;25355:411;;:::o;84886:1145::-;84983:4;84968:12;:19;84964:1067;;;85004:16;;;;:6;:16;;;;;:20;;-1:-1:-1;;85004:20:0;85023:1;85004:20;;;25425:341;25355:411;;:::o;84964:1067::-;85061:4;85046:12;:19;85042:989;;;85082:16;;;;:6;:16;;;;;:20;;-1:-1:-1;;85082:20:0;85101:1;85082:20;;;25425:341;25355:411;;:::o;85042:989::-;85139:4;85124:12;:19;85120:911;;;85160:16;;;;:6;:16;;;;;:20;;-1:-1:-1;;85160:20:0;85179:1;85160:20;;;25425:341;25355:411;;:::o;85120:911::-;85217:4;85202:12;:19;85198:833;;;85238:16;;;;:6;:16;;;;;:20;;-1:-1:-1;;85238:20:0;85257:1;85238:20;;;25425:341;25355:411;;:::o;85198:833::-;85295:4;85280:12;:19;85276:755;;;85316:16;;;;:6;:16;;;;;:20;;-1:-1:-1;;85316:20:0;85335:1;85316:20;;;25425:341;25355:411;;:::o;85276:755::-;85373:4;85358:12;:19;85354:677;;;85394:16;;;;:6;:16;;;;;:20;;-1:-1:-1;;85394:20:0;85413:1;85394:20;;;25425:341;25355:411;;:::o;85354:677::-;85451:4;85436:12;:19;85432:599;;;85472:16;;;;:6;:16;;;;;:20;;-1:-1:-1;;85472:20:0;85491:1;85472:20;;;25425:341;25355:411;;:::o;85432:599::-;85529:4;85514:12;:19;85510:521;;;85550:16;;;;:6;:16;;;;;:20;;-1:-1:-1;;85550:20:0;85569:1;85550:20;;;25425:341;25355:411;;:::o;85510:521::-;85607:4;85592:12;:19;85588:443;;;85628:16;;;;:6;:16;;;;;:21;;-1:-1:-1;;85628:21:0;85647:2;85628:21;;;25425:341;25355:411;;:::o;85588:443::-;85686:4;85671:12;:19;85667:364;;;85707:16;;;;:6;:16;;;;;:21;;-1:-1:-1;;85707:21:0;85726:2;85707:21;;;25425:341;25355:411;;:::o;85667:364::-;85765:4;85750:12;:19;85746:285;;;85786:16;;;;:6;:16;;;;;:21;;-1:-1:-1;;85786:21:0;85805:2;85786:21;;;25425:341;25355:411;;:::o;85746:285::-;85844:4;85829:12;:19;85825:206;;;85865:16;;;;:6;:16;;;;;:21;;-1:-1:-1;;85865:21:0;85884:2;85865:21;;;25425:341;25355:411;;:::o;85825:206::-;85923:4;85908:12;:19;85904:127;;;85944:16;;;;:6;:16;;;;;:21;;-1:-1:-1;;85944:21:0;85963:2;85944:21;;;25425:341;25355:411;;:::o;85904:127::-;85998:16;;;;:6;:16;;;;;:21;;-1:-1:-1;;85998:21:0;86017:2;85998:21;;;84693:1345;;84646:1392;:::o;86044:1189::-;86106:12;86121:29;;;;;;;;;;;;;;;;;;86141:8;86121:6;:29::i;:::-;86106:44;-1:-1:-1;86161:19:0;86183:11;86190:4;86106:44;86183:11;:::i;:::-;86161:33;;86230:3;86216:11;:17;86205:1021;;;-1:-1:-1;;86273:1:0;86250:20;;;:10;:20;;;;;:24;;-1:-1:-1;;86250:24:0;;;25355:411::o;86205:1021::-;86310:3;86296:11;:17;86292:934;;;86330:20;;;;:10;:20;;;;;:24;;-1:-1:-1;;86330:24:0;86353:1;86330:24;;;25425:341;25355:411;;:::o;86292:934::-;86390:3;86376:11;:17;86372:854;;;86410:20;;;;:10;:20;;;;;:24;;-1:-1:-1;;86410:24:0;86433:1;86410:24;;;25425:341;25355:411;;:::o;86372:854::-;86470:3;86456:11;:17;86452:774;;;86490:20;;;;:10;:20;;;;;:24;;-1:-1:-1;;86490:24:0;86513:1;86490:24;;;25425:341;25355:411;;:::o;86452:774::-;86550:3;86536:11;:17;86532:694;;;86570:20;;;;:10;:20;;;;;:24;;-1:-1:-1;;86570:24:0;86593:1;86570:24;;;25425:341;25355:411;;:::o;86532:694::-;86630:3;86616:11;:17;86612:614;;;86650:20;;;;:10;:20;;;;;:24;;-1:-1:-1;;86650:24:0;86673:1;86650:24;;;25425:341;25355:411;;:::o;86612:614::-;86710:3;86696:11;:17;86692:534;;;86730:20;;;;:10;:20;;;;;:24;;-1:-1:-1;;86730:24:0;86753:1;86730:24;;;25425:341;25355:411;;:::o;86692:534::-;86790:3;86776:11;:17;86772:454;;;86810:20;;;;:10;:20;;;;;:24;;-1:-1:-1;;86810:24:0;86833:1;86810:24;;;25425:341;25355:411;;:::o;86772:454::-;86870:3;86856:11;:17;86852:374;;;86890:20;;;;:10;:20;;;;;:24;;-1:-1:-1;;86890:24:0;86913:1;86890:24;;;25425:341;25355:411;;:::o;86852:374::-;86950:3;86936:11;:17;86932:294;;;86970:20;;;;:10;:20;;;;;:24;;-1:-1:-1;;86970:24:0;86993:1;86970:24;;;25425:341;25355:411;;:::o;86932:294::-;87030:3;87016:11;:17;87012:214;;;87050:20;;;;:10;:20;;;;;:25;;-1:-1:-1;;87050:25:0;87073:2;87050:25;;;25425:341;25355:411;;:::o;87012:214::-;87111:3;87097:11;:17;87093:133;;;87131:20;;;;:10;:20;;;;;:25;;-1:-1:-1;;87131:25:0;87154:2;87131:25;;;25425:341;25355:411;;:::o;87093:133::-;87189:20;;;;:10;:20;;;;;:25;;-1:-1:-1;;87189:25:0;87212:2;87189:25;;;86095:1138;;86044:1189;:::o;30210:110::-;30286:26;30296:2;30300:7;30286:26;;;;;;;;;;;;:9;:26::i;48244:173::-;48319:6;;;-1:-1:-1;;;;;48336:17:0;;;;;;;;;;;48369:40;;48319:6;;;48336:17;48319:6;;48369:40;;48300:16;;48369:40;48289:128;48244:173;:::o;28598:315::-;28755:28;28765:4;28771:2;28775:7;28755:9;:28::i;:::-;28802:48;28825:4;28831:2;28835:7;28844:5;28802:22;:48::i;:::-;28794:111;;;;-1:-1:-1;;;28794:111:0;;12022:2:1;28794:111:0;;;12004:21:1;12061:2;12041:18;;;12034:30;12100:34;12080:18;;;12073:62;12171:20;12151:18;;;12144:48;12209:19;;28794:111:0;11820:414:1;39014:589:0;-1:-1:-1;;;;;39220:18:0;;39216:187;;39255:40;39287:7;40430:10;:17;;40403:24;;;;:15;:24;;;;;:44;;;40458:24;;;;;;;;;;;;40326:164;39255:40;39216:187;;;39325:2;-1:-1:-1;;;;;39317:10:0;:4;-1:-1:-1;;;;;39317:10:0;;39313:90;;39344:47;39377:4;39383:7;39344:32;:47::i;:::-;-1:-1:-1;;;;;39417:16:0;;39413:183;;39450:45;39487:7;39450:36;:45::i;39413:183::-;39523:4;-1:-1:-1;;;;;39517:10:0;:2;-1:-1:-1;;;;;39517:10:0;;39513:83;;39544:40;39572:2;39576:7;39544:27;:40::i;96778:207::-;96852:7;96914:4;96920:15;96929:5;96920:8;:15::i;:::-;96937:25;96946:15;96937:8;:25::i;:::-;96964:10;96897:78;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;96887:89;;96897:78;96887:89;;;;;96778:207;-1:-1:-1;;;96778:207:0:o;30547:321::-;30677:18;30683:2;30687:7;30677:5;:18::i;:::-;30728:54;30759:1;30763:2;30767:7;30776:5;30728:22;:54::i;:::-;30706:154;;;;-1:-1:-1;;;30706:154:0;;12022:2:1;30706:154:0;;;12004:21:1;12061:2;12041:18;;;12034:30;12100:34;12080:18;;;12073:62;12171:20;12151:18;;;12144:48;12209:19;;30706:154:0;11820:414:1;33947:799:0;34102:4;-1:-1:-1;;;;;34123:13:0;;11181:20;11229:8;34119:620;;34159:72;;;;;-1:-1:-1;;;;;34159:36:0;;;;;:72;;18879:10;;34210:4;;34216:7;;34225:5;;34159:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34159:72:0;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;34155:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34401:13:0;;34397:272;;34444:60;;-1:-1:-1;;;34444:60:0;;12022:2:1;34444:60:0;;;12004:21:1;12061:2;12041:18;;;12034:30;12100:34;12080:18;;;12073:62;12171:20;12151:18;;;12144:48;12209:19;;34444:60:0;11820:414:1;34397:272:0;34619:6;34613:13;34604:6;34600:2;34596:15;34589:38;34155:529;34282:51;;34292:41;34282:51;;-1:-1:-1;34275:58:0;;34119:620;-1:-1:-1;34723:4:0;33947:799;;;;;;:::o;41117:988::-;41383:22;41433:1;41408:22;41425:4;41408:16;:22::i;:::-;:26;;;;:::i;:::-;41445:18;41466:26;;;:17;:26;;;;;;41383:51;;-1:-1:-1;41599:28:0;;;41595:328;;-1:-1:-1;;;;;41666:18:0;;41644:19;41666:18;;;:12;:18;;;;;;;;:34;;;;;;;;;41717:30;;;;;;:44;;;41834:30;;:17;:30;;;;;:43;;;41595:328;-1:-1:-1;42019:26:0;;;;:17;:26;;;;;;;;42012:33;;;-1:-1:-1;;;;;42063:18:0;;;;;:12;:18;;;;;:34;;;;;;;42056:41;41117:988::o;42400:1079::-;42678:10;:17;42653:22;;42678:21;;42698:1;;42678:21;:::i;:::-;42710:18;42731:24;;;:15;:24;;;;;;43104:10;:26;;42653:46;;-1:-1:-1;42731:24:0;;42653:46;;43104:26;;;;;;:::i;:::-;;;;;;;;;43082:48;;43168:11;43143:10;43154;43143:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;43248:28;;;:15;:28;;;;;;;:41;;;43420:24;;;;;43413:31;43455:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;42471:1008;;;42400:1079;:::o;39904:221::-;39989:14;40006:20;40023:2;40006:16;:20::i;:::-;-1:-1:-1;;;;;40037:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;40082:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;39904:221:0:o;96993:715::-;97049:13;97262:10;97258:53;;-1:-1:-1;;97289:10:0;;;;;;;;;;;;;;;;;;96993:715::o;97258:53::-;97336:5;97321:12;97377:78;97384:9;;97377:78;;97410:8;;;;:::i;:::-;;-1:-1:-1;97433:10:0;;-1:-1:-1;97441:2:0;97433:10;;:::i;:::-;;;97377:78;;;97465:19;97497:6;97487:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;97487:17:0;;97465:39;;97515:154;97522:10;;97515:154;;97549:11;97559:1;97549:11;;:::i;:::-;;-1:-1:-1;97618:10:0;97626:2;97618:5;:10;:::i;:::-;97605:24;;:2;:24;:::i;:::-;97592:39;;97575:6;97582;97575:14;;;;;;;;:::i;:::-;;;;:56;;;;;;;;;;-1:-1:-1;97646:11:0;97655:2;97646:11;;:::i;:::-;;;97515:154;;31204:382;-1:-1:-1;;;;;31284:16:0;;31276:61;;;;-1:-1:-1;;;31276:61:0;;19618:2:1;31276:61:0;;;19600:21:1;;;19637:18;;;19630:30;19696:34;19676:18;;;19669:62;19748:18;;31276:61:0;19416:356:1;31276:61:0;29291:4;29315:16;;;:7;:16;;;;;;-1:-1:-1;;;;;29315:16:0;:30;31348:58;;;;-1:-1:-1;;;31348:58:0;;13251:2:1;31348:58:0;;;13233:21:1;13290:2;13270:18;;;13263:30;13329;13309:18;;;13302:58;13377:18;;31348:58:0;13049:352:1;31348:58:0;31419:45;31448:1;31452:2;31456:7;31419:20;:45::i;:::-;-1:-1:-1;;;;;31477:13:0;;;;;;:9;:13;;;;;:18;;31494:1;;31477:13;:18;;31494:1;;31477:18;:::i;:::-;;;;-1:-1:-1;;31506:16:0;;;;:7;:16;;;;;;:21;;;;-1:-1:-1;;;;;31506:21:0;;;;;;;;31545:33;;31506:16;;;31545:33;;31506:16;;31545:33;31204:382;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:336:1;78:5;107:52;123:35;151:6;123:35;:::i;:::-;107:52;:::i;:::-;98:61;;182:6;175:5;168:21;222:3;213:6;208:3;204:16;201:25;198:45;;;239:1;236;229:12;198:45;288:6;283:3;276:4;269:5;265:16;252:43;342:1;335:4;326:6;319:5;315:18;311:29;304:40;14:336;;;;;:::o;355:196::-;423:20;;-1:-1:-1;;;;;472:54:1;;462:65;;452:93;;541:1;538;531:12;556:160;621:20;;677:13;;670:21;660:32;;650:60;;706:1;703;696:12;721:221;764:5;817:3;810:4;802:6;798:17;794:27;784:55;;835:1;832;825:12;784:55;857:79;932:3;923:6;910:20;903:4;895:6;891:17;857:79;:::i;:::-;848:88;721:221;-1:-1:-1;;;721:221:1:o;947:186::-;1006:6;1059:2;1047:9;1038:7;1034:23;1030:32;1027:52;;;1075:1;1072;1065:12;1027:52;1098:29;1117:9;1098:29;:::i;1138:260::-;1206:6;1214;1267:2;1255:9;1246:7;1242:23;1238:32;1235:52;;;1283:1;1280;1273:12;1235:52;1306:29;1325:9;1306:29;:::i;:::-;1296:39;;1354:38;1388:2;1377:9;1373:18;1354:38;:::i;:::-;1344:48;;1138:260;;;;;:::o;1403:328::-;1480:6;1488;1496;1549:2;1537:9;1528:7;1524:23;1520:32;1517:52;;;1565:1;1562;1555:12;1517:52;1588:29;1607:9;1588:29;:::i;:::-;1578:39;;1636:38;1670:2;1659:9;1655:18;1636:38;:::i;:::-;1626:48;;1721:2;1710:9;1706:18;1693:32;1683:42;;1403:328;;;;;:::o;1736:666::-;1831:6;1839;1847;1855;1908:3;1896:9;1887:7;1883:23;1879:33;1876:53;;;1925:1;1922;1915:12;1876:53;1948:29;1967:9;1948:29;:::i;:::-;1938:39;;1996:38;2030:2;2019:9;2015:18;1996:38;:::i;:::-;1986:48;;2081:2;2070:9;2066:18;2053:32;2043:42;;2136:2;2125:9;2121:18;2108:32;2163:18;2155:6;2152:30;2149:50;;;2195:1;2192;2185:12;2149:50;2218:22;;2271:4;2263:13;;2259:27;-1:-1:-1;2249:55:1;;2300:1;2297;2290:12;2249:55;2323:73;2388:7;2383:2;2370:16;2365:2;2361;2357:11;2323:73;:::i;:::-;2313:83;;;1736:666;;;;;;;:::o;2407:254::-;2472:6;2480;2533:2;2521:9;2512:7;2508:23;2504:32;2501:52;;;2549:1;2546;2539:12;2501:52;2572:29;2591:9;2572:29;:::i;:::-;2562:39;;2620:35;2651:2;2640:9;2636:18;2620:35;:::i;2666:254::-;2734:6;2742;2795:2;2783:9;2774:7;2770:23;2766:32;2763:52;;;2811:1;2808;2801:12;2763:52;2834:29;2853:9;2834:29;:::i;:::-;2824:39;2910:2;2895:18;;;;2882:32;;-1:-1:-1;;;2666:254:1:o;2925:963::-;3009:6;3040:2;3083;3071:9;3062:7;3058:23;3054:32;3051:52;;;3099:1;3096;3089:12;3051:52;3139:9;3126:23;3168:18;3209:2;3201:6;3198:14;3195:34;;;3225:1;3222;3215:12;3195:34;3263:6;3252:9;3248:22;3238:32;;3308:7;3301:4;3297:2;3293:13;3289:27;3279:55;;3330:1;3327;3320:12;3279:55;3366:2;3353:16;3388:2;3384;3381:10;3378:36;;;3394:18;;:::i;:::-;3440:2;3437:1;3433:10;3423:20;;3463:28;3487:2;3483;3479:11;3463:28;:::i;:::-;3525:15;;;3556:12;;;;3588:11;;;3618;;;3614:20;;3611:33;-1:-1:-1;3608:53:1;;;3657:1;3654;3647:12;3608:53;3679:1;3670:10;;3689:169;3703:2;3700:1;3697:9;3689:169;;;3760:23;3779:3;3760:23;:::i;:::-;3748:36;;3721:1;3714:9;;;;;3804:12;;;;3836;;3689:169;;;-1:-1:-1;3877:5:1;2925:963;-1:-1:-1;;;;;;;;2925:963:1:o;3893:245::-;3951:6;4004:2;3992:9;3983:7;3979:23;3975:32;3972:52;;;4020:1;4017;4010:12;3972:52;4059:9;4046:23;4078:30;4102:5;4078:30;:::i;4143:249::-;4212:6;4265:2;4253:9;4244:7;4240:23;4236:32;4233:52;;;4281:1;4278;4271:12;4233:52;4313:9;4307:16;4332:30;4356:5;4332:30;:::i;4397:322::-;4466:6;4519:2;4507:9;4498:7;4494:23;4490:32;4487:52;;;4535:1;4532;4525:12;4487:52;4575:9;4562:23;4608:18;4600:6;4597:30;4594:50;;;4640:1;4637;4630:12;4594:50;4663;4705:7;4696:6;4685:9;4681:22;4663:50;:::i;4724:635::-;4804:6;4857:2;4845:9;4836:7;4832:23;4828:32;4825:52;;;4873:1;4870;4863:12;4825:52;4906:9;4900:16;4939:18;4931:6;4928:30;4925:50;;;4971:1;4968;4961:12;4925:50;4994:22;;5047:4;5039:13;;5035:27;-1:-1:-1;5025:55:1;;5076:1;5073;5066:12;5025:55;5105:2;5099:9;5130:48;5146:31;5174:2;5146:31;:::i;5130:48::-;5201:2;5194:5;5187:17;5241:7;5236:2;5231;5227;5223:11;5219:20;5216:33;5213:53;;;5262:1;5259;5252:12;5213:53;5275:54;5326:2;5321;5314:5;5310:14;5305:2;5301;5297:11;5275:54;:::i;:::-;5348:5;4724:635;-1:-1:-1;;;;;4724:635:1:o;5364:180::-;5423:6;5476:2;5464:9;5455:7;5451:23;5447:32;5444:52;;;5492:1;5489;5482:12;5444:52;-1:-1:-1;5515:23:1;;5364:180;-1:-1:-1;5364:180:1:o;5549:757::-;5653:6;5661;5669;5677;5730:2;5718:9;5709:7;5705:23;5701:32;5698:52;;;5746:1;5743;5736:12;5698:52;5782:9;5769:23;5759:33;;5811:38;5845:2;5834:9;5830:18;5811:38;:::i;:::-;5801:48;;5900:2;5889:9;5885:18;5872:32;5923:18;5964:2;5956:6;5953:14;5950:34;;;5980:1;5977;5970:12;5950:34;6018:6;6007:9;6003:22;5993:32;;6063:7;6056:4;6052:2;6048:13;6044:27;6034:55;;6085:1;6082;6075:12;6034:55;6125:2;6112:16;6151:2;6143:6;6140:14;6137:34;;;6167:1;6164;6157:12;6137:34;6220:7;6215:2;6205:6;6202:1;6198:14;6194:2;6190:23;6186:32;6183:45;6180:65;;;6241:1;6238;6231:12;6180:65;5549:757;;;;-1:-1:-1;;6272:2:1;6264:11;;-1:-1:-1;;;5549:757:1:o;6311:248::-;6376:6;6384;6437:2;6425:9;6416:7;6412:23;6408:32;6405:52;;;6453:1;6450;6443:12;6405:52;6489:9;6476:23;6466:33;;6518:35;6549:2;6538:9;6534:18;6518:35;:::i;6564:390::-;6642:6;6650;6703:2;6691:9;6682:7;6678:23;6674:32;6671:52;;;6719:1;6716;6709:12;6671:52;6755:9;6742:23;6732:33;;6816:2;6805:9;6801:18;6788:32;6843:18;6835:6;6832:30;6829:50;;;6875:1;6872;6865:12;6829:50;6898;6940:7;6931:6;6920:9;6916:22;6898:50;:::i;:::-;6888:60;;;6564:390;;;;;:::o;6959:322::-;7036:6;7044;7052;7105:2;7093:9;7084:7;7080:23;7076:32;7073:52;;;7121:1;7118;7111:12;7073:52;7157:9;7144:23;7134:33;;7214:2;7203:9;7199:18;7186:32;7176:42;;7237:38;7271:2;7260:9;7256:18;7237:38;:::i;:::-;7227:48;;6959:322;;;;;:::o;7286:269::-;7343:6;7396:2;7384:9;7375:7;7371:23;7367:32;7364:52;;;7412:1;7409;7402:12;7364:52;7451:9;7438:23;7501:4;7494:5;7490:16;7483:5;7480:27;7470:55;;7521:1;7518;7511:12;7560:316;7601:3;7639:5;7633:12;7666:6;7661:3;7654:19;7682:63;7738:6;7731:4;7726:3;7722:14;7715:4;7708:5;7704:16;7682:63;:::i;:::-;7790:2;7778:15;7795:66;7774:88;7765:98;;;;7865:4;7761:109;;7560:316;-1:-1:-1;;7560:316:1:o;7881:276::-;8012:3;8050:6;8044:13;8066:53;8112:6;8107:3;8100:4;8092:6;8088:17;8066:53;:::i;:::-;8135:16;;;;;7881:276;-1:-1:-1;;7881:276:1:o;8162:840::-;8417:3;8455:6;8449:13;8471:53;8517:6;8512:3;8505:4;8497:6;8493:17;8471:53;:::i;:::-;8587:13;;8546:16;;;;8609:57;8587:13;8546:16;8643:4;8631:17;;8609:57;:::i;:::-;8733:13;;8688:20;;;8755:57;8733:13;8688:20;8789:4;8777:17;;8755:57;:::i;:::-;8885:2;8881:15;;;;8898:66;8877:88;8834:20;;8863:103;;;-1:-1:-1;;8993:2:1;8982:14;;8162:840;-1:-1:-1;;;8162:840:1:o;9719:511::-;9913:4;-1:-1:-1;;;;;10023:2:1;10015:6;10011:15;10000:9;9993:34;10075:2;10067:6;10063:15;10058:2;10047:9;10043:18;10036:43;;10115:6;10110:2;10099:9;10095:18;10088:34;10158:3;10153:2;10142:9;10138:18;10131:31;10179:45;10219:3;10208:9;10204:19;10196:6;10179:45;:::i;:::-;10171:53;9719:511;-1:-1:-1;;;;;;9719:511:1:o;10427:219::-;10576:2;10565:9;10558:21;10539:4;10596:44;10636:2;10625:9;10621:18;10613:6;10596:44;:::i;26177:604::-;26394:6;26383:9;26376:25;26437:2;26432;26421:9;26417:18;26410:30;26476:6;26471:2;26460:9;26456:18;26449:34;26357:4;26506:66;26498:6;26495:78;26492:98;;;26586:1;26583;26576:12;26492:98;26620:6;26617:1;26613:14;26677:6;26669;26664:2;26653:9;26649:18;26636:48;26754:1;26707:22;;26731:2;26703:31;26743:13;;;-1:-1:-1;26703:31:1;26177:604;-1:-1:-1;;;26177:604:1:o;27113:775::-;27311:4;27359:2;27348:9;27344:18;27389:6;27378:9;27371:25;27415:2;27453:6;27448:2;27437:9;27433:18;27426:34;27496:2;27491;27480:9;27476:18;27469:30;27519:6;27554;27548:13;27585:6;27577;27570:22;27623:3;27612:9;27608:19;27601:26;;27662:2;27654:6;27650:15;27636:29;;27683:1;27693:169;27707:6;27704:1;27701:13;27693:169;;;27768:13;;27756:26;;27837:15;;;;27802:12;;;;27729:1;27722:9;27693:169;;;-1:-1:-1;27879:3:1;;27113:775;-1:-1:-1;;;;;;;;27113:775:1:o;28082:334::-;28153:2;28147:9;28209:2;28199:13;;28214:66;28195:86;28183:99;;28312:18;28297:34;;28333:22;;;28294:62;28291:88;;;28359:18;;:::i;:::-;28395:2;28388:22;28082:334;;-1:-1:-1;28082:334:1:o;28421:245::-;28469:4;28502:18;28494:6;28491:30;28488:56;;;28524:18;;:::i;:::-;-1:-1:-1;28581:2:1;28569:15;28586:66;28565:88;28655:4;28561:99;;28421:245::o;28671:128::-;28711:3;28742:1;28738:6;28735:1;28732:13;28729:39;;;28748:18;;:::i;:::-;-1:-1:-1;28784:9:1;;28671:128::o;28804:120::-;28844:1;28870;28860:35;;28875:18;;:::i;:::-;-1:-1:-1;28909:9:1;;28804:120::o;28929:228::-;28969:7;29095:1;29027:66;29023:74;29020:1;29017:81;29012:1;29005:9;28998:17;28994:105;28991:131;;;29102:18;;:::i;:::-;-1:-1:-1;29142:9:1;;28929:228::o;29162:125::-;29202:4;29230:1;29227;29224:8;29221:34;;;29235:18;;:::i;:::-;-1:-1:-1;29272:9:1;;29162:125::o;29292:258::-;29364:1;29374:113;29388:6;29385:1;29382:13;29374:113;;;29464:11;;;29458:18;29445:11;;;29438:39;29410:2;29403:10;29374:113;;;29505:6;29502:1;29499:13;29496:48;;;-1:-1:-1;;29540:1:1;29522:16;;29515:27;29292:258::o;29555:238::-;29592:3;29636:4;29629:5;29625:16;29660:7;29650:41;;29671:18;;:::i;:::-;29720:66;29707:80;;29555:238;-1:-1:-1;;29555:238:1:o;29798:437::-;29877:1;29873:12;;;;29920;;;29941:61;;29995:4;29987:6;29983:17;29973:27;;29941:61;30048:2;30040:6;30037:14;30017:18;30014:38;30011:218;;;30085:77;30082:1;30075:88;30186:4;30183:1;30176:15;30214:4;30211:1;30204:15;30011:218;;29798:437;;;:::o;30240:195::-;30279:3;30310:66;30303:5;30300:77;30297:103;;;30380:18;;:::i;:::-;-1:-1:-1;30427:1:1;30416:13;;30240:195::o;30440:175::-;30477:3;30521:4;30514:5;30510:16;30550:4;30541:7;30538:17;30535:43;;;30558:18;;:::i;:::-;30607:1;30594:15;;30440:175;-1:-1:-1;;30440:175:1:o;30620:112::-;30652:1;30678;30668:35;;30683:18;;:::i;:::-;-1:-1:-1;30717:9:1;;30620:112::o;30737:184::-;30789:77;30786:1;30779:88;30886:4;30883:1;30876:15;30910:4;30907:1;30900:15;30926:184;30978:77;30975:1;30968:88;31075:4;31072:1;31065:15;31099:4;31096:1;31089:15;31115:184;31167:77;31164:1;31157:88;31264:4;31261:1;31254:15;31288:4;31285:1;31278:15;31304:184;31356:77;31353:1;31346:88;31453:4;31450:1;31443:15;31477:4;31474:1;31467:15;31493:184;31545:77;31542:1;31535:88;31642:4;31639:1;31632:15;31666:4;31663:1;31656:15;31682:177;31767:66;31760:5;31756:78;31749:5;31746:89;31736:117;;31849:1;31846;31839:12

Swarm Source

ipfs://17b7bf2668beda9087288055b1730da19237c9d3bbb5e70e857dd3af1a56b370
Loading