Token Artifex

NFT  
 

Overview

TokenID:
400010001

Transfers:
-

 
Loading
[ Download CSV Export  ] 
Loading
Loading

OVERVIEW

The Artifex Project honors digital artists via a collection of 1/1 original artworks and 3D sculpture edition NFTs with a roadmap for filters, metaverses and more. Custom and gold standard smart contracts. Each purchase comes with a RareRooms gallery enabled for 3D display.

# Exchange Pair Price  24H Volume % Volume
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Artifex

Compiler Version
v0.8.1+commit.df193b15

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-05-20
*/

// SPDX-License-Identifier: MIT

/**
 * @title Artifex Smart Contract
 * @author GigLabs, Brian Burns <[email protected]>
 */

pragma solidity ^0.8.0;

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

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

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{value: amount}("");
        require(
            success,
            "Address: unable to send value, recipient may have reverted"
        );
    }

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

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

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) private 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

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

/*
 * @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) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant alphabet = "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] = alphabet[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

/**
 * @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;
    mapping(address => uint8) private _otherOperators;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

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

    /**
     * @dev Returns the operator state for an address. State
     * of 1 means active operator of the contract. State of 0 means
     * not an operator of the contract.
     */
    function otherOperator(address operatorAddress)
        public
        view
        virtual
        returns (uint8)
    {
        return _otherOperators[operatorAddress];
    }

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

    /**
     * @dev Throws if called by any account other than an operator.
     */
    modifier anyOperator() {
        require(
            owner() == _msgSender() || _otherOperators[msg.sender] == 1,
            "Ownable: caller is not an operator"
        );
        _;
    }

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

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

    /**
     * @dev Sets the state of other operators for performaing certain
     * contract functions. Can only be called by the current owner.
     */
    function setOtherOperator(address _newOperator, uint8 _state)
        public
        virtual
        onlyOwner
    {
        require(_newOperator != address(0));
        _otherOperators[_newOperator] = _state;
    }
}

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

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

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
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;
}

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

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

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

/**
 * @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}. 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(to).onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert(
                        "ERC721: transfer to non ERC721Receiver implementer"
                    );
                } else {
                    // solhint-disable-next-line no-inline-assembly
                    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` 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 {}
}

/**
 * @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
    Context,
    ERC165,
    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, ERC165, 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();
    }
}

/**
 * @dev The Artifex main contract.
 *
 * Each Artifex token implements full on-chain metadata
 * in standard JSON format for anyone to retreive using the
 * getMetadata() function in this contract. A mirrored copy of the
 * metadata JSON is also stored on IPFS.
 *
 * Each NFT 2D image is stored on both IPFS and Arweave
 * Each NFT 3D model is stored on both IPFS and Arweave
 *
 * The metadata on-chain in this contract (and mirrored on IPFS)
 * return the hashes / locations of all NFT images and 3D model files
 * stored on IPFS and Arweave.
 *
 * The metadata on-chain in this contract (and mirrored on IPFS)
 * also return SHA256 hashes of the NFT images and 3D model files
 * for verifying authenticity of the NFTs.
 *
 * Metadata is retreivable using the tokenURI() call as specified
 * in the ERC721-Metadata standard. tokenURI can't point to on-chain
 * locations directly - it points to an off-chain URI for
 * returning metadata.
 */
contract Artifex is Ownable, ERC721Enumerable {
    // NOTE: `SafeMath` is no longer needed starting with Solidity 0.8.
    // The compiler now has built in overflow checking.
    //
    // using SafeMath for uint256;
    using Address for address;
    using Strings for uint256;

    // Core series metadata
    struct ArtistNFTSeriesInfo {
        uint256 totalEditions;
        string creatorName;
        string artistName;
        string artTitle;
        string description;
        string sha256ImageHash;
        string ipfsImageHash;
        string arweaveImageHash;
        string imageFileType;
    }

    // Extended series metadata
    struct ArtistNFTSeries3DModelInfo {
        string sha256ModelHash;
        string ipfs3DModelHash;
        string arweave3DModelHash;
        string modelFileType;
    }

    // Series ID => Core series metadata for NFT Type 1 (2D art piece)
    mapping(uint256 => ArtistNFTSeriesInfo) private artist2DSeriesInfo;

    // Series ID => Core series metadata for NFT Type 2 (3D art piece,
    // in 2D format)
    mapping(uint256 => ArtistNFTSeriesInfo) private artist3DSeriesInfo;

    // Series ID => Extended series metadata for NFT Type 2 (3D model
    // files for 3D art piece)
    mapping(uint256 => ArtistNFTSeries3DModelInfo)
        private artistSeries3DModelInfo;

    // Series ID => series locked state
    mapping(uint256 => bool) private artistSeriesLocked;

    // Token ID => token's IPFS Metadata hash
    mapping(uint256 => string) private tokenIdToIPFSMetadataHash;

    // Base token URI used as a prefix for all tokens to build
    // a full token URI string
    string private _baseTokenURI;

    // Base external token URI used as a prefix for all tokens
    // to build a full external token URI string
    string private _externalBaseTokenURI;

    // Multipliers for token Id calculations
    uint256 constant SERIES_MULTIPLIER = 100000000;
    uint256 constant NFT_TYPE_MULTIPLIER = 10000;

    /**
     * @notice Event emitted when the takenBaseUri is set after
     * contract deployment
     * @param tokenBaseUri the base URI for tokenURI calls
     */
    event TokenBaseUriSet(string tokenBaseUri);

    /**
     * @notice Event emitted when the externalBaseUri is set after
     * contract deployment.
     * @param externalBaseUri the new external base URI
     */
    event ExternalBaseUriSet(string externalBaseUri);

    /**
     * @notice Event emitted when a series is locked/sealed
     * @param seriesId the ID of the newly locked/sealed series
     */
    event SeriesLocked(uint256 seriesId);

    /**
     * @dev Constructor
     * @param name the token name
     * @param symbol the token symbol
     * @param base_uri the base URI for location of off-chain metadata
     * @param external_base_uri the base URI for viewing token on website
     */
    constructor(
        string memory name,
        string memory symbol,
        string memory base_uri,
        string memory external_base_uri
    ) ERC721(name, symbol) {
        _baseTokenURI = base_uri;
        _externalBaseTokenURI = external_base_uri;
    }

    /**
     * @notice Add core metadata for the 2D piece in an artist series.
     * NOTE: For Artifex, there will only be 100 artist series IDs (1-100).
     * Each series will have a 1 of 1 2D art piece (nftType 1) and a run
     * of 100 3D art pieces (nftType 2). Series ID 0 will be a gift
     * series and is not included in the 1-100 artist series IDs.
     * @param seriesId the ID of the series (0-100)
     * @param seriesInfo structure with series metadata
     */
    function addArtistSeries2dNftType(
        uint256 seriesId,
        ArtistNFTSeriesInfo calldata seriesInfo
    ) external anyOperator {
        // Series ID must be 0-100
        require(seriesId <= 100);

        // Once a series metadata is locked, it cannot be updated. The
        // information will live as permanent metadata in the contract.
        require(artistSeriesLocked[seriesId] == false, "Series is locked");

        artist2DSeriesInfo[seriesId] = seriesInfo;
    }

    /**
     * @notice Add core metadata for the 3D pieces in an artist series.
     * NOTE: For Artifex, there will only be 100 artist series IDs (1-100).
     * Each series will have a 1 of 1 2D art piece (nftType 1) and a run
     * of 100 3D art pieces (nftType 2). Series ID 0 will be a gift
     * series and is not included in the 1-100 artist series IDs.
     * @param seriesId the ID of the series (0-100)
     * @param seriesInfo structure with series metadata
     * @param series3DModelInfo structure with series 3D model metadata
     */
    function addArtistSeries3dNftType(
        uint256 seriesId,
        ArtistNFTSeriesInfo calldata seriesInfo,
        ArtistNFTSeries3DModelInfo calldata series3DModelInfo
    ) external anyOperator {
        // Series ID must be 0-100
        require(seriesId <= 100);

        // Once a series metadata is locked, it cannot be updated. The
        // information will live as permanent metadata in the contract and
        // on IFPS
        require(artistSeriesLocked[seriesId] == false, "Series is locked");

        artist3DSeriesInfo[seriesId] = seriesInfo;
        artistSeries3DModelInfo[seriesId] = series3DModelInfo;
    }

    /**
     * @dev Update the IPFS hash for a given token.
     * Series metadata must NOT be locked yet (must still be within
     * the series metadata update window)
     * Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token to set its URI
     * @param ipfsHash string IPFS link to assign
     */
    function updateTokenIPFSMetadataHash(
        uint256 tokenId,
        string calldata ipfsHash
    ) external anyOperator {
        require(
            artistSeriesLocked[getSeriesId(tokenId)] == false,
            "Series is locked"
        );
        _setTokenIPFSMetadataHash(tokenId, ipfsHash);
    }

    /**
     * @notice This function permanently locks metadata updates for all NFTs
     * in a Series. For practical reasons, a short period of time is given
     * for updates following a series mint. For example, maybe an artist
     * notices incorrect info in the description of their art after it is
     * minted. In most projects, metadata updates would be possible by changning
     * the metadata on the web server hosting the metadata. However, for
     * Artifex once metadata is locked, no updates to the metadata will be
     * possible - the information is permanent and immutable.
     *
     * The metadata will be permanent on-chain here in the contract, retrievable
     * as a JSON string via the getMetadata() call. A mirror of the metadata will
     * also live permanently on IPFS at the location stored in the
     * tokenIdToIPFSMetadataHash mapping in this contract.
     *
     * @param seriesId the ID of the series (0-100)
     */
    function lockSeries(uint256 seriesId) external anyOperator {
        // Series ID must be 0-100
        require(seriesId <= 100);

        // Series must not have been previously locked
        require(artistSeriesLocked[seriesId] == false, "Series is locked");

        // Lock the series. Once a series information is set, it can no
        // longer be updated. The information will live as permanent
        // metadata in the contract.
        artistSeriesLocked[seriesId] = true;

        // Emit the event
        emit SeriesLocked(seriesId);
    }

    /**
     * @notice Sets a new base token URI for accessing off-chain metadata
     * location. If this is changed, an event gets emitted.
     * @param newBaseTokenURI the new base token URI
     */
    function setBaseURI(string calldata newBaseTokenURI) external anyOperator {
        _baseTokenURI = newBaseTokenURI;

        // Emit the event
        emit TokenBaseUriSet(newBaseTokenURI);
    }

    /**
     * @notice Sets a new base external URI for accessing the nft on a web site.
     * If this is changed, an event gets emitted
     * @param newExternalBaseTokenURI the new base external token URI
     */
    function setExternalBaseURI(string calldata newExternalBaseTokenURI)
        external
        anyOperator
    {
        _externalBaseTokenURI = newExternalBaseTokenURI;

        // Emit the event
        emit ExternalBaseUriSet(newExternalBaseTokenURI);
    }

    /**
     * @dev Batch transfer of Artifex NFTs from one address to another
     * @param _to The address of the recipient
     * @param _tokenIds List of token IDs to transfer
     */
    function batchTransfer(address _to, uint256[] calldata _tokenIds) public {
        require(_tokenIds.length > 0);

        for (uint256 i = 0; i < _tokenIds.length; i++) {
            safeTransferFrom(msg.sender, _to, _tokenIds[i], "");
        }
    }

    /**
     * @notice Given a series ID, return the locked state
     * @param seriesId the series ID
     * @return true if series is locked, otherwise returns false
     */
    function isSeriesLocked(uint256 seriesId) external view returns (bool) {
        return artistSeriesLocked[seriesId];
    }

    /**
     * @notice return the base URI used for accessing off-chain metadata
     * @return base URI for location of the off-chain metadata
     */
    function baseURI() external view returns (string memory) {
        return _baseURI();
    }

    /**
     * @notice return the base external URI used for accessing nft on a web site.
     * @return base external URI
     */
    function externalBaseURI() external view returns (string memory) {
        return _externalBaseTokenURI;
    }

    /**
     * @notice Given a token ID, return whether or not it exists
     * @param tokenId the token ID
     * @return a bool which is true of the token exists
     */
    function exists(uint256 tokenId) external view returns (bool) {
        return _exists(tokenId);
    }

    /**
     * @notice Given a token ID, return all on-chain metadata for the
     * token as JSON string
     *
     * For each NFT, the following on-chain metadata is returned:
     *    - Name: The title of the art piece (includes creator of the art piece)
     *    - Descriptiom: Details about the art piece (includes the artist represented)
     *    - Image URI: The off-chain URI location of the image
     *    - External URI: Website to view the NFT
     *    - SHA256 Image Hash: The actual image hash stored on-chain for anyone
     *      to validate authenticity of their art piece
     *    - IPFS Image Hash: IFPS storage hash of the image
     *    - Arweave Image Hash: Arweave storage hash of the image
     *    - Image File Type: File extension of the image, since file stores such
     *      as IPFS may not return the image file type
     *
     *    IF 3D MODEL INFO AVAILABLE, THEN INCLUDE THIS IN METADATA
     *    - SHA256 3D Model Hash: The actual 3D Model hash stored
     *      on-chain for anyone to validate authenticity of their
     *       3D model asset
     *    - IPFS 3D Model Hash: IFPS storage hash of the 3D model
     *    - Arweave Image Hash: Arweave storage hash of the 3D model
     *    - 3D Model File Type: File extension of the 3D model
     *
     *    ATTRIBUTES INCLUDED:
     *    - Creator name: The creator of the art piece
     *    - Artist name: The artist represented / honored by the creator
     *    - Edition Number: The edition number of the NFT
     *    - Total Editions: Total editions that can ever exist in the series
     *
     * @param tokenId the token ID
     * @return metadata a JSON string of the metadata
     */
    function getMetadata(uint256 tokenId)
        external
        view
        returns (string memory metadata)
    {
        require(_exists(tokenId), "Token does not exist");

        uint256 seriesId = getSeriesId(tokenId);
        uint256 nftType = getNftType(tokenId);
        uint256 editionNum = getNftNum(tokenId);

        string memory creatorName;
        ArtistNFTSeriesInfo memory seriesInfo;
        ArtistNFTSeries3DModelInfo memory series3DModelInfo;
        if (nftType == 1) {
            seriesInfo = artist2DSeriesInfo[seriesId];
            creatorName = seriesInfo.artistName;
        } else if (nftType == 2) {
            seriesInfo = artist3DSeriesInfo[seriesId];
            creatorName = seriesInfo.creatorName;
            series3DModelInfo = artistSeries3DModelInfo[seriesId];
        }

        // Name
        metadata = string(
            abi.encodePacked('{\n  "name": "', seriesInfo.artistName)
        );
        metadata = string(abi.encodePacked(metadata, " Artifex #"));
        metadata = string(abi.encodePacked(metadata, editionNum.toString()));
        metadata = string(abi.encodePacked(metadata, " of "));
        metadata = string(
            abi.encodePacked(metadata, seriesInfo.totalEditions.toString())
        );
        metadata = string(abi.encodePacked(metadata, '",\n'));

        // Description: Generation
        metadata = string(abi.encodePacked(metadata, '  "description": "'));
        metadata = string(abi.encodePacked(metadata, seriesInfo.description));
        metadata = string(abi.encodePacked(metadata, '",\n'));

        // Image URI
        metadata = string(abi.encodePacked(metadata, '  "image": "'));
        metadata = string(abi.encodePacked(metadata, _baseTokenURI));
        metadata = string(abi.encodePacked(metadata, seriesInfo.ipfsImageHash));
        metadata = string(abi.encodePacked(metadata, '",\n'));

        // External URI
        metadata = string(abi.encodePacked(metadata, '  "external_url": "'));
        metadata = string(abi.encodePacked(metadata, externalURI(tokenId)));
        metadata = string(abi.encodePacked(metadata, '",\n'));

        // SHA256 Image Hash
        metadata = string(
            abi.encodePacked(metadata, '  "sha256_image_hash": "')
        );
        metadata = string(
            abi.encodePacked(metadata, seriesInfo.sha256ImageHash)
        );
        metadata = string(abi.encodePacked(metadata, '",\n'));

        // IPFS Image Hash
        metadata = string(abi.encodePacked(metadata, '  "ipfs_image_hash": "'));
        metadata = string(abi.encodePacked(metadata, seriesInfo.ipfsImageHash));
        metadata = string(abi.encodePacked(metadata, '",\n'));

        // Arweave Image Hash
        metadata = string(
            abi.encodePacked(metadata, '  "arweave_image_hash": "')
        );
        metadata = string(
            abi.encodePacked(metadata, seriesInfo.arweaveImageHash)
        );
        metadata = string(abi.encodePacked(metadata, '",\n'));

        // Image file type
        metadata = string(abi.encodePacked(metadata, '  "image_file_type": "'));
        metadata = string(abi.encodePacked(metadata, seriesInfo.imageFileType));
        metadata = string(abi.encodePacked(metadata, '",\n'));

        // Optional 3D Model metadata
        if (nftType == 2) {
            // SHA256 3D Model Hash
            metadata = string(
                abi.encodePacked(metadata, '  "sha256_3d_model_hash": "')
            );
            metadata = string(
                abi.encodePacked(metadata, series3DModelInfo.sha256ModelHash)
            );
            metadata = string(abi.encodePacked(metadata, '",\n'));

            // IPFS 3D Model Hash
            metadata = string(
                abi.encodePacked(metadata, '  "ipfs_3d_model_hash": "')
            );
            metadata = string(
                abi.encodePacked(metadata, series3DModelInfo.ipfs3DModelHash)
            );
            metadata = string(abi.encodePacked(metadata, '",\n'));

            // Arweave 3D Model Hash
            metadata = string(
                abi.encodePacked(metadata, '  "arweave_3d_model_hash": "')
            );
            metadata = string(
                abi.encodePacked(metadata, series3DModelInfo.arweave3DModelHash)
            );
            metadata = string(abi.encodePacked(metadata, '",\n'));

            // 3D model file type
            metadata = string(
                abi.encodePacked(metadata, '  "model_file_type": "')
            );
            metadata = string(
                abi.encodePacked(metadata, series3DModelInfo.modelFileType)
            );
            metadata = string(abi.encodePacked(metadata, '",\n'));
        }

        // Atributes section

        // Artist Name
        metadata = string(
            abi.encodePacked(
                metadata,
                '  "attributes": [\n     {"trait_type": "Artist", "value": "'
            )
        );
        metadata = string(abi.encodePacked(metadata, seriesInfo.artistName));
        metadata = string(abi.encodePacked(metadata, '"},\n'));

        // Creator Name
        metadata = string(
            abi.encodePacked(
                metadata,
                '     {"trait_type": "Creator", "value": "'
            )
        );
        metadata = string(abi.encodePacked(metadata, creatorName));
        metadata = string(abi.encodePacked(metadata, '"},\n'));

        // Edition Number
        metadata = string(
            abi.encodePacked(
                metadata,
                '     {"trait_type": "Edition", "value": '
            )
        );
        metadata = string(abi.encodePacked(metadata, editionNum.toString()));
        metadata = string(abi.encodePacked(metadata, ","));

        // Total Editions
        metadata = string(abi.encodePacked(metadata, ' "max_value": '));
        metadata = string(
            abi.encodePacked(metadata, seriesInfo.totalEditions.toString())
        );
        metadata = string(abi.encodePacked(metadata, ","));
        metadata = string(
            abi.encodePacked(metadata, ' "display_type": "number"}\n ]')
        );

        // Finish JSON object
        metadata = string(abi.encodePacked(metadata, "\n}"));
    }

    /**
     * @notice Mints an Artifex NFT
     * @param to address of the recipient
     * @param seriesId series to mint
     * @param nftType the type of nft - 1 for 2D piece, 2 for 3D piece
     * @param nftNum the edition number of the nft
     * @param ipfsHash the ipfsHash of a copy of the token's Metadata on ipfs
     */
    function mintArtifexNft(
        address to,
        uint256 seriesId,
        uint256 nftType,
        uint256 nftNum,
        string memory ipfsHash
    ) public anyOperator {
        // Ensure the series is not locked yet. No more minting can
        // happen once the series is locked
        require(artistSeriesLocked[seriesId] == false, "Series is locked");
        // Series 0 is a gift series. Only enforce edition limits
        // for artist Series > 0.
        if (seriesId > 0) {
            if (nftType == 1) {
                require(nftNum == 1, "Edition must be 1");
            } else if (nftType == 2) {
                require(nftNum <= 100, "Edition must be <= 100");
            }
        }
        uint256 tokenId = encodeTokenId(seriesId, nftType, nftNum);
        _safeMint(to, tokenId);
        _setTokenIPFSMetadataHash(tokenId, ipfsHash);
    }

    /**
     * @notice Mints multiple Artifex NFTs for same series and nftType
     * @param to address of the recipient
     * @param seriesId series to mint
     * @param nftType the type of nft - 1 for 2D piece, 2 for 3D piece
     * @param nftStartingNum the starting edition number of the nft
     * @param numTokens the number of tokens to mint in the edition,
     * starting from nftStartingNum edition number
     * @param ipfsHashes an array of ipfsHashes of each token's Metadata on ipfs
     */
    function batchMintArtifexNft(
        address to,
        uint256 seriesId,
        uint256 nftType,
        uint256 nftStartingNum,
        uint256 numTokens,
        string[] memory ipfsHashes
    ) public anyOperator {
        require(
            numTokens == ipfsHashes.length,
            "numTokens and num ipfsHashes must match"
        );
        for (uint256 i = 0; i < numTokens; i++) {
            mintArtifexNft(
                to,
                seriesId,
                nftType,
                nftStartingNum + i,
                ipfsHashes[i]
            );
        }
    }

    /**
     * @notice Given a token ID, return the series ID of the token
     * @param tokenId the token ID
     * @return the series ID of the token
     */
    function getSeriesId(uint256 tokenId) public pure returns (uint256) {
        return (uint256(tokenId / SERIES_MULTIPLIER));
    }

    /**
     * @notice Given a token ID, return the nft type of the token
     * @param tokenId the token ID
     * @return the nft type of the token
     */
    function getNftType(uint256 tokenId) public pure returns (uint256) {
        uint256 seriesId = getSeriesId(tokenId);
        return
            uint256(
                (tokenId - (SERIES_MULTIPLIER * seriesId)) / NFT_TYPE_MULTIPLIER
            );
    }

    /**
     * @notice Given a token ID, return the nft edition number of the token
     * @param tokenId the token ID
     * @return the nft edition number of the token
     */
    function getNftNum(uint256 tokenId) public pure returns (uint256) {
        uint256 seriesId = getSeriesId(tokenId);
        uint256 nftType = getNftType(tokenId);
        return
            uint256(
                tokenId -
                    (SERIES_MULTIPLIER * seriesId) -
                    (nftType * NFT_TYPE_MULTIPLIER)
            );
    }

    /**
     * @notice Generate a tokenId given the series ID, nft type,
     * and nft edition number
     * @param seriesId series to mint
     * @param nftType the type of nft - 1 for 2D piece, 2 for 3D piece
     * @param nftNum the edition number of the nft
     * @return the token ID
     */
    function encodeTokenId(
        uint256 seriesId,
        uint256 nftType,
        uint256 nftNum
    ) public pure returns (uint256) {
        return ((seriesId * SERIES_MULTIPLIER) +
            (nftType * NFT_TYPE_MULTIPLIER) +
            nftNum);
    }

    /**
     * @notice Given a token ID, return the name of the artist name
     * for the token
     * @param tokenId the token ID
     * @return artistName the name of the artist
     */
    function getArtistNameByTokenId(uint256 tokenId)
        public
        view
        returns (string memory artistName)
    {
        require(_exists(tokenId), "Token does not exist");
        if (getNftType(tokenId) == 1) {
            artistName = artist2DSeriesInfo[getSeriesId(tokenId)].artistName;
        } else if (getNftType(tokenId) == 2) {
            artistName = artist3DSeriesInfo[getSeriesId(tokenId)].artistName;
        }
    }

    /**
     * @notice Given a series ID and nft type, return information about the series
     * @param seriesId series to mint
     * @param nftType the type of nft - 1 for 2D piece, 2 for 3D piece
     * @return seriesInfo structure with series information
     */
    function getSeriesInfo(uint256 seriesId, uint256 nftType)
        public
        view
        returns (
            ArtistNFTSeriesInfo memory seriesInfo,
            ArtistNFTSeries3DModelInfo memory series3dModelInfo
        )
    {
        if (nftType == 1) {
            seriesInfo = artist2DSeriesInfo[seriesId];
        } else if (nftType == 2) {
            seriesInfo = artist3DSeriesInfo[seriesId];
            series3dModelInfo = artistSeries3DModelInfo[seriesId];
        }
    }

    /**
     * @notice Given a token ID, return information about the series
     * @param tokenId the token ID
     * @return seriesInfo structure with series information
     */
    function getSeriesInfoByTokenId(uint256 tokenId)
        public
        view
        returns (
            ArtistNFTSeriesInfo memory seriesInfo,
            ArtistNFTSeries3DModelInfo memory series3dModelInfo
        )
    {
        require(_exists(tokenId), "Token does not exist");
        (seriesInfo, series3dModelInfo) = getSeriesInfo(
            getSeriesId(tokenId),
            getNftType(tokenId)
        );
    }

    /**
     * @dev Returns an URI for a given token ID.
     * See {IERC721Metadata-tokenURI}.
     * @param tokenId uint256 ID of the token to query
     * @return URI for location of the off-chain metadata
     */
    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI query for nonexistent token"
        );

        return
            bytes(_baseTokenURI).length > 0
                ? string(
                    abi.encodePacked(
                        _baseTokenURI,
                        tokenIdToIPFSMetadataHash[tokenId]
                    )
                )
                : "";
    }

    /**
     * @dev Returns the actual CID hash pointing to the token's metadata on IPFS.
     * @param tokenId token ID of the token to query
     * @return the ipfs hash of the metadata
     */
    function tokenIPFSMetadataHash(uint256 tokenId)
        public
        view
        returns (string memory)
    {
        return tokenIdToIPFSMetadataHash[tokenId];
    }

    /**
     * @notice Given a token ID, return the external URI for viewing the nft on a
     * web site.
     * @param tokenId the token ID
     * @return external URI
     */
    function externalURI(uint256 tokenId) public view returns (string memory) {
        return
            string(abi.encodePacked(_externalBaseTokenURI, tokenId.toString()));
    }

    /**
     * @notice return the base URI used for accessing off-chain metadata
     * @return base URI for location of the off-chain metadata
     */
    function _baseURI() internal view virtual override returns (string memory) {
        return _baseTokenURI;
    }

    /**
     * @dev Private function to set the token IPFS hash for a given token.
     * Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token to set its URI
     * @param ipfs_hash string IPFS link to assign
     */
    function _setTokenIPFSMetadataHash(uint256 tokenId, string memory ipfs_hash)
        private
    {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI set of nonexistent token"
        );
        tokenIdToIPFSMetadataHash[tokenId] = ipfs_hash;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"base_uri","type":"string"},{"internalType":"string","name":"external_base_uri","type":"string"}],"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":"string","name":"externalBaseUri","type":"string"}],"name":"ExternalBaseUriSet","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":false,"internalType":"uint256","name":"seriesId","type":"uint256"}],"name":"SeriesLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"tokenBaseUri","type":"string"}],"name":"TokenBaseUriSet","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":"seriesId","type":"uint256"},{"components":[{"internalType":"uint256","name":"totalEditions","type":"uint256"},{"internalType":"string","name":"creatorName","type":"string"},{"internalType":"string","name":"artistName","type":"string"},{"internalType":"string","name":"artTitle","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"sha256ImageHash","type":"string"},{"internalType":"string","name":"ipfsImageHash","type":"string"},{"internalType":"string","name":"arweaveImageHash","type":"string"},{"internalType":"string","name":"imageFileType","type":"string"}],"internalType":"struct Artifex.ArtistNFTSeriesInfo","name":"seriesInfo","type":"tuple"}],"name":"addArtistSeries2dNftType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"seriesId","type":"uint256"},{"components":[{"internalType":"uint256","name":"totalEditions","type":"uint256"},{"internalType":"string","name":"creatorName","type":"string"},{"internalType":"string","name":"artistName","type":"string"},{"internalType":"string","name":"artTitle","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"sha256ImageHash","type":"string"},{"internalType":"string","name":"ipfsImageHash","type":"string"},{"internalType":"string","name":"arweaveImageHash","type":"string"},{"internalType":"string","name":"imageFileType","type":"string"}],"internalType":"struct Artifex.ArtistNFTSeriesInfo","name":"seriesInfo","type":"tuple"},{"components":[{"internalType":"string","name":"sha256ModelHash","type":"string"},{"internalType":"string","name":"ipfs3DModelHash","type":"string"},{"internalType":"string","name":"arweave3DModelHash","type":"string"},{"internalType":"string","name":"modelFileType","type":"string"}],"internalType":"struct Artifex.ArtistNFTSeries3DModelInfo","name":"series3DModelInfo","type":"tuple"}],"name":"addArtistSeries3dNftType","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":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"seriesId","type":"uint256"},{"internalType":"uint256","name":"nftType","type":"uint256"},{"internalType":"uint256","name":"nftStartingNum","type":"uint256"},{"internalType":"uint256","name":"numTokens","type":"uint256"},{"internalType":"string[]","name":"ipfsHashes","type":"string[]"}],"name":"batchMintArtifexNft","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"batchTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"seriesId","type":"uint256"},{"internalType":"uint256","name":"nftType","type":"uint256"},{"internalType":"uint256","name":"nftNum","type":"uint256"}],"name":"encodeTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"externalBaseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"externalURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","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":"getArtistNameByTokenId","outputs":[{"internalType":"string","name":"artistName","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getMetadata","outputs":[{"internalType":"string","name":"metadata","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getNftNum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getNftType","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getSeriesId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"seriesId","type":"uint256"},{"internalType":"uint256","name":"nftType","type":"uint256"}],"name":"getSeriesInfo","outputs":[{"components":[{"internalType":"uint256","name":"totalEditions","type":"uint256"},{"internalType":"string","name":"creatorName","type":"string"},{"internalType":"string","name":"artistName","type":"string"},{"internalType":"string","name":"artTitle","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"sha256ImageHash","type":"string"},{"internalType":"string","name":"ipfsImageHash","type":"string"},{"internalType":"string","name":"arweaveImageHash","type":"string"},{"internalType":"string","name":"imageFileType","type":"string"}],"internalType":"struct Artifex.ArtistNFTSeriesInfo","name":"seriesInfo","type":"tuple"},{"components":[{"internalType":"string","name":"sha256ModelHash","type":"string"},{"internalType":"string","name":"ipfs3DModelHash","type":"string"},{"internalType":"string","name":"arweave3DModelHash","type":"string"},{"internalType":"string","name":"modelFileType","type":"string"}],"internalType":"struct Artifex.ArtistNFTSeries3DModelInfo","name":"series3dModelInfo","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getSeriesInfoByTokenId","outputs":[{"components":[{"internalType":"uint256","name":"totalEditions","type":"uint256"},{"internalType":"string","name":"creatorName","type":"string"},{"internalType":"string","name":"artistName","type":"string"},{"internalType":"string","name":"artTitle","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"sha256ImageHash","type":"string"},{"internalType":"string","name":"ipfsImageHash","type":"string"},{"internalType":"string","name":"arweaveImageHash","type":"string"},{"internalType":"string","name":"imageFileType","type":"string"}],"internalType":"struct Artifex.ArtistNFTSeriesInfo","name":"seriesInfo","type":"tuple"},{"components":[{"internalType":"string","name":"sha256ModelHash","type":"string"},{"internalType":"string","name":"ipfs3DModelHash","type":"string"},{"internalType":"string","name":"arweave3DModelHash","type":"string"},{"internalType":"string","name":"modelFileType","type":"string"}],"internalType":"struct Artifex.ArtistNFTSeries3DModelInfo","name":"series3dModelInfo","type":"tuple"}],"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":"uint256","name":"seriesId","type":"uint256"}],"name":"isSeriesLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"seriesId","type":"uint256"}],"name":"lockSeries","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"seriesId","type":"uint256"},{"internalType":"uint256","name":"nftType","type":"uint256"},{"internalType":"uint256","name":"nftNum","type":"uint256"},{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"mintArtifexNft","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operatorAddress","type":"address"}],"name":"otherOperator","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"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":[],"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":"string","name":"newBaseTokenURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newExternalBaseTokenURI","type":"string"}],"name":"setExternalBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOperator","type":"address"},{"internalType":"uint8","name":"_state","type":"uint8"}],"name":"setOtherOperator","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":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenIPFSMetadataHash","outputs":[{"internalType":"string","name":"","type":"string"}],"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":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"updateTokenIPFSMetadataHash","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b5060405162005f7838038062005f7883398101604081905262000034916200024d565b8383600062000042620000f0565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508151620000a1906002906020850190620000f4565b508051620000b7906003906020840190620000f4565b50508251620000cf91506011906020850190620000f4565b508051620000e5906012906020840190620000f4565b505050505062000354565b3390565b828054620001029062000301565b90600052602060002090601f01602090048101928262000126576000855562000171565b82601f106200014157805160ff191683800117855562000171565b8280016001018555821562000171579182015b828111156200017157825182559160200191906001019062000154565b506200017f92915062000183565b5090565b5b808211156200017f576000815560010162000184565b600082601f830112620001ab578081fd5b81516001600160401b0380821115620001c857620001c86200033e565b604051601f8301601f19908116603f01168101908282118183101715620001f357620001f36200033e565b816040528381526020925086838588010111156200020f578485fd5b8491505b8382101562000232578582018301518183018401529082019062000213565b838211156200024357848385830101525b9695505050505050565b6000806000806080858703121562000263578384fd5b84516001600160401b03808211156200027a578586fd5b62000288888389016200019a565b955060208701519150808211156200029e578485fd5b620002ac888389016200019a565b94506040870151915080821115620002c2578384fd5b620002d0888389016200019a565b93506060870151915080821115620002e6578283fd5b50620002f5878288016200019a565b91505092959194509250565b6002810460018216806200031657607f821691505b602082108114156200033857634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b615c1480620003646000396000f3fe608060405234801561001057600080fd5b50600436106102745760003560e01c80636c0360eb11610151578063a574cea4116100c3578063c87b56dd11610087578063c87b56dd14610558578063d8bbe8cf1461056b578063e985e9c51461057e578063f2fde38b14610591578063f8654e82146105a4578063f9cc0f64146105b757610274565b8063a574cea414610504578063a82620d514610517578063ac3c99521461052a578063ae8d070b1461053d578063b88d4fde1461054557610274565b80638302d9fc116101155780638302d9fc146104a85780638da5cb5b146104bb578063959c45b7146104c357806395d89b41146104d65780639a96b657146104de578063a22cb465146104f157610274565b80636c0360eb1461045f57806370a0823114610467578063715018a61461047a57806374ca428314610482578063773283f61461049557610274565b80632f745c59116101ea5780634f6ccce7116101ae5780634f6ccce7146103ed57806353ffdbc51461040057806355f804b314610413578063580007e9146104265780635feaab23146104395780636352211e1461044c57610274565b80632f745c591461037357806330c3ed0b146103865780633e0d232b146103a657806342842e0e146103c75780634f558e79146103da57610274565b80630e8624d91161023c5780630e8624d9146102ff57806318160ddd146103125780631cb819851461032757806323b872dd1461033a57806324846c981461034d5780632d5fdb6a1461036057610274565b806301ffc9a71461027957806305b97ba2146102a257806306fdde03146102b7578063081812fc146102cc578063095ea7b3146102ec575b600080fd5b61028c6102873660046145dc565b6105ca565b6040516102999190614ebd565b60405180910390f35b6102b56102b036600461446f565b6105f7565b005b6102bf610715565b6040516102999190614ef7565b6102df6102da366004614653565b6107a7565b6040516102999190614e6c565b6102b56102fa366004614446565b6107ea565b6102bf61030d366004614653565b610882565b61031a610a27565b604051610299919061569d565b6102b56103353660046146b4565b610a2d565b6102b56103483660046142da565b610ae7565b6102b561035b3660046144d7565b610b1f565b6102b561036e366004614653565b610bff565b61031a610381366004614446565b610ced565b61039961039436600461428e565b610d3f565b60405161029991906156a6565b6103b96103b4366004614767565b610d5d565b60405161029992919061558f565b6102b56103d53660046142da565b61196a565b61028c6103e8366004614653565b611985565b61031a6103fb366004614653565b611990565b6102b561040e3660046146f8565b6119eb565b6102b5610421366004614614565b611ac2565b6102bf610434366004614653565b611b69565b61031a610447366004614653565b611b86565b6102df61045a366004614653565b611b96565b6102bf611bcb565b61031a61047536600461428e565b611bda565b6102b5611c1e565b6102bf610490366004614653565b611ca7565b61031a6104a3366004614653565b611cdb565b6103b96104b6366004614653565b611d2c565b6102df611d80565b61031a6104d1366004614788565b611d8f565b6102bf611dc0565b6102b56104ec36600461466b565b611dcf565b6102b56104ff36600461440c565b611eaa565b6102bf610512366004614653565b611f78565b61031a610525366004614653565b6133a0565b6102b561053836600461438d565b6133da565b6102bf613442565b6102b5610553366004614315565b613451565b6102bf610566366004614653565b61348a565b6102b56105793660046145ac565b613502565b61028c61058c3660046142a8565b613581565b6102b561059f36600461428e565b6135af565b6102b56105b2366004614614565b61366f565b61028c6105c5366004614653565b61370a565b60006001600160e01b0319821663780e9d6360e01b14806105ef57506105ef8261371f565b90505b919050565b6105ff61375f565b6001600160a01b0316610610611d80565b6001600160a01b0316148061063857503360009081526001602081905260409091205460ff16145b61065d5760405162461bcd60e51b815260040161065490615054565b60405180910390fd5b6000848152600f602052604090205460ff161561068c5760405162461bcd60e51b815260040161065490615565565b83156106ea5782600114156106c057816001146106bb5760405162461bcd60e51b81526004016106549061518b565b6106ea565b82600214156106ea5760648211156106ea5760405162461bcd60e51b815260040161065490615024565b60006106f7858585611d8f565b90506107038682613763565b61070d8183613781565b505050505050565b606060028054610724906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054610750906158ce565b801561079d5780601f106107725761010080835404028352916020019161079d565b820191906000526020600020905b81548152906001019060200180831161078057829003601f168201915b5050505050905090565b60006107b2826137c5565b6107ce5760405162461bcd60e51b8152600401610654906152db565b506000908152600660205260409020546001600160a01b031690565b60006107f582611b96565b9050806001600160a01b0316836001600160a01b031614156108295760405162461bcd60e51b815260040161065490615440565b806001600160a01b031661083b61375f565b6001600160a01b0316148061085757506108578161058c61375f565b6108735760405162461bcd60e51b8152600401610654906151b6565b61087d83836137e2565b505050565b606061088d826137c5565b6108a95760405162461bcd60e51b815260040161065490615111565b6108b2826133a0565b6001141561096857600c60006108c784611b86565b815260200190815260200160002060020180546108e3906158ce565b80601f016020809104026020016040519081016040528092919081815260200182805461090f906158ce565b801561095c5780601f106109315761010080835404028352916020019161095c565b820191906000526020600020905b81548152906001019060200180831161093f57829003601f168201915b505050505090506105f2565b610971826133a0565b600214156105f257600d600061098684611b86565b815260200190815260200160002060020180546109a2906158ce565b80601f01602080910402602001604051908101604052809291908181526020018280546109ce906158ce565b8015610a1b5780601f106109f057610100808354040283529160200191610a1b565b820191906000526020600020905b8154815290600101906020018083116109fe57829003601f168201915b50505050509050919050565b600a5490565b610a3561375f565b6001600160a01b0316610a46611d80565b6001600160a01b03161480610a6e57503360009081526001602081905260409091205460ff16145b610a8a5760405162461bcd60e51b815260040161065490615054565b6064821115610a9857600080fd5b6000828152600f602052604090205460ff1615610ac75760405162461bcd60e51b815260040161065490615565565b6000828152600c602052604090208190610ae18282615ada565b50505050565b610af8610af261375f565b82613850565b610b145760405162461bcd60e51b8152600401610654906154c8565b61087d8383836138cd565b610b2761375f565b6001600160a01b0316610b38611d80565b6001600160a01b03161480610b6057503360009081526001602081905260409091205460ff16145b610b7c5760405162461bcd60e51b815260040161065490615054565b80518214610b9c5760405162461bcd60e51b815260040161065490615481565b60005b82811015610bf657610be4878787610bb78589615734565b868681518110610bd757634e487b7160e01b600052603260045260246000fd5b60200260200101516105f7565b80610bee81615916565b915050610b9f565b50505050505050565b610c0761375f565b6001600160a01b0316610c18611d80565b6001600160a01b03161480610c4057503360009081526001602081905260409091205460ff16145b610c5c5760405162461bcd60e51b815260040161065490615054565b6064811115610c6a57600080fd5b6000818152600f602052604090205460ff1615610c995760405162461bcd60e51b815260040161065490615565565b6000818152600f602052604090819020805460ff19166001179055517f3b0b42be2fe8253dbff241e0b82900c74e5f809231f16925cd5f7aac5a9a2c6a90610ce290839061569d565b60405180910390a150565b6000610cf883611bda565b8210610d165760405162461bcd60e51b815260040161065490614f0a565b506001600160a01b03919091166000908152600860209081526040808320938352929052205490565b6001600160a01b031660009081526001602052604090205460ff1690565b610d65614029565b610d6d614075565b826001141561123657600c60008581526020019081526020016000206040518061012001604052908160008201548152602001600182018054610daf906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054610ddb906158ce565b8015610e285780601f10610dfd57610100808354040283529160200191610e28565b820191906000526020600020905b815481529060010190602001808311610e0b57829003601f168201915b50505050508152602001600282018054610e41906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054610e6d906158ce565b8015610eba5780601f10610e8f57610100808354040283529160200191610eba565b820191906000526020600020905b815481529060010190602001808311610e9d57829003601f168201915b50505050508152602001600382018054610ed3906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054610eff906158ce565b8015610f4c5780601f10610f2157610100808354040283529160200191610f4c565b820191906000526020600020905b815481529060010190602001808311610f2f57829003601f168201915b50505050508152602001600482018054610f65906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054610f91906158ce565b8015610fde5780601f10610fb357610100808354040283529160200191610fde565b820191906000526020600020905b815481529060010190602001808311610fc157829003601f168201915b50505050508152602001600582018054610ff7906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054611023906158ce565b80156110705780601f1061104557610100808354040283529160200191611070565b820191906000526020600020905b81548152906001019060200180831161105357829003601f168201915b50505050508152602001600682018054611089906158ce565b80601f01602080910402602001604051908101604052809291908181526020018280546110b5906158ce565b80156111025780601f106110d757610100808354040283529160200191611102565b820191906000526020600020905b8154815290600101906020018083116110e557829003601f168201915b5050505050815260200160078201805461111b906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054611147906158ce565b80156111945780601f1061116957610100808354040283529160200191611194565b820191906000526020600020905b81548152906001019060200180831161117757829003601f168201915b505050505081526020016008820180546111ad906158ce565b80601f01602080910402602001604051908101604052809291908181526020018280546111d9906158ce565b80156112265780601f106111fb57610100808354040283529160200191611226565b820191906000526020600020905b81548152906001019060200180831161120957829003601f168201915b5050505050815250509150611963565b826002141561196357600d60008581526020019081526020016000206040518061012001604052908160008201548152602001600182018054611278906158ce565b80601f01602080910402602001604051908101604052809291908181526020018280546112a4906158ce565b80156112f15780601f106112c6576101008083540402835291602001916112f1565b820191906000526020600020905b8154815290600101906020018083116112d457829003601f168201915b5050505050815260200160028201805461130a906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054611336906158ce565b80156113835780601f1061135857610100808354040283529160200191611383565b820191906000526020600020905b81548152906001019060200180831161136657829003601f168201915b5050505050815260200160038201805461139c906158ce565b80601f01602080910402602001604051908101604052809291908181526020018280546113c8906158ce565b80156114155780601f106113ea57610100808354040283529160200191611415565b820191906000526020600020905b8154815290600101906020018083116113f857829003601f168201915b5050505050815260200160048201805461142e906158ce565b80601f016020809104026020016040519081016040528092919081815260200182805461145a906158ce565b80156114a75780601f1061147c576101008083540402835291602001916114a7565b820191906000526020600020905b81548152906001019060200180831161148a57829003601f168201915b505050505081526020016005820180546114c0906158ce565b80601f01602080910402602001604051908101604052809291908181526020018280546114ec906158ce565b80156115395780601f1061150e57610100808354040283529160200191611539565b820191906000526020600020905b81548152906001019060200180831161151c57829003601f168201915b50505050508152602001600682018054611552906158ce565b80601f016020809104026020016040519081016040528092919081815260200182805461157e906158ce565b80156115cb5780601f106115a0576101008083540402835291602001916115cb565b820191906000526020600020905b8154815290600101906020018083116115ae57829003601f168201915b505050505081526020016007820180546115e4906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054611610906158ce565b801561165d5780601f106116325761010080835404028352916020019161165d565b820191906000526020600020905b81548152906001019060200180831161164057829003601f168201915b50505050508152602001600882018054611676906158ce565b80601f01602080910402602001604051908101604052809291908181526020018280546116a2906158ce565b80156116ef5780601f106116c4576101008083540402835291602001916116ef565b820191906000526020600020905b8154815290600101906020018083116116d257829003601f168201915b5050505050815250509150600e6000858152602001908152602001600020604051806080016040529081600082018054611728906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054611754906158ce565b80156117a15780601f10611776576101008083540402835291602001916117a1565b820191906000526020600020905b81548152906001019060200180831161178457829003601f168201915b505050505081526020016001820180546117ba906158ce565b80601f01602080910402602001604051908101604052809291908181526020018280546117e6906158ce565b80156118335780601f1061180857610100808354040283529160200191611833565b820191906000526020600020905b81548152906001019060200180831161181657829003601f168201915b5050505050815260200160028201805461184c906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054611878906158ce565b80156118c55780601f1061189a576101008083540402835291602001916118c5565b820191906000526020600020905b8154815290600101906020018083116118a857829003601f168201915b505050505081526020016003820180546118de906158ce565b80601f016020809104026020016040519081016040528092919081815260200182805461190a906158ce565b80156119575780601f1061192c57610100808354040283529160200191611957565b820191906000526020600020905b81548152906001019060200180831161193a57829003601f168201915b50505050508152505090505b9250929050565b61087d83838360405180602001604052806000815250613451565b60006105ef826137c5565b600061199a610a27565b82106119b85760405162461bcd60e51b815260040161065490615519565b600a82815481106119d957634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050919050565b6119f361375f565b6001600160a01b0316611a04611d80565b6001600160a01b03161480611a2c57503360009081526001602081905260409091205460ff16145b611a485760405162461bcd60e51b815260040161065490615054565b6064831115611a5657600080fd5b6000838152600f602052604090205460ff1615611a855760405162461bcd60e51b815260040161065490615565565b6000838152600d602052604090208290611a9f8282615ada565b50506000838152600e602052604090208190611abb8282615987565b5050505050565b611aca61375f565b6001600160a01b0316611adb611d80565b6001600160a01b03161480611b0357503360009081526001602081905260409091205460ff16145b611b1f5760405162461bcd60e51b815260040161065490615054565b611b2b6011838361409d565b507f8a4347b4934a2ce5ecaba977228c1a0bf7c66eadd142acc540931f4005836ea18282604051611b5d929190614ec8565b60405180910390a15050565b60008181526010602052604090208054606091906109a2906158ce565b60006105ef6305f5e1008361574c565b6000818152600460205260408120546001600160a01b0316806105ef5760405162461bcd60e51b81526004016106549061525d565b6060611bd56139fa565b905090565b60006001600160a01b038216611c025760405162461bcd60e51b815260040161065490615213565b506001600160a01b031660009081526005602052604090205490565b611c2661375f565b6001600160a01b0316611c37611d80565b6001600160a01b031614611c5d5760405162461bcd60e51b815260040161065490615373565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60606012611cb483613a09565b604051602001611cc5929190614e05565b6040516020818303038152906040529050919050565b600080611ce783611b86565b90506000611cf4846133a0565b9050611d0261271082615760565b611d10836305f5e100615760565b611d1a908661577f565b611d24919061577f565b949350505050565b611d34614029565b611d3c614075565b611d45836137c5565b611d615760405162461bcd60e51b815260040161065490615111565b611d76611d6d84611b86565b6103b4856133a0565b9094909350915050565b6000546001600160a01b031690565b600081611d9e61271085615760565b611dac6305f5e10087615760565b611db69190615734565b611d249190615734565b606060038054610724906158ce565b611dd761375f565b6001600160a01b0316611de8611d80565b6001600160a01b03161480611e1057503360009081526001602081905260409091205460ff16145b611e2c5760405162461bcd60e51b815260040161065490615054565b600f6000611e3985611b86565b815260208101919091526040016000205460ff1615611e6a5760405162461bcd60e51b815260040161065490615565565b61087d8383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061378192505050565b611eb261375f565b6001600160a01b0316826001600160a01b03161415611ee35760405162461bcd60e51b8152600401610654906150da565b8060076000611ef061375f565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611f3461375f565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611f6c9190614ebd565b60405180910390a35050565b6060611f83826137c5565b611f9f5760405162461bcd60e51b815260040161065490615111565b6000611faa83611b86565b90506000611fb7846133a0565b90506000611fc485611cdb565b90506060611fd0614029565b611fd8614075565b84600114156124a857600c6000878152602001908152602001600020604051806101200160405290816000820154815260200160018201805461201a906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054612046906158ce565b80156120935780601f1061206857610100808354040283529160200191612093565b820191906000526020600020905b81548152906001019060200180831161207657829003601f168201915b505050505081526020016002820180546120ac906158ce565b80601f01602080910402602001604051908101604052809291908181526020018280546120d8906158ce565b80156121255780601f106120fa57610100808354040283529160200191612125565b820191906000526020600020905b81548152906001019060200180831161210857829003601f168201915b5050505050815260200160038201805461213e906158ce565b80601f016020809104026020016040519081016040528092919081815260200182805461216a906158ce565b80156121b75780601f1061218c576101008083540402835291602001916121b7565b820191906000526020600020905b81548152906001019060200180831161219a57829003601f168201915b505050505081526020016004820180546121d0906158ce565b80601f01602080910402602001604051908101604052809291908181526020018280546121fc906158ce565b80156122495780601f1061221e57610100808354040283529160200191612249565b820191906000526020600020905b81548152906001019060200180831161222c57829003601f168201915b50505050508152602001600582018054612262906158ce565b80601f016020809104026020016040519081016040528092919081815260200182805461228e906158ce565b80156122db5780601f106122b0576101008083540402835291602001916122db565b820191906000526020600020905b8154815290600101906020018083116122be57829003601f168201915b505050505081526020016006820180546122f4906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054612320906158ce565b801561236d5780601f106123425761010080835404028352916020019161236d565b820191906000526020600020905b81548152906001019060200180831161235057829003601f168201915b50505050508152602001600782018054612386906158ce565b80601f01602080910402602001604051908101604052809291908181526020018280546123b2906158ce565b80156123ff5780601f106123d4576101008083540402835291602001916123ff565b820191906000526020600020905b8154815290600101906020018083116123e257829003601f168201915b50505050508152602001600882018054612418906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054612444906158ce565b80156124915780601f1061246657610100808354040283529160200191612491565b820191906000526020600020905b81548152906001019060200180831161247457829003601f168201915b505050505081525050915081604001519250612bdc565b8460021415612bdc57600d600087815260200190815260200160002060405180610120016040529081600082015481526020016001820180546124ea906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054612516906158ce565b80156125635780601f1061253857610100808354040283529160200191612563565b820191906000526020600020905b81548152906001019060200180831161254657829003601f168201915b5050505050815260200160028201805461257c906158ce565b80601f01602080910402602001604051908101604052809291908181526020018280546125a8906158ce565b80156125f55780601f106125ca576101008083540402835291602001916125f5565b820191906000526020600020905b8154815290600101906020018083116125d857829003601f168201915b5050505050815260200160038201805461260e906158ce565b80601f016020809104026020016040519081016040528092919081815260200182805461263a906158ce565b80156126875780601f1061265c57610100808354040283529160200191612687565b820191906000526020600020905b81548152906001019060200180831161266a57829003601f168201915b505050505081526020016004820180546126a0906158ce565b80601f01602080910402602001604051908101604052809291908181526020018280546126cc906158ce565b80156127195780601f106126ee57610100808354040283529160200191612719565b820191906000526020600020905b8154815290600101906020018083116126fc57829003601f168201915b50505050508152602001600582018054612732906158ce565b80601f016020809104026020016040519081016040528092919081815260200182805461275e906158ce565b80156127ab5780601f10612780576101008083540402835291602001916127ab565b820191906000526020600020905b81548152906001019060200180831161278e57829003601f168201915b505050505081526020016006820180546127c4906158ce565b80601f01602080910402602001604051908101604052809291908181526020018280546127f0906158ce565b801561283d5780601f106128125761010080835404028352916020019161283d565b820191906000526020600020905b81548152906001019060200180831161282057829003601f168201915b50505050508152602001600782018054612856906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054612882906158ce565b80156128cf5780601f106128a4576101008083540402835291602001916128cf565b820191906000526020600020905b8154815290600101906020018083116128b257829003601f168201915b505050505081526020016008820180546128e8906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054612914906158ce565b80156129615780601f1061293657610100808354040283529160200191612961565b820191906000526020600020905b81548152906001019060200180831161294457829003601f168201915b505050505081525050915081602001519250600e60008781526020019081526020016000206040518060800160405290816000820180546129a1906158ce565b80601f01602080910402602001604051908101604052809291908181526020018280546129cd906158ce565b8015612a1a5780601f106129ef57610100808354040283529160200191612a1a565b820191906000526020600020905b8154815290600101906020018083116129fd57829003601f168201915b50505050508152602001600182018054612a33906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054612a5f906158ce565b8015612aac5780601f10612a8157610100808354040283529160200191612aac565b820191906000526020600020905b815481529060010190602001808311612a8f57829003601f168201915b50505050508152602001600282018054612ac5906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054612af1906158ce565b8015612b3e5780601f10612b1357610100808354040283529160200191612b3e565b820191906000526020600020905b815481529060010190602001808311612b2157829003601f168201915b50505050508152602001600382018054612b57906158ce565b80601f0160208091040260200160405190810160405280929190818152602001828054612b83906158ce565b8015612bd05780601f10612ba557610100808354040283529160200191612bd0565b820191906000526020600020905b815481529060010190602001808311612bb357829003601f168201915b50505050508152505090505b8160400151604051602001612bf19190614e36565b604051602081830303815290604052965086604051602001612c139190614cd8565b604051602081830303815290604052965086612c2e85613a09565b604051602001612c3f9291906148b9565b604051602081830303815290604052965086604051602001612c619190614be7565b604051602081830303815290604052965086612c808360000151613a09565b604051602001612c919291906148b9565b604051602081830303815290604052965086604051602001612cb391906149db565b604051602081830303815290604052965086604051602001612cd59190614d6f565b6040516020818303038152906040529650868260800151604051602001612cfd9291906148b9565b604051602081830303815290604052965086604051602001612d1f91906149db565b604051602081830303815290604052965086604051602001612d419190614c76565b6040516020818303038152906040529650866011604051602001612d669291906148e8565b6040516020818303038152906040529650868260c00151604051602001612d8e9291906148b9565b604051602081830303815290604052965086604051602001612db091906149db565b604051602081830303815290604052965086604051602001612dd29190614a7d565b604051602081830303815290604052965086612ded89611ca7565b604051602001612dfe9291906148b9565b604051602081830303815290604052965086604051602001612e2091906149db565b604051602081830303815290604052965086604051602001612e429190614a02565b6040516020818303038152906040529650868260a00151604051602001612e6a9291906148b9565b604051602081830303815290604052965086604051602001612e8c91906149db565b604051602081830303815290604052965086604051602001612eae9190614da5565b6040516020818303038152906040529650868260c00151604051602001612ed69291906148b9565b604051602081830303815290604052965086604051602001612ef891906149db565b604051602081830303815290604052965086604051602001612f1a9190614ab4565b6040516020818303038152906040529650868260e00151604051602001612f429291906148b9565b604051602081830303815290604052965086604051602001612f6491906149db565b604051602081830303815290604052965086604051602001612f869190614a43565b604051602081830303815290604052965086826101000151604051602001612faf9291906148b9565b604051602081830303815290604052965086604051602001612fd191906149db565b604051602081830303815290604052965084600214156131995786604051602001612ffc919061499a565b60408051601f19818403018152908290528251909850613021918991906020016148b9565b60405160208183030381529060405296508660405160200161304391906149db565b6040516020818303038152906040529650866040516020016130659190614b6c565b604051602081830303815290604052965086816020015160405160200161308d9291906148b9565b6040516020818303038152906040529650866040516020016130af91906149db565b6040516020818303038152906040529650866040516020016130d19190614d2e565b60405160208183030381529060405296508681604001516040516020016130f99291906148b9565b60405160208183030381529060405296508660405160200161311b91906149db565b60405160208183030381529060405296508660405160200161313d9190614bad565b60405160208183030381529060405296508681606001516040516020016131659291906148b9565b60405160208183030381529060405296508660405160200161318791906149db565b60405160208183030381529060405296505b866040516020016131aa9190614c0f565b60405160208183030381529060405296508682604001516040516020016131d29291906148b9565b6040516020818303038152906040529650866040516020016131f49190614d06565b6040516020818303038152906040529650866040516020016132169190614947565b6040516020818303038152906040529650868360405160200161323a9291906148b9565b60405160208183030381529060405296508660405160200161325c9190614d06565b60405160208183030381529060405296508660405160200161327e9190614b1a565b60405160208183030381529060405296508661329985613a09565b6040516020016132aa9291906148b9565b6040516020818303038152906040529650866040516020016132cc9190614af5565b6040516020818303038152906040529650866040516020016132ee9190614ca6565b60405160208183030381529060405296508661330d8360000151613a09565b60405160200161331e9291906148b9565b6040516020818303038152906040529650866040516020016133409190614af5565b6040516020818303038152906040529650866040516020016133629190614906565b6040516020818303038152906040529650866040516020016133849190614ddf565b6040516020818303038152906040529650505050505050919050565b6000806133ac83611b86565b90506127106133bf826305f5e100615760565b6133c9908561577f565b6133d3919061574c565b9392505050565b806133e457600080fd5b60005b81811015610ae157613430338585858581811061341457634e487b7160e01b600052603260045260246000fd5b9050602002013560405180602001604052806000815250613451565b8061343a81615916565b9150506133e7565b606060128054610724906158ce565b61346261345c61375f565b83613850565b61347e5760405162461bcd60e51b8152600401610654906154c8565b610ae184848484613b23565b6060613495826137c5565b6134b15760405162461bcd60e51b8152600401610654906153f1565b6000601180546134c0906158ce565b9050116134dc57604051806020016040528060008152506105ef565b601160106000848152602001908152602001600020604051602001611cc5929190614e21565b61350a61375f565b6001600160a01b031661351b611d80565b6001600160a01b0316146135415760405162461bcd60e51b815260040161065490615373565b6001600160a01b03821661355457600080fd5b6001600160a01b03919091166000908152600160205260409020805460ff191660ff909216919091179055565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b6135b761375f565b6001600160a01b03166135c8611d80565b6001600160a01b0316146135ee5760405162461bcd60e51b815260040161065490615373565b6001600160a01b0381166136145760405162461bcd60e51b815260040161065490614fa7565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b61367761375f565b6001600160a01b0316613688611d80565b6001600160a01b031614806136b057503360009081526001602081905260409091205460ff16145b6136cc5760405162461bcd60e51b815260040161065490615054565b6136d86012838361409d565b507ff88454fecb0463161fc15dd20918379d883f8e548d08b9a96319fea3b6dc6dde8282604051611b5d929190614ec8565b6000908152600f602052604090205460ff1690565b60006001600160e01b031982166380ac58cd60e01b148061375057506001600160e01b03198216635b5e139f60e01b145b806105ef57506105ef82613b56565b3390565b61377d828260405180602001604052806000815250613b6f565b5050565b61378a826137c5565b6137a65760405162461bcd60e51b815260040161065490615327565b6000828152601060209081526040909120825161087d92840190614121565b6000908152600460205260409020546001600160a01b0316151590565b600081815260066020526040902080546001600160a01b0319166001600160a01b038416908117909155819061381782611b96565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061385b826137c5565b6138775760405162461bcd60e51b81526004016106549061513f565b600061388283611b96565b9050806001600160a01b0316846001600160a01b031614806138bd5750836001600160a01b03166138b2846107a7565b6001600160a01b0316145b80611d245750611d248185613581565b826001600160a01b03166138e082611b96565b6001600160a01b0316146139065760405162461bcd60e51b8152600401610654906153a8565b6001600160a01b03821661392c5760405162461bcd60e51b815260040161065490615096565b613937838383613ba2565b6139426000826137e2565b6001600160a01b038316600090815260056020526040812080546001929061396b90849061577f565b90915550506001600160a01b0382166000908152600560205260408120805460019290613999908490615734565b909155505060008181526004602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b606060118054610724906158ce565b606081613a2e57506040805180820190915260018152600360fc1b60208201526105f2565b8160005b8115613a585780613a4281615916565b9150613a519050600a8361574c565b9150613a32565b6000816001600160401b03811115613a8057634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015613aaa576020820181803683370190505b5090505b8415611d2457613abf60018361577f565b9150613acc600a86615931565b613ad7906030615734565b60f81b818381518110613afa57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350613b1c600a8661574c565b9450613aae565b613b2e8484846138cd565b613b3a84848484613c2b565b610ae15760405162461bcd60e51b815260040161065490614f55565b6001600160e01b031981166301ffc9a760e01b14919050565b613b798383613d46565b613b866000848484613c2b565b61087d5760405162461bcd60e51b815260040161065490614f55565b613bad83838361087d565b6001600160a01b038316613bc957613bc481613e25565b613bec565b816001600160a01b0316836001600160a01b031614613bec57613bec8382613e69565b6001600160a01b038216613c0857613c0381613f06565b61087d565b826001600160a01b0316826001600160a01b03161461087d5761087d8282613fdf565b6000613c3f846001600160a01b0316614023565b15613d3b57836001600160a01b031663150b7a02613c5b61375f565b8786866040518563ffffffff1660e01b8152600401613c7d9493929190614e80565b602060405180830381600087803b158015613c9757600080fd5b505af1925050508015613cc7575060408051601f3d908101601f19168201909252613cc4918101906145f8565b60015b613d21573d808015613cf5576040519150601f19603f3d011682016040523d82523d6000602084013e613cfa565b606091505b508051613d195760405162461bcd60e51b815260040161065490614f55565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611d24565b506001949350505050565b6001600160a01b038216613d6c5760405162461bcd60e51b8152600401610654906152a6565b613d75816137c5565b15613d925760405162461bcd60e51b815260040161065490614fed565b613d9e60008383613ba2565b6001600160a01b0382166000908152600560205260408120805460019290613dc7908490615734565b909155505060008181526004602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600a80546000838152600b60205260408120829055600182018355919091527fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a80155565b60006001613e7684611bda565b613e80919061577f565b600083815260096020526040902054909150808214613ed3576001600160a01b03841660009081526008602090815260408083208584528252808320548484528184208190558352600990915290208190555b5060009182526009602090815260408084208490556001600160a01b039094168352600881528383209183525290812055565b600a54600090613f189060019061577f565b6000838152600b6020526040812054600a8054939450909284908110613f4e57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905080600a8381548110613f7d57634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255828152600b9091526040808220849055858252812055600a805480613fc357634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905550505050565b6000613fea83611bda565b6001600160a01b039093166000908152600860209081526040808320868452825280832085905593825260099052919091209190915550565b3b151590565b6040518061012001604052806000815260200160608152602001606081526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b6040518060800160405280606081526020016060815260200160608152602001606081525090565b8280546140a9906158ce565b90600052602060002090601f0160209004810192826140cb5760008555614111565b82601f106140e45782800160ff19823516178555614111565b82800160010185558215614111579182015b828111156141115782358255916020019190600101906140f6565b5061411d929150614195565b5090565b82805461412d906158ce565b90600052602060002090601f01602090048101928261414f5760008555614111565b82601f1061416857805160ff1916838001178555614111565b82800160010185558215614111579182015b8281111561411157825182559160200191906001019061417a565b5b8082111561411d5760008155600101614196565b60006001600160401b038311156141c3576141c3615971565b6141d6601f8401601f19166020016156f8565b90508281528383830111156141ea57600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b03811681146105f257600080fd5b60008083601f840112614229578182fd5b5081356001600160401b0381111561423f578182fd5b60208301915083602082850101111561196357600080fd5b600082601f830112614267578081fd5b6133d3838335602085016141aa565b60006101208284031215614288578081fd5b50919050565b60006020828403121561429f578081fd5b6133d382614201565b600080604083850312156142ba578081fd5b6142c383614201565b91506142d160208401614201565b90509250929050565b6000806000606084860312156142ee578081fd5b6142f784614201565b925061430560208501614201565b9150604084013590509250925092565b6000806000806080858703121561432a578081fd5b61433385614201565b935061434160208601614201565b92506040850135915060608501356001600160401b03811115614362578182fd5b8501601f81018713614372578182fd5b614381878235602084016141aa565b91505092959194509250565b6000806000604084860312156143a1578283fd5b6143aa84614201565b925060208401356001600160401b03808211156143c5578384fd5b818601915086601f8301126143d8578384fd5b8135818111156143e6578485fd5b87602080830285010111156143f9578485fd5b6020830194508093505050509250925092565b6000806040838503121561441e578182fd5b61442783614201565b91506020830135801515811461443b578182fd5b809150509250929050565b60008060408385031215614458578182fd5b61446183614201565b946020939093013593505050565b600080600080600060a08688031215614486578081fd5b61448f86614201565b945060208601359350604086013592506060860135915060808601356001600160401b038111156144be578182fd5b6144ca88828901614257565b9150509295509295909350565b60008060008060008060c087890312156144ef578384fd5b6144f887614201565b9550602080880135955060408801359450606088013593506080880135925060a08801356001600160401b0380821115614530578384fd5b818a0191508a601f830112614543578384fd5b81358181111561455557614555615971565b61456284858302016156f8565b8181528481019250838501865b83811015614598576145868f888435890101614257565b8552938601939086019060010161456f565b505080955050505050509295509295509295565b600080604083850312156145be578182fd5b6145c783614201565b9150602083013560ff8116811461443b578182fd5b6000602082840312156145ed578081fd5b81356133d381615bc5565b600060208284031215614609578081fd5b81516133d381615bc5565b60008060208385031215614626578182fd5b82356001600160401b0381111561463b578283fd5b61464785828601614218565b90969095509350505050565b600060208284031215614664578081fd5b5035919050565b60008060006040848603121561467f578081fd5b8335925060208401356001600160401b0381111561469b578182fd5b6146a786828701614218565b9497909650939450505050565b600080604083850312156146c6578182fd5b8235915060208301356001600160401b038111156146e2578182fd5b6146ee85828601614276565b9150509250929050565b60008060006060848603121561470c578081fd5b8335925060208401356001600160401b0380821115614729578283fd5b61473587838801614276565b9350604086013591508082111561474a578283fd5b5084016080818703121561475c578182fd5b809150509250925092565b60008060408385031215614779578182fd5b50508035926020909101359150565b60008060006060848603121561479c578081fd5b505081359360208301359350604090920135919050565b600081518084526147cb8160208601602086016158a2565b601f01601f19169290920160200192915050565b600081546147ec816158ce565b60018281168015614804576001811461481557614844565b60ff19841687528287019450614844565b8560005260208060002060005b8581101561483b5781548a820152908401908201614822565b50505082870194505b5050505092915050565b600081516080845261486360808501826147b3565b90506020830151848203602086015261487c82826147b3565b9150506040830151848203604086015261489682826147b3565b915050606083015184820360608601526148b082826147b3565b95945050505050565b600083516148cb8184602088016158a2565b8351908301906148df8183602088016158a2565b01949350505050565b600083516148fa8184602088016158a2565b6148b0818401856147df565b600082516149188184602087016158a2565b7f2022646973706c61795f74797065223a20226e756d626572227d0a205d000000920191825250601d01919050565b600082516149598184602087016158a2565b7f20202020207b2274726169745f74797065223a202243726561746f72222c2022920191825250683b30b63ab2911d101160b91b6020820152602901919050565b600082516149ac8184602087016158a2565b7f2020227368613235365f33645f6d6f64656c5f68617368223a20220000000000920191825250601b01919050565b600082516149ed8184602087016158a2565b6211160560e91b920191825250600301919050565b60008251614a148184602087016158a2565b7f2020227368613235365f696d6167655f68617368223a20220000000000000000920191825250601801919050565b60008251614a558184602087016158a2565b7510101134b6b0b3b2afb334b632afba3cb832911d101160511b920191825250601601919050565b60008251614a8f8184602087016158a2565b7210101132bc3a32b93730b62fbab936111d101160691b920191825250601301919050565b60008251614ac68184602087016158a2565b7f202022617277656176655f696d6167655f68617368223a202200000000000000920191825250601901919050565b60008251614b078184602087016158a2565b600b60fa1b920191825250600101919050565b60008251614b2c8184602087016158a2565b7f20202020207b2274726169745f74797065223a202245646974696f6e222c20229201918252506703b30b63ab2911d160c51b6020820152602801919050565b60008251614b7e8184602087016158a2565b7f202022697066735f33645f6d6f64656c5f68617368223a202200000000000000920191825250601901919050565b60008251614bbf8184602087016158a2565b7510101136b7b232b62fb334b632afba3cb832911d101160511b920191825250601601919050565b60008251614bf98184602087016158a2565b6301037b3160e51b920191825250600401919050565b60008251614c218184602087016158a2565b7f20202261747472696275746573223a205b0a20202020207b2274726169745f749201918252507f797065223a2022417274697374222c202276616c7565223a20220000000000006020820152603a01919050565b60008251614c888184602087016158a2565b6b10101134b6b0b3b2911d101160a11b920191825250600c01919050565b60008251614cb88184602087016158a2565b6d0101136b0bc2fbb30b63ab2911d160951b920191825250600e01919050565b60008251614cea8184602087016158a2565b692041727469666578202360b01b920191825250600a01919050565b60008251614d188184602087016158a2565b63113e960560e11b920191825250600401919050565b60008251614d408184602087016158a2565b7f202022617277656176655f33645f6d6f64656c5f68617368223a202200000000920191825250601c01919050565b60008251614d818184602087016158a2565b711010113232b9b1b934b83a34b7b7111d101160711b920191825250601201919050565b60008251614db78184602087016158a2565b7510101134b83339afb4b6b0b3b2afb430b9b4111d101160511b920191825250601601919050565b60008251614df18184602087016158a2565b610a7d60f01b920191825250600201919050565b6000614e1182856147df565b83516148df8183602088016158a2565b6000611d24614e3083866147df565b846147df565b6c3d851010113730b6b2911d101160991b81528151600090614e5f81600d8501602087016158a2565b91909101600d0192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614eb3908301846147b3565b9695505050505050565b901515815260200190565b60006020825282602083015282846040840137818301604090810191909152601f909201601f19160101919050565b6000602082526133d360208301846147b3565b6020808252602b908201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560408201526a74206f6620626f756e647360a81b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b602080825260169082015275045646974696f6e206d757374206265203c3d203130360541b604082015260600190565b60208082526022908201527f4f776e61626c653a2063616c6c6572206973206e6f7420616e206f706572617460408201526137b960f11b606082015260800190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b602080825260149082015273151bdad95b88191bd95cc81b9bdd08195e1a5cdd60621b604082015260600190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526011908201527045646974696f6e206d757374206265203160781b604082015260600190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460408201526832b73a103a37b5b2b760b91b606082015260800190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252602c908201527f4552433732314d657461646174613a2055524920736574206f66206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b6020808252602f908201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60408201526e3732bc34b9ba32b73a103a37b5b2b760891b606082015260800190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b60208082526027908201527f6e756d546f6b656e7320616e64206e756d2069706673486173686573206d75736040820152660e840dac2e8c6d60cb1b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252602c908201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60408201526b7574206f6620626f756e647360a01b606082015260800190565b60208082526010908201526f14d95c9a595cc81a5cc81b1bd8dad95960821b604082015260600190565b6000604082528351604083015260208401516101208060608501526155b86101608501836147b3565b91506040860151603f19808685030160808701526155d684836147b3565b935060608801519150808685030160a08701526155f384836147b3565b935060808801519150808685030160c087015261561084836147b3565b935060a08801519150808685030160e087015261562d84836147b3565b935060c0880151915061010081878603018188015261564c85846147b3565b945060e0890151925081878603018488015261566885846147b3565b9450808901519350508086850301610140870152505061568882826147b3565b91505082810360208401526148b0818561484e565b90815260200190565b60ff91909116815260200190565b6000808335601e198436030181126156ca578283fd5b8301803591506001600160401b038211156156e3578283fd5b60200191503681900382131561196357600080fd5b604051601f8201601f191681016001600160401b038111828210171561572057615720615971565b604052919050565b60009081526020902090565b6000821982111561574757615747615945565b500190565b60008261575b5761575b61595b565b500490565b600081600019048311821515161561577a5761577a615945565b500290565b60008282101561579157615791615945565b500390565b5b8181101561377d5760008155600101615797565b6001600160401b038311156157c2576157c2615971565b6157cc81546158ce565b600080601f8611601f8411818117156157eb576157e886615728565b92505b801561581a576020601f890104830160208910156158065750825b6158186020601f880104850182615796565b505b50806001811461584657600094508715615835578387013594505b61583f8886615903565b8655615898565b601f198816945082845b868110156158705788860135825560209586019560019092019101615850565b508886101561588d57878501356000196008601f8c16021c191681555b506001600289020186555b5050505050505050565b60005b838110156158bd5781810151838201526020016158a5565b83811115610ae15750506000910152565b6002810460018216806158e257607f821691505b6020821081141561428857634e487b7160e01b600052602260045260246000fd5b600019600883021c191660029091021790565b600060001982141561592a5761592a615945565b5060010190565b6000826159405761594061595b565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b61599182836156b4565b6001600160401b038111156159a8576159a8615971565b6159b283546158ce565b600080601f8411601f8411818117156159d1576159ce88615728565b92505b8015615a00576020601f870104830160208710156159ec5750825b6159fe6020601f880104850182615796565b505b508060018114615a2c57600094508515615a1b578387013594505b615a258686615903565b8855615a7e565b601f198616945082845b86811015615a565788860135825560209586019560019092019101615a36565b5086861015615a7357878501356000196008601f8a16021c191681555b506001600287020188555b50505050505050615a9260208301836156b4565b615aa08183600186016157ab565b5050615aaf60408301836156b4565b615abd8183600286016157ab565b5050615acc60608301836156b4565b610ae18183600386016157ab565b81358155615aeb60208301836156b4565b615af98183600186016157ab565b5050615b0860408301836156b4565b615b168183600286016157ab565b5050615b2560608301836156b4565b615b338183600386016157ab565b5050615b4260808301836156b4565b615b508183600486016157ab565b5050615b5f60a08301836156b4565b615b6d8183600586016157ab565b5050615b7c60c08301836156b4565b615b8a8183600686016157ab565b5050615b9960e08301836156b4565b615ba78183600786016157ab565b5050615bb76101008301836156b4565b610ae18183600886016157ab565b6001600160e01b031981168114615bdb57600080fd5b5056fea26469706673582212209f8cbc42b7f9fb994edadbfb0a2f8ac4451bc42c2991eccc64186c6f6c33fcb864736f6c63430008010033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000007417274696665780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074152544946455800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002268747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066732f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001468747470733a2f2f617274696665782e6172742f000000000000000000000000

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

000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000007417274696665780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074152544946455800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002268747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066732f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001468747470733a2f2f617274696665782e6172742f000000000000000000000000

-----Decoded View---------------
Arg [0] : name (string): Artifex
Arg [1] : symbol (string): ARTIFEX
Arg [2] : base_uri (string): https://gateway.pinata.cloud/ipfs/
Arg [3] : external_base_uri (string): https://artifex.art/

-----Encoded View---------------
13 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [5] : 4172746966657800000000000000000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [7] : 4152544946455800000000000000000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000022
Arg [9] : 68747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066
Arg [10] : 732f000000000000000000000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [12] : 68747470733a2f2f617274696665782e6172742f000000000000000000000000


Deployed ByteCode Sourcemap

46546:26951:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39152:308;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65140:895;;;;;;:::i;:::-;;:::i;:::-;;26383:100;;;:::i;:::-;;;;;;;:::i;27965:308::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;27488:411::-;;;;;;:::i;:::-;;:::i;69245:454::-;;;;;;:::i;:::-;;:::i;39963:113::-;;;:::i;:::-;;;;;;;:::i;50245:496::-;;;;;;:::i;:::-;;:::i;29024:376::-;;;;;;:::i;:::-;;:::i;66560:614::-;;;;;;:::i;:::-;;:::i;53610:569::-;;;;;;:::i;:::-;;:::i;39544:343::-;;;;;;:::i;:::-;;:::i;13059:183::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;69981:504::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;29471:185::-;;;;;;:::i;:::-;;:::i;56562:104::-;;;;;;:::i;:::-;;:::i;40153:320::-;;;;;;:::i;:::-;;:::i;51310:647::-;;;;;;:::i;:::-;;:::i;54395:201::-;;;;;;:::i;:::-;;:::i;72119:176::-;;;;;;:::i;:::-;;:::i;67347:132::-;;;;;;:::i;:::-;;:::i;25990:326::-;;;;;;:::i;:::-;;:::i;56029:93::-;;;:::i;25633:295::-;;;;;;:::i;:::-;;:::i;14098:148::-;;;:::i;72487:180::-;;;;;;:::i;:::-;;:::i;68102:360::-;;;;;;:::i;:::-;;:::i;70678:437::-;;;;;;:::i;:::-;;:::i;12774:87::-;;;:::i;68777:265::-;;;;;;:::i;:::-;;:::i;26552:104::-;;;:::i;52309:315::-;;;;;;:::i;:::-;;:::i;28345:327::-;;;;;;:::i;:::-;;:::i;58403:6389::-;;;;;;:::i;:::-;;:::i;67650:261::-;;;;;;:::i;:::-;;:::i;55293:258::-;;;;;;:::i;:::-;;:::i;56265:112::-;;;:::i;29727:365::-;;;;;;:::i;:::-;;:::i;71346:564::-;;;;;;:::i;:::-;;:::i;14848:222::-;;;;;;:::i;:::-;;:::i;28743:214::-;;;;;;:::i;:::-;;:::i;14401:281::-;;;;;;:::i;:::-;;:::i;54825:267::-;;;;;;:::i;:::-;;:::i;55740:125::-;;;;;;:::i;:::-;;:::i;39152:308::-;39307:4;-1:-1:-1;;;;;;39349:50:0;;-1:-1:-1;;;39349:50:0;;:103;;;39416:36;39440:11;39416:23;:36::i;:::-;39329:123;;39152:308;;;;:::o;65140:895::-;13617:12;:10;:12::i;:::-;-1:-1:-1;;;;;13606:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;13606:23:0;;:59;;;-1:-1:-1;13649:10:0;13633:27;;;;:15;:27;;;;;;;;;;;:32;13606:59;13584:143;;;;-1:-1:-1;;;13584:143:0;;;;;;;:::i;:::-;;;;;;;;;65455:28:::1;::::0;;;:18:::1;:28;::::0;;;;;::::1;;:37;65447:66;;;;-1:-1:-1::0;;;65447:66:0::1;;;;;;;:::i;:::-;65630:12:::0;;65626:245:::1;;65663:7;65674:1;65663:12;65659:201;;;65704:6;65714:1;65704:11;65696:41;;;;-1:-1:-1::0;;;65696:41:0::1;;;;;;;:::i;:::-;65659:201;;;65763:7;65774:1;65763:12;65759:101;;;65814:3;65804:6;:13;;65796:48;;;;-1:-1:-1::0;;;65796:48:0::1;;;;;;;:::i;:::-;65881:15;65899:40;65913:8;65923:7;65932:6;65899:13;:40::i;:::-;65881:58;;65950:22;65960:2;65964:7;65950:9;:22::i;:::-;65983:44;66009:7;66018:8;65983:25;:44::i;:::-;13738:1;65140:895:::0;;;;;:::o;26383:100::-;26437:13;26470:5;26463:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26383:100;:::o;27965:308::-;28086:7;28133:16;28141:7;28133;:16::i;:::-;28111:110;;;;-1:-1:-1;;;28111:110:0;;;;;;;:::i;:::-;-1:-1:-1;28241:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;28241:24:0;;27965:308::o;27488:411::-;27569:13;27585:23;27600:7;27585:14;:23::i;:::-;27569:39;;27633:5;-1:-1:-1;;;;;27627:11:0;:2;-1:-1:-1;;;;;27627:11:0;;;27619:57;;;;-1:-1:-1;;;27619:57:0;;;;;;;:::i;:::-;27727:5;-1:-1:-1;;;;;27711:21:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;27711:21:0;;:62;;;;27736:37;27753:5;27760:12;:10;:12::i;27736:37::-;27689:168;;;;-1:-1:-1;;;27689:168:0;;;;;;;:::i;:::-;27870:21;27879:2;27883:7;27870:8;:21::i;:::-;27488:411;;;:::o;69245:454::-;69342:24;69392:16;69400:7;69392;:16::i;:::-;69384:49;;;;-1:-1:-1;;;69384:49:0;;;;;;;:::i;:::-;69448:19;69459:7;69448:10;:19::i;:::-;69471:1;69448:24;69444:248;;;69502:18;:40;69521:20;69533:7;69521:11;:20::i;:::-;69502:40;;;;;;;;;;;:51;;69489:64;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69444:248;;;69575:19;69586:7;69575:10;:19::i;:::-;69598:1;69575:24;69571:121;;;69629:18;:40;69648:20;69660:7;69648:11;:20::i;:::-;69629:40;;;;;;;;;;;:51;;69616:64;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69245:454;;;:::o;39963:113::-;40051:10;:17;39963:113;:::o;50245:496::-;13617:12;:10;:12::i;:::-;-1:-1:-1;;;;;13606:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;13606:23:0;;:59;;;-1:-1:-1;13649:10:0;13633:27;;;;:15;:27;;;;;;;;;;;:32;13606:59;13584:143;;;;-1:-1:-1;;;13584:143:0;;;;;;;:::i;:::-;50451:3:::1;50439:8;:15;;50431:24;;;::::0;::::1;;50621:28;::::0;;;:18:::1;:28;::::0;;;;;::::1;;:37;50613:66;;;;-1:-1:-1::0;;;50613:66:0::1;;;;;;;:::i;:::-;50692:28;::::0;;;:18:::1;:28;::::0;;;;50723:10;;50692:41:::1;50723:10:::0;50692:28;:41:::1;:::i;:::-;-1:-1:-1::0;;;;50245:496:0:o;29024:376::-;29233:41;29252:12;:10;:12::i;:::-;29266:7;29233:18;:41::i;:::-;29211:140;;;;-1:-1:-1;;;29211:140:0;;;;;;;:::i;:::-;29364:28;29374:4;29380:2;29384:7;29364:9;:28::i;66560:614::-;13617:12;:10;:12::i;:::-;-1:-1:-1;;;;;13606:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;13606:23:0;;:59;;;-1:-1:-1;13649:10:0;13633:27;;;;:15;:27;;;;;;;;;;;:32;13606:59;13584:143;;;;-1:-1:-1;;;13584:143:0;;;;;;;:::i;:::-;66833:10:::1;:17;66820:9;:30;66798:119;;;;-1:-1:-1::0;;;66798:119:0::1;;;;;;;:::i;:::-;66933:9;66928:239;66952:9;66948:1;:13;66928:239;;;66983:172;67016:2:::0;67037:8;67064:7;67090:18:::1;67107:1:::0;67090:14;:18:::1;:::i;:::-;67127:10;67138:1;67127:13;;;;;;-1:-1:-1::0;;;67127:13:0::1;;;;;;;;;;;;;;;66983:14;:172::i;:::-;66963:3:::0;::::1;::::0;::::1;:::i;:::-;;;;66928:239;;;;66560:614:::0;;;;;;:::o;53610:569::-;13617:12;:10;:12::i;:::-;-1:-1:-1;;;;;13606:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;13606:23:0;;:59;;;-1:-1:-1;13649:10:0;13633:27;;;;:15;:27;;;;;;;;;;;:32;13606:59;13584:143;;;;-1:-1:-1;;;13584:143:0;;;;;;;:::i;:::-;53736:3:::1;53724:8;:15;;53716:24;;;::::0;::::1;;53817:28;::::0;;;:18:::1;:28;::::0;;;;;::::1;;:37;53809:66;;;;-1:-1:-1::0;;;53809:66:0::1;;;;;;;:::i;:::-;54069:28;::::0;;;:18:::1;:28;::::0;;;;;;:35;;-1:-1:-1;;54069:35:0::1;54100:4;54069:35;::::0;;54149:22;::::1;::::0;::::1;::::0;54088:8;;54149:22:::1;:::i;:::-;;;;;;;;53610:569:::0;:::o;39544:343::-;39686:7;39741:23;39758:5;39741:16;:23::i;:::-;39733:5;:31;39711:124;;;;-1:-1:-1;;;39711:124:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;39853:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;39544:343::o;13059:183::-;-1:-1:-1;;;;;13202:32:0;13172:5;13202:32;;;:15;:32;;;;;;;;;13059:183::o;69981:504::-;70101:37;;:::i;:::-;70153:51;;:::i;:::-;70236:7;70247:1;70236:12;70232:246;;;70278:18;:28;70297:8;70278:28;;;;;;;;;;;70265:41;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70232:246;;;70328:7;70339:1;70328:12;70324:154;;;70370:18;:28;70389:8;70370:28;;;;;;;;;;;70357:41;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70433:23;:33;70457:8;70433:33;;;;;;;;;;;70413:53;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70324:154;69981:504;;;;;:::o;29471:185::-;29609:39;29626:4;29632:2;29636:7;29609:39;;;;;;;;;;;;:16;:39::i;56562:104::-;56618:4;56642:16;56650:7;56642;:16::i;40153:320::-;40273:7;40328:30;:28;:30::i;:::-;40320:5;:38;40298:132;;;;-1:-1:-1;;;40298:132:0;;;;;;;:::i;:::-;40448:10;40459:5;40448:17;;;;;;-1:-1:-1;;;40448:17:0;;;;;;;;;;;;;;;;;40441:24;;40153:320;;;:::o;51310:647::-;13617:12;:10;:12::i;:::-;-1:-1:-1;;;;;13606:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;13606:23:0;;:59;;;-1:-1:-1;13649:10:0;13633:27;;;;:15;:27;;;;;;;;;;;:32;13606:59;13584:143;;;;-1:-1:-1;;;13584:143:0;;;;;;;:::i;:::-;51580:3:::1;51568:8;:15;;51560:24;;;::::0;::::1;;51773:28;::::0;;;:18:::1;:28;::::0;;;;;::::1;;:37;51765:66;;;;-1:-1:-1::0;;;51765:66:0::1;;;;;;;:::i;:::-;51844:28;::::0;;;:18:::1;:28;::::0;;;;51875:10;;51844:41:::1;51875:10:::0;51844:28;:41:::1;:::i;:::-;-1:-1:-1::0;;51896:33:0::1;::::0;;;:23:::1;:33;::::0;;;;51932:17;;51896:53:::1;51932:17:::0;51896:33;:53:::1;:::i;:::-;-1:-1:-1::0;;;;;51310:647:0:o;54395:201::-;13617:12;:10;:12::i;:::-;-1:-1:-1;;;;;13606:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;13606:23:0;;:59;;;-1:-1:-1;13649:10:0;13633:27;;;;:15;:27;;;;;;;;;;;:32;13606:59;13584:143;;;;-1:-1:-1;;;13584:143:0;;;;;;;:::i;:::-;54480:31:::1;:13;54496:15:::0;;54480:31:::1;:::i;:::-;;54556:32;54572:15;;54556:32;;;;;;;:::i;:::-;;;;;;;;54395:201:::0;;:::o;72119:176::-;72253:34;;;;:25;:34;;;;;72246:41;;72215:13;;72253:34;72246:41;;;:::i;67347:132::-;67406:7;67442:27;48507:9;67442:7;:27;:::i;25990:326::-;26107:7;26148:16;;;:7;:16;;;;;;-1:-1:-1;;;;;26148:16:0;26197:19;26175:110;;;;-1:-1:-1;;;26175:110:0;;;;;;;:::i;56029:93::-;56071:13;56104:10;:8;:10::i;:::-;56097:17;;56029:93;:::o;25633:295::-;25750:7;-1:-1:-1;;;;;25797:19:0;;25775:111;;;;-1:-1:-1;;;25775:111:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;25904:16:0;;;;;:9;:16;;;;;;;25633:295::o;14098:148::-;13386:12;:10;:12::i;:::-;-1:-1:-1;;;;;13375:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;13375:23:0;;13367:68;;;;-1:-1:-1;;;13367:68:0;;;;;;;:::i;:::-;14205:1:::1;14189:6:::0;;14168:40:::1;::::0;-1:-1:-1;;;;;14189:6:0;;::::1;::::0;14168:40:::1;::::0;14205:1;;14168:40:::1;14236:1;14219:19:::0;;-1:-1:-1;;;;;;14219:19:0::1;::::0;;14098:148::o;72487:180::-;72546:13;72616:21;72639:18;:7;:16;:18::i;:::-;72599:59;;;;;;;;;:::i;:::-;;;;;;;;;;;;;72572:87;;72487:180;;;:::o;68102:360::-;68159:7;68179:16;68198:20;68210:7;68198:11;:20::i;:::-;68179:39;;68229:15;68247:19;68258:7;68247:10;:19::i;:::-;68229:37;-1:-1:-1;68409:29:0;48562:5;68229:37;68409:29;:::i;:::-;68355:28;68375:8;48507:9;68355:28;:::i;:::-;68323:61;;:7;:61;:::i;:::-;:116;;;;:::i;:::-;68277:177;68102:360;-1:-1:-1;;;;68102:360:0:o;70678:437::-;70789:37;;:::i;:::-;70841:51;;:::i;:::-;70928:16;70936:7;70928;:16::i;:::-;70920:49;;;;-1:-1:-1;;;70920:49:0;;;;;;;:::i;:::-;71014:93;71042:20;71054:7;71042:11;:20::i;:::-;71077:19;71088:7;71077:10;:19::i;71014:93::-;70980:127;;;;-1:-1:-1;70678:437:0;-1:-1:-1;;70678:437:0:o;12774:87::-;12820:7;12847:6;-1:-1:-1;;;;;12847:6:0;12774:87;:::o;68777:265::-;68906:7;69027:6;68981:29;48562:5;68981:7;:29;:::i;:::-;68935:28;48507:9;68935:8;:28;:::i;:::-;68934:77;;;;:::i;:::-;:99;;;;:::i;26552:104::-;26608:13;26641:7;26634:14;;;;;:::i;52309:315::-;13617:12;:10;:12::i;:::-;-1:-1:-1;;;;;13606:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;13606:23:0;;:59;;;-1:-1:-1;13649:10:0;13633:27;;;;:15;:27;;;;;;;;;;;:32;13606:59;13584:143;;;;-1:-1:-1;;;13584:143:0;;;;;;;:::i;:::-;52468:18:::1;:40;52487:20;52499:7;52487:11;:20::i;:::-;52468:40:::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;52468:40:0;;::::1;;:49;52446:115;;;;-1:-1:-1::0;;;52446:115:0::1;;;;;;;:::i;:::-;52572:44;52598:7;52607:8;;52572:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;52572:25:0::1;::::0;-1:-1:-1;;;52572:44:0:i:1;28345:327::-:0;28492:12;:10;:12::i;:::-;-1:-1:-1;;;;;28480:24:0;:8;-1:-1:-1;;;;;28480:24:0;;;28472:62;;;;-1:-1:-1;;;28472:62:0;;;;;;;:::i;:::-;28592:8;28547:18;:32;28566:12;:10;:12::i;:::-;-1:-1:-1;;;;;28547:32:0;;;;;;;;;;;;;;;;;-1:-1:-1;28547:32:0;;;:42;;;;;;;;;;;;:53;;-1:-1:-1;;28547:53:0;;;;;;;;;;;28631:12;:10;:12::i;:::-;-1:-1:-1;;;;;28616:48:0;;28655:8;28616:48;;;;;;:::i;:::-;;;;;;;;28345:327;;:::o;58403:6389::-;58491:22;58539:16;58547:7;58539;:16::i;:::-;58531:49;;;;-1:-1:-1;;;58531:49:0;;;;;;;:::i;:::-;58593:16;58612:20;58624:7;58612:11;:20::i;:::-;58593:39;;58643:15;58661:19;58672:7;58661:10;:19::i;:::-;58643:37;;58691:18;58712;58722:7;58712:9;:18::i;:::-;58691:39;;58743:25;58779:37;;:::i;:::-;58827:51;;:::i;:::-;58893:7;58904:1;58893:12;58889:347;;;58935:18;:28;58954:8;58935:28;;;;;;;;;;;58922:41;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58992:10;:21;;;58978:35;;58889:347;;;59035:7;59046:1;59035:12;59031:205;;;59077:18;:28;59096:8;59077:28;;;;;;;;;;;59064:41;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59134:10;:22;;;59120:36;;59191:23;:33;59215:8;59191:33;;;;;;;;;;;59171:53;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59031:205;59332:10;:21;;;59297:57;;;;;;;;:::i;:::-;;;;;;;;;;;;;59265:100;;59411:8;59394:40;;;;;;;;:::i;:::-;;;;;;;;;;;;;59376:59;;59481:8;59491:21;:10;:19;:21::i;:::-;59464:49;;;;;;;;;:::i;:::-;;;;;;;;;;;;;59446:68;;59560:8;59543:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;59525:53;;59638:8;59648:35;:10;:24;;;:33;:35::i;:::-;59621:63;;;;;;;;;:::i;:::-;;;;;;;;;;;;;59589:106;;59741:8;59724:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;59706:53;;59843:8;59826:48;;;;;;;;:::i;:::-;;;;;;;;;;;;;59808:67;;59921:8;59931:10;:22;;;59904:50;;;;;;;;;:::i;:::-;;;;;;;;;;;;;59886:69;;60001:8;59984:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;59966:53;;60089:8;60072:42;;;;;;;;:::i;:::-;;;;;;;;;;;;;60054:61;;60161:8;60171:13;60144:41;;;;;;;;;:::i;:::-;;;;;;;;;;;;;60126:60;;60232:8;60242:10;:24;;;60215:52;;;;;;;;;:::i;:::-;;;;;;;;;;;;;60197:71;;60314:8;60297:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;60279:53;;60405:8;60388:49;;;;;;;;:::i;:::-;;;;;;;;;;;;;60370:68;;60484:8;60494:20;60506:7;60494:11;:20::i;:::-;60467:48;;;;;;;;;:::i;:::-;;;;;;;;;;;;;60449:67;;60562:8;60545:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;60527:53;;60672:8;60655:54;;;;;;;;:::i;:::-;;;;;;;;;;;;;60623:97;;60780:8;60790:10;:26;;;60763:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;60731:97;;60874:8;60857:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;60839:53;;60968:8;60951:52;;;;;;;;:::i;:::-;;;;;;;;;;;;;60933:71;;61050:8;61060:10;:24;;;61033:52;;;;;;;;;:::i;:::-;;;;;;;;;;;;;61015:71;;61132:8;61115:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;61097:53;;61243:8;61226:55;;;;;;;;:::i;:::-;;;;;;;;;;;;;61194:98;;61352:8;61362:10;:27;;;61335:55;;;;;;;;;:::i;:::-;;;;;;;;;;;;;61303:98;;61447:8;61430:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;61412:53;;61541:8;61524:52;;;;;;;;:::i;:::-;;;;;;;;;;;;;61506:71;;61623:8;61633:10;:24;;;61606:52;;;;;;;;;:::i;:::-;;;;;;;;;;;;;61588:71;;61705:8;61688:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;61670:53;;61779:7;61790:1;61779:12;61775:1448;;;61898:8;61881:57;;;;;;;;:::i;:::-;;;;-1:-1:-1;;61881:57:0;;;;;;;;;;62031:33;;61881:57;;-1:-1:-1;62004:61:0;;61881:57;;62031:33;61881:57;62004:61;;:::i;:::-;;;;;;;;;;;;;61968:112;;62130:8;62113:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;62095:53;;62253:8;62236:55;;;;;;;;:::i;:::-;;;;;;;;;;;;;62200:106;;62374:8;62384:17;:33;;;62357:61;;;;;;;;;:::i;:::-;;;;;;;;;;;;;62321:112;;62483:8;62466:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;62448:53;;62609:8;62592:58;;;;;;;;:::i;:::-;;;;;;;;;;;;;62556:109;;62733:8;62743:17;:36;;;62716:64;;;;;;;;;:::i;:::-;;;;;;;;;;;;;62680:115;;62845:8;62828:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;62810:53;;62968:8;62951:52;;;;;;;;:::i;:::-;;;;;;;;;;;;;62915:103;;63086:8;63096:17;:31;;;63069:59;;;;;;;;;:::i;:::-;;;;;;;;;;;;;63033:110;;63193:8;63176:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;63158:53;;61775:1448;63358:8;63323:138;;;;;;;;:::i;:::-;;;;;;;;;;;;;63291:181;;63518:8;63528:10;:21;;;63501:49;;;;;;;;;:::i;:::-;;;;;;;;;;;;;63483:68;;63597:8;63580:35;;;;;;;;:::i;:::-;;;;;;;;;;;;;63562:54;;63721:8;63686:120;;;;;;;;:::i;:::-;;;;;;;;;;;;;63654:163;;63863:8;63873:11;63846:39;;;;;;;;;:::i;:::-;;;;;;;;;;;;;63828:58;;63932:8;63915:35;;;;;;;;:::i;:::-;;;;;;;;;;;;;63897:54;;64058:8;64023:119;;;;;;;;:::i;:::-;;;;;;;;;;;;;63991:162;;64199:8;64209:21;:10;:19;:21::i;:::-;64182:49;;;;;;;;;:::i;:::-;;;;;;;;;;;;;64164:68;;64278:8;64261:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;64243:50;;64368:8;64351:44;;;;;;;;:::i;:::-;;;;;;;;;;;;;64333:63;;64456:8;64466:35;:10;:24;;;:33;:35::i;:::-;64439:63;;;;;;;;;:::i;:::-;;;;;;;;;;;;;64407:106;;64559:8;64542:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;64524:50;;64634:8;64617:60;;;;;;;;:::i;:::-;;;;;;;;;;;;;64585:103;;64767:8;64750:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;64732:52;;58403:6389;;;;;;;;;:::o;67650:261::-;67708:7;67728:16;67747:20;67759:7;67747:11;:20::i;:::-;67728:39;-1:-1:-1;48562:5:0;67836:28;67728:39;48507:9;67836:28;:::i;:::-;67825:40;;:7;:40;:::i;:::-;67824:64;;;;:::i;:::-;67778:125;67650:261;-1:-1:-1;;;67650:261:0:o;55293:258::-;55385:20;55377:29;;;;;;55424:9;55419:125;55439:20;;;55419:125;;;55481:51;55498:10;55510:3;55515:9;;55525:1;55515:12;;;;;-1:-1:-1;;;55515:12:0;;;;;;;;;;;;;;;55481:51;;;;;;;;;;;;:16;:51::i;:::-;55461:3;;;;:::i;:::-;;;;55419:125;;56265:112;56315:13;56348:21;56341:28;;;;;:::i;29727:365::-;29916:41;29935:12;:10;:12::i;:::-;29949:7;29916:18;:41::i;:::-;29894:140;;;;-1:-1:-1;;;29894:140:0;;;;;;;:::i;:::-;30045:39;30059:4;30065:2;30069:7;30078:5;30045:13;:39::i;71346:564::-;71464:13;71517:16;71525:7;71517;:16::i;:::-;71495:113;;;;-1:-1:-1;;;71495:113:0;;;;;;;:::i;:::-;71671:1;71647:13;71641:27;;;;;:::i;:::-;;;:31;:261;;;;;;;;;;;;;;;;;71764:13;71804:25;:34;71830:7;71804:34;;;;;;;;;;;71721:140;;;;;;;;;:::i;14848:222::-;13386:12;:10;:12::i;:::-;-1:-1:-1;;;;;13375:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;13375:23:0;;13367:68;;;;-1:-1:-1;;;13367:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;14986:26:0;::::1;14978:35;;;::::0;::::1;;-1:-1:-1::0;;;;;15024:29:0;;;::::1;;::::0;;;:15:::1;:29;::::0;;;;:38;;-1:-1:-1;;15024:38:0::1;;::::0;;::::1;::::0;;;::::1;::::0;;14848:222::o;28743:214::-;-1:-1:-1;;;;;28914:25:0;;;28885:4;28914:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;28743:214::o;14401:281::-;13386:12;:10;:12::i;:::-;-1:-1:-1;;;;;13375:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;13375:23:0;;13367:68;;;;-1:-1:-1;;;13367:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;14504:22:0;::::1;14482:110;;;;-1:-1:-1::0;;;14482:110:0::1;;;;;;;:::i;:::-;14629:6;::::0;;14608:38:::1;::::0;-1:-1:-1;;;;;14608:38:0;;::::1;::::0;14629:6;::::1;::::0;14608:38:::1;::::0;::::1;14657:6;:17:::0;;-1:-1:-1;;;;;;14657:17:0::1;-1:-1:-1::0;;;;;14657:17:0;;;::::1;::::0;;;::::1;::::0;;14401:281::o;54825:267::-;13617:12;:10;:12::i;:::-;-1:-1:-1;;;;;13606:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;13606:23:0;;:59;;;-1:-1:-1;13649:10:0;13633:27;;;;:15;:27;;;;;;;;;;;:32;13606:59;13584:143;;;;-1:-1:-1;;;13584:143:0;;;;;;;:::i;:::-;54949:47:::1;:21;54973:23:::0;;54949:47:::1;:::i;:::-;;55041:43;55060:23;;55041:43;;;;;;;:::i;55740:125::-:0;55805:4;55829:28;;;:18;:28;;;;;;;;;55740:125::o;25214:355::-;25361:4;-1:-1:-1;;;;;;25403:40:0;;-1:-1:-1;;;25403:40:0;;:105;;-1:-1:-1;;;;;;;25460:48:0;;-1:-1:-1;;;25460:48:0;25403:105;:158;;;;25525:36;25549:11;25525:23;:36::i;9329:98::-;9409:10;9329:98;:::o;32727:110::-;32803:26;32813:2;32817:7;32803:26;;;;;;;;;;;;:9;:26::i;:::-;32727:110;;:::o;73209:285::-;73341:16;73349:7;73341;:16::i;:::-;73319:110;;;;-1:-1:-1;;;73319:110:0;;;;;;;:::i;:::-;73440:34;;;;:25;:34;;;;;;;;:46;;;;;;;;:::i;31639:127::-;31704:4;31728:16;;;:7;:16;;;;;;-1:-1:-1;;;;;31728:16:0;:30;;;31639:127::o;35762:174::-;35837:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;35837:29:0;-1:-1:-1;;;;;35837:29:0;;;;;;;;:24;;35891:23;35837:24;35891:14;:23::i;:::-;-1:-1:-1;;;;;35882:46:0;;;;;;;;;;;35762:174;;:::o;31933:452::-;32062:4;32106:16;32114:7;32106;:16::i;:::-;32084:110;;;;-1:-1:-1;;;32084:110:0;;;;;;;:::i;:::-;32205:13;32221:23;32236:7;32221:14;:23::i;:::-;32205:39;;32274:5;-1:-1:-1;;;;;32263:16:0;:7;-1:-1:-1;;;;;32263:16:0;;:64;;;;32320:7;-1:-1:-1;;;;;32296:31:0;:20;32308:7;32296:11;:20::i;:::-;-1:-1:-1;;;;;32296:31:0;;32263:64;:113;;;;32344:32;32361:5;32368:7;32344:16;:32::i;35029:615::-;35202:4;-1:-1:-1;;;;;35175:31:0;:23;35190:7;35175:14;:23::i;:::-;-1:-1:-1;;;;;35175:31:0;;35153:122;;;;-1:-1:-1;;;35153:122:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;35294:16:0;;35286:65;;;;-1:-1:-1;;;35286:65:0;;;;;;;:::i;:::-;35364:39;35385:4;35391:2;35395:7;35364:20;:39::i;:::-;35468:29;35485:1;35489:7;35468:8;:29::i;:::-;-1:-1:-1;;;;;35510:15:0;;;;;;:9;:15;;;;;:20;;35529:1;;35510:15;:20;;35529:1;;35510:20;:::i;:::-;;;;-1:-1:-1;;;;;;;35541:13:0;;;;;;:9;:13;;;;;:18;;35558:1;;35541:13;:18;;35558:1;;35541:18;:::i;:::-;;;;-1:-1:-1;;35570:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;35570:21:0;-1:-1:-1;;;;;35570:21:0;;;;;;;;;35609:27;;35570:16;;35609:27;;;;;;;35029:615;;;:::o;72831:114::-;72891:13;72924;72917:20;;;;;:::i;9899:723::-;9955:13;10176:10;10172:53;;-1:-1:-1;10203:10:0;;;;;;;;;;;;-1:-1:-1;;;10203:10:0;;;;;;10172:53;10250:5;10235:12;10291:78;10298:9;;10291:78;;10324:8;;;;:::i;:::-;;-1:-1:-1;10347:10:0;;-1:-1:-1;10355:2:0;10347:10;;:::i;:::-;;;10291:78;;;10379:19;10411:6;-1:-1:-1;;;;;10401:17:0;;;;;-1:-1:-1;;;10401:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10401:17:0;;10379:39;;10429:154;10436:10;;10429:154;;10463:11;10473:1;10463:11;;:::i;:::-;;-1:-1:-1;10532:10:0;10540:2;10532:5;:10;:::i;:::-;10519:24;;:2;:24;:::i;:::-;10506:39;;10489:6;10496;10489:14;;;;;;-1:-1:-1;;;10489:14:0;;;;;;;;;;;;:56;-1:-1:-1;;;;;10489:56:0;;;;;;;;-1:-1:-1;10560:11:0;10569:2;10560:11;;:::i;:::-;;;10429:154;;30974:352;31131:28;31141:4;31147:2;31151:7;31131:9;:28::i;:::-;31192:48;31215:4;31221:2;31225:7;31234:5;31192:22;:48::i;:::-;31170:148;;;;-1:-1:-1;;;31170:148:0;;;;;;;:::i;22250:207::-;-1:-1:-1;;;;;;22409:40:0;;-1:-1:-1;;;22409:40:0;22250:207;;;:::o;33064:321::-;33194:18;33200:2;33204:7;33194:5;:18::i;:::-;33245:54;33276:1;33280:2;33284:7;33293:5;33245:22;:54::i;:::-;33223:154;;;;-1:-1:-1;;;33223:154:0;;;;;;;:::i;41086:589::-;41230:45;41257:4;41263:2;41267:7;41230:26;:45::i;:::-;-1:-1:-1;;;;;41292:18:0;;41288:187;;41327:40;41359:7;41327:31;:40::i;:::-;41288:187;;;41397:2;-1:-1:-1;;;;;41389:10:0;:4;-1:-1:-1;;;;;41389:10:0;;41385:90;;41416:47;41449:4;41455:7;41416:32;:47::i;:::-;-1:-1:-1;;;;;41489:16:0;;41485:183;;41522:45;41559:7;41522:36;:45::i;:::-;41485:183;;;41595:4;-1:-1:-1;;;;;41589:10:0;:2;-1:-1:-1;;;;;41589:10:0;;41585:83;;41616:40;41644:2;41648:7;41616:27;:40::i;36501:1053::-;36656:4;36677:15;:2;-1:-1:-1;;;;;36677:13:0;;:15::i;:::-;36673:874;;;36746:2;-1:-1:-1;;;;;36730:36:0;;36789:12;:10;:12::i;:::-;36824:4;36851:7;36881:5;36730:175;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36730:175:0;;;;;;;;-1:-1:-1;;36730:175:0;;;;;;;;;;;;:::i;:::-;;;36709:783;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37092:13:0;;37088:389;;37135:108;;-1:-1:-1;;;37135:108:0;;;;;;;:::i;37088:389::-;37427:6;37421:13;37412:6;37408:2;37404:15;37397:38;36709:783;-1:-1:-1;;;;;;36969:55:0;-1:-1:-1;;;36969:55:0;;-1:-1:-1;36962:62:0;;36673:874;-1:-1:-1;37531:4:0;36501:1053;;;;;;:::o;33721:382::-;-1:-1:-1;;;;;33801:16:0;;33793:61;;;;-1:-1:-1;;;33793:61:0;;;;;;;:::i;:::-;33874:16;33882:7;33874;:16::i;:::-;33873:17;33865:58;;;;-1:-1:-1;;;33865:58:0;;;;;;;:::i;:::-;33936:45;33965:1;33969:2;33973:7;33936:20;:45::i;:::-;-1:-1:-1;;;;;33994:13:0;;;;;;:9;:13;;;;;:18;;34011:1;;33994:13;:18;;34011:1;;33994:18;:::i;:::-;;;;-1:-1:-1;;34023:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;34023:21:0;-1:-1:-1;;;;;34023:21:0;;;;;;;;34062:33;;34023:16;;;34062:33;;34023:16;;34062:33;33721:382;;:::o;42398:164::-;42502:10;:17;;42475:24;;;;:15;:24;;;;;:44;;;42530:24;;;;;;;;;;;;42398:164::o;43189:1002::-;43469:22;43519:1;43494:22;43511:4;43494:16;:22::i;:::-;:26;;;;:::i;:::-;43531:18;43552:26;;;:17;:26;;;;;;43469:51;;-1:-1:-1;43685:28:0;;;43681:328;;-1:-1:-1;;;;;43752:18:0;;43730:19;43752:18;;;:12;:18;;;;;;;;:34;;;;;;;;;43803:30;;;;;;:44;;;43920:30;;:17;:30;;;;;:43;;;43681:328;-1:-1:-1;44105:26:0;;;;:17;:26;;;;;;;;44098:33;;;-1:-1:-1;;;;;44149:18:0;;;;;:12;:18;;;;;:34;;;;;;;44142:41;43189:1002::o;44486:1079::-;44764:10;:17;44739:22;;44764:21;;44784:1;;44764:21;:::i;:::-;44796:18;44817:24;;;:15;:24;;;;;;45190:10;:26;;44739:46;;-1:-1:-1;44817:24:0;;44739:46;;45190:26;;;;-1:-1:-1;;;45190:26:0;;;;;;;;;;;;;;;;;45168:48;;45254:11;45229:10;45240;45229:22;;;;;;-1:-1:-1;;;45229:22:0;;;;;;;;;;;;;;;;;;;;:36;;;;45334:28;;;:15;:28;;;;;;;:41;;;45506:24;;;;;45499:31;45541:10;:16;;;;;-1:-1:-1;;;45541:16:0;;;;;;;;;;;;;;;;;;;;;;;;;;44486:1079;;;;:::o;41976:221::-;42061:14;42078:20;42095:2;42078:16;:20::i;:::-;-1:-1:-1;;;;;42109:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;42154:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;41976:221:0:o;841:444::-;1221:20;1269:8;;;841:444::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:408:1;;-1:-1:-1;;;;;106:6:1;103:30;100:2;;;136:18;;:::i;:::-;174:57;219:2;198:15;;-1:-1:-1;;194:29:1;225:4;190:40;174:57;:::i;:::-;165:66;;254:6;247:5;240:21;294:3;285:6;280:3;276:16;273:25;270:2;;;311:1;308;301:12;270:2;360:6;355:3;348:4;341:5;337:16;324:43;414:1;407:4;398:6;391:5;387:18;383:29;376:40;90:332;;;;;:::o;427:175::-;497:20;;-1:-1:-1;;;;;546:31:1;;536:42;;526:2;;592:1;589;582:12;607:378;;;725:3;718:4;710:6;706:17;702:27;692:2;;750:8;740;733:26;692:2;-1:-1:-1;780:20:1;;-1:-1:-1;;;;;812:30:1;;809:2;;;862:8;852;845:26;809:2;906:4;898:6;894:17;882:29;;958:3;951:4;942:6;934;930:19;926:30;923:39;920:2;;;975:1;972;965:12;990:233;;1088:3;1081:4;1073:6;1069:17;1065:27;1055:2;;1110:5;1103;1096:20;1055:2;1136:81;1213:3;1204:6;1191:20;1184:4;1176:6;1172:17;1136:81;:::i;1228:179::-;;1348:3;1339:6;1334:3;1330:16;1326:26;1323:2;;;1369:5;1362;1355:20;1323:2;-1:-1:-1;1395:6:1;1313:94;-1:-1:-1;1313:94:1:o;1412:198::-;;1524:2;1512:9;1503:7;1499:23;1495:32;1492:2;;;1545:6;1537;1530:22;1492:2;1573:31;1594:9;1573:31;:::i;1615:274::-;;;1744:2;1732:9;1723:7;1719:23;1715:32;1712:2;;;1765:6;1757;1750:22;1712:2;1793:31;1814:9;1793:31;:::i;:::-;1783:41;;1843:40;1879:2;1868:9;1864:18;1843:40;:::i;:::-;1833:50;;1702:187;;;;;:::o;1894:342::-;;;;2040:2;2028:9;2019:7;2015:23;2011:32;2008:2;;;2061:6;2053;2046:22;2008:2;2089:31;2110:9;2089:31;:::i;:::-;2079:41;;2139:40;2175:2;2164:9;2160:18;2139:40;:::i;:::-;2129:50;;2226:2;2215:9;2211:18;2198:32;2188:42;;1998:238;;;;;:::o;2241:702::-;;;;;2413:3;2401:9;2392:7;2388:23;2384:33;2381:2;;;2435:6;2427;2420:22;2381:2;2463:31;2484:9;2463:31;:::i;:::-;2453:41;;2513:40;2549:2;2538:9;2534:18;2513:40;:::i;:::-;2503:50;;2600:2;2589:9;2585:18;2572:32;2562:42;;2655:2;2644:9;2640:18;2627:32;-1:-1:-1;;;;;2674:6:1;2671:30;2668:2;;;2719:6;2711;2704:22;2668:2;2747:22;;2800:4;2792:13;;2788:27;-1:-1:-1;2778:2:1;;2834:6;2826;2819:22;2778:2;2862:75;2929:7;2924:2;2911:16;2906:2;2902;2898:11;2862:75;:::i;:::-;2852:85;;;2371:572;;;;;;;:::o;2948:742::-;;;;3112:2;3100:9;3091:7;3087:23;3083:32;3080:2;;;3133:6;3125;3118:22;3080:2;3161:31;3182:9;3161:31;:::i;:::-;3151:41;;3243:2;3232:9;3228:18;3215:32;-1:-1:-1;;;;;3307:2:1;3299:6;3296:14;3293:2;;;3328:6;3320;3313:22;3293:2;3371:6;3360:9;3356:22;3346:32;;3416:7;3409:4;3405:2;3401:13;3397:27;3387:2;;3443:6;3435;3428:22;3387:2;3488;3475:16;3514:2;3506:6;3503:14;3500:2;;;3535:6;3527;3520:22;3500:2;3594:7;3589:2;3583;3575:6;3571:15;3567:2;3563:24;3559:33;3556:46;3553:2;;;3620:6;3612;3605:22;3553:2;3656;3652;3648:11;3638:21;;3678:6;3668:16;;;;;3070:620;;;;;:::o;3695:369::-;;;3821:2;3809:9;3800:7;3796:23;3792:32;3789:2;;;3842:6;3834;3827:22;3789:2;3870:31;3891:9;3870:31;:::i;:::-;3860:41;;3951:2;3940:9;3936:18;3923:32;3998:5;3991:13;3984:21;3977:5;3974:32;3964:2;;4025:6;4017;4010:22;3964:2;4053:5;4043:15;;;3779:285;;;;;:::o;4069:266::-;;;4198:2;4186:9;4177:7;4173:23;4169:32;4166:2;;;4219:6;4211;4204:22;4166:2;4247:31;4268:9;4247:31;:::i;:::-;4237:41;4325:2;4310:18;;;;4297:32;;-1:-1:-1;;;4156:179:1:o;4340:626::-;;;;;;4530:3;4518:9;4509:7;4505:23;4501:33;4498:2;;;4552:6;4544;4537:22;4498:2;4580:31;4601:9;4580:31;:::i;:::-;4570:41;;4658:2;4647:9;4643:18;4630:32;4620:42;;4709:2;4698:9;4694:18;4681:32;4671:42;;4760:2;4749:9;4745:18;4732:32;4722:42;;4815:3;4804:9;4800:19;4787:33;-1:-1:-1;;;;;4835:6:1;4832:30;4829:2;;;4880:6;4872;4865:22;4829:2;4908:52;4952:7;4943:6;4932:9;4928:22;4908:52;:::i;:::-;4898:62;;;4488:478;;;;;;;;:::o;4971:1319::-;;;;;;;5203:3;5191:9;5182:7;5178:23;5174:33;5171:2;;;5225:6;5217;5210:22;5171:2;5253:31;5274:9;5253:31;:::i;:::-;5243:41;;5303:2;5352;5341:9;5337:18;5324:32;5314:42;;5403:2;5392:9;5388:18;5375:32;5365:42;;5454:2;5443:9;5439:18;5426:32;5416:42;;5505:3;5494:9;5490:19;5477:33;5467:43;;5561:3;5550:9;5546:19;5533:33;-1:-1:-1;;;;;5626:2:1;5618:6;5615:14;5612:2;;;5647:6;5639;5632:22;5612:2;5690:6;5679:9;5675:22;5665:32;;5735:7;5728:4;5724:2;5720:13;5716:27;5706:2;;5762:6;5754;5747:22;5706:2;5803;5790:16;5825:2;5821;5818:10;5815:2;;;5831:18;;:::i;:::-;5871:37;5904:2;5899;5895;5891:11;5887:20;5871:37;:::i;:::-;5942:15;;;5973:12;;;;-1:-1:-1;6005:11:1;;;6034:6;6049:211;6063:2;6060:1;6057:9;6049:211;;;6120:65;6177:7;6172:2;6165:3;6152:17;6148:2;6144:26;6140:35;6120:65;:::i;:::-;6108:78;;6206:12;;;;6238;;;;6081:1;6074:9;6049:211;;;6053:3;;6279:5;6269:15;;;;;;;5161:1129;;;;;;;;:::o;6295:365::-;;;6422:2;6410:9;6401:7;6397:23;6393:32;6390:2;;;6443:6;6435;6428:22;6390:2;6471:31;6492:9;6471:31;:::i;:::-;6461:41;;6552:2;6541:9;6537:18;6524:32;6596:4;6589:5;6585:16;6578:5;6575:27;6565:2;;6621:6;6613;6606:22;6665:257;;6776:2;6764:9;6755:7;6751:23;6747:32;6744:2;;;6797:6;6789;6782:22;6744:2;6841:9;6828:23;6860:32;6886:5;6860:32;:::i;6927:261::-;;7049:2;7037:9;7028:7;7024:23;7020:32;7017:2;;;7070:6;7062;7055:22;7017:2;7107:9;7101:16;7126:32;7152:5;7126:32;:::i;7193:433::-;;;7325:2;7313:9;7304:7;7300:23;7296:32;7293:2;;;7346:6;7338;7331:22;7293:2;7391:9;7378:23;-1:-1:-1;;;;;7416:6:1;7413:30;7410:2;;;7461:6;7453;7446:22;7410:2;7505:61;7558:7;7549:6;7538:9;7534:22;7505:61;:::i;:::-;7585:8;;7479:87;;-1:-1:-1;7283:343:1;-1:-1:-1;;;;7283:343:1:o;7631:190::-;;7743:2;7731:9;7722:7;7718:23;7714:32;7711:2;;;7764:6;7756;7749:22;7711:2;-1:-1:-1;7792:23:1;;7701:120;-1:-1:-1;7701:120:1:o;7826:501::-;;;;7975:2;7963:9;7954:7;7950:23;7946:32;7943:2;;;7996:6;7988;7981:22;7943:2;8037:9;8024:23;8014:33;;8098:2;8087:9;8083:18;8070:32;-1:-1:-1;;;;;8117:6:1;8114:30;8111:2;;;8162:6;8154;8147:22;8111:2;8206:61;8259:7;8250:6;8239:9;8235:22;8206:61;:::i;:::-;7933:394;;8286:8;;-1:-1:-1;8180:87:1;;-1:-1:-1;;;;7933:394:1:o;8332:471::-;;;8500:2;8488:9;8479:7;8475:23;8471:32;8468:2;;;8521:6;8513;8506:22;8468:2;8562:9;8549:23;8539:33;;8623:2;8612:9;8608:18;8595:32;-1:-1:-1;;;;;8642:6:1;8639:30;8636:2;;;8687:6;8679;8672:22;8636:2;8715:82;8789:7;8780:6;8769:9;8765:22;8715:82;:::i;:::-;8705:92;;;8458:345;;;;;:::o;8808:796::-;;;;9039:2;9027:9;9018:7;9014:23;9010:32;9007:2;;;9060:6;9052;9045:22;9007:2;9101:9;9088:23;9078:33;;9162:2;9151:9;9147:18;9134:32;-1:-1:-1;;;;;9226:2:1;9218:6;9215:14;9212:2;;;9247:6;9239;9232:22;9212:2;9275:82;9349:7;9340:6;9329:9;9325:22;9275:82;:::i;:::-;9265:92;;9410:2;9399:9;9395:18;9382:32;9366:48;;9439:2;9429:8;9426:16;9423:2;;;9460:6;9452;9445:22;9423:2;-1:-1:-1;9488:24:1;;9546:3;9528:16;;;9524:26;9521:2;;;9568:6;9560;9553:22;9521:2;9596;9586:12;;;8997:607;;;;;:::o;9609:258::-;;;9738:2;9726:9;9717:7;9713:23;9709:32;9706:2;;;9759:6;9751;9744:22;9706:2;-1:-1:-1;;9787:23:1;;;9857:2;9842:18;;;9829:32;;-1:-1:-1;9696:171:1:o;9872:326::-;;;;10018:2;10006:9;9997:7;9993:23;9989:32;9986:2;;;10039:6;10031;10024:22;9986:2;-1:-1:-1;;10067:23:1;;;10137:2;10122:18;;10109:32;;-1:-1:-1;10188:2:1;10173:18;;;10160:32;;9976:222;-1:-1:-1;9976:222:1:o;10203:259::-;;10284:5;10278:12;10311:6;10306:3;10299:19;10327:63;10383:6;10376:4;10371:3;10367:14;10360:4;10353:5;10349:16;10327:63;:::i;:::-;10444:2;10423:15;-1:-1:-1;;10419:29:1;10410:39;;;;10451:4;10406:50;;10254:208;-1:-1:-1;;10254:208:1:o;10467:695::-;;10560:5;10554:12;10589:36;10615:9;10589:36;:::i;:::-;10644:1;10661:18;;;10688:104;;;;10806:1;10801:355;;;;10654:502;;10688:104;-1:-1:-1;;10721:24:1;;10709:37;;10766:16;;;;-1:-1:-1;10688:104:1;;10801:355;10832:5;10829:1;10822:16;10861:4;10906:2;10903:1;10893:16;10931:1;10945:165;10959:6;10956:1;10953:13;10945:165;;;11037:14;;11024:11;;;11017:35;11080:16;;;;10974:10;;10945:165;;;10949:3;;;11139:6;11134:3;11130:16;11123:23;;10654:502;;;;;10527:635;;;;:::o;11167:716::-;;11283:5;11277:12;11310:4;11305:3;11298:17;11336:48;11378:4;11373:3;11369:14;11355:12;11336:48;:::i;:::-;11324:60;;11432:4;11425:5;11421:16;11415:23;11480:3;11474:4;11470:14;11463:4;11458:3;11454:14;11447:38;11508:40;11543:4;11527:14;11508:40;:::i;:::-;11494:54;;;11596:4;11589:5;11585:16;11579:23;11646:3;11638:6;11634:16;11627:4;11622:3;11618:14;11611:40;11674:42;11709:6;11693:14;11674:42;:::i;:::-;11660:56;;;11764:4;11757:5;11753:16;11747:23;11814:3;11806:6;11802:16;11795:4;11790:3;11786:14;11779:40;11835:42;11870:6;11854:14;11835:42;:::i;:::-;11828:49;11247:636;-1:-1:-1;;;;;11247:636:1:o;11888:470::-;;12105:6;12099:13;12121:53;12167:6;12162:3;12155:4;12147:6;12143:17;12121:53;:::i;:::-;12237:13;;12196:16;;;;12259:57;12237:13;12196:16;12293:4;12281:17;;12259:57;:::i;:::-;12332:20;;12075:283;-1:-1:-1;;;;12075:283:1:o;12363:358::-;;12577:6;12571:13;12593:53;12639:6;12634:3;12627:4;12619:6;12615:17;12593:53;:::i;:::-;12662;12707:6;12702:3;12698:16;12690:6;12662:53;:::i;12726:503::-;;12996:6;12990:13;13012:53;13058:6;13053:3;13046:4;13038:6;13034:17;13012:53;:::i;:::-;13126:66;13087:16;;13112:81;;;-1:-1:-1;13220:2:1;13209:14;;12966:263;-1:-1:-1;12966:263:1:o;13234:568::-;;13504:6;13498:13;13520:53;13566:6;13561:3;13554:4;13546:6;13542:17;13520:53;:::i;:::-;13634:66;13595:16;;13620:81;;;-1:-1:-1;;;;13728:4:1;13717:16;;13710:56;13793:2;13782:14;;13474:328;-1:-1:-1;13474:328:1:o;13807:503::-;;14077:6;14071:13;14093:53;14139:6;14134:3;14127:4;14119:6;14115:17;14093:53;:::i;:::-;14207:66;14168:16;;14193:81;;;-1:-1:-1;14301:2:1;14290:14;;14047:263;-1:-1:-1;14047:263:1:o;14315:453::-;;14585:6;14579:13;14601:53;14647:6;14642:3;14635:4;14627:6;14623:17;14601:53;:::i;:::-;-1:-1:-1;;;14676:16:1;;14701:32;;;-1:-1:-1;14760:1:1;14749:13;;14555:213;-1:-1:-1;14555:213:1:o;14773:503::-;;15043:6;15037:13;15059:53;15105:6;15100:3;15093:4;15085:6;15081:17;15059:53;:::i;:::-;15173:66;15134:16;;15159:81;;;-1:-1:-1;15267:2:1;15256:14;;15013:263;-1:-1:-1;15013:263:1:o;15281:492::-;;15551:6;15545:13;15567:53;15613:6;15608:3;15601:4;15593:6;15589:17;15567:53;:::i;:::-;-1:-1:-1;;;15642:16:1;;15667:70;;;-1:-1:-1;15764:2:1;15753:14;;15521:252;-1:-1:-1;15521:252:1:o;15778:487::-;;16048:6;16042:13;16064:53;16110:6;16105:3;16098:4;16090:6;16086:17;16064:53;:::i;:::-;-1:-1:-1;;;16139:16:1;;16164:65;;;-1:-1:-1;16256:2:1;16245:14;;16018:247;-1:-1:-1;16018:247:1:o;16270:503::-;;16540:6;16534:13;16556:53;16602:6;16597:3;16590:4;16582:6;16578:17;16556:53;:::i;:::-;16670:66;16631:16;;16656:81;;;-1:-1:-1;16764:2:1;16753:14;;16510:263;-1:-1:-1;16510:263:1:o;16778:439::-;;17048:6;17042:13;17064:53;17110:6;17105:3;17098:4;17090:6;17086:17;17064:53;:::i;:::-;-1:-1:-1;;;17139:16:1;;17164:18;;;-1:-1:-1;17209:1:1;17198:13;;17018:199;-1:-1:-1;17018:199:1:o;17222:566::-;;17492:6;17486:13;17508:53;17554:6;17549:3;17542:4;17534:6;17530:17;17508:53;:::i;:::-;17622:66;17583:16;;17608:81;;;-1:-1:-1;;;;17716:4:1;17705:16;;17698:54;17779:2;17768:14;;17462:326;-1:-1:-1;17462:326:1:o;17793:503::-;;18063:6;18057:13;18079:53;18125:6;18120:3;18113:4;18105:6;18101:17;18079:53;:::i;:::-;18193:66;18154:16;;18179:81;;;-1:-1:-1;18287:2:1;18276:14;;18033:263;-1:-1:-1;18033:263:1:o;18301:492::-;;18571:6;18565:13;18587:53;18633:6;18628:3;18621:4;18613:6;18609:17;18587:53;:::i;:::-;-1:-1:-1;;;18662:16:1;;18687:70;;;-1:-1:-1;18784:2:1;18773:14;;18541:252;-1:-1:-1;18541:252:1:o;18798:442::-;;19068:6;19062:13;19084:53;19130:6;19125:3;19118:4;19110:6;19106:17;19084:53;:::i;:::-;-1:-1:-1;;;19159:16:1;;19184:21;;;-1:-1:-1;19232:1:1;19221:13;;19038:202;-1:-1:-1;19038:202:1:o;19245:604::-;;19515:6;19509:13;19531:53;19577:6;19572:3;19565:4;19557:6;19553:17;19531:53;:::i;:::-;19645:66;19606:16;;19631:81;;;-1:-1:-1;19746:66:1;19739:4;19728:16;;19721:92;19840:2;19829:14;;19485:364;-1:-1:-1;19485:364:1:o;19854:473::-;;20124:6;20118:13;20140:53;20186:6;20181:3;20174:4;20166:6;20162:17;20140:53;:::i;:::-;-1:-1:-1;;;20215:16:1;;20240:51;;;-1:-1:-1;20318:2:1;20307:14;;20094:233;-1:-1:-1;20094:233:1:o;20332:477::-;;20602:6;20596:13;20618:53;20664:6;20659:3;20652:4;20644:6;20640:17;20618:53;:::i;:::-;-1:-1:-1;;;20693:16:1;;20718:55;;;-1:-1:-1;20800:2:1;20789:14;;20572:237;-1:-1:-1;20572:237:1:o;20814:449::-;;21084:6;21078:13;21100:53;21146:6;21141:3;21134:4;21126:6;21122:17;21100:53;:::i;:::-;-1:-1:-1;;;21175:16:1;;21200:27;;;-1:-1:-1;21254:2:1;21243:14;;21054:209;-1:-1:-1;21054:209:1:o;21268:456::-;;21538:6;21532:13;21554:53;21600:6;21595:3;21588:4;21580:6;21576:17;21554:53;:::i;:::-;-1:-1:-1;;;21629:16:1;;21654:35;;;-1:-1:-1;21716:1:1;21705:13;;21508:216;-1:-1:-1;21508:216:1:o;21729:503::-;;21999:6;21993:13;22015:53;22061:6;22056:3;22049:4;22041:6;22037:17;22015:53;:::i;:::-;22129:66;22090:16;;22115:81;;;-1:-1:-1;22223:2:1;22212:14;;21969:263;-1:-1:-1;21969:263:1:o;22237:485::-;;22507:6;22501:13;22523:53;22569:6;22564:3;22557:4;22549:6;22545:17;22523:53;:::i;:::-;-1:-1:-1;;;22598:16:1;;22623:63;;;-1:-1:-1;22713:2:1;22702:14;;22477:245;-1:-1:-1;22477:245:1:o;22727:492::-;;22997:6;22991:13;23013:53;23059:6;23054:3;23047:4;23039:6;23035:17;23013:53;:::i;:::-;-1:-1:-1;;;23088:16:1;;23113:70;;;-1:-1:-1;23210:2:1;23199:14;;22967:252;-1:-1:-1;22967:252:1:o;23224:450::-;;23494:6;23488:13;23510:53;23556:6;23551:3;23544:4;23536:6;23532:17;23510:53;:::i;:::-;-1:-1:-1;;;23585:16:1;;23610:29;;;-1:-1:-1;23666:1:1;23655:13;;23464:210;-1:-1:-1;23464:210:1:o;23679:378::-;;23883:40;23919:3;23911:6;23883:40;:::i;:::-;23952:6;23946:13;23968:52;24013:6;24009:2;24002:4;23994:6;23990:17;23968:52;:::i;24062:281::-;;24260:77;24296:40;24332:3;24324:6;24296:40;:::i;:::-;24288:6;24260:77;:::i;24348:455::-;-1:-1:-1;;;24598:51:1;;24672:13;;24348:455;;24694:62;24672:13;24744:2;24735:12;;24728:4;24716:17;;24694:62;:::i;:::-;24776:16;;;;24794:2;24772:25;;24588:215;-1:-1:-1;;24588:215:1:o;24808:203::-;-1:-1:-1;;;;;24972:32:1;;;;24954:51;;24942:2;24927:18;;24909:102::o;25016:490::-;-1:-1:-1;;;;;25285:15:1;;;25267:34;;25337:15;;25332:2;25317:18;;25310:43;25384:2;25369:18;;25362:34;;;25432:3;25427:2;25412:18;;25405:31;;;25016:490;;25453:47;;25480:19;;25472:6;25453:47;:::i;:::-;25445:55;25219:287;-1:-1:-1;;;;;;25219:287:1:o;25511:187::-;25676:14;;25669:22;25651:41;;25639:2;25624:18;;25606:92::o;25703:393::-;;25862:2;25851:9;25844:21;25901:6;25896:2;25885:9;25881:18;25874:34;25958:6;25950;25945:2;25934:9;25930:18;25917:48;25985:22;;;26009:2;25981:31;;;25974:45;;;;26080:2;26059:15;;;-1:-1:-1;;26055:29:1;26040:45;26036:54;;25834:262;-1:-1:-1;25834:262:1:o;26101:221::-;;26250:2;26239:9;26232:21;26270:46;26312:2;26301:9;26297:18;26289:6;26270:46;:::i;26327:407::-;26529:2;26511:21;;;26568:2;26548:18;;;26541:30;26607:34;26602:2;26587:18;;26580:62;-1:-1:-1;;;26673:2:1;26658:18;;26651:41;26724:3;26709:19;;26501:233::o;26739:414::-;26941:2;26923:21;;;26980:2;26960:18;;;26953:30;27019:34;27014:2;26999:18;;26992:62;-1:-1:-1;;;27085:2:1;27070:18;;27063:48;27143:3;27128:19;;26913:240::o;27158:402::-;27360:2;27342:21;;;27399:2;27379:18;;;27372:30;27438:34;27433:2;27418:18;;27411:62;-1:-1:-1;;;27504:2:1;27489:18;;27482:36;27550:3;27535:19;;27332:228::o;27565:352::-;27767:2;27749:21;;;27806:2;27786:18;;;27779:30;27845;27840:2;27825:18;;27818:58;27908:2;27893:18;;27739:178::o;27922:346::-;28124:2;28106:21;;;28163:2;28143:18;;;28136:30;-1:-1:-1;;;28197:2:1;28182:18;;28175:52;28259:2;28244:18;;28096:172::o;28273:398::-;28475:2;28457:21;;;28514:2;28494:18;;;28487:30;28553:34;28548:2;28533:18;;28526:62;-1:-1:-1;;;28619:2:1;28604:18;;28597:32;28661:3;28646:19;;28447:224::o;28676:400::-;28878:2;28860:21;;;28917:2;28897:18;;;28890:30;28956:34;28951:2;28936:18;;28929:62;-1:-1:-1;;;29022:2:1;29007:18;;29000:34;29066:3;29051:19;;28850:226::o;29081:349::-;29283:2;29265:21;;;29322:2;29302:18;;;29295:30;29361:27;29356:2;29341:18;;29334:55;29421:2;29406:18;;29255:175::o;29435:344::-;29637:2;29619:21;;;29676:2;29656:18;;;29649:30;-1:-1:-1;;;29710:2:1;29695:18;;29688:50;29770:2;29755:18;;29609:170::o;29784:408::-;29986:2;29968:21;;;30025:2;30005:18;;;29998:30;30064:34;30059:2;30044:18;;30037:62;-1:-1:-1;;;30130:2:1;30115:18;;30108:42;30182:3;30167:19;;29958:234::o;30197:341::-;30399:2;30381:21;;;30438:2;30418:18;;;30411:30;-1:-1:-1;;;30472:2:1;30457:18;;30450:47;30529:2;30514:18;;30371:167::o;30543:420::-;30745:2;30727:21;;;30784:2;30764:18;;;30757:30;30823:34;30818:2;30803:18;;30796:62;30894:26;30889:2;30874:18;;30867:54;30953:3;30938:19;;30717:246::o;30968:406::-;31170:2;31152:21;;;31209:2;31189:18;;;31182:30;31248:34;31243:2;31228:18;;31221:62;-1:-1:-1;;;31314:2:1;31299:18;;31292:40;31364:3;31349:19;;31142:232::o;31379:405::-;31581:2;31563:21;;;31620:2;31600:18;;;31593:30;31659:34;31654:2;31639:18;;31632:62;-1:-1:-1;;;31725:2:1;31710:18;;31703:39;31774:3;31759:19;;31553:231::o;31789:356::-;31991:2;31973:21;;;32010:18;;;32003:30;32069:34;32064:2;32049:18;;32042:62;32136:2;32121:18;;31963:182::o;32150:408::-;32352:2;32334:21;;;32391:2;32371:18;;;32364:30;32430:34;32425:2;32410:18;;32403:62;-1:-1:-1;;;32496:2:1;32481:18;;32474:42;32548:3;32533:19;;32324:234::o;32563:408::-;32765:2;32747:21;;;32804:2;32784:18;;;32777:30;32843:34;32838:2;32823:18;;32816:62;-1:-1:-1;;;32909:2:1;32894:18;;32887:42;32961:3;32946:19;;32737:234::o;32976:356::-;33178:2;33160:21;;;33197:18;;;33190:30;33256:34;33251:2;33236:18;;33229:62;33323:2;33308:18;;33150:182::o;33337:405::-;33539:2;33521:21;;;33578:2;33558:18;;;33551:30;33617:34;33612:2;33597:18;;33590:62;-1:-1:-1;;;33683:2:1;33668:18;;33661:39;33732:3;33717:19;;33511:231::o;33747:411::-;33949:2;33931:21;;;33988:2;33968:18;;;33961:30;34027:34;34022:2;34007:18;;34000:62;-1:-1:-1;;;34093:2:1;34078:18;;34071:45;34148:3;34133:19;;33921:237::o;34163:397::-;34365:2;34347:21;;;34404:2;34384:18;;;34377:30;34443:34;34438:2;34423:18;;34416:62;-1:-1:-1;;;34509:2:1;34494:18;;34487:31;34550:3;34535:19;;34337:223::o;34565:403::-;34767:2;34749:21;;;34806:2;34786:18;;;34779:30;34845:34;34840:2;34825:18;;34818:62;-1:-1:-1;;;34911:2:1;34896:18;;34889:37;34958:3;34943:19;;34739:229::o;34973:413::-;35175:2;35157:21;;;35214:2;35194:18;;;35187:30;35253:34;35248:2;35233:18;;35226:62;-1:-1:-1;;;35319:2:1;35304:18;;35297:47;35376:3;35361:19;;35147:239::o;35391:408::-;35593:2;35575:21;;;35632:2;35612:18;;;35605:30;35671:34;35666:2;35651:18;;35644:62;-1:-1:-1;;;35737:2:1;35722:18;;35715:42;35789:3;35774:19;;35565:234::o;35804:340::-;36006:2;35988:21;;;36045:2;36025:18;;;36018:30;-1:-1:-1;;;36079:2:1;36064:18;;36057:46;36135:2;36120:18;;35978:166::o;36149:2062::-;;36468:2;36457:9;36450:21;36513:6;36507:13;36502:2;36491:9;36487:18;36480:41;36568:4;36560:6;36556:17;36550:24;36593:6;36635:2;36630;36619:9;36615:18;36608:30;36661:53;36709:3;36698:9;36694:19;36680:12;36661:53;:::i;:::-;36647:67;;36763:2;36755:6;36751:15;36745:22;36790:2;36786:7;36858:2;36846:9;36838:6;36834:22;36830:31;36824:3;36813:9;36809:19;36802:60;36885:42;36920:6;36904:14;36885:42;:::i;:::-;36871:56;;36976:2;36968:6;36964:15;36958:22;36936:44;;37045:2;37033:9;37025:6;37021:22;37017:31;37011:3;37000:9;36996:19;36989:60;37072:42;37107:6;37091:14;37072:42;:::i;:::-;37058:56;;37163:3;37155:6;37151:16;37145:23;37123:45;;37233:2;37221:9;37213:6;37209:22;37205:31;37199:3;37188:9;37184:19;37177:60;37260:42;37295:6;37279:14;37260:42;:::i;:::-;37246:56;;37351:3;37343:6;37339:16;37333:23;37311:45;;37421:2;37409:9;37401:6;37397:22;37393:31;37387:3;37376:9;37372:19;37365:60;37448:42;37483:6;37467:14;37448:42;:::i;:::-;37434:56;;37539:3;37531:6;37527:16;37521:23;37499:45;;37563:3;37630:2;37618:9;37610:6;37606:22;37602:31;37597:2;37586:9;37582:18;37575:59;37657:42;37692:6;37676:14;37657:42;:::i;:::-;37643:56;;37748:3;37740:6;37736:16;37730:23;37708:45;;37817:2;37805:9;37797:6;37793:22;37789:31;37784:2;37773:9;37769:18;37762:59;37844:42;37879:6;37863:14;37844:42;:::i;:::-;37830:56;;37935:2;37927:6;37923:15;37917:22;37895:44;;;38004:2;37992:9;37984:6;37980:22;37976:31;37970:3;37959:9;37955:19;37948:60;;;38028:42;38063:6;38047:14;38028:42;:::i;:::-;38017:53;;;38117:9;38112:3;38108:19;38101:4;38090:9;38086:20;38079:49;38145:60;38201:3;38193:6;38145:60;:::i;38216:177::-;38362:25;;;38350:2;38335:18;;38317:76::o;38398:184::-;38570:4;38558:17;;;;38540:36;;38528:2;38513:18;;38495:87::o;38587:530::-;;;38727:11;38714:25;38821:2;38817:7;38806:8;38790:14;38786:29;38782:43;38762:18;38758:68;38748:2;;38843:4;38837;38830:18;38748:2;38873:33;;38925:20;;;-1:-1:-1;;;;;;38957:30:1;;38954:2;;;39003:4;38997;38990:18;38954:2;39039:4;39027:17;;-1:-1:-1;39070:14:1;39066:27;;;39056:38;;39053:2;;;39107:1;39104;39097:12;39122:275;39193:2;39187:9;39258:2;39239:13;;-1:-1:-1;;39235:27:1;39223:40;;-1:-1:-1;;;;;39278:34:1;;39314:22;;;39275:62;39272:2;;;39340:18;;:::i;:::-;39376:2;39369:22;39167:230;;-1:-1:-1;39167:230:1:o;39402:129::-;;39470:17;;;39520:4;39504:21;;;39460:71::o;39536:128::-;;39607:1;39603:6;39600:1;39597:13;39594:2;;;39613:18;;:::i;:::-;-1:-1:-1;39649:9:1;;39584:80::o;39669:120::-;;39735:1;39725:2;;39740:18;;:::i;:::-;-1:-1:-1;39774:9:1;;39715:74::o;39794:168::-;;39900:1;39896;39892:6;39888:14;39885:1;39882:21;39877:1;39870:9;39863:17;39859:45;39856:2;;;39907:18;;:::i;:::-;-1:-1:-1;39947:9:1;;39846:116::o;39967:125::-;;40035:1;40032;40029:8;40026:2;;;40040:18;;:::i;:::-;-1:-1:-1;40077:9:1;;40016:76::o;40097:148::-;40161:78;40179:3;40172:5;40169:14;40161:78;;;40235:1;40221:16;;40206:1;40195:13;40161:78;;40250:1594;-1:-1:-1;;;;;40365:3:1;40362:27;40359:2;;;40392:18;;:::i;:::-;40435:38;40467:4;40461:11;40435:38;:::i;:::-;40499:1;40528:9;40564:2;40559:3;40556:11;40597:2;40589:6;40586:14;40619:2;40615;40612:10;40609:2;;;40660:37;40692:4;40660:37;:::i;:::-;40645:52;;40609:2;40719;40716;;;40798;40793;40788:3;40784:12;40780:21;40767:11;40763:39;40826:2;40821:3;40818:11;40815:2;;;-1:-1:-1;40847:11:1;40815:2;40873:85;40953:2;40948;40940:6;40936:15;40932:24;40919:11;40915:42;40902:11;40873:85;:::i;:::-;;40716:2;;40984;41000:1;40995:591;;;;41630:1;41617:14;;41647:3;41644:2;;;41712:9;41707:3;41703:19;41690:33;41681:42;;41644:2;41763:64;41823:3;41816:5;41763:64;:::i;:::-;41757:4;41750:78;40977:861;;40995:591;-1:-1:-1;;41031:17:1;;;-1:-1:-1;41075:11:1;41108:9;41130:229;41144:7;41141:1;41138:14;41130:229;;;41233:19;;;41220:33;41205:49;;41340:4;41325:20;;;;41293:1;41281:14;;;;41160:12;41130:229;;;41134:3;41387;41378:7;41375:16;41372:2;;;41454:19;;;41441:33;-1:-1:-1;;41488:1:1;41500:2;41491:12;;41484:20;41480:33;41476:38;41437:78;41422:94;;41372:2;;41573:1;41569;41564:3;41560:11;41556:19;41550:4;41543:33;40977:861;;;;;;40349:1495;;;:::o;41849:258::-;41921:1;41931:113;41945:6;41942:1;41939:13;41931:113;;;42021:11;;;42015:18;42002:11;;;41995:39;41967:2;41960:10;41931:113;;;42062:6;42059:1;42056:13;42053:2;;;-1:-1:-1;;42097:1:1;42079:16;;42072:27;41902:205::o;42112:380::-;42197:1;42187:12;;42244:1;42234:12;;;42255:2;;42309:4;42301:6;42297:17;42287:27;;42255:2;42362;42354:6;42351:14;42331:18;42328:38;42325:2;;;42408:10;42403:3;42399:20;42396:1;42389:31;42443:4;42440:1;42433:15;42471:4;42468:1;42461:15;42497:166;-1:-1:-1;;42625:1:1;42621:11;;42617:24;42613:29;42603:40;42649:1;42645:11;;;42600:57;;42582:81::o;42668:135::-;;-1:-1:-1;;42728:17:1;;42725:2;;;42748:18;;:::i;:::-;-1:-1:-1;42795:1:1;42784:13;;42715:88::o;42808:112::-;;42866:1;42856:2;;42871:18;;:::i;:::-;-1:-1:-1;42905:9:1;;42846:74::o;42925:127::-;42986:10;42981:3;42977:20;42974:1;42967:31;43017:4;43014:1;43007:15;43041:4;43038:1;43031:15;43057:127;43118:10;43113:3;43109:20;43106:1;43099:31;43149:4;43146:1;43139:15;43173:4;43170:1;43163:15;43189:127;43250:10;43245:3;43241:20;43238:1;43231:31;43281:4;43278:1;43271:15;43305:4;43302:1;43295:15;43321:2569;43530:52;43576:5;43569;43530:52;:::i;:::-;-1:-1:-1;;;;;43597:13:1;43594:37;43591:2;;;43634:18;;:::i;:::-;43677:38;43709:4;43703:11;43677:38;:::i;:::-;43741:1;43770:9;43816:2;43801:13;43798:21;43849:2;43841:6;43838:14;43871:2;43867;43864:10;43861:2;;;43912:37;43944:4;43912:37;:::i;:::-;43897:52;;43861:2;43971;43968;;;44060;44055;44040:13;44036:22;44032:31;44019:11;44015:49;44098:2;44083:13;44080:21;44077:2;;;-1:-1:-1;44119:11:1;44077:2;44145:85;44225:2;44220;44212:6;44208:15;44204:24;44191:11;44187:42;44174:11;44145:85;:::i;:::-;;43968:2;;44256;44272:1;44267:647;;;;44960:1;44945:16;;44977:13;44974:2;;;45062:9;45049:11;45045:27;45032:41;45021:52;;44974:2;45113:76;45175:13;45166:7;45113:76;:::i;:::-;45107:4;45100:90;44249:951;;44267:647;-1:-1:-1;;44303:27:1;;;-1:-1:-1;44357:11:1;44390:9;44412:237;44426:7;44423:1;44420:14;44412:237;;;44515:27;;;44502:41;44487:57;;44630:4;44615:20;;;;44583:1;44571:14;;;;44442:12;44412:237;;;44416:3;44677:13;44668:7;44665:26;44662:2;;;44754:27;;;44741:41;-1:-1:-1;;44796:1:1;44818:2;44799:22;;44792:30;44788:43;44784:48;44737:96;44722:112;;44662:2;;44901:1;44897;44882:13;44878:21;44874:29;44868:4;44861:43;44249:951;;;;;;;;45245:61;45302:2;45295:5;45291:14;45284:5;45245:61;:::i;:::-;45315:113;45414:13;45399;45395:1;45389:4;45385:12;45315:113;:::i;:::-;;;45473:61;45530:2;45523:5;45519:14;45512:5;45473:61;:::i;:::-;45543:113;45642:13;45627;45623:1;45617:4;45613:12;45543:113;:::i;:::-;;;45701:61;45758:2;45751:5;45747:14;45740:5;45701:61;:::i;:::-;45771:113;45870:13;45855;45851:1;45845:4;45841:12;45771:113;:::i;45895:2037::-;46082:5;46069:19;46063:4;46056:33;46132:61;46189:2;46182:5;46178:14;46171:5;46132:61;:::i;:::-;46202:111;46299:13;46286:11;46282:1;46276:4;46272:12;46202:111;:::i;:::-;;;46358:61;46415:2;46408:5;46404:14;46397:5;46358:61;:::i;:::-;46428:113;46527:13;46512;46508:1;46502:4;46498:12;46428:113;:::i;:::-;;;46586:61;46643:2;46636:5;46632:14;46625:5;46586:61;:::i;:::-;46656:113;46755:13;46740;46736:1;46730:4;46726:12;46656:113;:::i;:::-;;;46814:62;46871:3;46864:5;46860:15;46853:5;46814:62;:::i;:::-;46885:113;46984:13;46969;46965:1;46959:4;46955:12;46885:113;:::i;:::-;;;47043:62;47100:3;47093:5;47089:15;47082:5;47043:62;:::i;:::-;47114:113;47213:13;47198;47194:1;47188:4;47184:12;47114:113;:::i;:::-;;;47274:62;47331:3;47324:5;47320:15;47313:5;47274:62;:::i;:::-;47345:115;47445:14;47429;47425:1;47419:4;47415:12;47345:115;:::i;:::-;;;47507:62;47564:3;47557:5;47553:15;47546:5;47507:62;:::i;:::-;47578:115;47678:14;47662;47658:1;47652:4;47648:12;47578:115;:::i;:::-;;;47740:62;47797:3;47790:5;47786:15;47779:5;47740:62;:::i;:::-;47811:115;47911:14;47895;47891:1;47885:4;47881:12;47811:115;:::i;47937:133::-;-1:-1:-1;;;;;;48013:32:1;;48003:43;;47993:2;;48060:1;48057;48050:12;47993:2;47983:87;:::o

Swarm Source

ipfs://9f8cbc42b7f9fb994edadbfb0a2f8ac4451bc42c2991eccc64186c6f6c33fcb8

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