ETH Price: $3,482.70 (-0.24%)

Token

Feral File — Peer to Peer (FF024)
 

Overview

Max Total Supply

746 FF024

Holders

424

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
2 FF024
0x4b7fd3e7ae0fc78f1338e7880b25096d8322e486
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
FeralfileExhibitionV3_3

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-11-26
*/

// File: github/bitmark-inc/feralfile-exhibition-smart-contract/FF_V3_3_AKG%2BV3_2/contracts/operator-filter-registry/IOperatorFilterRegistry.sol


pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);
    function register(address registrant) external;
    function registerAndSubscribe(address registrant, address subscription) external;
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;
    function unregister(address addr) external;
    function updateOperator(address registrant, address operator, bool filtered) external;
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
    function subscribe(address registrant, address registrantToSubscribe) external;
    function unsubscribe(address registrant, bool copyExistingEntries) external;
    function subscriptionOf(address addr) external returns (address registrant);
    function subscribers(address registrant) external returns (address[] memory);
    function subscriberAt(address registrant, uint256 index) external returns (address);
    function copyEntriesOf(address registrant, address registrantToCopy) external;
    function isOperatorFiltered(address registrant, address operator) external returns (bool);
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
    function filteredOperators(address addr) external returns (address[] memory);
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
    function isRegistered(address addr) external returns (bool);
    function codeHashOf(address addr) external returns (bytes32);
}

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


// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // 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
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

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


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @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 `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

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


// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

// File: @openzeppelin/contracts/interfaces/IERC2981.sol


// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 *
 * _Available since v4.5._
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}

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


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;


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

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


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;


/**
 * @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`.
     *
     * 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 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 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * 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 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 the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

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

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;


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

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

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;


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

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

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

// File: github/bitmark-inc/feralfile-exhibition-smart-contract/FF_V3_3_AKG%2BV3_2/contracts/Decentraland.sol


pragma solidity ^0.8.0;

// Decentraland interface
contract Decentraland {
    function ownerOf(uint256 tokenId) public view returns (address) {}
}

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


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

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


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;


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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

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

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

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

// File: github/bitmark-inc/feralfile-exhibition-smart-contract/FF_V3_3_AKG%2BV3_2/contracts/Authorizable.sol


pragma solidity >=0.4.22 <0.9.0;


contract Authorizable is Ownable {
    mapping(address => bool) public trustees;

    constructor() {}

    modifier onlyAuthorized() {
        require(trustees[msg.sender] || msg.sender == owner());
        _;
    }

    function addTrustee(address _trustee) public onlyOwner {
        trustees[_trustee] = true;
    }

    function removeTrustee(address _trustee) public onlyOwner {
        delete trustees[_trustee];
    }
}

// File: github/bitmark-inc/feralfile-exhibition-smart-contract/FF_V3_3_AKG%2BV3_2/contracts/UpdateableOperatorFilterer.sol


pragma solidity ^0.8.13;



/**
 * @title  UpdateableOperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 */
abstract contract UpdateableOperatorFilterer is Authorizable {
    error OperatorNotAllowed(address operator);

    address constant DEFAULT_OPERATOR_FILTER_REGISTRY_ADDRESS =
        address(0x000000000000AAeB6D7670E522A718067333cd4E);

    address constant DEFAULT_SUBSCRIPTION =
        address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    IOperatorFilterRegistry public OperatorFilterRegistry =
        IOperatorFilterRegistry(DEFAULT_OPERATOR_FILTER_REGISTRY_ADDRESS);

    constructor() {
        if (address(OperatorFilterRegistry).code.length > 0) {
            OperatorFilterRegistry.registerAndSubscribe(
                address(this),
                DEFAULT_SUBSCRIPTION
            );
        }
    }

    modifier onlyAllowedOperator(address from) virtual {
        // Allow spending tokens from addresses with balance
        // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
        // from an EOA.
        if (from != msg.sender) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    function _checkFilterOperator(address operator) internal view virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(OperatorFilterRegistry).code.length > 0) {
            require(
                OperatorFilterRegistry.isOperatorAllowed(
                    address(this),
                    operator
                ),
                "operator is not allowed"
            );
        }
    }

    /**
     * @notice update the operator filter registry
     */
    function updateOperatorFilterRegistry(address operatorFilterRegisterAddress)
        external
        onlyOwner
    {
        OperatorFilterRegistry = IOperatorFilterRegistry(
            operatorFilterRegisterAddress
        );
    }
}

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


// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides a set of functions to operate with Base64 strings.
 *
 * _Available since v4.5._
 */
library Base64 {
    /**
     * @dev Base64 Encoding/Decoding Table
     */
    string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /**
     * @dev Converts a `bytes` to its Bytes64 `string` representation.
     */
    function encode(bytes memory data) internal pure returns (string memory) {
        /**
         * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence
         * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol
         */
        if (data.length == 0) return "";

        // Loads the table into memory
        string memory table = _TABLE;

        // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter
        // and split into 4 numbers of 6 bits.
        // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up
        // - `data.length + 2`  -> Round up
        // - `/ 3`              -> Number of 3-bytes chunks
        // - `4 *`              -> 4 characters for each chunk
        string memory result = new string(4 * ((data.length + 2) / 3));

        /// @solidity memory-safe-assembly
        assembly {
            // Prepare the lookup table (skip the first "length" byte)
            let tablePtr := add(table, 1)

            // Prepare result pointer, jump over length
            let resultPtr := add(result, 32)

            // Run over the input, 3 bytes at a time
            for {
                let dataPtr := data
                let endPtr := add(data, mload(data))
            } lt(dataPtr, endPtr) {

            } {
                // Advance 3 bytes
                dataPtr := add(dataPtr, 3)
                let input := mload(dataPtr)

                // To write each character, shift the 3 bytes (18 bits) chunk
                // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)
                // and apply logical AND with 0x3F which is the number of
                // the previous character in the ASCII table prior to the Base64 Table
                // The result is then added to the table to get the character to write,
                // and finally write it in the result pointer but with a left shift
                // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits

                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance
            }

            // When data `bytes` is not exactly 3 bytes long
            // it is padded with `=` characters at the end
            switch mod(mload(data), 3)
            case 1 {
                mstore8(sub(resultPtr, 1), 0x3d)
                mstore8(sub(resultPtr, 2), 0x3d)
            }
            case 2 {
                mstore8(sub(resultPtr, 1), 0x3d)
            }
        }

        return result;
    }
}

// File: @openzeppelin/contracts/utils/math/Math.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

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

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

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

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

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10**64) {
                value /= 10**64;
                result += 64;
            }
            if (value >= 10**32) {
                value /= 10**32;
                result += 32;
            }
            if (value >= 10**16) {
                value /= 10**16;
                result += 16;
            }
            if (value >= 10**8) {
                value /= 10**8;
                result += 8;
            }
            if (value >= 10**4) {
                value /= 10**4;
                result += 4;
            }
            if (value >= 10**2) {
                value /= 10**2;
                result += 2;
            }
            if (value >= 10**1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
        }
    }
}

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


// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)

pragma solidity ^0.8.0;


/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @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] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

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


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;








/**
 * @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: address zero is not a valid owner");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _ownerOf(tokenId);
        require(owner != address(0), "ERC721: invalid token ID");
        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) {
        _requireMinted(tokenId);

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

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overridden 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 token owner or approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_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: caller is not token owner or 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: caller is not token owner or 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 the owner of the `tokenId`. Does NOT revert if token doesn't exist
     */
    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
        return _owners[tokenId];
    }

    /**
     * @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 _ownerOf(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) {
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == 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, 1);

        // Check that tokenId was not minted by `_beforeTokenTransfer` hook
        require(!_exists(tokenId), "ERC721: token already minted");

        unchecked {
            // Will not overflow unless all 2**256 token ids are minted to the same owner.
            // Given that tokens are minted one by one, it is impossible in practice that
            // this ever happens. Might change if we allow batch minting.
            // The ERC fails to describe this case.
            _balances[to] += 1;
        }

        _owners[tokenId] = to;

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

        _afterTokenTransfer(address(0), to, tokenId, 1);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     * This is an internal function that does not check if the sender is authorized to operate on the token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

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

        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
        owner = ERC721.ownerOf(tokenId);

        // Clear approvals
        delete _tokenApprovals[tokenId];

        unchecked {
            // Cannot overflow, as that would require more tokens to be burned/transferred
            // out than the owner initially received through minting and transferring in.
            _balances[owner] -= 1;
        }
        delete _owners[tokenId];

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

        _afterTokenTransfer(owner, address(0), tokenId, 1);
    }

    /**
     * @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 from incorrect owner");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId, 1);

        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");

        // Clear approvals from the previous owner
        delete _tokenApprovals[tokenId];

        unchecked {
            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:
            // `from`'s balance is the number of token held, which is at least one before the current
            // transfer.
            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require
            // all 2**256 token ids to be minted, which in practice is impossible.
            _balances[from] -= 1;
            _balances[to] += 1;
        }
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId, 1);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits an {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    /// @solidity memory-safe-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. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
     * - When `from` is zero, the tokens will be minted for `to`.
     * - When `to` is zero, ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256, /* firstTokenId */
        uint256 batchSize
    ) internal virtual {
        if (batchSize > 1) {
            if (from != address(0)) {
                _balances[from] -= batchSize;
            }
            if (to != address(0)) {
                _balances[to] += batchSize;
            }
        }
    }

    /**
     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
     * - When `from` is zero, the tokens were minted for `to`.
     * - When `to` is zero, ``from``'s tokens were burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual {}
}

// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol)

pragma solidity ^0.8.0;



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

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

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

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

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

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

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

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

    /**
     * @dev See {ERC721-_beforeTokenTransfer}.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, firstTokenId, batchSize);

        if (batchSize > 1) {
            // Will only trigger during construction. Batch transferring (minting) is not available afterwards.
            revert("ERC721Enumerable: consecutive transfers not supported");
        }

        uint256 tokenId = firstTokenId;

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

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

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

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

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

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

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

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

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

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

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

// File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;


/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV // Deprecated in v4.8
    }

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

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

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

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

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }

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

        return (signer, RecoverError.NoError);
    }

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

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

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

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

// File: github/bitmark-inc/feralfile-exhibition-smart-contract/FF_V3_3_AKG%2BV3_2/contracts/FeralfileArtworkV3.sol


pragma solidity ^0.8.0;






contract FeralfileExhibitionV3 is ERC721Enumerable, Authorizable, IERC2981 {
    using Strings for uint256;

    // royalty payout address
    address public royaltyPayoutAddress;

    // the basis points of royalty payments for each secondary sales
    uint256 public immutable secondarySaleRoyaltyBPS;

    // the maximum basis points of royalty payments
    uint256 public constant MAX_ROYALITY_BPS = 100_00;

    // version code of contract
    string public constant codeVersion = "FeralfileExhibitionV3";

    // burnable
    bool public isBurnable;

    // bridgeable
    bool public isBridgeable;

    // token base URI
    string internal _tokenBaseURI;

    // contract URI
    string private _contractURI;

    /// @notice A structure for Feral File artwork
    struct Artwork {
        string title;
        string artistName;
        string fingerprint;
        uint256 editionSize;
        uint256 AEAmount;
        uint256 PPAmount;
    }

    struct ArtworkEdition {
        uint256 editionID;
        string ipfsCID;
    }

    struct TransferArtworkParam {
        address from;
        address to;
        uint256 tokenID;
        uint256 expireTime;
        bytes32 r_;
        bytes32 s_;
        uint8 v_;
    }

    struct MintArtworkParam {
        uint256 artworkID;
        uint256 edition;
        address artist;
        address owner;
        string ipfsCID;
    }

    struct ArtworkEditionIndex {
        uint256 artworkID;
        uint256 index;
    }

    uint256[] private _allArtworks;
    mapping(uint256 => Artwork) public artworks; // artworkID => Artwork
    mapping(uint256 => ArtworkEdition) public artworkEditions; // artworkEditionID => ArtworkEdition
    mapping(uint256 => uint256[]) internal allArtworkEditions; // artworkID => []ArtworkEditionID
    mapping(string => bool) internal registeredIPFSCIDs; // ipfsCID => bool
    mapping(uint256 => ArtworkEditionIndex) internal allArtworkEditionsIndex; // editionID => ArtworkEditionIndex

    constructor(
        string memory name_,
        string memory symbol_,
        uint256 secondarySaleRoyaltyBPS_,
        address royaltyPayoutAddress_,
        string memory contractURI_,
        string memory tokenBaseURI_,
        bool isBurnable_,
        bool isBridgeable_
    ) ERC721(name_, symbol_) {
        require(
            secondarySaleRoyaltyBPS_ <= MAX_ROYALITY_BPS,
            "royalty BPS for secondary sales can not be greater than the maximum royalty BPS"
        );
        require(
            royaltyPayoutAddress_ != address(0),
            "invalid royalty payout address"
        );

        secondarySaleRoyaltyBPS = secondarySaleRoyaltyBPS_;
        royaltyPayoutAddress = royaltyPayoutAddress_;
        _contractURI = contractURI_;
        _tokenBaseURI = tokenBaseURI_;
        isBurnable = isBurnable_;
        isBridgeable = isBridgeable_;
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(ERC721Enumerable, IERC165)
        returns (bool)
    {
        return
            interfaceId == type(IERC721Enumerable).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /// @notice Call to create an artwork in the exhibition
    /// @param fingerprint - the fingerprint of an artwork
    /// @param title - the title of an artwork
    /// @param artistName - the artist of an artwork
    /// @param editionSize - the maximum edition size of an artwork
    function _createArtwork(
        string memory fingerprint,
        string memory title,
        string memory artistName,
        uint256 editionSize,
        uint256 aeAmount,
        uint256 ppAmount
    ) internal returns (uint256) {
        require(bytes(title).length != 0, "title can not be empty");
        require(bytes(artistName).length != 0, "artist can not be empty");
        require(bytes(fingerprint).length != 0, "fingerprint can not be empty");
        require(editionSize > 0, "edition size needs to be at least 1");

        uint256 artworkID = uint256(keccak256(abi.encode(fingerprint)));

        /// @notice make sure the artwork have not been registered
        require(
            bytes(artworks[artworkID].fingerprint).length == 0,
            "an artwork with the same fingerprint has already registered"
        );

        Artwork memory artwork = Artwork(
            title = title,
            artistName = artistName,
            fingerprint = fingerprint,
            editionSize = editionSize,
            aeAmount = aeAmount,
            ppAmount = ppAmount
        );

        _allArtworks.push(artworkID);
        artworks[artworkID] = artwork;

        emit NewArtwork(artworkID);

        return artworkID;
    }

    /// @notice createArtworks use for create list of artworks in a transaction
    /// @param artworks_ - the array of artwork
    function createArtworks(Artwork[] memory artworks_)
        external
        onlyAuthorized
    {
        for (uint256 i = 0; i < artworks_.length; i++) {
            _createArtwork(
                artworks_[i].fingerprint,
                artworks_[i].title,
                artworks_[i].artistName,
                artworks_[i].editionSize,
                artworks_[i].AEAmount,
                artworks_[i].PPAmount
            );
        }
    }

    /// @notice Return a count of artworks registered in this exhibition
    function totalArtworks() public view virtual returns (uint256) {
        return _allArtworks.length;
    }

    /// @notice Return the token identifier for the `index`th artwork
    function getArtworkByIndex(uint256 index)
        public
        view
        virtual
        returns (uint256)
    {
        require(
            index < totalArtworks(),
            "artworks: global index out of bounds"
        );
        return _allArtworks[index];
    }

    /// @notice Update the IPFS cid of an edition to a new value
    function updateArtworkEditionIPFSCid(uint256 tokenId, string memory ipfsCID)
        external
        onlyAuthorized
    {
        require(_exists(tokenId), "artwork edition is not found");
        require(!registeredIPFSCIDs[ipfsCID], "ipfs id has registered");

        ArtworkEdition storage edition = artworkEditions[tokenId];
        delete registeredIPFSCIDs[edition.ipfsCID];
        registeredIPFSCIDs[ipfsCID] = true;
        edition.ipfsCID = ipfsCID;
    }

    /// @notice setRoyaltyPayoutAddress assigns a payout address so
    //          that we can split the royalty.
    /// @param royaltyPayoutAddress_ - the new royalty payout address
    function setRoyaltyPayoutAddress(address royaltyPayoutAddress_)
        external
        onlyAuthorized
    {
        require(
            royaltyPayoutAddress_ != address(0),
            "invalid royalty payout address"
        );
        royaltyPayoutAddress = royaltyPayoutAddress_;
    }

    /// @notice Return the edition counts for an artwork
    function totalEditionOfArtwork(uint256 artworkID)
        public
        view
        returns (uint256)
    {
        return allArtworkEditions[artworkID].length;
    }

    /// @notice Return the edition id of an artwork by index
    function getArtworkEditionByIndex(uint256 artworkID, uint256 index)
        public
        view
        returns (uint256)
    {
        require(index < totalEditionOfArtwork(artworkID));
        return allArtworkEditions[artworkID][index];
    }

    /// @notice A distinct Uniform Resource Identifier (URI) for a given asset.
    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI query for nonexistent token"
        );

        string memory baseURI = _tokenBaseURI;
        if (bytes(baseURI).length == 0) {
            baseURI = "ipfs://";
        }

        return
            string(abi.encodePacked(baseURI, artworkEditions[tokenId].ipfsCID));
    }

    /// @notice Update the base URI for all tokens
    function setTokenBaseURI(string memory baseURI_) external onlyAuthorized {
        _tokenBaseURI = baseURI_;
    }

    /// @notice A URL for the opensea storefront-level metadata
    function contractURI() public view returns (string memory) {
        return _contractURI;
    }

    /// @notice Called with the sale price to determine how much royalty
    //          is owed and to whom.
    /// @param tokenId - the NFT asset queried for royalty information
    /// @param salePrice - the sale price of the NFT asset specified by tokenId
    /// @return receiver - address of who should be sent the royalty payment
    /// @return royaltyAmount - the royalty payment amount for salePrice
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        override
        returns (address receiver, uint256 royaltyAmount)
    {
        require(
            _exists(tokenId),
            "ERC2981: query royalty info for nonexistent token"
        );

        receiver = royaltyPayoutAddress;

        royaltyAmount =
            (salePrice * secondarySaleRoyaltyBPS) /
            MAX_ROYALITY_BPS;
    }

    /// @notice isValidRequest validates a message by ecrecover to ensure
    //          it is signed by owner of token.
    /// @param message_ - the raw message for signing
    /// @param owner_ - owner address of token
    /// @param r_ - part of signature for validating parameters integrity
    /// @param s_ - part of signature for validating parameters integrity
    /// @param v_ - part of signature for validating parameters integrity
    function isValidRequest(
        bytes32 message_,
        address owner_,
        bytes32 r_,
        bytes32 s_,
        uint8 v_
    ) internal pure returns (bool) {
        address signer = ECDSA.recover(
            ECDSA.toEthSignedMessageHash(message_),
            v_,
            r_,
            s_
        );
        return signer == owner_;
    }

    /// @notice authorizedTransfer use for transfer list of items in a transaction
    /// @param transferParams_ - the array of transfer parameters
    function authorizedTransfer(TransferArtworkParam[] memory transferParams_)
        external
        onlyAuthorized
    {
        for (uint256 i = 0; i < transferParams_.length; i++) {
            _authorizedTransfer(transferParams_[i]);
        }
    }

    function _authorizedTransfer(TransferArtworkParam memory transferParam_)
        private
    {
        require(
            _exists(transferParam_.tokenID),
            "ERC721: artwork edition is not found"
        );

        require(
            _isApprovedOrOwner(transferParam_.from, transferParam_.tokenID),
            "ERC721: caller is not token owner nor approved"
        );

        require(
            block.timestamp <= transferParam_.expireTime,
            "FeralfileExhibitionV3: the transfer request is expired"
        );

        bytes32 requestHash = keccak256(
            abi.encode(
                transferParam_.from,
                transferParam_.to,
                transferParam_.tokenID,
                transferParam_.expireTime
            )
        );

        require(
            isValidRequest(
                requestHash,
                transferParam_.from,
                transferParam_.r_,
                transferParam_.s_,
                transferParam_.v_
            ),
            "FeralfileExhibitionV3: the transfer request is not authorized"
        );

        _safeTransfer(
            transferParam_.from,
            transferParam_.to,
            transferParam_.tokenID,
            ""
        );
    }

    /// @notice batchMint is function mint array of tokens
    /// @param mintParams_ - the array of transfer parameters
    function batchMint(MintArtworkParam[] memory mintParams_)
        external
        onlyAuthorized
    {
        for (uint256 i = 0; i < mintParams_.length; i++) {
            _mintArtwork(
                mintParams_[i].artworkID,
                mintParams_[i].edition,
                mintParams_[i].artist,
                mintParams_[i].owner,
                mintParams_[i].ipfsCID
            );
        }
    }

    /// @notice mint artwork to ERC721
    /// @param artworkID_ - the artwork id where the new edition is referenced to
    /// @param editionNumber_ - the edition number of the artwork edition
    /// @param artist_ - the artist address of the new minted token
    /// @param owner_ - the owner address of the new minted token
    /// @param ipfsCID_ - the IPFS cid for the new token
    function _mintArtwork(
        uint256 artworkID_,
        uint256 editionNumber_,
        address artist_,
        address owner_,
        string memory ipfsCID_
    ) private {
        /// @notice the edition size is not set implies the artwork is not created
        require(
            artworks[artworkID_].editionSize > 0,
            "FeralfileExhibitionV3: artwork is not found"
        );
        /// @notice The range of editionNumber should be between 0 to artwork.editionSize + artwork.AEAmount + artwork.PPAmount - 1
        require(
            editionNumber_ <
                artworks[artworkID_].editionSize +
                    artworks[artworkID_].AEAmount +
                    artworks[artworkID_].PPAmount,
            "FeralfileExhibitionV3: edition number exceed the edition size of the artwork"
        );
        require(artist_ != address(0), "invalid artist address");
        require(owner_ != address(0), "invalid owner address");
        require(!registeredIPFSCIDs[ipfsCID_], "ipfs id has registered");

        uint256 editionID = artworkID_ + editionNumber_;
        require(
            artworkEditions[editionID].editionID == 0,
            "FeralfileExhibitionV3: the edition is existent"
        );

        ArtworkEdition memory edition = ArtworkEdition(editionID, ipfsCID_);

        artworkEditions[editionID] = edition;
        allArtworkEditions[artworkID_].push(editionID);
        allArtworkEditionsIndex[editionID] = ArtworkEditionIndex(
            artworkID_,
            allArtworkEditions[artworkID_].length - 1
        );

        registeredIPFSCIDs[ipfsCID_] = true;

        _safeMint(artist_, editionID);

        if (artist_ != owner_) {
            _safeTransfer(artist_, owner_, editionID, "");
        }

        emit NewArtworkEdition(owner_, artworkID_, editionID);
    }

    /// @notice remove an edition from allArtworkEditions
    /// @param editionID - the edition id where we are going to remove from allArtworkEditions
    function _removeEditionFromAllArtworkEditions(uint256 editionID) private {
        ArtworkEditionIndex
            memory artworkEditionIndex = allArtworkEditionsIndex[editionID];

        require(
            artworkEditionIndex.artworkID > 0,
            "FeralfileExhibitionV3: artworkID is no found for the artworkEditionIndex"
        );

        uint256[] storage artworkEditions_ = allArtworkEditions[
            artworkEditionIndex.artworkID
        ];

        require(
            artworkEditions_.length > 0,
            "FeralfileExhibitionV3: no editions in this artwork of allArtworkEditions"
        );

        uint256 lastEditionIndex = artworkEditions_.length - 1;
        uint256 lastEditionID = artworkEditions_[artworkEditions_.length - 1];

        // Swap between the last token and the to-delete token and pop up the last token
        artworkEditions_[artworkEditionIndex.index] = lastEditionID;
        artworkEditions_[lastEditionIndex] = artworkEditionIndex.index;
        artworkEditions_.pop();

        delete allArtworkEditionsIndex[editionID];
    }

    /// @notice burn editions
    /// @param editionIDs_ - the list of edition id will be burned
    function burnEditions(uint256[] memory editionIDs_) public {
        require(isBurnable, "FeralfileExhibitionV3: not allow burn edition");

        for (uint256 i = 0; i < editionIDs_.length; i++) {
            require(
                _exists(editionIDs_[i]),
                "ERC721: artwork edition is not found"
            );
            require(
                _isApprovedOrOwner(_msgSender(), editionIDs_[i]),
                "ERC721: caller is not token owner nor approved"
            );
            ArtworkEdition memory edition = artworkEditions[editionIDs_[i]];

            delete registeredIPFSCIDs[edition.ipfsCID];
            delete artworkEditions[editionIDs_[i]];

            _removeEditionFromAllArtworkEditions(editionIDs_[i]);

            _burn(editionIDs_[i]);

            emit BurnArtworkEdition(editionIDs_[i]);
        }
    }

    event NewArtwork(uint256 indexed artworkID);
    event NewArtworkEdition(
        address indexed owner,
        uint256 indexed artworkID,
        uint256 indexed editionID
    );
    event BurnArtworkEdition(uint256 indexed editionID);
}

// File: github/bitmark-inc/feralfile-exhibition-smart-contract/FF_V3_3_AKG%2BV3_2/contracts/FeralfileArtworkV3_2.sol


pragma solidity ^0.8.0;






contract FeralfileExhibitionV3_2 is
    FeralfileExhibitionV3,
    UpdateableOperatorFilterer
{
    constructor(
        string memory name_,
        string memory symbol_,
        uint256 secondarySaleRoyaltyBPS_,
        address royaltyPayoutAddress_,
        string memory contractURI_,
        string memory tokenBaseURI_,
        bool isBurnable_,
        bool isBridgeable_
    )
        FeralfileExhibitionV3(
            name_,
            symbol_,
            secondarySaleRoyaltyBPS_,
            royaltyPayoutAddress_,
            contractURI_,
            tokenBaseURI_,
            isBurnable_,
            isBridgeable_
        )
    {}

    function setApprovalForAll(address operator, bool approved)
        public
        override(ERC721, IERC721)
        onlyAllowedOperatorApproval(operator)
    {
        super.setApprovalForAll(operator, approved);
    }

    function approve(address operator, uint256 tokenId)
        public
        override(ERC721, IERC721)
        onlyAllowedOperatorApproval(operator)
    {
        super.approve(operator, tokenId);
    }

    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public override(ERC721, IERC721) onlyAllowedOperator(from) {
        super.transferFrom(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public override(ERC721, IERC721) onlyAllowedOperator(from) {
        super.safeTransferFrom(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) public override(ERC721, IERC721) onlyAllowedOperator(from) {
        super.safeTransferFrom(from, to, tokenId, data);
    }
}

// File: github/bitmark-inc/feralfile-exhibition-smart-contract/FF_V3_3_AKG%2BV3_2/contracts/FeralfileArtworkV3_3.sol


pragma solidity ^0.8.0;






contract FeralfileExhibitionV3_3 is FeralfileExhibitionV3_2 {
    using Strings for uint256;

    struct ExternalArtworkData {
        string thumbnailCID;
        string artworkCID;
    }

    mapping(uint256 => ExternalArtworkData) public externalArtworkIPFSCID; // artworkID => ExternalArtworkData

    constructor(
        string memory name_,
        string memory symbol_,
        uint256 secondarySaleRoyaltyBPS_,
        address royaltyPayoutAddress_,
        string memory contractURI_,
        string memory tokenBaseURI_,
        bool isBurnable_,
        bool isBridgeable_
    )
        FeralfileExhibitionV3_2(
            name_,
            symbol_,
            secondarySaleRoyaltyBPS_,
            royaltyPayoutAddress_,
            contractURI_,
            tokenBaseURI_,
            isBurnable_,
            isBridgeable_
        )
    {}

    address public decentralandAddress =
        0xF87E31492Faf9A91B02Ee0dEAAd50d51d56D5d4d;
    uint256 public decentralandTokenID =
        115792089237316195423570985008687907826047395311965486962387615413371672723439;

    function updateDecentralandInfo(address contractAddress, uint256 tokenId)
        external
        onlyOwner
    {
        decentralandAddress = contractAddress;
        decentralandTokenID = tokenId;
    }

    /// @notice createArtworkWithIPFSCID creates an artwork with a specific
    /// artwork IPFS CID given.
    /// @param artwork - the artwork information to be created
    /// @param thumbnailCID - the thumbnail CID of the external artwork file
    /// @param artworkCID - the artwork CID of the external artwork file
    function createArtworkWithIPFSCID(
        Artwork memory artwork,
        string memory thumbnailCID,
        string memory artworkCID
    ) external onlyAuthorized {
        require(
            bytes(thumbnailCID).length != 0,
            "thumbnail IPFS CID can not be empty"
        );

        require(
            bytes(artworkCID).length != 0,
            "artwork IPFS CID can not be empty"
        );

        uint256 artworkID = _createArtwork(
            artwork.fingerprint,
            artwork.title,
            artwork.artistName,
            artwork.editionSize,
            artwork.AEAmount,
            artwork.PPAmount
        );

        externalArtworkIPFSCID[artworkID] = ExternalArtworkData(
            thumbnailCID,
            artworkCID
        );
    }

    /// @notice createArtworkWithIPFSCID creates an artwork with a specific
    /// artwork IPFS CID given.
    /// @param artworkID - the artwork ID for updateing external artwork files
    /// @param thumbnailCID - the thumbnail CID of the external artwork file
    /// @param artworkCID - the artwork CID of the external artwork file
    function updateExternalArtworkIPFSCID(
        uint256 artworkID,
        string memory thumbnailCID,
        string memory artworkCID
    ) external onlyOwner {
        /// @notice make sure the artwork has already registered
        require(
            bytes(artworks[artworkID].fingerprint).length != 0,
            "the target artwork is not existent"
        );

        /// @notice remove external artwork info for an artwork if both
        /// thumbnailCID and thumbnailCID are empty
        if (bytes(thumbnailCID).length == 0 && bytes(artworkCID).length == 0) {
            delete externalArtworkIPFSCID[artworkID];
            return;
        }

        externalArtworkIPFSCID[artworkID] = ExternalArtworkData(
            thumbnailCID,
            artworkCID
        );
    }

    /// @notice tokenEditionNumber returns the edition number of a token
    function tokenEditionNumber(uint256 tokenID)
        public
        view
        returns (string memory)
    {
        ArtworkEditionIndex
            memory artworkEditionIndex = allArtworkEditionsIndex[tokenID];

        uint256 artworkID = artworkEditionIndex.artworkID;

        Artwork memory artwork = artworks[artworkID];
        uint256 ppStart = artworkID + artwork.AEAmount;
        uint256 neStart = artworkID + artwork.AEAmount + artwork.PPAmount;

        if (tokenID < ppStart) {
            return "AE";
        } else if (tokenID < neStart) {
            return "PP";
        } else {
            return
                string(
                    abi.encodePacked("#", (tokenID - neStart + 1).toString())
                );
        }
    }

    /// @notice buildArtworkData returns an object of artwork which would push to the actually artwork
    /// @param artworkID - the artwork ID for building artwork data
    function buildArtworkData(uint256 artworkID)
        private
        view
        returns (string memory)
    {
        Decentraland dc = Decentraland(decentralandAddress);
        uint256[] memory editionIDs = allArtworkEditions[artworkID];
        bytes memory ownersMap = bytes("{");

        for (uint256 i = 0; i < editionIDs.length; i++) {
            uint256 tokenID = editionIDs[i];
            ownersMap = abi.encodePacked(
                ownersMap,
                (tokenID - artworkID).toString(),
                ':"',
                Strings.toHexString(ownerOf(tokenID)),
                '",'
            );
        }

        ownersMap = abi.encodePacked(ownersMap, "}");

        return
            string(
                abi.encodePacked(
                    "{"
                    'landOwner:"',
                    Strings.toHexString(dc.ownerOf(decentralandTokenID)),
                    '", ownerMap:',
                    string(ownersMap),
                    "}"
                )
            );
    }

    /// @notice buildIframe returns a base64 encoded data for ff-frame
    /// @param artworkData - the artwork data which would bring into the artwork
    /// @param iframeURI - the artwork URL to loaded into iframe
    function buildIframe(string memory artworkData, string memory iframeURI)
        private
        pure
        returns (string memory)
    {
        return
            Base64.encode(
                abi.encodePacked(
                    '<!DOCTYPE html><html lang="en"><head><script> var defaultArtworkData= ',
                    artworkData,
                    "</script><script>"
                    'let allowOrigins={"https://feralfile.com":!0};function resizeIframe(e){let t=document.getElementById("mainframe");e&&(t.style.minHeight=e+"px")}'
                    "function initData(){defaultArtworkData.ownerArray=[];let e=defaultArtworkData.ownerMap;Object.keys(e).sort((e,t)=>e<t).forEach(t=>{defaultArtworkData.ownerArray.push(e[t])}),"
                    'pushArtworkDataToIframe(defaultArtworkData)}function pushArtworkDataToIframe(e){e&&document.getElementById("mainframe").contentWindow.postMessage(e,"*")}'
                    'function updateArtowrkData(e){document.getElementById("mainframe").contentWindow.postMessage(e,"*")}window.addEventListener("message",function(e){allowOrigins[e.origin]?'
                    '"update-artwork-data"===e.data.type&&updateArtowrkData(e.data.artworkData):"object"==typeof e.data&&"resize-iframe"===e.data.type&&resizeIframe(e.data.newHeight)});'
                    '</script></head><body style="overflow-x:hidden;padding:0;margin:0;width:100%;" onload="initData()">'
                    '<iframe id="mainframe" style="display:block;padding:0;margin:0;border:none;width:100%;height:100vh;" src="',
                    iframeURI,
                    '"></iframe> </body></html>'
                )
            );
    }

    /// @notice buildDataURL returns a base64 encoded data for ff-frame
    /// @param artworkID - the artwork ID for building artwork data
    /// @param tokenID - the token ID for building artwork data
    /// @param thumbnailCID - the thumbnail ipfs CID for this specific artwork
    /// @param artworkCID - the artwork ipfs CID for this specific artwork
    function buildDataURL(
        uint256 artworkID,
        uint256 tokenID,
        string memory thumbnailCID,
        string memory artworkCID
    ) private view returns (string memory) {
        Artwork memory artwork = artworks[artworkID];

        string memory editionNumber = tokenEditionNumber(tokenID);
        string memory tokenName = string(
            abi.encodePacked(artwork.title, " ", editionNumber)
        );
        return
            string(
                abi.encodePacked(
                    "data:application/json;base64,",
                    Base64.encode(
                        // We need to encode twice since the parameters are too many and
                        // cause the `Stack too deep` error on compilation.
                        abi.encodePacked(
                            abi.encodePacked(
                                '{"id":"',
                                tokenID.toString(),
                                '", "name":"',
                                tokenName,
                                '", "artist":"',
                                artwork.artistName,
                                '", "artwork_id":"',
                                artworkID.toHexString(),
                                '", "edition_index":"',
                                (tokenID - artworkID).toString(),
                                '", "edition_number":"',
                                editionNumber
                            ),
                            '", "external_url":"https://feralfile.com", "image":"',
                            buildIPFSURL(thumbnailCID),
                            '", "animation_url":"data:text/html;base64,',
                            buildIframe(
                                buildArtworkData(artworkID),
                                buildIPFSURL(artworkCID)
                            ),
                            '"}'
                        )
                    )
                )
            );
    }

    /// @notice buildIPFSURL returns a formatted IPFS link based on the _tokenBaseURI
    /// @param ipfsCID - thei IPFS Cid
    function buildIPFSURL(string memory ipfsCID)
        private
        view
        returns (string memory)
    {
        string memory baseURI = _tokenBaseURI;
        if (bytes(baseURI).length == 0) {
            baseURI = "ipfs://";
        }

        return string(abi.encodePacked(baseURI, ipfsCID));
    }

    /// @notice A distinct Uniform Resource Identifier (URI) for a given asset.
    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI query for nonexistent token"
        );

        ArtworkEditionIndex
            memory artworkEditionIndex = allArtworkEditionsIndex[tokenId];

        uint256 artworkID = artworkEditionIndex.artworkID;
        string memory thumbnailCID = externalArtworkIPFSCID[artworkID]
            .thumbnailCID;
        string memory artworkCID = externalArtworkIPFSCID[artworkID].artworkCID;

        if (bytes(artworkCID).length > 0 && bytes(thumbnailCID).length > 0) {
            return buildDataURL(artworkID, tokenId, thumbnailCID, artworkCID);
        } else {
            return buildIPFSURL(artworkEditions[tokenId].ipfsCID);
        }
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint256","name":"secondarySaleRoyaltyBPS_","type":"uint256"},{"internalType":"address","name":"royaltyPayoutAddress_","type":"address"},{"internalType":"string","name":"contractURI_","type":"string"},{"internalType":"string","name":"tokenBaseURI_","type":"string"},{"internalType":"bool","name":"isBurnable_","type":"bool"},{"internalType":"bool","name":"isBridgeable_","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"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":true,"internalType":"uint256","name":"editionID","type":"uint256"}],"name":"BurnArtworkEdition","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"artworkID","type":"uint256"}],"name":"NewArtwork","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"artworkID","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"editionID","type":"uint256"}],"name":"NewArtworkEdition","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_ROYALITY_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OperatorFilterRegistry","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_trustee","type":"address"}],"name":"addTrustee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"artworkEditions","outputs":[{"internalType":"uint256","name":"editionID","type":"uint256"},{"internalType":"string","name":"ipfsCID","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"artworks","outputs":[{"internalType":"string","name":"title","type":"string"},{"internalType":"string","name":"artistName","type":"string"},{"internalType":"string","name":"fingerprint","type":"string"},{"internalType":"uint256","name":"editionSize","type":"uint256"},{"internalType":"uint256","name":"AEAmount","type":"uint256"},{"internalType":"uint256","name":"PPAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenID","type":"uint256"},{"internalType":"uint256","name":"expireTime","type":"uint256"},{"internalType":"bytes32","name":"r_","type":"bytes32"},{"internalType":"bytes32","name":"s_","type":"bytes32"},{"internalType":"uint8","name":"v_","type":"uint8"}],"internalType":"struct FeralfileExhibitionV3.TransferArtworkParam[]","name":"transferParams_","type":"tuple[]"}],"name":"authorizedTransfer","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":[{"components":[{"internalType":"uint256","name":"artworkID","type":"uint256"},{"internalType":"uint256","name":"edition","type":"uint256"},{"internalType":"address","name":"artist","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"string","name":"ipfsCID","type":"string"}],"internalType":"struct FeralfileExhibitionV3.MintArtworkParam[]","name":"mintParams_","type":"tuple[]"}],"name":"batchMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"editionIDs_","type":"uint256[]"}],"name":"burnEditions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"codeVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"title","type":"string"},{"internalType":"string","name":"artistName","type":"string"},{"internalType":"string","name":"fingerprint","type":"string"},{"internalType":"uint256","name":"editionSize","type":"uint256"},{"internalType":"uint256","name":"AEAmount","type":"uint256"},{"internalType":"uint256","name":"PPAmount","type":"uint256"}],"internalType":"struct FeralfileExhibitionV3.Artwork","name":"artwork","type":"tuple"},{"internalType":"string","name":"thumbnailCID","type":"string"},{"internalType":"string","name":"artworkCID","type":"string"}],"name":"createArtworkWithIPFSCID","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"title","type":"string"},{"internalType":"string","name":"artistName","type":"string"},{"internalType":"string","name":"fingerprint","type":"string"},{"internalType":"uint256","name":"editionSize","type":"uint256"},{"internalType":"uint256","name":"AEAmount","type":"uint256"},{"internalType":"uint256","name":"PPAmount","type":"uint256"}],"internalType":"struct FeralfileExhibitionV3.Artwork[]","name":"artworks_","type":"tuple[]"}],"name":"createArtworks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decentralandAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decentralandTokenID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"externalArtworkIPFSCID","outputs":[{"internalType":"string","name":"thumbnailCID","type":"string"},{"internalType":"string","name":"artworkCID","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":"index","type":"uint256"}],"name":"getArtworkByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"artworkID","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getArtworkEditionByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[],"name":"isBridgeable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isBurnable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_trustee","type":"address"}],"name":"removeTrustee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyPayoutAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":[],"name":"secondarySaleRoyaltyBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"royaltyPayoutAddress_","type":"address"}],"name":"setRoyaltyPayoutAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI_","type":"string"}],"name":"setTokenBaseURI","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":"tokenEditionNumber","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":"totalArtworks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"artworkID","type":"uint256"}],"name":"totalEditionOfArtwork","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"address","name":"","type":"address"}],"name":"trustees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"ipfsCID","type":"string"}],"name":"updateArtworkEditionIPFSCid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"updateDecentralandInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"artworkID","type":"uint256"},{"internalType":"string","name":"thumbnailCID","type":"string"},{"internalType":"string","name":"artworkCID","type":"string"}],"name":"updateExternalArtworkIPFSCID","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operatorFilterRegisterAddress","type":"address"}],"name":"updateOperatorFilterRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a0604052601580546001600160a01b03199081166daaeb6d7670e522a718067333cd4e179091556017805490911673f87e31492faf9a91b02ee0deaad50d51d56d5d4d1790556010600560841b01196018553480156200005f57600080fd5b506040516200667438038062006674833981016040819052620000829162000420565b8787878787878787878787878787878787876000620000a28382620005aa565b506001620000b18282620005aa565b505050620000ce620000c8620002d760201b60201c565b620002db565b612710861115620001645760405162461bcd60e51b815260206004820152604f60248201527f726f79616c74792042505320666f72207365636f6e646172792073616c65732060448201527f63616e206e6f742062652067726561746572207468616e20746865206d61786960648201526e6d756d20726f79616c74792042505360881b608482015260a4015b60405180910390fd5b6001600160a01b038516620001bc5760405162461bcd60e51b815260206004820152601e60248201527f696e76616c696420726f79616c7479207061796f75742061646472657373000060448201526064016200015b565b6080869052600c80546001600160a01b0319166001600160a01b038716179055600e620001ea8582620005aa565b50600d620001f98482620005aa565b50600c805461ffff60a01b1916600160a01b9315159390930260ff60a81b191692909217600160a81b9115159190910217905550506015546001600160a01b03163b159350620002c19250505057601554604051633e9f1edf60e11b8152306004820152733cc6cdda760b79bafa08df41ecfa224f810dceb660248201526001600160a01b0390911690637d3e3dbe90604401600060405180830381600087803b158015620002a757600080fd5b505af1158015620002bc573d6000803e3d6000fd5b505050505b5050505050505050505050505050505062000676565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200035557600080fd5b81516001600160401b03808211156200037257620003726200032d565b604051601f8301601f19908116603f011681019082821181831017156200039d576200039d6200032d565b81604052838152602092508683858801011115620003ba57600080fd5b600091505b83821015620003de5785820183015181830184015290820190620003bf565b600093810190920192909252949350505050565b80516001600160a01b03811681146200040a57600080fd5b919050565b805180151581146200040a57600080fd5b600080600080600080600080610100898b0312156200043e57600080fd5b88516001600160401b03808211156200045657600080fd5b620004648c838d0162000343565b995060208b01519150808211156200047b57600080fd5b620004898c838d0162000343565b985060408b01519750620004a060608c01620003f2565b965060808b0151915080821115620004b757600080fd5b620004c58c838d0162000343565b955060a08b0151915080821115620004dc57600080fd5b50620004eb8b828c0162000343565b935050620004fc60c08a016200040f565b91506200050c60e08a016200040f565b90509295985092959890939650565b600181811c908216806200053057607f821691505b6020821081036200055157634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620005a557600081815260208120601f850160051c81016020861015620005805750805b601f850160051c820191505b81811015620005a1578281556001016200058c565b5050505b505050565b81516001600160401b03811115620005c657620005c66200032d565b620005de81620005d784546200051b565b8462000557565b602080601f831160018114620006165760008415620005fd5750858301515b600019600386901b1c1916600185901b178555620005a1565b600085815260208120601f198616915b82811015620006475788860151825594840194600190910190840162000626565b5085821015620006665787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051615fdb62000699600039600081816106fe0152610c060152615fdb6000f3fe608060405234801561001057600080fd5b506004361061030c5760003560e01c806370a082311161019d578063b88d4fde116100e9578063ea211d7c116100a2578063f07e7fd01161007c578063f07e7fd01461074c578063f2fde38b1461075f578063fc05ea6814610772578063fe2a3bf31461078557600080fd5b8063ea211d7c146106f9578063ec9cbb4414610720578063eee608a41461072957600080fd5b8063b88d4fde14610674578063c87b56dd14610687578063dc78ac1c1461069a578063e4a233e1146106ad578063e8a3d485146106b5578063e985e9c5146106bd57600080fd5b80638ef79e9111610156578063a170bf0311610130578063a170bf0314610628578063a22cb4651461063b578063b48837031461064e578063b6358d991461066157600080fd5b80638ef79e91146105fa57806395d89b411461060d5780639fbf39cd1461061557600080fd5b806370a0823114610593578063715018a6146105a65780637ca5ea89146105ae5780637e22b1a4146105c2578063883356d9146105d55780638da5cb5b146105e957600080fd5b8063367d14971161025c5780634b6026731161021557806362fe2131116101ef57806362fe2131146105185780636352211e1461053957806363e602301461054c578063641b18e91461058057600080fd5b80634b602673146104cd5780634f6ccce7146104f2578063587056f61461050557600080fd5b8063367d1497146104575780633f6805ba1461047857806342842e0e1461048b57806343deaf761461049e57806345aeefde146104b15780634744254b146104c457600080fd5b8063114ba8ee116102c957806318701151116102a357806318701151146103ec57806323b872dd146103ff5780632a55205a146104125780632f745c591461044457600080fd5b8063114ba8ee146103b457806312d907b9146103c757806318160ddd146103da57600080fd5b806301ffc9a714610311578063031205061461033957806306fdde031461034e578063081812fc14610363578063095ea7b31461038e5780630cfcb5f1146103a1575b600080fd5b61032461031f3660046147ba565b6107a5565b60405190151581526020015b60405180910390f35b61034c6103473660046147ec565b6107d0565b005b6103566107f9565b6040516103309190614859565b61037661037136600461486c565b61088b565b6040516001600160a01b039091168152602001610330565b61034c61039c366004614885565b6108b2565b61034c6103af3660046149da565b6108cb565b61034c6103c23660046147ec565b610a3e565b61034c6103d5366004614a43565b610a68565b6008545b604051908152602001610330565b601754610376906001600160a01b031681565b61034c61040d366004614b6a565b610b59565b610425610420366004614bab565b610b7e565b604080516001600160a01b039093168352602083019190915201610330565b6103de610452366004614885565b610c3e565b61046a61046536600461486c565b610cd4565b604051610330929190614bcd565b600c54610376906001600160a01b031681565b61034c610499366004614b6a565b610e00565b61034c6104ac366004614cac565b610e25565b61034c6104bf3660046147ec565b610f31565b6103de60185481565b6104e06104db36600461486c565b610fda565b60405161033096959493929190614d4f565b6103de61050036600461486c565b6111a6565b61034c610513366004614da7565b611239565b61052b61052636600461486c565b611347565b604051610330929190614e13565b61037661054736600461486c565b611369565b61035660405180604001604052806015815260200174466572616c66696c6545786869626974696f6e563360581b81525081565b6103de61058e366004614bab565b6113c9565b6103de6105a13660046147ec565b611416565b61034c61149c565b600c5461032490600160a81b900460ff1681565b61034c6105d0366004614e2c565b6114b0565b600c5461032490600160a01b900460ff1681565b600a546001600160a01b0316610376565b61034c610608366004614e7a565b611614565b610356611651565b61034c610623366004614eae565b611660565b61034c610636366004614885565b6116d1565b61034c610649366004614fc3565b6116ff565b6103de61065c36600461486c565b611713565b61035661066f36600461486c565b61178b565b61034c610682366004614ffc565b611a79565b61035661069536600461486c565b611a9f565b61034c6106a83660046147ec565b611d43565b600f546103de565b610356611d6f565b6103246106cb36600461507b565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6103de7f000000000000000000000000000000000000000000000000000000000000000081565b6103de61271081565b6103246107373660046147ec565b600b6020526000908152604090205460ff1681565b601554610376906001600160a01b031681565b61034c61076d3660046147ec565b611d7e565b61034c6107803660046150a9565b611df7565b6103de61079336600461486c565b60009081526012602052604090205490565b60006001600160e01b0319821663780e9d6360e01b14806107ca57506107ca826120d9565b92915050565b6107d86120fe565b6001600160a01b03166000908152600b60205260409020805460ff19169055565b60606000805461080890615139565b80601f016020809104026020016040519081016040528092919081815260200182805461083490615139565b80156108815780601f1061085657610100808354040283529160200191610881565b820191906000526020600020905b81548152906001019060200180831161086457829003601f168201915b5050505050905090565b600061089682612158565b506000908152600460205260409020546001600160a01b031690565b816108bc816121a8565b6108c6838361227a565b505050565b336000908152600b602052604090205460ff16806108f35750600a546001600160a01b031633145b6108fc57600080fd5b6109058261238a565b6109565760405162461bcd60e51b815260206004820152601c60248201527f617274776f726b2065646974696f6e206973206e6f7420666f756e640000000060448201526064015b60405180910390fd5b601381604051610966919061518f565b9081526040519081900360200190205460ff16156109bf5760405162461bcd60e51b81526020600482015260166024820152751a5c199cc81a59081a185cc81c9959da5cdd195c995960521b604482015260640161094d565b6000828152601160205260409081902090516013906109e29060018401906151ab565b908152604051908190036020018120805460ff19169055600190601390610a0a90859061518f565b908152604051908190036020019020805491151560ff1990921691909117905560018101610a388382615267565b50505050565b610a466120fe565b601580546001600160a01b0319166001600160a01b0392909216919091179055565b336000908152600b602052604090205460ff1680610a905750600a546001600160a01b031633145b610a9957600080fd5b60005b8151811015610b5557610b43828281518110610aba57610aba615326565b602002602001015160000151838381518110610ad857610ad8615326565b602002602001015160200151848481518110610af657610af6615326565b602002602001015160400151858581518110610b1457610b14615326565b602002602001015160600151868681518110610b3257610b32615326565b6020026020010151608001516123a7565b80610b4d81615352565b915050610a9c565b5050565b826001600160a01b0381163314610b7357610b73336121a8565b610a388484846127b3565b600080610b8a8461238a565b610bf05760405162461bcd60e51b815260206004820152603160248201527f455243323938313a20717565727920726f79616c747920696e666f20666f72206044820152703737b732bc34b9ba32b73a103a37b5b2b760791b606482015260840161094d565b600c546001600160a01b03169150612710610c2b7f00000000000000000000000000000000000000000000000000000000000000008561536b565b610c359190615382565b90509250929050565b6000610c4983611416565b8210610cab5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161094d565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b601660205260009081526040902080548190610cef90615139565b80601f0160208091040260200160405190810160405280929190818152602001828054610d1b90615139565b8015610d685780601f10610d3d57610100808354040283529160200191610d68565b820191906000526020600020905b815481529060010190602001808311610d4b57829003601f168201915b505050505090806001018054610d7d90615139565b80601f0160208091040260200160405190810160405280929190818152602001828054610da990615139565b8015610df65780601f10610dcb57610100808354040283529160200191610df6565b820191906000526020600020905b815481529060010190602001808311610dd957829003601f168201915b5050505050905082565b826001600160a01b0381163314610e1a57610e1a336121a8565b610a388484846127e4565b336000908152600b602052604090205460ff1680610e4d5750600a546001600160a01b031633145b610e5657600080fd5b60005b8151811015610b5557610f1e828281518110610e7757610e77615326565b602002602001015160400151838381518110610e9557610e95615326565b602002602001015160000151848481518110610eb357610eb3615326565b602002602001015160200151858581518110610ed157610ed1615326565b602002602001015160600151868681518110610eef57610eef615326565b602002602001015160800151878781518110610f0d57610f0d615326565b602002602001015160a001516127ff565b5080610f2981615352565b915050610e59565b336000908152600b602052604090205460ff1680610f595750600a546001600160a01b031633145b610f6257600080fd5b6001600160a01b038116610fb85760405162461bcd60e51b815260206004820152601e60248201527f696e76616c696420726f79616c7479207061796f757420616464726573730000604482015260640161094d565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b601060205260009081526040902080548190610ff590615139565b80601f016020809104026020016040519081016040528092919081815260200182805461102190615139565b801561106e5780601f106110435761010080835404028352916020019161106e565b820191906000526020600020905b81548152906001019060200180831161105157829003601f168201915b50505050509080600101805461108390615139565b80601f01602080910402602001604051908101604052809291908181526020018280546110af90615139565b80156110fc5780601f106110d1576101008083540402835291602001916110fc565b820191906000526020600020905b8154815290600101906020018083116110df57829003601f168201915b50505050509080600201805461111190615139565b80601f016020809104026020016040519081016040528092919081815260200182805461113d90615139565b801561118a5780601f1061115f5761010080835404028352916020019161118a565b820191906000526020600020905b81548152906001019060200180831161116d57829003601f168201915b5050505050908060030154908060040154908060050154905086565b60006111b160085490565b82106112145760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161094d565b6008828154811061122757611227615326565b90600052602060002001549050919050565b6112416120fe565b6000838152601060205260409020600201805461125d90615139565b90506000036112b95760405162461bcd60e51b815260206004820152602260248201527f7468652074617267657420617274776f726b206973206e6f74206578697374656044820152611b9d60f21b606482015260840161094d565b81511580156112c757508051155b156112fa576000838152601660205260408120906112e58282614756565b6112f3600183016000614756565b5050505050565b604080518082018252838152602080820184905260008681526016909152919091208151819061132a9082615267565b506020820151600182019061133f9082615267565b505050505050565b60116020526000908152604090208054600182018054919291610d7d90615139565b6000818152600260205260408120546001600160a01b0316806107ca5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604482015260640161094d565b60008281526012602052604081205482106113e357600080fd5b600083815260126020526040902080548390811061140357611403615326565b9060005260206000200154905092915050565b60006001600160a01b0382166114805760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b606482015260840161094d565b506001600160a01b031660009081526003602052604090205490565b6114a46120fe565b6114ae6000612b08565b565b336000908152600b602052604090205460ff16806114d85750600a546001600160a01b031633145b6114e157600080fd5b815160000361153e5760405162461bcd60e51b815260206004820152602360248201527f7468756d626e61696c2049504653204349442063616e206e6f7420626520656d60448201526270747960e81b606482015260840161094d565b80516000036115995760405162461bcd60e51b815260206004820152602160248201527f617274776f726b2049504653204349442063616e206e6f7420626520656d70746044820152607960f81b606482015260840161094d565b60006115c1846040015185600001518660200151876060015188608001518960a001516127ff565b604080518082018252858152602080820186905260008481526016909152919091208151929350909181906115f69082615267565b506020820151600182019061160b9082615267565b50505050505050565b336000908152600b602052604090205460ff168061163c5750600a546001600160a01b031633145b61164557600080fd5b600d610b558282615267565b60606001805461080890615139565b336000908152600b602052604090205460ff16806116885750600a546001600160a01b031633145b61169157600080fd5b60005b8151811015610b55576116bf8282815181106116b2576116b2615326565b6020026020010151612b5a565b806116c981615352565b915050611694565b6116d96120fe565b601780546001600160a01b0319166001600160a01b039390931692909217909155601855565b81611709816121a8565b6108c68383612d3f565b600061171e600f5490565b82106117785760405162461bcd60e51b8152602060048201526024808201527f617274776f726b733a20676c6f62616c20696e646578206f7574206f6620626f604482015263756e647360e01b606482015260840161094d565b600f828154811061122757611227615326565b6000818152601460209081526040808320815180830183528154808252600190920154818501528185526010909352818420825160c08101909352805460609592939190829082906117dc90615139565b80601f016020809104026020016040519081016040528092919081815260200182805461180890615139565b80156118555780601f1061182a57610100808354040283529160200191611855565b820191906000526020600020905b81548152906001019060200180831161183857829003601f168201915b5050505050815260200160018201805461186e90615139565b80601f016020809104026020016040519081016040528092919081815260200182805461189a90615139565b80156118e75780601f106118bc576101008083540402835291602001916118e7565b820191906000526020600020905b8154815290600101906020018083116118ca57829003601f168201915b5050505050815260200160028201805461190090615139565b80601f016020809104026020016040519081016040528092919081815260200182805461192c90615139565b80156119795780601f1061194e57610100808354040283529160200191611979565b820191906000526020600020905b81548152906001019060200180831161195c57829003601f168201915b505050505081526020016003820154815260200160048201548152602001600582015481525050905060008160800151836119b491906153a4565b905060008260a001518360800151856119cd91906153a4565b6119d791906153a4565b905081871015611a05575050604080518082019091526002815261414560f01b602082015295945050505050565b80871015611a31575050604080518082019091526002815261050560f41b602082015295945050505050565b611a4e611a3e82896153b7565b611a499060016153a4565b612d4a565b604051602001611a5e91906153ca565b60405160208183030381529060405295505050505050919050565b836001600160a01b0381163314611a9357611a93336121a8565b6112f385858585612ddc565b6060611aaa8261238a565b611b0e5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b606482015260840161094d565b6000828152601460209081526040808320815180830183528154808252600190920154818501528185526016909352908320805492939192611b4f90615139565b80601f0160208091040260200160405190810160405280929190818152602001828054611b7b90615139565b8015611bc85780601f10611b9d57610100808354040283529160200191611bc8565b820191906000526020600020905b815481529060010190602001808311611bab57829003601f168201915b505050505090506000601660008481526020019081526020016000206001018054611bf290615139565b80601f0160208091040260200160405190810160405280929190818152602001828054611c1e90615139565b8015611c6b5780601f10611c4057610100808354040283529160200191611c6b565b820191906000526020600020905b815481529060010190602001808311611c4e57829003601f168201915b5050505050905060008151118015611c84575060008251115b15611c9f57611c9583878484612e0e565b9695505050505050565b60008681526011602052604090206001018054611c959190611cc090615139565b80601f0160208091040260200160405190810160405280929190818152602001828054611cec90615139565b8015611d395780601f10611d0e57610100808354040283529160200191611d39565b820191906000526020600020905b815481529060010190602001808311611d1c57829003601f168201915b5050505050613100565b611d4b6120fe565b6001600160a01b03166000908152600b60205260409020805460ff19166001179055565b6060600e805461080890615139565b611d866120fe565b6001600160a01b038116611deb5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161094d565b611df481612b08565b50565b600c54600160a01b900460ff16611e665760405162461bcd60e51b815260206004820152602d60248201527f466572616c66696c6545786869626974696f6e56333a206e6f7420616c6c6f7760448201526c10313ab9371032b234ba34b7b760991b606482015260840161094d565b60005b8151811015610b5557611e94828281518110611e8757611e87615326565b602002602001015161238a565b611eb05760405162461bcd60e51b815260040161094d906153f3565b611ed333838381518110611ec657611ec6615326565b60200260200101516131e4565b611eef5760405162461bcd60e51b815260040161094d90615437565b600060116000848481518110611f0757611f07615326565b6020026020010151815260200190815260200160002060405180604001604052908160008201548152602001600182018054611f4290615139565b80601f0160208091040260200160405190810160405280929190818152602001828054611f6e90615139565b8015611fbb5780601f10611f9057610100808354040283529160200191611fbb565b820191906000526020600020905b815481529060010190602001808311611f9e57829003601f168201915b505050505081525050905060138160200151604051611fda919061518f565b908152604051908190036020019020805460ff19169055825160119060009085908590811061200b5761200b615326565b6020026020010151815260200190815260200160002060008082016000905560018201600061203a9190614756565b505061205e83838151811061205157612051615326565b6020026020010151613262565b61208083838151811061207357612073615326565b602002602001015161347b565b82828151811061209257612092615326565b60200260200101517fa5a44c7ed36966786612323ee2cb0cb453d4a9282b90c6befe72cde41d83f48860405160405180910390a250806120d181615352565b915050611e69565b60006001600160e01b0319821663780e9d6360e01b14806107ca57506107ca8261351e565b600a546001600160a01b031633146114ae5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161094d565b6121618161238a565b611df45760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604482015260640161094d565b6015546001600160a01b03163b15611df457601554604051633185c44d60e21b81523060048201526001600160a01b0383811660248301529091169063c617113490604401602060405180830381865afa15801561220a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061222e9190615485565b611df45760405162461bcd60e51b815260206004820152601760248201527f6f70657261746f72206973206e6f7420616c6c6f776564000000000000000000604482015260640161094d565b600061228582611369565b9050806001600160a01b0316836001600160a01b0316036122f25760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161094d565b336001600160a01b038216148061230e575061230e81336106cb565b6123805760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000606482015260840161094d565b6108c6838361356e565b6000908152600260205260409020546001600160a01b0316151590565b6000858152601060205260409020600301546124195760405162461bcd60e51b815260206004820152602b60248201527f466572616c66696c6545786869626974696f6e56333a20617274776f726b206960448201526a1cc81b9bdd08199bdd5b9960aa1b606482015260840161094d565b6000858152601060205260409020600581015460048201546003909201549091612442916153a4565b61244c91906153a4565b84106124d55760405162461bcd60e51b815260206004820152604c60248201527f466572616c66696c6545786869626974696f6e56333a2065646974696f6e206e60448201527f756d62657220657863656564207468652065646974696f6e2073697a65206f6660648201526b2074686520617274776f726b60a01b608482015260a40161094d565b6001600160a01b0383166125245760405162461bcd60e51b8152602060048201526016602482015275696e76616c696420617274697374206164647265737360501b604482015260640161094d565b6001600160a01b0382166125725760405162461bcd60e51b8152602060048201526015602482015274696e76616c6964206f776e6572206164647265737360581b604482015260640161094d565b601381604051612582919061518f565b9081526040519081900360200190205460ff16156125db5760405162461bcd60e51b81526020600482015260166024820152751a5c199cc81a59081a185cc81c9959da5cdd195c995960521b604482015260640161094d565b60006125e785876153a4565b6000818152601160205260409020549091501561265d5760405162461bcd60e51b815260206004820152602e60248201527f466572616c66696c6545786869626974696f6e56333a2074686520656469746960448201526d1bdb881a5cc8195e1a5cdd195b9d60921b606482015260840161094d565b6040805180820182528281526020808201858152600085815260119092529290208151815591519091829160018201906126979082615267565b505050600087815260126020818152604080842080546001818101835582875284872090910188905582518084019093528c8352948c905292825291549192908301916126e491906153b7565b9052600083815260146020908152604091829020835181559201516001928301555160139061271490869061518f565b908152604051908190036020019020805491151560ff1990921691909117905561273e85836135dc565b836001600160a01b0316856001600160a01b03161461277257612772858584604051806020016040528060008152506135f6565b8187856001600160a01b03167f4f21e8cd53f1df1da42ec94ba03f881c1185607b26e4dcb81941535157d73dd460405160405180910390a450505050505050565b6127bd33826131e4565b6127d95760405162461bcd60e51b815260040161094d906154a2565b6108c6838383613629565b6108c683838360405180602001604052806000815250611a79565b6000855160000361284b5760405162461bcd60e51b81526020600482015260166024820152757469746c652063616e206e6f7420626520656d70747960501b604482015260640161094d565b845160000361289c5760405162461bcd60e51b815260206004820152601760248201527f6172746973742063616e206e6f7420626520656d707479000000000000000000604482015260640161094d565b86516000036128ed5760405162461bcd60e51b815260206004820152601c60248201527f66696e6765727072696e742063616e206e6f7420626520656d70747900000000604482015260640161094d565b600084116129495760405162461bcd60e51b815260206004820152602360248201527f65646974696f6e2073697a65206e6565647320746f206265206174206c65617360448201526274203160e81b606482015260840161094d565b60008760405160200161295c9190614859565b60408051601f19818403018152918152815160209283012060008181526010909352912060020180549192509061299290615139565b159050612a075760405162461bcd60e51b815260206004820152603b60248201527f616e20617274776f726b2077697468207468652073616d652066696e6765727060448201527f72696e742068617320616c726561647920726567697374657265640000000000606482015260840161094d565b6040805160c08101825288815260208082018990528183018b9052606082018890526080820187905260a08201869052600f8054600181019091557f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80201849055600084815260109091529190912081518291908190612a869082615267565b5060208201516001820190612a9b9082615267565b5060408201516002820190612ab09082615267565b50606082015160038201556080820151600482015560a09091015160059091015560405182907f22350b25f1b72bb3621199a79abefeb4fcd77bb1e65638cd09350666e4db089190600090a250979650505050505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b612b67816040015161238a565b612b835760405162461bcd60e51b815260040161094d906153f3565b612b95816000015182604001516131e4565b612bb15760405162461bcd60e51b815260040161094d90615437565b8060600151421115612c245760405162461bcd60e51b815260206004820152603660248201527f466572616c66696c6545786869626974696f6e56333a20746865207472616e7360448201527519995c881c995c5d595cdd081a5cc8195e1c1a5c995960521b606482015260840161094d565b60008160000151826020015183604001518460600151604051602001612c7194939291906001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b604051602081830303815290604052805190602001209050612ca681836000015184608001518560a001518660c0015161379a565b612d185760405162461bcd60e51b815260206004820152603d60248201527f466572616c66696c6545786869626974696f6e56333a20746865207472616e7360448201527f6665722072657175657374206973206e6f7420617574686f72697a6564000000606482015260840161094d565b610b55826000015183602001518460400151604051806020016040528060008152506135f6565b610b5533838361381a565b60606000612d57836138e8565b60010190506000816001600160401b03811115612d7657612d766148b1565b6040519080825280601f01601f191660200182016040528015612da0576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084612daa57509392505050565b612de633836131e4565b612e025760405162461bcd60e51b815260040161094d906154a2565b610a38848484846135f6565b60606000601060008781526020019081526020016000206040518060c0016040529081600082018054612e4090615139565b80601f0160208091040260200160405190810160405280929190818152602001828054612e6c90615139565b8015612eb95780601f10612e8e57610100808354040283529160200191612eb9565b820191906000526020600020905b815481529060010190602001808311612e9c57829003601f168201915b50505050508152602001600182018054612ed290615139565b80601f0160208091040260200160405190810160405280929190818152602001828054612efe90615139565b8015612f4b5780601f10612f2057610100808354040283529160200191612f4b565b820191906000526020600020905b815481529060010190602001808311612f2e57829003601f168201915b50505050508152602001600282018054612f6490615139565b80601f0160208091040260200160405190810160405280929190818152602001828054612f9090615139565b8015612fdd5780601f10612fb257610100808354040283529160200191612fdd565b820191906000526020600020905b815481529060010190602001808311612fc057829003601f168201915b505050505081526020016003820154815260200160048201548152602001600582015481525050905060006130118661178b565b9050600082600001518260405160200161302c9291906154ef565b60405160208183030381529060405290506130d361304988612d4a565b8285602001516130588c6139c0565b613065611a498e8e6153b7565b8760405160200161307b9695949392919061552b565b60405160208183030381529060405261309388613100565b6130ad61309f8c6139d7565b6130a88a613100565b613b97565b6040516020016130bf9392919061564f565b604051602081830303815290604052613bb6565b6040516020016130e39190615726565b60405160208183030381529060405293505050505b949350505050565b60606000600d805461311190615139565b80601f016020809104026020016040519081016040528092919081815260200182805461313d90615139565b801561318a5780601f1061315f5761010080835404028352916020019161318a565b820191906000526020600020905b81548152906001019060200180831161316d57829003601f168201915b5050505050905080516000036131ba5750604080518082019091526007815266697066733a2f2f60c81b60208201525b80836040516020016131cd92919061576b565b604051602081830303815290604052915050919050565b6000806131f083611369565b9050806001600160a01b0316846001600160a01b0316148061323757506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806130f85750836001600160a01b03166132508461088b565b6001600160a01b031614949350505050565b60008181526014602090815260409182902082518084019093528054808452600190910154918301919091526133115760405162461bcd60e51b815260206004820152604860248201527f466572616c66696c6545786869626974696f6e56333a20617274776f726b494460448201527f206973206e6f20666f756e6420666f722074686520617274776f726b456469746064820152670d2dedc92dcc8caf60c31b608482015260a40161094d565b8051600090815260126020526040902080546133a65760405162461bcd60e51b815260206004820152604860248201527f466572616c66696c6545786869626974696f6e56333a206e6f2065646974696f60448201527f6e7320696e207468697320617274776f726b206f6620616c6c417274776f726b60648201526745646974696f6e7360c01b608482015260a40161094d565b80546000906133b7906001906153b7565b9050600082600184805490506133cd91906153b7565b815481106133dd576133dd615326565b90600052602060002001549050808385602001518154811061340157613401615326565b9060005260206000200181905550836020015183838154811061342657613426615326565b9060005260206000200181905550828054806134445761344461579a565b6000828152602080822083016000199081018390559092019092559581526014909552505060408320838155600101929092555050565b600061348682611369565b9050613496816000846001613d08565b61349f82611369565b600083815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526003845282852080546000190190558785526002909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60006001600160e01b031982166380ac58cd60e01b148061354f57506001600160e01b03198216635b5e139f60e01b145b806107ca57506301ffc9a760e01b6001600160e01b03198316146107ca565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906135a382611369565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b610b55828260405180602001604052806000815250613e41565b613601848484613629565b61360d84848484613e74565b610a385760405162461bcd60e51b815260040161094d906157b0565b826001600160a01b031661363c82611369565b6001600160a01b0316146136625760405162461bcd60e51b815260040161094d90615802565b6001600160a01b0382166136c45760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161094d565b6136d18383836001613d08565b826001600160a01b03166136e482611369565b6001600160a01b03161461370a5760405162461bcd60e51b815260040161094d90615802565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000806137ff6137f7886040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b848787613f72565b6001600160a01b039081169087161491505095945050505050565b816001600160a01b0316836001600160a01b03160361387b5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161094d565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106139275772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310613953576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061397157662386f26fc10000830492506010015b6305f5e1008310613989576305f5e100830492506008015b612710831061399d57612710830492506004015b606483106139af576064830492506002015b600a83106107ca5760010192915050565b60606107ca826139cf84613f9a565b600101614004565b601754600082815260126020908152604080832080548251818502810185019093528083526060956001600160a01b03169493830182828015613a3957602002820191906000526020600020905b815481526020019060010190808311613a25575b50506040805180820190915260018152607b60f81b60208201529394506000925050505b8251811015613adc576000838281518110613a7a57613a7a615326565b6020026020010151905082613a948883611a4991906153b7565b613aa5613aa084611369565b61419f565b604051602001613ab793929190615847565b6040516020818303038152906040529250508080613ad490615352565b915050613a5d565b5080604051602001613aee91906158a7565b60408051601f19818403018152908290526018546331a9108f60e11b835260048301529150613b6c906001600160a01b03851690636352211e90602401602060405180830381865afa158015613b48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613aa091906158cc565b81604051602001613b7e9291906158e9565b6040516020818303038152906040529350505050919050565b6060613baf83836040516020016130bf929190615957565b9392505050565b60608151600003613bd557505060408051602081019091526000815290565b6000604051806060016040528060408152602001615f666040913990506000600384516002613c0491906153a4565b613c0e9190615382565b613c1990600461536b565b6001600160401b03811115613c3057613c306148b1565b6040519080825280601f01601f191660200182016040528015613c5a576020820181803683370190505b509050600182016020820185865187015b80821015613cc6576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250613c6b565b5050600386510660018114613ce25760028114613cf557613cfd565b603d6001830353603d6002830353613cfd565b603d60018303535b509195945050505050565b613d14848484846141b5565b6001811115613d835760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b606482015260840161094d565b816001600160a01b038516613ddf57613dda81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b613e02565b836001600160a01b0316856001600160a01b031614613e0257613e02858261423d565b6001600160a01b038416613e1e57613e19816142da565b6112f3565b846001600160a01b0316846001600160a01b0316146112f3576112f38482614389565b613e4b83836143cd565b613e586000848484613e74565b6108c65760405162461bcd60e51b815260040161094d906157b0565b60006001600160a01b0384163b15613f6a57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613eb8903390899088908890600401615ee8565b6020604051808303816000875af1925050508015613ef3575060408051601f3d908101601f19168201909252613ef091810190615f1b565b60015b613f50573d808015613f21576040519150601f19603f3d011682016040523d82523d6000602084013e613f26565b606091505b508051600003613f485760405162461bcd60e51b815260040161094d906157b0565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506130f8565b5060016130f8565b6000806000613f8387878787614548565b91509150613f908161460c565b5095945050505050565b600080608083901c15613fb25760809290921c916010015b604083901c15613fc75760409290921c916008015b602083901c15613fdc5760209290921c916004015b601083901c15613ff15760109290921c916002015b600883901c156107ca5760010192915050565b6060600061401383600261536b565b61401e9060026153a4565b6001600160401b03811115614035576140356148b1565b6040519080825280601f01601f19166020018201604052801561405f576020820181803683370190505b509050600360fc1b8160008151811061407a5761407a615326565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106140a9576140a9615326565b60200101906001600160f81b031916908160001a90535060006140cd84600261536b565b6140d89060016153a4565b90505b6001811115614150576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061410c5761410c615326565b1a60f81b82828151811061412257614122615326565b60200101906001600160f81b031916908160001a90535060049490941c9361414981615f38565b90506140db565b508315613baf5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161094d565b60606107ca6001600160a01b0383166014614004565b6001811115610a38576001600160a01b038416156141fb576001600160a01b038416600090815260036020526040812080548392906141f59084906153b7565b90915550505b6001600160a01b03831615610a38576001600160a01b038316600090815260036020526040812080548392906142329084906153a4565b909155505050505050565b6000600161424a84611416565b61425491906153b7565b6000838152600760205260409020549091508082146142a7576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b6008546000906142ec906001906153b7565b6000838152600960205260408120546008805493945090928490811061431457614314615326565b90600052602060002001549050806008838154811061433557614335615326565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061436d5761436d61579a565b6001900381819060005260206000200160009055905550505050565b600061439483611416565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b0382166144235760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161094d565b61442c8161238a565b156144795760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161094d565b614487600083836001613d08565b6144908161238a565b156144dd5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161094d565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561457f5750600090506003614603565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156145d3573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166145fc57600060019250925050614603565b9150600090505b94509492505050565b600081600481111561462057614620615f4f565b036146285750565b600181600481111561463c5761463c615f4f565b036146895760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161094d565b600281600481111561469d5761469d615f4f565b036146ea5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161094d565b60038160048111156146fe576146fe615f4f565b03611df45760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161094d565b50805461476290615139565b6000825580601f10614772575050565b601f016020900490600052602060002090810190611df491905b808211156147a0576000815560010161478c565b5090565b6001600160e01b031981168114611df457600080fd5b6000602082840312156147cc57600080fd5b8135613baf816147a4565b6001600160a01b0381168114611df457600080fd5b6000602082840312156147fe57600080fd5b8135613baf816147d7565b60005b8381101561482457818101518382015260200161480c565b50506000910152565b60008151808452614845816020860160208601614809565b601f01601f19169290920160200192915050565b602081526000613baf602083018461482d565b60006020828403121561487e57600080fd5b5035919050565b6000806040838503121561489857600080fd5b82356148a3816147d7565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b03811182821017156148e9576148e96148b1565b60405290565b60405160c081016001600160401b03811182821017156148e9576148e96148b1565b60405160e081016001600160401b03811182821017156148e9576148e96148b1565b604051601f8201601f191681016001600160401b038111828210171561495b5761495b6148b1565b604052919050565b60006001600160401b0383111561497c5761497c6148b1565b61498f601f8401601f1916602001614933565b90508281528383830111156149a357600080fd5b828260208301376000602084830101529392505050565b600082601f8301126149cb57600080fd5b613baf83833560208501614963565b600080604083850312156149ed57600080fd5b8235915060208301356001600160401b03811115614a0a57600080fd5b614a16858286016149ba565b9150509250929050565b60006001600160401b03821115614a3957614a396148b1565b5060051b60200190565b60006020808385031215614a5657600080fd5b82356001600160401b0380821115614a6d57600080fd5b818501915085601f830112614a8157600080fd5b8135614a94614a8f82614a20565b614933565b81815260059190911b83018401908481019088831115614ab357600080fd5b8585015b83811015614b5d57803585811115614acf5760008081fd5b860160a0818c03601f1901811315614ae75760008081fd5b614aef6148c7565b8983013581526040808401358b830152606080850135614b0e816147d7565b8083850152506080915081850135614b25816147d7565b90830152918301359188831115614b3c5760008081fd5b614b4a8e8c858701016149ba565b9082015285525050918601918601614ab7565b5098975050505050505050565b600080600060608486031215614b7f57600080fd5b8335614b8a816147d7565b92506020840135614b9a816147d7565b929592945050506040919091013590565b60008060408385031215614bbe57600080fd5b50508035926020909101359150565b604081526000614be0604083018561482d565b8281036020840152614bf2818561482d565b95945050505050565b600060c08284031215614c0d57600080fd5b614c156148ef565b905081356001600160401b0380821115614c2e57600080fd5b614c3a858386016149ba565b83526020840135915080821115614c5057600080fd5b614c5c858386016149ba565b60208401526040840135915080821115614c7557600080fd5b50614c82848285016149ba565b604083015250606082013560608201526080820135608082015260a082013560a082015292915050565b60006020808385031215614cbf57600080fd5b82356001600160401b0380821115614cd657600080fd5b818501915085601f830112614cea57600080fd5b8135614cf8614a8f82614a20565b81815260059190911b83018401908481019088831115614d1757600080fd5b8585015b83811015614b5d57803585811115614d335760008081fd5b614d418b89838a0101614bfb565b845250918601918601614d1b565b60c081526000614d6260c083018961482d565b8281036020840152614d74818961482d565b90508281036040840152614d88818861482d565b60608401969096525050608081019290925260a0909101529392505050565b600080600060608486031215614dbc57600080fd5b8335925060208401356001600160401b0380821115614dda57600080fd5b614de6878388016149ba565b93506040860135915080821115614dfc57600080fd5b50614e09868287016149ba565b9150509250925092565b8281526040602082015260006130f8604083018461482d565b600080600060608486031215614e4157600080fd5b83356001600160401b0380821115614e5857600080fd5b614e6487838801614bfb565b94506020860135915080821115614dda57600080fd5b600060208284031215614e8c57600080fd5b81356001600160401b03811115614ea257600080fd5b6130f8848285016149ba565b60006020808385031215614ec157600080fd5b82356001600160401b03811115614ed757600080fd5b8301601f81018513614ee857600080fd5b8035614ef6614a8f82614a20565b81815260e09182028301840191848201919088841115614f1557600080fd5b938501935b83851015614fa95780858a031215614f325760008081fd5b614f3a614911565b8535614f45816147d7565b815285870135614f54816147d7565b8188015260408681013590820152606080870135908201526080808701359082015260a0808701359082015260c08087013560ff81168114614f965760008081fd5b9082015283529384019391850191614f1a565b50979650505050505050565b8015158114611df457600080fd5b60008060408385031215614fd657600080fd5b8235614fe1816147d7565b91506020830135614ff181614fb5565b809150509250929050565b6000806000806080858703121561501257600080fd5b843561501d816147d7565b9350602085013561502d816147d7565b92506040850135915060608501356001600160401b0381111561504f57600080fd5b8501601f8101871361506057600080fd5b61506f87823560208401614963565b91505092959194509250565b6000806040838503121561508e57600080fd5b8235615099816147d7565b91506020830135614ff1816147d7565b600060208083850312156150bc57600080fd5b82356001600160401b038111156150d257600080fd5b8301601f810185136150e357600080fd5b80356150f1614a8f82614a20565b81815260059190911b8201830190838101908783111561511057600080fd5b928401925b8284101561512e57833582529284019290840190615115565b979650505050505050565b600181811c9082168061514d57607f821691505b60208210810361516d57634e487b7160e01b600052602260045260246000fd5b50919050565b60008151615185818560208601614809565b9290920192915050565b600082516151a1818460208701614809565b9190910192915050565b60008083546151b981615139565b600182811680156151d157600181146151e657615215565b60ff1984168752821515830287019450615215565b8760005260208060002060005b8581101561520c5781548a8201529084019082016151f3565b50505082870194505b50929695505050505050565b601f8211156108c657600081815260208120601f850160051c810160208610156152485750805b601f850160051c820191505b8181101561133f57828155600101615254565b81516001600160401b03811115615280576152806148b1565b6152948161528e8454615139565b84615221565b602080601f8311600181146152c957600084156152b15750858301515b600019600386901b1c1916600185901b17855561133f565b600085815260208120601f198616915b828110156152f8578886015182559484019460019091019084016152d9565b50858210156153165787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016153645761536461533c565b5060010190565b80820281158282048414176107ca576107ca61533c565b60008261539f57634e487b7160e01b600052601260045260246000fd5b500490565b808201808211156107ca576107ca61533c565b818103818111156107ca576107ca61533c565b602360f81b8152600082516153e6816001850160208701614809565b9190910160010192915050565b60208082526024908201527f4552433732313a20617274776f726b2065646974696f6e206973206e6f7420666040820152631bdd5b9960e21b606082015260800190565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b60006020828403121561549757600080fd5b8151613baf81614fb5565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60008351615501818460208801614809565b600160fd1b908301908152835161551f816001840160208801614809565b01600101949350505050565b663d9134b2111d1160c91b8152865160009061554e816007850160208c01614809565b6a111610113730b6b2911d1160a91b6007918401918201528751615579816012840160208c01614809565b6c1116101130b93a34b9ba111d1160991b6012929091019182015286516155a781601f840160208b01614809565b701116101130b93a3bb7b935afb4b2111d1160791b601f929091019182015285516155d9816030840160208a01614809565b731116101132b234ba34b7b72fb4b73232bc111d1160611b60309290910191820152845161560e816044840160208901614809565b61564161563b604483850101741116101132b234ba34b7b72fb73ab6b132b9111d1160591b815260150190565b86615173565b9a9950505050505050505050565b60008451615661818460208901614809565b80830190507f222c202265787465726e616c5f75726c223a2268747470733a2f2f666572616c8152733334b6329731b7b69116101134b6b0b3b2911d1160611b602082015284516156b9816034840160208901614809565b7f222c2022616e696d6174696f6e5f75726c223a22646174613a746578742f687460349290910191820152691b5b0ed8985cd94d8d0b60b21b6054820152835161570a81605e840160208801614809565b61227d60f01b605e929091019182015260600195945050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161575e81601d850160208701614809565b91909101601d0192915050565b6000835161577d818460208801614809565b835190830190615791818360208801614809565b01949350505050565b634e487b7160e01b600052603160045260246000fd5b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60008451615859818460208901614809565b84519083019061586d818360208901614809565b611d1160f11b9101908152835161588b816002840160208801614809565b61088b60f21b6002929091019182015260040195945050505050565b600082516158b9818460208701614809565b607d60f81b920191825250600101919050565b6000602082840312156158de57600080fd5b8151613baf816147d7565b6b3db630b73227bbb732b91d1160a11b8152825160009061591181600c850160208801614809565b6b11161037bbb732b926b0b81d60a11b600c91840191820152835161593d816018840160208801614809565b607d60f81b60189290910191820152601901949350505050565b7f3c21444f43545950452068746d6c3e3c68746d6c206c616e673d22656e223e3c81527f686561643e3c7363726970743e207661722064656661756c74417274776f726b60208201526502230ba309e960d51b6040820152600083516159c4816046850160208801614809565b7f3c2f7363726970743e3c7363726970743e6c657420616c6c6f774f726967696e6046918401918201527f733d7b2268747470733a2f2f666572616c66696c652e636f6d223a21307d3b6660668201527f756e6374696f6e20726573697a65496672616d652865297b6c657420743d646f60868201527f63756d656e742e676574456c656d656e744279496428226d61696e6672616d6560a68201527f22293b65262628742e7374796c652e6d696e4865696768743d652b227078222960c68201527f7d66756e6374696f6e20696e69744461746128297b64656661756c744172747760e68201527f6f726b446174612e6f776e657241727261793d5b5d3b6c657420653d646566616101068201527f756c74417274776f726b446174612e6f776e65724d61703b4f626a6563742e6b6101268201527f6579732865292e736f72742828652c74293d3e653c74292e666f7245616368286101468201527f743d3e7b64656661756c74417274776f726b446174612e6f776e6572417272616101668201527f792e7075736828655b745d297d292c70757368417274776f726b44617461546f6101868201527f496672616d652864656661756c74417274776f726b44617461297d66756e63746101a68201527f696f6e2070757368417274776f726b44617461546f496672616d652865297b656101c68201527f2626646f63756d656e742e676574456c656d656e744279496428226d61696e666101e68201527f72616d6522292e636f6e74656e7457696e646f772e706f73744d6573736167656102068201527f28652c222a22297d66756e6374696f6e207570646174654172746f77726b44616102268201527f74612865297b646f63756d656e742e676574456c656d656e744279496428226d6102468201527f61696e6672616d6522292e636f6e74656e7457696e646f772e706f73744d65736102668201527f7361676528652c222a22297d77696e646f772e6164644576656e744c697374656102868201527f6e657228226d657373616765222c66756e6374696f6e2865297b616c6c6f774f6102a68201527f726967696e735b652e6f726967696e5d3f227570646174652d617274776f726b6102c68201527f2d64617461223d3d3d652e646174612e7479706526267570646174654172746f6102e68201527f77726b4461746128652e646174612e617274776f726b44617461293a226f626a6103068201527f656374223d3d747970656f6620652e64617461262622726573697a652d6966726103268201527f616d65223d3d3d652e646174612e747970652626726573697a65496672616d656103468201527f28652e646174612e6e6577486569676874297d293b3c2f7363726970743e3c2f6103668201527f686561643e3c626f6479207374796c653d226f766572666c6f772d783a6869646103868201527f64656e3b70616464696e673a303b6d617267696e3a303b77696474683a3130306103a68201527f253b22206f6e6c6f61643d22696e6974446174612829223e3c696672616d65206103c68201527f69643d226d61696e6672616d6522207374796c653d22646973706c61793a626c6103e68201527f6f636b3b70616464696e673a303b6d617267696e3a303b626f726465723a6e6f6104068201527f6e653b77696474683a313030253b6865696768743a31303076683b2220737263610426820152611e9160f11b610446820152614bf2615ebf610448830186615173565b7f223e3c2f696672616d653e203c2f626f64793e3c2f68746d6c3e0000000000008152601a0190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611c959083018461482d565b600060208284031215615f2d57600080fd5b8151613baf816147a4565b600081615f4757615f4761533c565b506000190190565b634e487b7160e01b600052602160045260246000fdfe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa264697066735822122042d0608f6bdeba088885bbc80c16f7e3dcf49b66daa3e70507924c01e202d7ef64736f6c634300081100330000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000007d0000000000000000000000000080feb125ba730d6d12789b6aaab01f4e31d8bd10000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001b466572616c2046696c6520e28094205065657220746f2050656572000000000000000000000000000000000000000000000000000000000000000000000000054646303234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c68747470733a2f2f697066732e6269746d61726b2e636f6d2f697066732f516d6278476e45594e6b313478466331465545736662515944387a6a4d396f6e6f696d55393135596e384761784c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e68747470733a2f2f697066732e6269746d61726b2e636f6d2f697066732f0000

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061030c5760003560e01c806370a082311161019d578063b88d4fde116100e9578063ea211d7c116100a2578063f07e7fd01161007c578063f07e7fd01461074c578063f2fde38b1461075f578063fc05ea6814610772578063fe2a3bf31461078557600080fd5b8063ea211d7c146106f9578063ec9cbb4414610720578063eee608a41461072957600080fd5b8063b88d4fde14610674578063c87b56dd14610687578063dc78ac1c1461069a578063e4a233e1146106ad578063e8a3d485146106b5578063e985e9c5146106bd57600080fd5b80638ef79e9111610156578063a170bf0311610130578063a170bf0314610628578063a22cb4651461063b578063b48837031461064e578063b6358d991461066157600080fd5b80638ef79e91146105fa57806395d89b411461060d5780639fbf39cd1461061557600080fd5b806370a0823114610593578063715018a6146105a65780637ca5ea89146105ae5780637e22b1a4146105c2578063883356d9146105d55780638da5cb5b146105e957600080fd5b8063367d14971161025c5780634b6026731161021557806362fe2131116101ef57806362fe2131146105185780636352211e1461053957806363e602301461054c578063641b18e91461058057600080fd5b80634b602673146104cd5780634f6ccce7146104f2578063587056f61461050557600080fd5b8063367d1497146104575780633f6805ba1461047857806342842e0e1461048b57806343deaf761461049e57806345aeefde146104b15780634744254b146104c457600080fd5b8063114ba8ee116102c957806318701151116102a357806318701151146103ec57806323b872dd146103ff5780632a55205a146104125780632f745c591461044457600080fd5b8063114ba8ee146103b457806312d907b9146103c757806318160ddd146103da57600080fd5b806301ffc9a714610311578063031205061461033957806306fdde031461034e578063081812fc14610363578063095ea7b31461038e5780630cfcb5f1146103a1575b600080fd5b61032461031f3660046147ba565b6107a5565b60405190151581526020015b60405180910390f35b61034c6103473660046147ec565b6107d0565b005b6103566107f9565b6040516103309190614859565b61037661037136600461486c565b61088b565b6040516001600160a01b039091168152602001610330565b61034c61039c366004614885565b6108b2565b61034c6103af3660046149da565b6108cb565b61034c6103c23660046147ec565b610a3e565b61034c6103d5366004614a43565b610a68565b6008545b604051908152602001610330565b601754610376906001600160a01b031681565b61034c61040d366004614b6a565b610b59565b610425610420366004614bab565b610b7e565b604080516001600160a01b039093168352602083019190915201610330565b6103de610452366004614885565b610c3e565b61046a61046536600461486c565b610cd4565b604051610330929190614bcd565b600c54610376906001600160a01b031681565b61034c610499366004614b6a565b610e00565b61034c6104ac366004614cac565b610e25565b61034c6104bf3660046147ec565b610f31565b6103de60185481565b6104e06104db36600461486c565b610fda565b60405161033096959493929190614d4f565b6103de61050036600461486c565b6111a6565b61034c610513366004614da7565b611239565b61052b61052636600461486c565b611347565b604051610330929190614e13565b61037661054736600461486c565b611369565b61035660405180604001604052806015815260200174466572616c66696c6545786869626974696f6e563360581b81525081565b6103de61058e366004614bab565b6113c9565b6103de6105a13660046147ec565b611416565b61034c61149c565b600c5461032490600160a81b900460ff1681565b61034c6105d0366004614e2c565b6114b0565b600c5461032490600160a01b900460ff1681565b600a546001600160a01b0316610376565b61034c610608366004614e7a565b611614565b610356611651565b61034c610623366004614eae565b611660565b61034c610636366004614885565b6116d1565b61034c610649366004614fc3565b6116ff565b6103de61065c36600461486c565b611713565b61035661066f36600461486c565b61178b565b61034c610682366004614ffc565b611a79565b61035661069536600461486c565b611a9f565b61034c6106a83660046147ec565b611d43565b600f546103de565b610356611d6f565b6103246106cb36600461507b565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6103de7f00000000000000000000000000000000000000000000000000000000000007d081565b6103de61271081565b6103246107373660046147ec565b600b6020526000908152604090205460ff1681565b601554610376906001600160a01b031681565b61034c61076d3660046147ec565b611d7e565b61034c6107803660046150a9565b611df7565b6103de61079336600461486c565b60009081526012602052604090205490565b60006001600160e01b0319821663780e9d6360e01b14806107ca57506107ca826120d9565b92915050565b6107d86120fe565b6001600160a01b03166000908152600b60205260409020805460ff19169055565b60606000805461080890615139565b80601f016020809104026020016040519081016040528092919081815260200182805461083490615139565b80156108815780601f1061085657610100808354040283529160200191610881565b820191906000526020600020905b81548152906001019060200180831161086457829003601f168201915b5050505050905090565b600061089682612158565b506000908152600460205260409020546001600160a01b031690565b816108bc816121a8565b6108c6838361227a565b505050565b336000908152600b602052604090205460ff16806108f35750600a546001600160a01b031633145b6108fc57600080fd5b6109058261238a565b6109565760405162461bcd60e51b815260206004820152601c60248201527f617274776f726b2065646974696f6e206973206e6f7420666f756e640000000060448201526064015b60405180910390fd5b601381604051610966919061518f565b9081526040519081900360200190205460ff16156109bf5760405162461bcd60e51b81526020600482015260166024820152751a5c199cc81a59081a185cc81c9959da5cdd195c995960521b604482015260640161094d565b6000828152601160205260409081902090516013906109e29060018401906151ab565b908152604051908190036020018120805460ff19169055600190601390610a0a90859061518f565b908152604051908190036020019020805491151560ff1990921691909117905560018101610a388382615267565b50505050565b610a466120fe565b601580546001600160a01b0319166001600160a01b0392909216919091179055565b336000908152600b602052604090205460ff1680610a905750600a546001600160a01b031633145b610a9957600080fd5b60005b8151811015610b5557610b43828281518110610aba57610aba615326565b602002602001015160000151838381518110610ad857610ad8615326565b602002602001015160200151848481518110610af657610af6615326565b602002602001015160400151858581518110610b1457610b14615326565b602002602001015160600151868681518110610b3257610b32615326565b6020026020010151608001516123a7565b80610b4d81615352565b915050610a9c565b5050565b826001600160a01b0381163314610b7357610b73336121a8565b610a388484846127b3565b600080610b8a8461238a565b610bf05760405162461bcd60e51b815260206004820152603160248201527f455243323938313a20717565727920726f79616c747920696e666f20666f72206044820152703737b732bc34b9ba32b73a103a37b5b2b760791b606482015260840161094d565b600c546001600160a01b03169150612710610c2b7f00000000000000000000000000000000000000000000000000000000000007d08561536b565b610c359190615382565b90509250929050565b6000610c4983611416565b8210610cab5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161094d565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b601660205260009081526040902080548190610cef90615139565b80601f0160208091040260200160405190810160405280929190818152602001828054610d1b90615139565b8015610d685780601f10610d3d57610100808354040283529160200191610d68565b820191906000526020600020905b815481529060010190602001808311610d4b57829003601f168201915b505050505090806001018054610d7d90615139565b80601f0160208091040260200160405190810160405280929190818152602001828054610da990615139565b8015610df65780601f10610dcb57610100808354040283529160200191610df6565b820191906000526020600020905b815481529060010190602001808311610dd957829003601f168201915b5050505050905082565b826001600160a01b0381163314610e1a57610e1a336121a8565b610a388484846127e4565b336000908152600b602052604090205460ff1680610e4d5750600a546001600160a01b031633145b610e5657600080fd5b60005b8151811015610b5557610f1e828281518110610e7757610e77615326565b602002602001015160400151838381518110610e9557610e95615326565b602002602001015160000151848481518110610eb357610eb3615326565b602002602001015160200151858581518110610ed157610ed1615326565b602002602001015160600151868681518110610eef57610eef615326565b602002602001015160800151878781518110610f0d57610f0d615326565b602002602001015160a001516127ff565b5080610f2981615352565b915050610e59565b336000908152600b602052604090205460ff1680610f595750600a546001600160a01b031633145b610f6257600080fd5b6001600160a01b038116610fb85760405162461bcd60e51b815260206004820152601e60248201527f696e76616c696420726f79616c7479207061796f757420616464726573730000604482015260640161094d565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b601060205260009081526040902080548190610ff590615139565b80601f016020809104026020016040519081016040528092919081815260200182805461102190615139565b801561106e5780601f106110435761010080835404028352916020019161106e565b820191906000526020600020905b81548152906001019060200180831161105157829003601f168201915b50505050509080600101805461108390615139565b80601f01602080910402602001604051908101604052809291908181526020018280546110af90615139565b80156110fc5780601f106110d1576101008083540402835291602001916110fc565b820191906000526020600020905b8154815290600101906020018083116110df57829003601f168201915b50505050509080600201805461111190615139565b80601f016020809104026020016040519081016040528092919081815260200182805461113d90615139565b801561118a5780601f1061115f5761010080835404028352916020019161118a565b820191906000526020600020905b81548152906001019060200180831161116d57829003601f168201915b5050505050908060030154908060040154908060050154905086565b60006111b160085490565b82106112145760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161094d565b6008828154811061122757611227615326565b90600052602060002001549050919050565b6112416120fe565b6000838152601060205260409020600201805461125d90615139565b90506000036112b95760405162461bcd60e51b815260206004820152602260248201527f7468652074617267657420617274776f726b206973206e6f74206578697374656044820152611b9d60f21b606482015260840161094d565b81511580156112c757508051155b156112fa576000838152601660205260408120906112e58282614756565b6112f3600183016000614756565b5050505050565b604080518082018252838152602080820184905260008681526016909152919091208151819061132a9082615267565b506020820151600182019061133f9082615267565b505050505050565b60116020526000908152604090208054600182018054919291610d7d90615139565b6000818152600260205260408120546001600160a01b0316806107ca5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604482015260640161094d565b60008281526012602052604081205482106113e357600080fd5b600083815260126020526040902080548390811061140357611403615326565b9060005260206000200154905092915050565b60006001600160a01b0382166114805760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b606482015260840161094d565b506001600160a01b031660009081526003602052604090205490565b6114a46120fe565b6114ae6000612b08565b565b336000908152600b602052604090205460ff16806114d85750600a546001600160a01b031633145b6114e157600080fd5b815160000361153e5760405162461bcd60e51b815260206004820152602360248201527f7468756d626e61696c2049504653204349442063616e206e6f7420626520656d60448201526270747960e81b606482015260840161094d565b80516000036115995760405162461bcd60e51b815260206004820152602160248201527f617274776f726b2049504653204349442063616e206e6f7420626520656d70746044820152607960f81b606482015260840161094d565b60006115c1846040015185600001518660200151876060015188608001518960a001516127ff565b604080518082018252858152602080820186905260008481526016909152919091208151929350909181906115f69082615267565b506020820151600182019061160b9082615267565b50505050505050565b336000908152600b602052604090205460ff168061163c5750600a546001600160a01b031633145b61164557600080fd5b600d610b558282615267565b60606001805461080890615139565b336000908152600b602052604090205460ff16806116885750600a546001600160a01b031633145b61169157600080fd5b60005b8151811015610b55576116bf8282815181106116b2576116b2615326565b6020026020010151612b5a565b806116c981615352565b915050611694565b6116d96120fe565b601780546001600160a01b0319166001600160a01b039390931692909217909155601855565b81611709816121a8565b6108c68383612d3f565b600061171e600f5490565b82106117785760405162461bcd60e51b8152602060048201526024808201527f617274776f726b733a20676c6f62616c20696e646578206f7574206f6620626f604482015263756e647360e01b606482015260840161094d565b600f828154811061122757611227615326565b6000818152601460209081526040808320815180830183528154808252600190920154818501528185526010909352818420825160c08101909352805460609592939190829082906117dc90615139565b80601f016020809104026020016040519081016040528092919081815260200182805461180890615139565b80156118555780601f1061182a57610100808354040283529160200191611855565b820191906000526020600020905b81548152906001019060200180831161183857829003601f168201915b5050505050815260200160018201805461186e90615139565b80601f016020809104026020016040519081016040528092919081815260200182805461189a90615139565b80156118e75780601f106118bc576101008083540402835291602001916118e7565b820191906000526020600020905b8154815290600101906020018083116118ca57829003601f168201915b5050505050815260200160028201805461190090615139565b80601f016020809104026020016040519081016040528092919081815260200182805461192c90615139565b80156119795780601f1061194e57610100808354040283529160200191611979565b820191906000526020600020905b81548152906001019060200180831161195c57829003601f168201915b505050505081526020016003820154815260200160048201548152602001600582015481525050905060008160800151836119b491906153a4565b905060008260a001518360800151856119cd91906153a4565b6119d791906153a4565b905081871015611a05575050604080518082019091526002815261414560f01b602082015295945050505050565b80871015611a31575050604080518082019091526002815261050560f41b602082015295945050505050565b611a4e611a3e82896153b7565b611a499060016153a4565b612d4a565b604051602001611a5e91906153ca565b60405160208183030381529060405295505050505050919050565b836001600160a01b0381163314611a9357611a93336121a8565b6112f385858585612ddc565b6060611aaa8261238a565b611b0e5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b606482015260840161094d565b6000828152601460209081526040808320815180830183528154808252600190920154818501528185526016909352908320805492939192611b4f90615139565b80601f0160208091040260200160405190810160405280929190818152602001828054611b7b90615139565b8015611bc85780601f10611b9d57610100808354040283529160200191611bc8565b820191906000526020600020905b815481529060010190602001808311611bab57829003601f168201915b505050505090506000601660008481526020019081526020016000206001018054611bf290615139565b80601f0160208091040260200160405190810160405280929190818152602001828054611c1e90615139565b8015611c6b5780601f10611c4057610100808354040283529160200191611c6b565b820191906000526020600020905b815481529060010190602001808311611c4e57829003601f168201915b5050505050905060008151118015611c84575060008251115b15611c9f57611c9583878484612e0e565b9695505050505050565b60008681526011602052604090206001018054611c959190611cc090615139565b80601f0160208091040260200160405190810160405280929190818152602001828054611cec90615139565b8015611d395780601f10611d0e57610100808354040283529160200191611d39565b820191906000526020600020905b815481529060010190602001808311611d1c57829003601f168201915b5050505050613100565b611d4b6120fe565b6001600160a01b03166000908152600b60205260409020805460ff19166001179055565b6060600e805461080890615139565b611d866120fe565b6001600160a01b038116611deb5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161094d565b611df481612b08565b50565b600c54600160a01b900460ff16611e665760405162461bcd60e51b815260206004820152602d60248201527f466572616c66696c6545786869626974696f6e56333a206e6f7420616c6c6f7760448201526c10313ab9371032b234ba34b7b760991b606482015260840161094d565b60005b8151811015610b5557611e94828281518110611e8757611e87615326565b602002602001015161238a565b611eb05760405162461bcd60e51b815260040161094d906153f3565b611ed333838381518110611ec657611ec6615326565b60200260200101516131e4565b611eef5760405162461bcd60e51b815260040161094d90615437565b600060116000848481518110611f0757611f07615326565b6020026020010151815260200190815260200160002060405180604001604052908160008201548152602001600182018054611f4290615139565b80601f0160208091040260200160405190810160405280929190818152602001828054611f6e90615139565b8015611fbb5780601f10611f9057610100808354040283529160200191611fbb565b820191906000526020600020905b815481529060010190602001808311611f9e57829003601f168201915b505050505081525050905060138160200151604051611fda919061518f565b908152604051908190036020019020805460ff19169055825160119060009085908590811061200b5761200b615326565b6020026020010151815260200190815260200160002060008082016000905560018201600061203a9190614756565b505061205e83838151811061205157612051615326565b6020026020010151613262565b61208083838151811061207357612073615326565b602002602001015161347b565b82828151811061209257612092615326565b60200260200101517fa5a44c7ed36966786612323ee2cb0cb453d4a9282b90c6befe72cde41d83f48860405160405180910390a250806120d181615352565b915050611e69565b60006001600160e01b0319821663780e9d6360e01b14806107ca57506107ca8261351e565b600a546001600160a01b031633146114ae5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161094d565b6121618161238a565b611df45760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604482015260640161094d565b6015546001600160a01b03163b15611df457601554604051633185c44d60e21b81523060048201526001600160a01b0383811660248301529091169063c617113490604401602060405180830381865afa15801561220a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061222e9190615485565b611df45760405162461bcd60e51b815260206004820152601760248201527f6f70657261746f72206973206e6f7420616c6c6f776564000000000000000000604482015260640161094d565b600061228582611369565b9050806001600160a01b0316836001600160a01b0316036122f25760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161094d565b336001600160a01b038216148061230e575061230e81336106cb565b6123805760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000606482015260840161094d565b6108c6838361356e565b6000908152600260205260409020546001600160a01b0316151590565b6000858152601060205260409020600301546124195760405162461bcd60e51b815260206004820152602b60248201527f466572616c66696c6545786869626974696f6e56333a20617274776f726b206960448201526a1cc81b9bdd08199bdd5b9960aa1b606482015260840161094d565b6000858152601060205260409020600581015460048201546003909201549091612442916153a4565b61244c91906153a4565b84106124d55760405162461bcd60e51b815260206004820152604c60248201527f466572616c66696c6545786869626974696f6e56333a2065646974696f6e206e60448201527f756d62657220657863656564207468652065646974696f6e2073697a65206f6660648201526b2074686520617274776f726b60a01b608482015260a40161094d565b6001600160a01b0383166125245760405162461bcd60e51b8152602060048201526016602482015275696e76616c696420617274697374206164647265737360501b604482015260640161094d565b6001600160a01b0382166125725760405162461bcd60e51b8152602060048201526015602482015274696e76616c6964206f776e6572206164647265737360581b604482015260640161094d565b601381604051612582919061518f565b9081526040519081900360200190205460ff16156125db5760405162461bcd60e51b81526020600482015260166024820152751a5c199cc81a59081a185cc81c9959da5cdd195c995960521b604482015260640161094d565b60006125e785876153a4565b6000818152601160205260409020549091501561265d5760405162461bcd60e51b815260206004820152602e60248201527f466572616c66696c6545786869626974696f6e56333a2074686520656469746960448201526d1bdb881a5cc8195e1a5cdd195b9d60921b606482015260840161094d565b6040805180820182528281526020808201858152600085815260119092529290208151815591519091829160018201906126979082615267565b505050600087815260126020818152604080842080546001818101835582875284872090910188905582518084019093528c8352948c905292825291549192908301916126e491906153b7565b9052600083815260146020908152604091829020835181559201516001928301555160139061271490869061518f565b908152604051908190036020019020805491151560ff1990921691909117905561273e85836135dc565b836001600160a01b0316856001600160a01b03161461277257612772858584604051806020016040528060008152506135f6565b8187856001600160a01b03167f4f21e8cd53f1df1da42ec94ba03f881c1185607b26e4dcb81941535157d73dd460405160405180910390a450505050505050565b6127bd33826131e4565b6127d95760405162461bcd60e51b815260040161094d906154a2565b6108c6838383613629565b6108c683838360405180602001604052806000815250611a79565b6000855160000361284b5760405162461bcd60e51b81526020600482015260166024820152757469746c652063616e206e6f7420626520656d70747960501b604482015260640161094d565b845160000361289c5760405162461bcd60e51b815260206004820152601760248201527f6172746973742063616e206e6f7420626520656d707479000000000000000000604482015260640161094d565b86516000036128ed5760405162461bcd60e51b815260206004820152601c60248201527f66696e6765727072696e742063616e206e6f7420626520656d70747900000000604482015260640161094d565b600084116129495760405162461bcd60e51b815260206004820152602360248201527f65646974696f6e2073697a65206e6565647320746f206265206174206c65617360448201526274203160e81b606482015260840161094d565b60008760405160200161295c9190614859565b60408051601f19818403018152918152815160209283012060008181526010909352912060020180549192509061299290615139565b159050612a075760405162461bcd60e51b815260206004820152603b60248201527f616e20617274776f726b2077697468207468652073616d652066696e6765727060448201527f72696e742068617320616c726561647920726567697374657265640000000000606482015260840161094d565b6040805160c08101825288815260208082018990528183018b9052606082018890526080820187905260a08201869052600f8054600181019091557f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80201849055600084815260109091529190912081518291908190612a869082615267565b5060208201516001820190612a9b9082615267565b5060408201516002820190612ab09082615267565b50606082015160038201556080820151600482015560a09091015160059091015560405182907f22350b25f1b72bb3621199a79abefeb4fcd77bb1e65638cd09350666e4db089190600090a250979650505050505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b612b67816040015161238a565b612b835760405162461bcd60e51b815260040161094d906153f3565b612b95816000015182604001516131e4565b612bb15760405162461bcd60e51b815260040161094d90615437565b8060600151421115612c245760405162461bcd60e51b815260206004820152603660248201527f466572616c66696c6545786869626974696f6e56333a20746865207472616e7360448201527519995c881c995c5d595cdd081a5cc8195e1c1a5c995960521b606482015260840161094d565b60008160000151826020015183604001518460600151604051602001612c7194939291906001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b604051602081830303815290604052805190602001209050612ca681836000015184608001518560a001518660c0015161379a565b612d185760405162461bcd60e51b815260206004820152603d60248201527f466572616c66696c6545786869626974696f6e56333a20746865207472616e7360448201527f6665722072657175657374206973206e6f7420617574686f72697a6564000000606482015260840161094d565b610b55826000015183602001518460400151604051806020016040528060008152506135f6565b610b5533838361381a565b60606000612d57836138e8565b60010190506000816001600160401b03811115612d7657612d766148b1565b6040519080825280601f01601f191660200182016040528015612da0576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084612daa57509392505050565b612de633836131e4565b612e025760405162461bcd60e51b815260040161094d906154a2565b610a38848484846135f6565b60606000601060008781526020019081526020016000206040518060c0016040529081600082018054612e4090615139565b80601f0160208091040260200160405190810160405280929190818152602001828054612e6c90615139565b8015612eb95780601f10612e8e57610100808354040283529160200191612eb9565b820191906000526020600020905b815481529060010190602001808311612e9c57829003601f168201915b50505050508152602001600182018054612ed290615139565b80601f0160208091040260200160405190810160405280929190818152602001828054612efe90615139565b8015612f4b5780601f10612f2057610100808354040283529160200191612f4b565b820191906000526020600020905b815481529060010190602001808311612f2e57829003601f168201915b50505050508152602001600282018054612f6490615139565b80601f0160208091040260200160405190810160405280929190818152602001828054612f9090615139565b8015612fdd5780601f10612fb257610100808354040283529160200191612fdd565b820191906000526020600020905b815481529060010190602001808311612fc057829003601f168201915b505050505081526020016003820154815260200160048201548152602001600582015481525050905060006130118661178b565b9050600082600001518260405160200161302c9291906154ef565b60405160208183030381529060405290506130d361304988612d4a565b8285602001516130588c6139c0565b613065611a498e8e6153b7565b8760405160200161307b9695949392919061552b565b60405160208183030381529060405261309388613100565b6130ad61309f8c6139d7565b6130a88a613100565b613b97565b6040516020016130bf9392919061564f565b604051602081830303815290604052613bb6565b6040516020016130e39190615726565b60405160208183030381529060405293505050505b949350505050565b60606000600d805461311190615139565b80601f016020809104026020016040519081016040528092919081815260200182805461313d90615139565b801561318a5780601f1061315f5761010080835404028352916020019161318a565b820191906000526020600020905b81548152906001019060200180831161316d57829003601f168201915b5050505050905080516000036131ba5750604080518082019091526007815266697066733a2f2f60c81b60208201525b80836040516020016131cd92919061576b565b604051602081830303815290604052915050919050565b6000806131f083611369565b9050806001600160a01b0316846001600160a01b0316148061323757506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806130f85750836001600160a01b03166132508461088b565b6001600160a01b031614949350505050565b60008181526014602090815260409182902082518084019093528054808452600190910154918301919091526133115760405162461bcd60e51b815260206004820152604860248201527f466572616c66696c6545786869626974696f6e56333a20617274776f726b494460448201527f206973206e6f20666f756e6420666f722074686520617274776f726b456469746064820152670d2dedc92dcc8caf60c31b608482015260a40161094d565b8051600090815260126020526040902080546133a65760405162461bcd60e51b815260206004820152604860248201527f466572616c66696c6545786869626974696f6e56333a206e6f2065646974696f60448201527f6e7320696e207468697320617274776f726b206f6620616c6c417274776f726b60648201526745646974696f6e7360c01b608482015260a40161094d565b80546000906133b7906001906153b7565b9050600082600184805490506133cd91906153b7565b815481106133dd576133dd615326565b90600052602060002001549050808385602001518154811061340157613401615326565b9060005260206000200181905550836020015183838154811061342657613426615326565b9060005260206000200181905550828054806134445761344461579a565b6000828152602080822083016000199081018390559092019092559581526014909552505060408320838155600101929092555050565b600061348682611369565b9050613496816000846001613d08565b61349f82611369565b600083815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526003845282852080546000190190558785526002909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60006001600160e01b031982166380ac58cd60e01b148061354f57506001600160e01b03198216635b5e139f60e01b145b806107ca57506301ffc9a760e01b6001600160e01b03198316146107ca565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906135a382611369565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b610b55828260405180602001604052806000815250613e41565b613601848484613629565b61360d84848484613e74565b610a385760405162461bcd60e51b815260040161094d906157b0565b826001600160a01b031661363c82611369565b6001600160a01b0316146136625760405162461bcd60e51b815260040161094d90615802565b6001600160a01b0382166136c45760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161094d565b6136d18383836001613d08565b826001600160a01b03166136e482611369565b6001600160a01b03161461370a5760405162461bcd60e51b815260040161094d90615802565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000806137ff6137f7886040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b848787613f72565b6001600160a01b039081169087161491505095945050505050565b816001600160a01b0316836001600160a01b03160361387b5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161094d565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106139275772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310613953576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061397157662386f26fc10000830492506010015b6305f5e1008310613989576305f5e100830492506008015b612710831061399d57612710830492506004015b606483106139af576064830492506002015b600a83106107ca5760010192915050565b60606107ca826139cf84613f9a565b600101614004565b601754600082815260126020908152604080832080548251818502810185019093528083526060956001600160a01b03169493830182828015613a3957602002820191906000526020600020905b815481526020019060010190808311613a25575b50506040805180820190915260018152607b60f81b60208201529394506000925050505b8251811015613adc576000838281518110613a7a57613a7a615326565b6020026020010151905082613a948883611a4991906153b7565b613aa5613aa084611369565b61419f565b604051602001613ab793929190615847565b6040516020818303038152906040529250508080613ad490615352565b915050613a5d565b5080604051602001613aee91906158a7565b60408051601f19818403018152908290526018546331a9108f60e11b835260048301529150613b6c906001600160a01b03851690636352211e90602401602060405180830381865afa158015613b48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613aa091906158cc565b81604051602001613b7e9291906158e9565b6040516020818303038152906040529350505050919050565b6060613baf83836040516020016130bf929190615957565b9392505050565b60608151600003613bd557505060408051602081019091526000815290565b6000604051806060016040528060408152602001615f666040913990506000600384516002613c0491906153a4565b613c0e9190615382565b613c1990600461536b565b6001600160401b03811115613c3057613c306148b1565b6040519080825280601f01601f191660200182016040528015613c5a576020820181803683370190505b509050600182016020820185865187015b80821015613cc6576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250613c6b565b5050600386510660018114613ce25760028114613cf557613cfd565b603d6001830353603d6002830353613cfd565b603d60018303535b509195945050505050565b613d14848484846141b5565b6001811115613d835760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b606482015260840161094d565b816001600160a01b038516613ddf57613dda81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b613e02565b836001600160a01b0316856001600160a01b031614613e0257613e02858261423d565b6001600160a01b038416613e1e57613e19816142da565b6112f3565b846001600160a01b0316846001600160a01b0316146112f3576112f38482614389565b613e4b83836143cd565b613e586000848484613e74565b6108c65760405162461bcd60e51b815260040161094d906157b0565b60006001600160a01b0384163b15613f6a57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613eb8903390899088908890600401615ee8565b6020604051808303816000875af1925050508015613ef3575060408051601f3d908101601f19168201909252613ef091810190615f1b565b60015b613f50573d808015613f21576040519150601f19603f3d011682016040523d82523d6000602084013e613f26565b606091505b508051600003613f485760405162461bcd60e51b815260040161094d906157b0565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506130f8565b5060016130f8565b6000806000613f8387878787614548565b91509150613f908161460c565b5095945050505050565b600080608083901c15613fb25760809290921c916010015b604083901c15613fc75760409290921c916008015b602083901c15613fdc5760209290921c916004015b601083901c15613ff15760109290921c916002015b600883901c156107ca5760010192915050565b6060600061401383600261536b565b61401e9060026153a4565b6001600160401b03811115614035576140356148b1565b6040519080825280601f01601f19166020018201604052801561405f576020820181803683370190505b509050600360fc1b8160008151811061407a5761407a615326565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106140a9576140a9615326565b60200101906001600160f81b031916908160001a90535060006140cd84600261536b565b6140d89060016153a4565b90505b6001811115614150576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061410c5761410c615326565b1a60f81b82828151811061412257614122615326565b60200101906001600160f81b031916908160001a90535060049490941c9361414981615f38565b90506140db565b508315613baf5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161094d565b60606107ca6001600160a01b0383166014614004565b6001811115610a38576001600160a01b038416156141fb576001600160a01b038416600090815260036020526040812080548392906141f59084906153b7565b90915550505b6001600160a01b03831615610a38576001600160a01b038316600090815260036020526040812080548392906142329084906153a4565b909155505050505050565b6000600161424a84611416565b61425491906153b7565b6000838152600760205260409020549091508082146142a7576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b6008546000906142ec906001906153b7565b6000838152600960205260408120546008805493945090928490811061431457614314615326565b90600052602060002001549050806008838154811061433557614335615326565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061436d5761436d61579a565b6001900381819060005260206000200160009055905550505050565b600061439483611416565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b0382166144235760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161094d565b61442c8161238a565b156144795760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161094d565b614487600083836001613d08565b6144908161238a565b156144dd5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161094d565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561457f5750600090506003614603565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156145d3573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166145fc57600060019250925050614603565b9150600090505b94509492505050565b600081600481111561462057614620615f4f565b036146285750565b600181600481111561463c5761463c615f4f565b036146895760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161094d565b600281600481111561469d5761469d615f4f565b036146ea5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161094d565b60038160048111156146fe576146fe615f4f565b03611df45760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161094d565b50805461476290615139565b6000825580601f10614772575050565b601f016020900490600052602060002090810190611df491905b808211156147a0576000815560010161478c565b5090565b6001600160e01b031981168114611df457600080fd5b6000602082840312156147cc57600080fd5b8135613baf816147a4565b6001600160a01b0381168114611df457600080fd5b6000602082840312156147fe57600080fd5b8135613baf816147d7565b60005b8381101561482457818101518382015260200161480c565b50506000910152565b60008151808452614845816020860160208601614809565b601f01601f19169290920160200192915050565b602081526000613baf602083018461482d565b60006020828403121561487e57600080fd5b5035919050565b6000806040838503121561489857600080fd5b82356148a3816147d7565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b03811182821017156148e9576148e96148b1565b60405290565b60405160c081016001600160401b03811182821017156148e9576148e96148b1565b60405160e081016001600160401b03811182821017156148e9576148e96148b1565b604051601f8201601f191681016001600160401b038111828210171561495b5761495b6148b1565b604052919050565b60006001600160401b0383111561497c5761497c6148b1565b61498f601f8401601f1916602001614933565b90508281528383830111156149a357600080fd5b828260208301376000602084830101529392505050565b600082601f8301126149cb57600080fd5b613baf83833560208501614963565b600080604083850312156149ed57600080fd5b8235915060208301356001600160401b03811115614a0a57600080fd5b614a16858286016149ba565b9150509250929050565b60006001600160401b03821115614a3957614a396148b1565b5060051b60200190565b60006020808385031215614a5657600080fd5b82356001600160401b0380821115614a6d57600080fd5b818501915085601f830112614a8157600080fd5b8135614a94614a8f82614a20565b614933565b81815260059190911b83018401908481019088831115614ab357600080fd5b8585015b83811015614b5d57803585811115614acf5760008081fd5b860160a0818c03601f1901811315614ae75760008081fd5b614aef6148c7565b8983013581526040808401358b830152606080850135614b0e816147d7565b8083850152506080915081850135614b25816147d7565b90830152918301359188831115614b3c5760008081fd5b614b4a8e8c858701016149ba565b9082015285525050918601918601614ab7565b5098975050505050505050565b600080600060608486031215614b7f57600080fd5b8335614b8a816147d7565b92506020840135614b9a816147d7565b929592945050506040919091013590565b60008060408385031215614bbe57600080fd5b50508035926020909101359150565b604081526000614be0604083018561482d565b8281036020840152614bf2818561482d565b95945050505050565b600060c08284031215614c0d57600080fd5b614c156148ef565b905081356001600160401b0380821115614c2e57600080fd5b614c3a858386016149ba565b83526020840135915080821115614c5057600080fd5b614c5c858386016149ba565b60208401526040840135915080821115614c7557600080fd5b50614c82848285016149ba565b604083015250606082013560608201526080820135608082015260a082013560a082015292915050565b60006020808385031215614cbf57600080fd5b82356001600160401b0380821115614cd657600080fd5b818501915085601f830112614cea57600080fd5b8135614cf8614a8f82614a20565b81815260059190911b83018401908481019088831115614d1757600080fd5b8585015b83811015614b5d57803585811115614d335760008081fd5b614d418b89838a0101614bfb565b845250918601918601614d1b565b60c081526000614d6260c083018961482d565b8281036020840152614d74818961482d565b90508281036040840152614d88818861482d565b60608401969096525050608081019290925260a0909101529392505050565b600080600060608486031215614dbc57600080fd5b8335925060208401356001600160401b0380821115614dda57600080fd5b614de6878388016149ba565b93506040860135915080821115614dfc57600080fd5b50614e09868287016149ba565b9150509250925092565b8281526040602082015260006130f8604083018461482d565b600080600060608486031215614e4157600080fd5b83356001600160401b0380821115614e5857600080fd5b614e6487838801614bfb565b94506020860135915080821115614dda57600080fd5b600060208284031215614e8c57600080fd5b81356001600160401b03811115614ea257600080fd5b6130f8848285016149ba565b60006020808385031215614ec157600080fd5b82356001600160401b03811115614ed757600080fd5b8301601f81018513614ee857600080fd5b8035614ef6614a8f82614a20565b81815260e09182028301840191848201919088841115614f1557600080fd5b938501935b83851015614fa95780858a031215614f325760008081fd5b614f3a614911565b8535614f45816147d7565b815285870135614f54816147d7565b8188015260408681013590820152606080870135908201526080808701359082015260a0808701359082015260c08087013560ff81168114614f965760008081fd5b9082015283529384019391850191614f1a565b50979650505050505050565b8015158114611df457600080fd5b60008060408385031215614fd657600080fd5b8235614fe1816147d7565b91506020830135614ff181614fb5565b809150509250929050565b6000806000806080858703121561501257600080fd5b843561501d816147d7565b9350602085013561502d816147d7565b92506040850135915060608501356001600160401b0381111561504f57600080fd5b8501601f8101871361506057600080fd5b61506f87823560208401614963565b91505092959194509250565b6000806040838503121561508e57600080fd5b8235615099816147d7565b91506020830135614ff1816147d7565b600060208083850312156150bc57600080fd5b82356001600160401b038111156150d257600080fd5b8301601f810185136150e357600080fd5b80356150f1614a8f82614a20565b81815260059190911b8201830190838101908783111561511057600080fd5b928401925b8284101561512e57833582529284019290840190615115565b979650505050505050565b600181811c9082168061514d57607f821691505b60208210810361516d57634e487b7160e01b600052602260045260246000fd5b50919050565b60008151615185818560208601614809565b9290920192915050565b600082516151a1818460208701614809565b9190910192915050565b60008083546151b981615139565b600182811680156151d157600181146151e657615215565b60ff1984168752821515830287019450615215565b8760005260208060002060005b8581101561520c5781548a8201529084019082016151f3565b50505082870194505b50929695505050505050565b601f8211156108c657600081815260208120601f850160051c810160208610156152485750805b601f850160051c820191505b8181101561133f57828155600101615254565b81516001600160401b03811115615280576152806148b1565b6152948161528e8454615139565b84615221565b602080601f8311600181146152c957600084156152b15750858301515b600019600386901b1c1916600185901b17855561133f565b600085815260208120601f198616915b828110156152f8578886015182559484019460019091019084016152d9565b50858210156153165787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016153645761536461533c565b5060010190565b80820281158282048414176107ca576107ca61533c565b60008261539f57634e487b7160e01b600052601260045260246000fd5b500490565b808201808211156107ca576107ca61533c565b818103818111156107ca576107ca61533c565b602360f81b8152600082516153e6816001850160208701614809565b9190910160010192915050565b60208082526024908201527f4552433732313a20617274776f726b2065646974696f6e206973206e6f7420666040820152631bdd5b9960e21b606082015260800190565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b60006020828403121561549757600080fd5b8151613baf81614fb5565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60008351615501818460208801614809565b600160fd1b908301908152835161551f816001840160208801614809565b01600101949350505050565b663d9134b2111d1160c91b8152865160009061554e816007850160208c01614809565b6a111610113730b6b2911d1160a91b6007918401918201528751615579816012840160208c01614809565b6c1116101130b93a34b9ba111d1160991b6012929091019182015286516155a781601f840160208b01614809565b701116101130b93a3bb7b935afb4b2111d1160791b601f929091019182015285516155d9816030840160208a01614809565b731116101132b234ba34b7b72fb4b73232bc111d1160611b60309290910191820152845161560e816044840160208901614809565b61564161563b604483850101741116101132b234ba34b7b72fb73ab6b132b9111d1160591b815260150190565b86615173565b9a9950505050505050505050565b60008451615661818460208901614809565b80830190507f222c202265787465726e616c5f75726c223a2268747470733a2f2f666572616c8152733334b6329731b7b69116101134b6b0b3b2911d1160611b602082015284516156b9816034840160208901614809565b7f222c2022616e696d6174696f6e5f75726c223a22646174613a746578742f687460349290910191820152691b5b0ed8985cd94d8d0b60b21b6054820152835161570a81605e840160208801614809565b61227d60f01b605e929091019182015260600195945050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161575e81601d850160208701614809565b91909101601d0192915050565b6000835161577d818460208801614809565b835190830190615791818360208801614809565b01949350505050565b634e487b7160e01b600052603160045260246000fd5b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60008451615859818460208901614809565b84519083019061586d818360208901614809565b611d1160f11b9101908152835161588b816002840160208801614809565b61088b60f21b6002929091019182015260040195945050505050565b600082516158b9818460208701614809565b607d60f81b920191825250600101919050565b6000602082840312156158de57600080fd5b8151613baf816147d7565b6b3db630b73227bbb732b91d1160a11b8152825160009061591181600c850160208801614809565b6b11161037bbb732b926b0b81d60a11b600c91840191820152835161593d816018840160208801614809565b607d60f81b60189290910191820152601901949350505050565b7f3c21444f43545950452068746d6c3e3c68746d6c206c616e673d22656e223e3c81527f686561643e3c7363726970743e207661722064656661756c74417274776f726b60208201526502230ba309e960d51b6040820152600083516159c4816046850160208801614809565b7f3c2f7363726970743e3c7363726970743e6c657420616c6c6f774f726967696e6046918401918201527f733d7b2268747470733a2f2f666572616c66696c652e636f6d223a21307d3b6660668201527f756e6374696f6e20726573697a65496672616d652865297b6c657420743d646f60868201527f63756d656e742e676574456c656d656e744279496428226d61696e6672616d6560a68201527f22293b65262628742e7374796c652e6d696e4865696768743d652b227078222960c68201527f7d66756e6374696f6e20696e69744461746128297b64656661756c744172747760e68201527f6f726b446174612e6f776e657241727261793d5b5d3b6c657420653d646566616101068201527f756c74417274776f726b446174612e6f776e65724d61703b4f626a6563742e6b6101268201527f6579732865292e736f72742828652c74293d3e653c74292e666f7245616368286101468201527f743d3e7b64656661756c74417274776f726b446174612e6f776e6572417272616101668201527f792e7075736828655b745d297d292c70757368417274776f726b44617461546f6101868201527f496672616d652864656661756c74417274776f726b44617461297d66756e63746101a68201527f696f6e2070757368417274776f726b44617461546f496672616d652865297b656101c68201527f2626646f63756d656e742e676574456c656d656e744279496428226d61696e666101e68201527f72616d6522292e636f6e74656e7457696e646f772e706f73744d6573736167656102068201527f28652c222a22297d66756e6374696f6e207570646174654172746f77726b44616102268201527f74612865297b646f63756d656e742e676574456c656d656e744279496428226d6102468201527f61696e6672616d6522292e636f6e74656e7457696e646f772e706f73744d65736102668201527f7361676528652c222a22297d77696e646f772e6164644576656e744c697374656102868201527f6e657228226d657373616765222c66756e6374696f6e2865297b616c6c6f774f6102a68201527f726967696e735b652e6f726967696e5d3f227570646174652d617274776f726b6102c68201527f2d64617461223d3d3d652e646174612e7479706526267570646174654172746f6102e68201527f77726b4461746128652e646174612e617274776f726b44617461293a226f626a6103068201527f656374223d3d747970656f6620652e64617461262622726573697a652d6966726103268201527f616d65223d3d3d652e646174612e747970652626726573697a65496672616d656103468201527f28652e646174612e6e6577486569676874297d293b3c2f7363726970743e3c2f6103668201527f686561643e3c626f6479207374796c653d226f766572666c6f772d783a6869646103868201527f64656e3b70616464696e673a303b6d617267696e3a303b77696474683a3130306103a68201527f253b22206f6e6c6f61643d22696e6974446174612829223e3c696672616d65206103c68201527f69643d226d61696e6672616d6522207374796c653d22646973706c61793a626c6103e68201527f6f636b3b70616464696e673a303b6d617267696e3a303b626f726465723a6e6f6104068201527f6e653b77696474683a313030253b6865696768743a31303076683b2220737263610426820152611e9160f11b610446820152614bf2615ebf610448830186615173565b7f223e3c2f696672616d653e203c2f626f64793e3c2f68746d6c3e0000000000008152601a0190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611c959083018461482d565b600060208284031215615f2d57600080fd5b8151613baf816147a4565b600081615f4757615f4761533c565b506000190190565b634e487b7160e01b600052602160045260246000fdfe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa264697066735822122042d0608f6bdeba088885bbc80c16f7e3dcf49b66daa3e70507924c01e202d7ef64736f6c63430008110033

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

0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000007d0000000000000000000000000080feb125ba730d6d12789b6aaab01f4e31d8bd10000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001b466572616c2046696c6520e28094205065657220746f2050656572000000000000000000000000000000000000000000000000000000000000000000000000054646303234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c68747470733a2f2f697066732e6269746d61726b2e636f6d2f697066732f516d6278476e45594e6b313478466331465545736662515944387a6a4d396f6e6f696d55393135596e384761784c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e68747470733a2f2f697066732e6269746d61726b2e636f6d2f697066732f0000

-----Decoded View---------------
Arg [0] : name_ (string): Feral File — Peer to Peer
Arg [1] : symbol_ (string): FF024
Arg [2] : secondarySaleRoyaltyBPS_ (uint256): 2000
Arg [3] : royaltyPayoutAddress_ (address): 0x080FEB125bA730D6D12789B6AAAB01f4E31D8Bd1
Arg [4] : contractURI_ (string): https://ipfs.bitmark.com/ipfs/QmbxGnEYNk14xFc1FUEsfbQYD8zjM9onoimU915Yn8GaxL
Arg [5] : tokenBaseURI_ (string): https://ipfs.bitmark.com/ipfs/
Arg [6] : isBurnable_ (bool): True
Arg [7] : isBridgeable_ (bool): True

-----Encoded View---------------
18 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [2] : 00000000000000000000000000000000000000000000000000000000000007d0
Arg [3] : 000000000000000000000000080feb125ba730d6d12789b6aaab01f4e31d8bd1
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000180
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000200
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [8] : 000000000000000000000000000000000000000000000000000000000000001b
Arg [9] : 466572616c2046696c6520e28094205065657220746f20506565720000000000
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [11] : 4646303234000000000000000000000000000000000000000000000000000000
Arg [12] : 000000000000000000000000000000000000000000000000000000000000004c
Arg [13] : 68747470733a2f2f697066732e6269746d61726b2e636f6d2f697066732f516d
Arg [14] : 6278476e45594e6b313478466331465545736662515944387a6a4d396f6e6f69
Arg [15] : 6d55393135596e384761784c0000000000000000000000000000000000000000
Arg [16] : 000000000000000000000000000000000000000000000000000000000000001e
Arg [17] : 68747470733a2f2f697066732e6269746d61726b2e636f6d2f697066732f0000


Deployed Bytecode Sourcemap

101365:11522:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84788:310;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;84788:310:0;;;;;;;;26974:102;;;;;;:::i;:::-;;:::i;:::-;;51022:100;;;:::i;:::-;;;;;;;:::i;52534:171::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2107:32:1;;;2089:51;;2077:2;2062:18;52534:171:0;1943:203:1;100276:206:0;;;;;;:::i;:::-;;:::i;87918:478::-;;;;;;:::i;:::-;;:::i;29590:241::-;;;;;;:::i;:::-;;:::i;93974:430::-;;;;;;:::i;:::-;;:::i;67600:113::-;67688:10;:17;67600:113;;;7177:25:1;;;7165:2;7150:18;67600:113:0;7031:177:1;102261:88:0;;;;;-1:-1:-1;;;;;102261:88:0;;;100490:214;;;;;;:::i;:::-;;:::i;90822:460::-;;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;8119:32:1;;;8101:51;;8183:2;8168:18;;8161:34;;;;8074:18;90822:460:0;7927:274:1;67268:256:0;;;;;;:::i;:::-;;:::i;101567:69::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;81961:35::-;;;;;-1:-1:-1;;;;;81961:35:0;;;100712:222;;;;;;:::i;:::-;;:::i;86824:465::-;;;;;;:::i;:::-;;:::i;88592:300::-;;;;;;:::i;:::-;;:::i;102356:124::-;;;;;;83405:43;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;:::i;67790:233::-;;;;;;:::i;:::-;;:::i;104195:810::-;;;;;;:::i;:::-;;:::i;83479:57::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;50732:223::-;;;;;;:::i;:::-;;:::i;82276:60::-;;;;;;;;;;;;;;;-1:-1:-1;;;82276:60:0;;;;;89202:252;;;;;;:::i;:::-;;:::i;50463:207::-;;;;;;:::i;:::-;;:::i;25665:103::-;;;:::i;82412:24::-;;;;;-1:-1:-1;;;82412:24:0;;;;;;103035:810;;;;;;:::i;:::-;;:::i;82362:22::-;;;;;-1:-1:-1;;;82362:22:0;;;;;;25017:87;25090:6;;-1:-1:-1;;;;;25090:6:0;25017:87;;90111:116;;;;;;:::i;:::-;;:::i;51191:104::-;;;:::i;92272:259::-;;;;;;:::i;:::-;;:::i;102489:212::-;;;;;;:::i;:::-;;:::i;100043:225::-;;;;;;:::i;:::-;;:::i;87558:286::-;;;;;;:::i;:::-;;:::i;105087:780::-;;;;;;:::i;:::-;;:::i;100942:256::-;;;;;;:::i;:::-;;:::i;112005:879::-;;;;;;:::i;:::-;;:::i;26867:99::-;;;;;;:::i;:::-;;:::i;87371:108::-;87452:12;:19;87371:108;;90300:97;;;:::i;53003:164::-;;;;;;:::i;:::-;-1:-1:-1;;;;;53124:25:0;;;53100:4;53124:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;53003:164;82075:48;;;;;82185:49;;82228:6;82185:49;;26675:40;;;;;;:::i;:::-;;;;;;;;;;;;;;;;28136:130;;;;;-1:-1:-1;;;;;28136:130:0;;;25923:201;;;;;;:::i;:::-;;:::i;98064:879::-;;;;;;:::i;:::-;;:::i;88958:174::-;;;;;;:::i;:::-;89056:7;89088:29;;;:18;:29;;;;;:36;;88958:174;84788:310;84945:4;-1:-1:-1;;;;;;84987:50:0;;-1:-1:-1;;;84987:50:0;;:103;;;85054:36;85078:11;85054:23;:36::i;:::-;84967:123;84788:310;-1:-1:-1;;84788:310:0:o;26974:102::-;24903:13;:11;:13::i;:::-;-1:-1:-1;;;;;27050:18:0::1;;::::0;;;:8:::1;:18;::::0;;;;27043:25;;-1:-1:-1;;27043:25:0::1;::::0;;26974:102::o;51022:100::-;51076:13;51109:5;51102:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51022:100;:::o;52534:171::-;52610:7;52630:23;52645:7;52630:14;:23::i;:::-;-1:-1:-1;52673:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;52673:24:0;;52534:171::o;100276:206::-;100416:8;28969:30;28990:8;28969:20;:30::i;:::-;100442:32:::1;100456:8;100466:7;100442:13;:32::i;:::-;100276:206:::0;;;:::o;87918:478::-;26802:10;26793:20;;;;:8;:20;;;;;;;;;:45;;-1:-1:-1;25090:6:0;;-1:-1:-1;;;;;25090:6:0;26817:10;:21;26793:45;26785:54;;;;;;88061:16:::1;88069:7;88061;:16::i;:::-;88053:57;;;::::0;-1:-1:-1;;;88053:57:0;;19027:2:1;88053:57:0::1;::::0;::::1;19009:21:1::0;19066:2;19046:18;;;19039:30;19105;19085:18;;;19078:58;19153:18;;88053:57:0::1;;;;;;;;;88130:18;88149:7;88130:27;;;;;;:::i;:::-;::::0;;;::::1;::::0;;;;;::::1;::::0;;;;::::1;;88129:28;88121:63;;;::::0;-1:-1:-1;;;88121:63:0;;19881:2:1;88121:63:0::1;::::0;::::1;19863:21:1::0;19920:2;19900:18;;;19893:30;-1:-1:-1;;;19939:18:1;;;19932:52;20001:18;;88121:63:0::1;19679:346:1::0;88121:63:0::1;88197:30;88230:24:::0;;;:15:::1;:24;::::0;;;;;;88272:35;;:18:::1;::::0;:35:::1;::::0;88291:15:::1;::::0;::::1;::::0;88272:35:::1;:::i;:::-;::::0;;;::::1;::::0;;;;;::::1;::::0;;;88265:42;;-1:-1:-1;;88265:42:0::1;::::0;;;;88318:18:::1;::::0;:27:::1;::::0;88337:7;;88318:27:::1;:::i;:::-;::::0;;;::::1;::::0;;;;;::::1;::::0;;;:34;;;::::1;;-1:-1:-1::0;;88318:34:0;;::::1;::::0;;;::::1;::::0;;;88363:15;::::1;:25;88381:7:::0;88363:15;:25:::1;:::i;:::-;;88042:354;87918:478:::0;;:::o;29590:241::-;24903:13;:11;:13::i;:::-;29720:22:::1;:103:::0;;-1:-1:-1;;;;;;29720:103:0::1;-1:-1:-1::0;;;;;29720:103:0;;;::::1;::::0;;;::::1;::::0;;29590:241::o;93974:430::-;26802:10;26793:20;;;;:8;:20;;;;;;;;;:45;;-1:-1:-1;25090:6:0;;-1:-1:-1;;;;;25090:6:0;26817:10;:21;26793:45;26785:54;;;;;;94095:9:::1;94090:307;94114:11;:18;94110:1;:22;94090:307;;;94154:231;94185:11;94197:1;94185:14;;;;;;;;:::i;:::-;;;;;;;:24;;;94228:11;94240:1;94228:14;;;;;;;;:::i;:::-;;;;;;;:22;;;94269:11;94281:1;94269:14;;;;;;;;:::i;:::-;;;;;;;:21;;;94309:11;94321:1;94309:14;;;;;;;;:::i;:::-;;;;;;;:20;;;94348:11;94360:1;94348:14;;;;;;;;:::i;:::-;;;;;;;:22;;;94154:12;:231::i;:::-;94134:3:::0;::::1;::::0;::::1;:::i;:::-;;;;94090:307;;;;93974:430:::0;:::o;100490:214::-;100642:4;-1:-1:-1;;;;;28789:18:0;;28797:10;28789:18;28785:83;;28824:32;28845:10;28824:20;:32::i;:::-;100659:37:::1;100678:4;100684:2;100688:7;100659:18;:37::i;90822:460::-:0;90947:16;90965:21;91026:16;91034:7;91026;:16::i;:::-;91004:115;;;;-1:-1:-1;;;91004:115:0;;23687:2:1;91004:115:0;;;23669:21:1;23726:2;23706:18;;;23699:30;23765:34;23745:18;;;23738:62;-1:-1:-1;;;23816:18:1;;;23809:47;23873:19;;91004:115:0;23485:413:1;91004:115:0;91143:20;;-1:-1:-1;;;;;91143:20:0;;-1:-1:-1;82228:6:0;91206:35;91218:23;91206:9;:35;:::i;:::-;91205:69;;;;:::i;:::-;91176:98;;90822:460;;;;;:::o;67268:256::-;67365:7;67401:23;67418:5;67401:16;:23::i;:::-;67393:5;:31;67385:87;;;;-1:-1:-1;;;67385:87:0;;24632:2:1;67385:87:0;;;24614:21:1;24671:2;24651:18;;;24644:30;24710:34;24690:18;;;24683:62;-1:-1:-1;;;24761:18:1;;;24754:41;24812:19;;67385:87:0;24430:407:1;67385:87:0;-1:-1:-1;;;;;;67490:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;67268:256::o;101567:69::-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;100712:222::-;100868:4;-1:-1:-1;;;;;28789:18:0;;28797:10;28789:18;28785:83;;28824:32;28845:10;28824:20;:32::i;:::-;100885:41:::1;100908:4;100914:2;100918:7;100885:22;:41::i;86824:465::-:0;26802:10;26793:20;;;;:8;:20;;;;;;;;;:45;;-1:-1:-1;25090:6:0;;-1:-1:-1;;;;;25090:6:0;26817:10;:21;26793:45;26785:54;;;;;;86939:9:::1;86934:348;86958:9;:16;86954:1;:20;86934:348;;;86996:274;87029:9;87039:1;87029:12;;;;;;;;:::i;:::-;;;;;;;:24;;;87072:9;87082:1;87072:12;;;;;;;;:::i;:::-;;;;;;;:18;;;87109:9;87119:1;87109:12;;;;;;;;:::i;:::-;;;;;;;:23;;;87151:9;87161:1;87151:12;;;;;;;;:::i;:::-;;;;;;;:24;;;87194:9;87204:1;87194:12;;;;;;;;:::i;:::-;;;;;;;:21;;;87234:9;87244:1;87234:12;;;;;;;;:::i;:::-;;;;;;;:21;;;86996:14;:274::i;:::-;-1:-1:-1::0;86976:3:0;::::1;::::0;::::1;:::i;:::-;;;;86934:348;;88592:300:::0;26802:10;26793:20;;;;:8;:20;;;;;;;;;:45;;-1:-1:-1;25090:6:0;;-1:-1:-1;;;;;25090:6:0;26817:10;:21;26793:45;26785:54;;;;;;-1:-1:-1;;;;;88736:35:0;::::1;88714:115;;;::::0;-1:-1:-1;;;88714:115:0;;25044:2:1;88714:115:0::1;::::0;::::1;25026:21:1::0;25083:2;25063:18;;;25056:30;25122:32;25102:18;;;25095:60;25172:18;;88714:115:0::1;24842:354:1::0;88714:115:0::1;88840:20;:44:::0;;-1:-1:-1;;;;;;88840:44:0::1;-1:-1:-1::0;;;;;88840:44:0;;;::::1;::::0;;;::::1;::::0;;88592:300::o;83405:43::-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;67790:233::-;67865:7;67901:30;67688:10;:17;;67600:113;67901:30;67893:5;:38;67885:95;;;;-1:-1:-1;;;67885:95:0;;25403:2:1;67885:95:0;;;25385:21:1;25442:2;25422:18;;;25415:30;25481:34;25461:18;;;25454:62;-1:-1:-1;;;25532:18:1;;;25525:42;25584:19;;67885:95:0;25201:408:1;67885:95:0;67998:10;68009:5;67998:17;;;;;;;;:::i;:::-;;;;;;;;;67991:24;;67790:233;;;:::o;104195:810::-;24903:13;:11;:13::i;:::-;104464:19:::1;::::0;;;:8:::1;:19;::::0;;;;:31:::1;;104458:45:::0;;::::1;::::0;::::1;:::i;:::-;;;104507:1;104458:50:::0;104436:134:::1;;;::::0;-1:-1:-1;;;104436:134:0;;25816:2:1;104436:134:0::1;::::0;::::1;25798:21:1::0;25855:2;25835:18;;;25828:30;25894:34;25874:18;;;25867:62;-1:-1:-1;;;25945:18:1;;;25938:32;25987:19;;104436:134:0::1;25614:398:1::0;104436:134:0::1;104713:26:::0;;:31;:64;::::1;;;-1:-1:-1::0;104748:24:0;;:29;104713:64:::1;104709:158;;;104801:33;::::0;;;:22:::1;:33;::::0;;;;;104794:40:::1;104801:33:::0;;104794:40:::1;:::i;:::-;;;::::0;::::1;;;:::i;:::-;;;100276:206:::0;;;:::o;104709:158::-:1;104915:82;::::0;;;;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;;;-1:-1:-1;104879:33:0;;;:22:::1;:33:::0;;;;;;;:118;;:33;;:118:::1;::::0;:33;:118:::1;:::i;:::-;-1:-1:-1::0;104879:118:0::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;-1:-1:-1::0;;;104195:810:0;;;:::o;83479:57::-;;;;;;;;;;;;;;;;;;;;;;;;:::i;50732:223::-;50804:7;55619:16;;;:7;:16;;;;;;-1:-1:-1;;;;;55619:16:0;;50868:56;;;;-1:-1:-1;;;50868:56:0;;26219:2:1;50868:56:0;;;26201:21:1;26258:2;26238:18;;;26231:30;-1:-1:-1;;;26277:18:1;;;26270:54;26341:18;;50868:56:0;26017:348:1;89202:252:0;89318:7;89088:29;;;:18;:29;;;;;:36;89351:5;:40;89343:49;;;;;;89410:29;;;;:18;:29;;;;;:36;;89440:5;;89410:36;;;;;;:::i;:::-;;;;;;;;;89403:43;;89202:252;;;;:::o;50463:207::-;50535:7;-1:-1:-1;;;;;50563:19:0;;50555:73;;;;-1:-1:-1;;;50555:73:0;;26572:2:1;50555:73:0;;;26554:21:1;26611:2;26591:18;;;26584:30;26650:34;26630:18;;;26623:62;-1:-1:-1;;;26701:18:1;;;26694:39;26750:19;;50555:73:0;26370:405:1;50555:73:0;-1:-1:-1;;;;;;50646:16:0;;;;;:9;:16;;;;;;;50463:207::o;25665:103::-;24903:13;:11;:13::i;:::-;25730:30:::1;25757:1;25730:18;:30::i;:::-;25665:103::o:0;103035:810::-;26802:10;26793:20;;;;:8;:20;;;;;;;;;:45;;-1:-1:-1;25090:6:0;;-1:-1:-1;;;;;25090:6:0;26817:10;:21;26793:45;26785:54;;;;;;103244:12:::1;103238:26;103268:1;103238:31:::0;103216:116:::1;;;::::0;-1:-1:-1;;;103216:116:0;;26982:2:1;103216:116:0::1;::::0;::::1;26964:21:1::0;27021:2;27001:18;;;26994:30;27060:34;27040:18;;;27033:62;-1:-1:-1;;;27111:18:1;;;27104:33;27154:19;;103216:116:0::1;26780:399:1::0;103216:116:0::1;103373:10;103367:24;103395:1;103367:29:::0;103345:112:::1;;;::::0;-1:-1:-1;;;103345:112:0;;27386:2:1;103345:112:0::1;::::0;::::1;27368:21:1::0;27425:2;27405:18;;;27398:30;27464:34;27444:18;;;27437:62;-1:-1:-1;;;27515:18:1;;;27508:31;27556:19;;103345:112:0::1;27184:397:1::0;103345:112:0::1;103470:17;103490:216;103519:7;:19;;;103553:7;:13;;;103581:7;:18;;;103614:7;:19;;;103648:7;:16;;;103679:7;:16;;;103490:14;:216::i;:::-;103755:82;::::0;;;;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;;;-1:-1:-1;103719:33:0;;;:22:::1;:33:::0;;;;;;;:118;;103470:236;;-1:-1:-1;103755:82:0;;103719:33;;:118:::1;::::0;:33;:118:::1;:::i;:::-;-1:-1:-1::0;103719:118:0::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;-1:-1:-1::0;;;;;;;103035:810:0:o;90111:116::-;26802:10;26793:20;;;;:8;:20;;;;;;;;;:45;;-1:-1:-1;25090:6:0;;-1:-1:-1;;;;;25090:6:0;26817:10;:21;26793:45;26785:54;;;;;;90195:13:::1;:24;90211:8:::0;90195:13;:24:::1;:::i;51191:104::-:0;51247:13;51280:7;51273:14;;;;;:::i;92272:259::-;26802:10;26793:20;;;;:8;:20;;;;;;;;;:45;;-1:-1:-1;25090:6:0;;-1:-1:-1;;;;;25090:6:0;26817:10;:21;26793:45;26785:54;;;;;;92410:9:::1;92405:119;92429:15;:22;92425:1;:26;92405:119;;;92473:39;92493:15;92509:1;92493:18;;;;;;;;:::i;:::-;;;;;;;92473:19;:39::i;:::-;92453:3:::0;::::1;::::0;::::1;:::i;:::-;;;;92405:119;;102489:212:::0;24903:13;:11;:13::i;:::-;102616:19:::1;:37:::0;;-1:-1:-1;;;;;;102616:37:0::1;-1:-1:-1::0;;;;;102616:37:0;;;::::1;::::0;;;::::1;::::0;;;102664:19:::1;:29:::0;102489:212::o;100043:225::-;100191:8;28969:30;28990:8;28969:20;:30::i;:::-;100217:43:::1;100241:8;100251;100217:23;:43::i;87558:286::-:0;87665:7;87720:15;87452:12;:19;;87371:108;87720:15;87712:5;:23;87690:109;;;;-1:-1:-1;;;87690:109:0;;27788:2:1;87690:109:0;;;27770:21:1;27827:2;27807:18;;;27800:30;27866:34;27846:18;;;27839:62;-1:-1:-1;;;27917:18:1;;;27910:34;27961:19;;87690:109:0;27586:400:1;87690:109:0;87817:12;87830:5;87817:19;;;;;;;;:::i;105087:780::-;105211:59;105273:32;;;:23;:32;;;;;;;;105211:94;;;;;;;;;;;;;;;;;;;;;105405:19;;;:8;:19;;;;;;105380:44;;;;;;;;;;105180:13;;105211:94;;105380:44;105405:19;105380:44;;105405:19;;105380:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105435:15;105465:7;:16;;;105453:9;:28;;;;:::i;:::-;105435:46;;105492:15;105541:7;:16;;;105522:7;:16;;;105510:9;:28;;;;:::i;:::-;:47;;;;:::i;:::-;105492:65;;105584:7;105574;:17;105570:290;;;-1:-1:-1;;105608:11:0;;;;;;;;;;;;-1:-1:-1;;;105608:11:0;;;;;105087:780;-1:-1:-1;;;;;105087:780:0:o;105570:290::-;105651:7;105641;:17;105637:223;;;-1:-1:-1;;105675:11:0;;;;;;;;;;;;-1:-1:-1;;;105675:11:0;;;;;105087:780;-1:-1:-1;;;;;105087:780:0:o;105637:223::-;105794:34;105795:17;105805:7;105795;:17;:::i;:::-;:21;;105815:1;105795:21;:::i;:::-;105794:32;:34::i;:::-;105772:57;;;;;;;;:::i;:::-;;;;;;;;;;;;;105719:129;;;;;;;105087:780;;;:::o;100942:256::-;101126:4;-1:-1:-1;;;;;28789:18:0;;28797:10;28789:18;28785:83;;28824:32;28845:10;28824:20;:32::i;:::-;101143:47:::1;101166:4;101172:2;101176:7;101185:4;101143:22;:47::i;112005:879::-:0;112123:13;112176:16;112184:7;112176;:16::i;:::-;112154:113;;;;-1:-1:-1;;;112154:113:0;;28892:2:1;112154:113:0;;;28874:21:1;28931:2;28911:18;;;28904:30;28970:34;28950:18;;;28943:62;-1:-1:-1;;;29021:18:1;;;29014:45;29076:19;;112154:113:0;28690:411:1;112154:113:0;112280:59;112342:32;;;:23;:32;;;;;;;;112280:94;;;;;;;;;;;;;;;;;;;;;112476:33;;;:22;:33;;;;;;112447:89;;112280:94;;;;112447:89;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;112547:24;112574:22;:33;112597:9;112574:33;;;;;;;;;;;:44;;112547:71;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;112662:1;112641:10;112635:24;:28;:62;;;;;112696:1;112673:12;112667:26;:30;112635:62;112631:246;;;112721:58;112734:9;112745:7;112754:12;112768:10;112721:12;:58::i;:::-;112714:65;112005:879;-1:-1:-1;;;;;;112005:879:0:o;112631:246::-;112832:24;;;;:15;:24;;;;;:32;;112819:46;;;;112832:32;112819:46;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:12;:46::i;26867:99::-;24903:13;:11;:13::i;:::-;-1:-1:-1;;;;;26933:18:0::1;;::::0;;;:8:::1;:18;::::0;;;;:25;;-1:-1:-1;;26933:25:0::1;26954:4;26933:25;::::0;;26867:99::o;90300:97::-;90344:13;90377:12;90370:19;;;;;:::i;25923:201::-;24903:13;:11;:13::i;:::-;-1:-1:-1;;;;;26012:22:0;::::1;26004:73;;;::::0;-1:-1:-1;;;26004:73:0;;29308:2:1;26004:73:0::1;::::0;::::1;29290:21:1::0;29347:2;29327:18;;;29320:30;29386:34;29366:18;;;29359:62;-1:-1:-1;;;29437:18:1;;;29430:36;29483:19;;26004:73:0::1;29106:402:1::0;26004:73:0::1;26088:28;26107:8;26088:18;:28::i;:::-;25923:201:::0;:::o;98064:879::-;98142:10;;-1:-1:-1;;;98142:10:0;;;;98134:68;;;;-1:-1:-1;;;98134:68:0;;29715:2:1;98134:68:0;;;29697:21:1;29754:2;29734:18;;;29727:30;29793:34;29773:18;;;29766:62;-1:-1:-1;;;29844:18:1;;;29837:43;29897:19;;98134:68:0;29513:409:1;98134:68:0;98220:9;98215:721;98239:11;:18;98235:1;:22;98215:721;;;98305:23;98313:11;98325:1;98313:14;;;;;;;;:::i;:::-;;;;;;;98305:7;:23::i;:::-;98279:121;;;;-1:-1:-1;;;98279:121:0;;;;;;;:::i;:::-;98441:48;23648:10;98474:11;98486:1;98474:14;;;;;;;;:::i;:::-;;;;;;;98441:18;:48::i;:::-;98415:156;;;;-1:-1:-1;;;98415:156:0;;;;;;;:::i;:::-;98586:29;98618:15;:31;98634:11;98646:1;98634:14;;;;;;;;:::i;:::-;;;;;;;98618:31;;;;;;;;;;;98586:63;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;98673:18;98692:7;:15;;;98673:35;;;;;;:::i;:::-;;;;;;;;;;;;;;98666:42;;-1:-1:-1;;98666:42:0;;;98746:14;;98730:15;;98673:35;;98746:11;;98758:1;;98746:14;;;;;;:::i;:::-;;;;;;;98730:31;;;;;;;;;;;;98723:38;;;;;;;;;;;;;;:::i;:::-;;;98778:52;98815:11;98827:1;98815:14;;;;;;;;:::i;:::-;;;;;;;98778:36;:52::i;:::-;98847:21;98853:11;98865:1;98853:14;;;;;;;;:::i;:::-;;;;;;;98847:5;:21::i;:::-;98909:11;98921:1;98909:14;;;;;;;;:::i;:::-;;;;;;;98890:34;;;;;;;;;;-1:-1:-1;98259:3:0;;;;:::i;:::-;;;;98215:721;;66960:224;67062:4;-1:-1:-1;;;;;;67086:50:0;;-1:-1:-1;;;67086:50:0;;:90;;;67140:36;67164:11;67140:23;:36::i;25182:132::-;25090:6;;-1:-1:-1;;;;;25090:6:0;23648:10;25246:23;25238:68;;;;-1:-1:-1;;;25238:68:0;;30949:2:1;25238:68:0;;;30931:21:1;;;30968:18;;;30961:30;31027:34;31007:18;;;31000:62;31079:18;;25238:68:0;30747:356:1;62353:135:0;62435:16;62443:7;62435;:16::i;:::-;62427:53;;;;-1:-1:-1;;;62427:53:0;;26219:2:1;62427:53:0;;;26201:21:1;26258:2;26238:18;;;26231:30;-1:-1:-1;;;26277:18:1;;;26270:54;26341:18;;62427:53:0;26017:348:1;29027:485:0;29226:22;;-1:-1:-1;;;;;29226:22:0;29218:43;:47;29214:291;;29308:22;;:126;;-1:-1:-1;;;29308:126:0;;29379:4;29308:126;;;31320:34:1;-1:-1:-1;;;;;31390:15:1;;;31370:18;;;31363:43;29308:22:0;;;;:40;;31255:18:1;;29308:126:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;29282:211;;;;-1:-1:-1;;;29282:211:0;;31869:2:1;29282:211:0;;;31851:21:1;31908:2;31888:18;;;31881:30;31947:25;31927:18;;;31920:53;31990:18;;29282:211:0;31667:347:1;52052:416:0;52133:13;52149:23;52164:7;52149:14;:23::i;:::-;52133:39;;52197:5;-1:-1:-1;;;;;52191:11:0;:2;-1:-1:-1;;;;;52191:11:0;;52183:57;;;;-1:-1:-1;;;52183:57:0;;32221:2:1;52183:57:0;;;32203:21:1;32260:2;32240:18;;;32233:30;32299:34;32279:18;;;32272:62;-1:-1:-1;;;32350:18:1;;;32343:31;32391:19;;52183:57:0;32019:397:1;52183:57:0;23648:10;-1:-1:-1;;;;;52275:21:0;;;;:62;;-1:-1:-1;52300:37:0;52317:5;23648:10;53003:164;:::i;52300:37::-;52253:173;;;;-1:-1:-1;;;52253:173:0;;32623:2:1;52253:173:0;;;32605:21:1;32662:2;32642:18;;;32635:30;32701:34;32681:18;;;32674:62;32772:31;32752:18;;;32745:59;32821:19;;52253:173:0;32421:425:1;52253:173:0;52439:21;52448:2;52452:7;52439:8;:21::i;55956:128::-;56021:4;55619:16;;;:7;:16;;;;;;-1:-1:-1;;;;;55619:16:0;56045:31;;;55956:128::o;94804:1880::-;95139:1;95104:20;;;:8;:20;;;;;:32;;;95082:129;;;;-1:-1:-1;;;95082:129:0;;33053:2:1;95082:129:0;;;33035:21:1;33092:2;33072:18;;;33065:30;33131:34;33111:18;;;33104:62;-1:-1:-1;;;33182:18:1;;;33175:41;33233:19;;95082:129:0;32851:407:1;95082:129:0;95520:20;;;;:8;:20;;;;;:29;;;;95467;;;;95411:32;;;;;95520:29;;95411:85;;;:::i;:::-;:138;;;;:::i;:::-;95377:14;:172;95355:298;;;;-1:-1:-1;;;95355:298:0;;33465:2:1;95355:298:0;;;33447:21:1;33504:2;33484:18;;;33477:30;33543:34;33523:18;;;33516:62;33614:34;33594:18;;;33587:62;-1:-1:-1;;;33665:19:1;;;33658:43;33718:19;;95355:298:0;33263:480:1;95355:298:0;-1:-1:-1;;;;;95672:21:0;;95664:56;;;;-1:-1:-1;;;95664:56:0;;33950:2:1;95664:56:0;;;33932:21:1;33989:2;33969:18;;;33962:30;-1:-1:-1;;;34008:18:1;;;34001:52;34070:18;;95664:56:0;33748:346:1;95664:56:0;-1:-1:-1;;;;;95739:20:0;;95731:54;;;;-1:-1:-1;;;95731:54:0;;34301:2:1;95731:54:0;;;34283:21:1;34340:2;34320:18;;;34313:30;-1:-1:-1;;;34359:18:1;;;34352:51;34420:18;;95731:54:0;34099:345:1;95731:54:0;95805:18;95824:8;95805:28;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;95804:29;95796:64;;;;-1:-1:-1;;;95796:64:0;;19881:2:1;95796:64:0;;;19863:21:1;19920:2;19900:18;;;19893:30;-1:-1:-1;;;19939:18:1;;;19932:52;20001:18;;95796:64:0;19679:346:1;95796:64:0;95873:17;95893:27;95906:14;95893:10;:27;:::i;:::-;95953:26;;;;:15;:26;;;;;:36;95873:47;;-1:-1:-1;95953:41:0;95931:137;;;;-1:-1:-1;;;95931:137:0;;34651:2:1;95931:137:0;;;34633:21:1;34690:2;34670:18;;;34663:30;34729:34;34709:18;;;34702:62;-1:-1:-1;;;34780:18:1;;;34773:44;34834:19;;95931:137:0;34449:410:1;95931:137:0;96113:35;;;;;;;;;;;;;;;;;;96081:29;96161:26;;;:15;:26;;;;;;:36;;;;;;96113:35;;;;96161:36;;;;;;;;:::i;:::-;-1:-1:-1;;;96208:30:0;;;;:18;:30;;;;;;;;:46;;;;;;;;;;;;;;;;;;;;96302:111;;;;;;;;;;;96361:30;;;;;;;:37;;96302:111;;;;;;96361:41;;96208:46;96361:41;:::i;:::-;96302:111;;96265:34;;;;:23;:34;;;;;;;;;:148;;;;;;;;;;;;96426:28;:18;;:28;;96445:8;;96426:28;:::i;:::-;;;;;;;;;;;;;;:35;;;;;-1:-1:-1;;96426:35:0;;;;;;;;;96474:29;96484:7;96493:9;96474;:29::i;:::-;96531:6;-1:-1:-1;;;;;96520:17:0;:7;-1:-1:-1;;;;;96520:17:0;;96516:95;;96554:45;96568:7;96577:6;96585:9;96554:45;;;;;;;;;;;;:13;:45::i;:::-;96666:9;96654:10;96646:6;-1:-1:-1;;;;;96628:48:0;;;;;;;;;;;94987:1697;;94804:1880;;;;;:::o;53234:335::-;53429:41;23648:10;53462:7;53429:18;:41::i;:::-;53421:99;;;;-1:-1:-1;;;53421:99:0;;;;;;;:::i;:::-;53533:28;53543:4;53549:2;53553:7;53533:9;:28::i;53640:185::-;53778:39;53795:4;53801:2;53805:7;53778:39;;;;;;;;;;;;:16;:39::i;85398:1288::-;85632:7;85666:5;85660:19;85683:1;85660:24;85652:59;;;;-1:-1:-1;;;85652:59:0;;35480:2:1;85652:59:0;;;35462:21:1;35519:2;35499:18;;;35492:30;-1:-1:-1;;;35538:18:1;;;35531:52;35600:18;;85652:59:0;35278:346:1;85652:59:0;85736:10;85730:24;85758:1;85730:29;85722:65;;;;-1:-1:-1;;;85722:65:0;;35831:2:1;85722:65:0;;;35813:21:1;35870:2;35850:18;;;35843:30;35909:25;35889:18;;;35882:53;35952:18;;85722:65:0;35629:347:1;85722:65:0;85812:11;85806:25;85835:1;85806:30;85798:71;;;;-1:-1:-1;;;85798:71:0;;36183:2:1;85798:71:0;;;36165:21:1;36222:2;36202:18;;;36195:30;36261;36241:18;;;36234:58;36309:18;;85798:71:0;35981:352:1;85798:71:0;85902:1;85888:11;:15;85880:63;;;;-1:-1:-1;;;85880:63:0;;36540:2:1;85880:63:0;;;36522:21:1;36579:2;36559:18;;;36552:30;36618:34;36598:18;;;36591:62;-1:-1:-1;;;36669:18:1;;;36662:33;36712:19;;85880:63:0;36338:399:1;85880:63:0;85956:17;86005:11;85994:23;;;;;;;;:::i;:::-;;;;-1:-1:-1;;85994:23:0;;;;;;;;;85984:34;;85994:23;85984:34;;;;85976:43;86128:19;;;:8;:19;;;;;:31;;86122:45;;85984:34;;-1:-1:-1;86128:31:0;86122:45;;;:::i;:::-;:50;;-1:-1:-1;86100:159:0;;;;-1:-1:-1;;;86100:159:0;;36944:2:1;86100:159:0;;;36926:21:1;36983:2;36963:18;;;36956:30;37022:34;37002:18;;;36995:62;37093:29;37073:18;;;37066:57;37140:19;;86100:159:0;36742:423:1;86100:159:0;86297:232;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86542:12;:28;;;;;;;;;;;;;86272:22;86581:19;;;:8;:19;;;;;;;:29;;86297:232;;86581:19;;;:29;;:19;:29;:::i;:::-;-1:-1:-1;86581:29:0;;;;;;;;;;;;:::i;:::-;-1:-1:-1;86581:29:0;;;;;;;;;;;;:::i;:::-;-1:-1:-1;86581:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;86628:21;;86639:9;;86628:21;;-1:-1:-1;;86628:21:0;-1:-1:-1;86669:9:0;85398:1288;-1:-1:-1;;;;;;;85398:1288:0:o;26284:191::-;26377:6;;;-1:-1:-1;;;;;26394:17:0;;;-1:-1:-1;;;;;;26394:17:0;;;;;;;26427:40;;26377:6;;;26394:17;26377:6;;26427:40;;26358:16;;26427:40;26347:128;26284:191;:::o;92539:1304::-;92667:31;92675:14;:22;;;92667:7;:31::i;:::-;92645:117;;;;-1:-1:-1;;;92645:117:0;;;;;;;:::i;:::-;92797:63;92816:14;:19;;;92837:14;:22;;;92797:18;:63::i;:::-;92775:159;;;;-1:-1:-1;;;92775:159:0;;;;;;;:::i;:::-;92988:14;:25;;;92969:15;:44;;92947:148;;;;-1:-1:-1;;;92947:148:0;;37372:2:1;92947:148:0;;;37354:21:1;37411:2;37391:18;;;37384:30;37450:34;37430:18;;;37423:62;-1:-1:-1;;;37501:18:1;;;37494:52;37563:19;;92947:148:0;37170:418:1;92947:148:0;93108:19;93183:14;:19;;;93221:14;:17;;;93257:14;:22;;;93298:14;:25;;;93154:184;;;;;;;;;;-1:-1:-1;;;;;37880:15:1;;;37862:34;;37932:15;;;;37927:2;37912:18;;37905:43;37979:2;37964:18;;37957:34;38022:2;38007:18;;38000:34;;;;37811:3;37796:19;;37593:447;93154:184:0;;;;;;;;;;;;;93130:219;;;;;;93108:241;;93384:205;93417:11;93447:14;:19;;;93485:14;:17;;;93521:14;:17;;;93557:14;:17;;;93384:14;:205::i;:::-;93362:316;;;;-1:-1:-1;;;93362:316:0;;38247:2:1;93362:316:0;;;38229:21:1;38286:2;38266:18;;;38259:30;38325:34;38305:18;;;38298:62;38396:31;38376:18;;;38369:59;38445:19;;93362:316:0;38045:425:1;93362:316:0;93691:144;93719:14;:19;;;93753:14;:17;;;93785:14;:22;;;93691:144;;;;;;;;;;;;:13;:144::i;52777:155::-;52872:52;23648:10;52905:8;52915;52872:18;:52::i;46793:716::-;46849:13;46900:14;46917:17;46928:5;46917:10;:17::i;:::-;46937:1;46917:21;46900:38;;46953:20;46987:6;-1:-1:-1;;;;;46976:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;46976:18:0;-1:-1:-1;46953:41:0;-1:-1:-1;47118:28:0;;;47134:2;47118:28;47175:288;-1:-1:-1;;47207:5:0;-1:-1:-1;;;47344:2:0;47333:14;;47328:30;47207:5;47315:44;47405:2;47396:11;;;-1:-1:-1;47426:21:0;47175:288;47426:21;-1:-1:-1;47484:6:0;46793:716;-1:-1:-1;;;46793:716:0:o;53896:322::-;54070:41;23648:10;54103:7;54070:18;:41::i;:::-;54062:99;;;;-1:-1:-1;;;54062:99:0;;;;;;;:::i;:::-;54172:38;54186:4;54192:2;54196:7;54205:4;54172:13;:38::i;109402:2059::-;109579:13;109605:22;109630:8;:19;109639:9;109630:19;;;;;;;;;;;109605:44;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;109662:27;109692;109711:7;109692:18;:27::i;:::-;109662:57;;109730:23;109794:7;:13;;;109814;109777:51;;;;;;;;;:::i;:::-;;;;;;;;;;;;;109730:109;;109988:1431;110337:18;:7;:16;:18::i;:::-;110438:9;110532:7;:18;;;110639:23;:9;:21;:23::i;:::-;110754:32;110755:19;110765:9;110755:7;:19;:::i;110754:32::-;110879:13;110242:681;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;111039:26;111052:12;111039;:26::i;:::-;111171:163;111217:27;111234:9;111217:16;:27::i;:::-;111279:24;111292:10;111279:12;:24::i;:::-;111171:11;:163::i;:::-;110195:1201;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;109988:13;:1431::i;:::-;109895:1543;;;;;;;;:::i;:::-;;;;;;;;;;;;;109850:1603;;;;;109402:2059;;;;;;;:::o;111596:320::-;111690:13;111721:21;111745:13;111721:37;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;111779:7;111773:21;111798:1;111773:26;111769:78;;-1:-1:-1;111816:19:0;;;;;;;;;;;;-1:-1:-1;;;111816:19:0;;;;111769:78;111890:7;111899;111873:34;;;;;;;;;:::i;:::-;;;;;;;;;;;;;111859:49;;;111596:320;;;:::o;56251:264::-;56344:4;56361:13;56377:23;56392:7;56377:14;:23::i;:::-;56361:39;;56430:5;-1:-1:-1;;;;;56419:16:0;:7;-1:-1:-1;;;;;56419:16:0;;:52;;;-1:-1:-1;;;;;;53124:25:0;;;53100:4;53124:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;56439:32;56419:87;;;;56499:7;-1:-1:-1;;;;;56475:31:0;:20;56487:7;56475:11;:20::i;:::-;-1:-1:-1;;;;;56475:31:0;;56411:96;56251:264;-1:-1:-1;;;;56251:264:0:o;96847:1110::-;96931:59;96993:34;;;:23;:34;;;;;;;;;96931:96;;;;;;;;;;;;;;;;;;;;;;;;;97040:155;;;;-1:-1:-1;;;97040:155:0;;44052:2:1;97040:155:0;;;44034:21:1;44091:2;44071:18;;;44064:30;44130:34;44110:18;;;44103:62;44201:34;44181:18;;;44174:62;-1:-1:-1;;;44252:19:1;;;44245:39;44301:19;;97040:155:0;43850:476:1;97040:155:0;97278:29;;97208:34;97245:73;;;:18;:73;;;;;97353:23;;97331:149;;;;-1:-1:-1;;;97331:149:0;;44533:2:1;97331:149:0;;;44515:21:1;44572:2;44552:18;;;44545:30;44611:34;44591:18;;;44584:62;44682:34;44662:18;;;44655:62;-1:-1:-1;;;44733:19:1;;;44726:39;44782:19;;97331:149:0;44331:476:1;97331:149:0;97520:23;;97493:24;;97520:27;;97546:1;;97520:27;:::i;:::-;97493:54;;97558:21;97582:16;97625:1;97599:16;:23;;;;:27;;;;:::i;:::-;97582:45;;;;;;;;:::i;:::-;;;;;;;;;97558:69;;97776:13;97730:16;97747:19;:25;;;97730:43;;;;;;;;:::i;:::-;;;;;;;;:59;;;;97837:19;:25;;;97800:16;97817;97800:34;;;;;;;;:::i;:::-;;;;;;;;:62;;;;97873:16;:22;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;97873:22:0;;;;;;;;;;;;97915:34;;;:23;:34;;;-1:-1:-1;;97915:34:0;;;97908:41;;;97873:22;97908:41;;;;;-1:-1:-1;;96847:1110:0:o;59130:783::-;59190:13;59206:23;59221:7;59206:14;:23::i;:::-;59190:39;;59242:51;59263:5;59278:1;59282:7;59291:1;59242:20;:51::i;:::-;59406:23;59421:7;59406:14;:23::i;:::-;59477:24;;;;:15;:24;;;;;;;;59470:31;;-1:-1:-1;;;;;;59470:31:0;;;;;;-1:-1:-1;;;;;59722:16:0;;;;;:9;:16;;;;;:21;;-1:-1:-1;;59722:21:0;;;59772:16;;;:7;:16;;;;;;59765:23;;;;;;;59806:36;59398:31;;-1:-1:-1;59493:7:0;;59806:36;;59477:24;;59806:36;94090:307:::1;93974:430:::0;:::o;50094:305::-;50196:4;-1:-1:-1;;;;;;50233:40:0;;-1:-1:-1;;;50233:40:0;;:105;;-1:-1:-1;;;;;;;50290:48:0;;-1:-1:-1;;;50290:48:0;50233:105;:158;;;-1:-1:-1;;;;;;;;;;15566:40:0;;;50355:36;15457:157;61632:174;61707:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;61707:29:0;-1:-1:-1;;;;;61707:29:0;;;;;;;;:24;;61761:23;61707:24;61761:14;:23::i;:::-;-1:-1:-1;;;;;61752:46:0;;;;;;;;;;;61632:174;;:::o;56857:110::-;56933:26;56943:2;56947:7;56933:26;;;;;;;;;;;;:9;:26::i;55099:313::-;55255:28;55265:4;55271:2;55275:7;55255:9;:28::i;:::-;55302:47;55325:4;55331:2;55335:7;55344:4;55302:22;:47::i;:::-;55294:110;;;;-1:-1:-1;;;55294:110:0;;;;;;;:::i;60250:1263::-;60409:4;-1:-1:-1;;;;;60382:31:0;:23;60397:7;60382:14;:23::i;:::-;-1:-1:-1;;;;;60382:31:0;;60374:81;;;;-1:-1:-1;;;60374:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;60474:16:0;;60466:65;;;;-1:-1:-1;;;60466:65:0;;45971:2:1;60466:65:0;;;45953:21:1;46010:2;45990:18;;;45983:30;46049:34;46029:18;;;46022:62;-1:-1:-1;;;46100:18:1;;;46093:34;46144:19;;60466:65:0;45769:400:1;60466:65:0;60544:42;60565:4;60571:2;60575:7;60584:1;60544:20;:42::i;:::-;60716:4;-1:-1:-1;;;;;60689:31:0;:23;60704:7;60689:14;:23::i;:::-;-1:-1:-1;;;;;60689:31:0;;60681:81;;;;-1:-1:-1;;;60681:81:0;;;;;;;:::i;:::-;60834:24;;;;:15;:24;;;;;;;;60827:31;;-1:-1:-1;;;;;;60827:31:0;;;;;;-1:-1:-1;;;;;61310:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;61310:20:0;;;61345:13;;;;;;;;;:18;;60827:31;61345:18;;;61385:16;;;:7;:16;;;;;;:21;;;;;;;;;;61424:27;;60850:7;;61424:27;;;100276:206;;;:::o;91742:371::-;91909:4;91926:14;91943:128;91971:38;92000:8;80543:58;;54530:66:1;80543:58:0;;;54518:79:1;54613:12;;;54606:28;;;80410:7:0;;54650:12:1;;80543:58:0;;;;;;;;;;;;80533:69;;;;;;80526:76;;80341:269;;;;91971:38;92024:2;92041;92058;91943:13;:128::i;:::-;-1:-1:-1;;;;;92089:16:0;;;;;;;;-1:-1:-1;;91742:371:0;;;;;;;:::o;61949:315::-;62104:8;-1:-1:-1;;;;;62095:17:0;:5;-1:-1:-1;;;;;62095:17:0;;62087:55;;;;-1:-1:-1;;;62087:55:0;;46376:2:1;62087:55:0;;;46358:21:1;46415:2;46395:18;;;46388:30;46454:27;46434:18;;;46427:55;46499:18;;62087:55:0;46174:349:1;62087:55:0;-1:-1:-1;;;;;62153:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;62153:46:0;;;;;;;;;;62215:41;;540::1;;;62215::0;;513:18:1;62215:41:0;;;;;;;61949:315;;;:::o;43659:922::-;43712:7;;-1:-1:-1;;;43790:15:0;;43786:102;;-1:-1:-1;;;43826:15:0;;;-1:-1:-1;43870:2:0;43860:12;43786:102;43915:6;43906:5;:15;43902:102;;43951:6;43942:15;;;-1:-1:-1;43986:2:0;43976:12;43902:102;44031:6;44022:5;:15;44018:102;;44067:6;44058:15;;;-1:-1:-1;44102:2:0;44092:12;44018:102;44147:5;44138;:14;44134:99;;44182:5;44173:14;;;-1:-1:-1;44216:1:0;44206:11;44134:99;44260:5;44251;:14;44247:99;;44295:5;44286:14;;;-1:-1:-1;44329:1:0;44319:11;44247:99;44373:5;44364;:14;44360:99;;44408:5;44399:14;;;-1:-1:-1;44442:1:0;44432:11;44360:99;44486:5;44477;:14;44473:66;;44522:1;44512:11;44567:6;43659:922;-1:-1:-1;;43659:922:0:o;47619:178::-;47678:13;47736:42;47748:5;47755:18;47767:5;47755:11;:18::i;:::-;47776:1;47755:22;47736:11;:42::i;106048:1061::-;106204:19;;106173:15;106265:29;;;:18;:29;;;;;;;;106235:59;;;;;;;;;;;;;;;;;106142:13;;-1:-1:-1;;;;;106204:19:0;;106173:15;106235:59;;106265:29;106235:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;106330:10:0;;;;;;;;;;;;-1:-1:-1;;;106330:10:0;;;;106235:59;;-1:-1:-1;106305:22:0;;-1:-1:-1;;;106353:345:0;106377:10;:17;106373:1;:21;106353:345;;;106416:15;106434:10;106445:1;106434:13;;;;;;;;:::i;:::-;;;;;;;106416:31;;106509:9;106537:32;106548:9;106538:7;:19;;;;:::i;106537:32::-;106611:37;106631:16;106639:7;106631;:16::i;:::-;106611:19;:37::i;:::-;106474:212;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;106462:224;;106401:297;106396:3;;;;;:::i;:::-;;;;106353:345;;;;106739:9;106722:32;;;;;;;;:::i;:::-;;;;-1:-1:-1;;106722:32:0;;;;;;;;;;106943:19;;-1:-1:-1;;;106932:31:0;;;;;7177:25:1;106722:32:0;-1:-1:-1;106912:52:0;;-1:-1:-1;;;;;106932:10:0;;;;;7150:18:1;;106932:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;106912:52::-;107031:9;106812:274;;;;;;;;;:::i;:::-;;;;;;;;;;;;;106767:334;;;;;106048:1061;;;:::o;107337:1694::-;107459:13;107510:1513;107676:11;108929:9;107542:1466;;;;;;;;;:::i;107510:1513::-;107490:1533;107337:1694;-1:-1:-1;;;107337:1694:0:o;30384:3097::-;30442:13;30679:4;:11;30694:1;30679:16;30675:31;;-1:-1:-1;;30697:9:0;;;;;;;;;-1:-1:-1;30697:9:0;;;30384:3097::o;30675:31::-;30759:19;30781:6;;;;;;;;;;;;;;;;;30759:28;;31198:20;31257:1;31238:4;:11;31252:1;31238:15;;;;:::i;:::-;31237:21;;;;:::i;:::-;31232:27;;:1;:27;:::i;:::-;-1:-1:-1;;;;;31221:39:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31221:39:0;;31198:62;;31440:1;31433:5;31429:13;31544:2;31536:6;31532:15;31655:4;31707;31701:11;31695:4;31691:22;31617:1432;31741:6;31732:7;31729:19;31617:1432;;;31847:1;31838:7;31834:15;31823:26;;31886:7;31880:14;32539:4;32531:5;32527:2;32523:14;32519:25;32509:8;32505:40;32499:47;32488:9;32480:67;32593:1;32582:9;32578:17;32565:30;;32685:4;32677:5;32673:2;32669:14;32665:25;32655:8;32651:40;32645:47;32634:9;32626:67;32739:1;32728:9;32724:17;32711:30;;32830:4;32822:5;32819:1;32815:13;32811:24;32801:8;32797:39;32791:46;32780:9;32772:66;32884:1;32873:9;32869:17;32856:30;;32967:4;32960:5;32956:16;32946:8;32942:31;32936:38;32925:9;32917:58;;33021:1;33010:9;33006:17;32993:30;;31617:1432;;;31621:107;;33211:1;33204:4;33198:11;33194:19;33232:1;33227:123;;;;33369:1;33364:73;;;;33187:250;;33227:123;33280:4;33276:1;33265:9;33261:17;33253:32;33330:4;33326:1;33315:9;33311:17;33303:32;33227:123;;33364:73;33417:4;33413:1;33402:9;33398:17;33390:32;33187:250;-1:-1:-1;33467:6:0;;30384:3097;-1:-1:-1;;;;;30384:3097:0:o;68097:915::-;68274:61;68301:4;68307:2;68311:12;68325:9;68274:26;:61::i;:::-;68364:1;68352:9;:13;68348:222;;;68495:63;;-1:-1:-1;;;68495:63:0;;53309:2:1;68495:63:0;;;53291:21:1;53348:2;53328:18;;;53321:30;53387:34;53367:18;;;53360:62;-1:-1:-1;;;53438:18:1;;;53431:51;53499:19;;68495:63:0;53107:417:1;68348:222:0;68600:12;-1:-1:-1;;;;;68629:18:0;;68625:187;;68664:40;68696:7;69839:10;:17;;69812:24;;;;:15;:24;;;;;:44;;;69867:24;;;;;;;;;;;;69735:164;68664:40;68625:187;;;68734:2;-1:-1:-1;;;;;68726:10:0;:4;-1:-1:-1;;;;;68726:10:0;;68722:90;;68753:47;68786:4;68792:7;68753:32;:47::i;:::-;-1:-1:-1;;;;;68826:16:0;;68822:183;;68859:45;68896:7;68859:36;:45::i;:::-;68822:183;;;68932:4;-1:-1:-1;;;;;68926:10:0;:2;-1:-1:-1;;;;;68926:10:0;;68922:83;;68953:40;68981:2;68985:7;68953:27;:40::i;57194:319::-;57323:18;57329:2;57333:7;57323:5;:18::i;:::-;57374:53;57405:1;57409:2;57413:7;57422:4;57374:22;:53::i;:::-;57352:153;;;;-1:-1:-1;;;57352:153:0;;;;;;;:::i;63052:853::-;63206:4;-1:-1:-1;;;;;63227:13:0;;3823:19;:23;63223:675;;63263:71;;-1:-1:-1;;;63263:71:0;;-1:-1:-1;;;;;63263:36:0;;;;;:71;;23648:10;;63314:4;;63320:7;;63329:4;;63263:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63263:71:0;;;;;;;;-1:-1:-1;;63263:71:0;;;;;;;;;;;;:::i;:::-;;;63259:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63504:6;:13;63521:1;63504:18;63500:328;;63547:60;;-1:-1:-1;;;63547:60:0;;;;;;;:::i;63500:328::-;63778:6;63772:13;63763:6;63759:2;63755:15;63748:38;63259:584;-1:-1:-1;;;;;;63385:51:0;-1:-1:-1;;;63385:51:0;;-1:-1:-1;63378:58:0;;63223:675;-1:-1:-1;63882:4:0;63875:11;;79762:279;79890:7;79911:17;79930:18;79952:25;79963:4;79969:1;79972;79975;79952:10;:25::i;:::-;79910:67;;;;79988:18;80000:5;79988:11;:18::i;:::-;-1:-1:-1;80024:9:0;79762:279;-1:-1:-1;;;;;79762:279:0:o;45251:687::-;45305:7;;45392:3;45383:12;;;:16;45379:101;;45430:3;45420:13;;;;;45462:2;45452:12;45379:101;45507:2;45498:11;;;:15;45494:98;;45544:2;45534:12;;;;;45575:1;45565:11;45494:98;45619:2;45610:11;;;:15;45606:98;;45656:2;45646:12;;;;;45687:1;45677:11;45606:98;45731:2;45722:11;;;:15;45718:98;;45768:2;45758:12;;;;;45799:1;45789:11;45718:98;45843:1;45834:10;;;:14;45830:66;;45879:1;45869:11;45924:6;45251:687;-1:-1:-1;;45251:687:0:o;47925:447::-;48000:13;48026:19;48058:10;48062:6;48058:1;:10;:::i;:::-;:14;;48071:1;48058:14;:::i;:::-;-1:-1:-1;;;;;48048:25:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48048:25:0;;48026:47;;-1:-1:-1;;;48084:6:0;48091:1;48084:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;48084:15:0;;;;;;;;;-1:-1:-1;;;48110:6:0;48117:1;48110:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;48110:15:0;;;;;;;;-1:-1:-1;48141:9:0;48153:10;48157:6;48153:1;:10;:::i;:::-;:14;;48166:1;48153:14;:::i;:::-;48141:26;;48136:131;48173:1;48169;:5;48136:131;;;-1:-1:-1;;;48217:5:0;48225:3;48217:11;48208:21;;;;;;;:::i;:::-;;;;48196:6;48203:1;48196:9;;;;;;;;:::i;:::-;;;;:33;-1:-1:-1;;;;;48196:33:0;;;;;;;;-1:-1:-1;48254:1:0;48244:11;;;;;48176:3;;;:::i;:::-;;;48136:131;;;-1:-1:-1;48285:10:0;;48277:55;;;;-1:-1:-1;;;48277:55:0;;55016:2:1;48277:55:0;;;54998:21:1;;;55035:18;;;55028:30;55094:34;55074:18;;;55067:62;55146:18;;48277:55:0;54814:356:1;48529:151:0;48587:13;48620:52;-1:-1:-1;;;;;48632:22:0;;46684:2;48620:11;:52::i;64637:410::-;64827:1;64815:9;:13;64811:229;;;-1:-1:-1;;;;;64849:18:0;;;64845:87;;-1:-1:-1;;;;;64888:15:0;;;;;;:9;:15;;;;;:28;;64907:9;;64888:15;:28;;64907:9;;64888:28;:::i;:::-;;;;-1:-1:-1;;64845:87:0;-1:-1:-1;;;;;64950:16:0;;;64946:83;;-1:-1:-1;;;;;64987:13:0;;;;;;:9;:13;;;;;:26;;65004:9;;64987:13;:26;;65004:9;;64987:26;:::i;:::-;;;;-1:-1:-1;;64637:410:0;;;;:::o;70526:988::-;70792:22;70842:1;70817:22;70834:4;70817:16;:22::i;:::-;:26;;;;:::i;:::-;70854:18;70875:26;;;:17;:26;;;;;;70792:51;;-1:-1:-1;71008:28:0;;;71004:328;;-1:-1:-1;;;;;71075:18:0;;71053:19;71075:18;;;:12;:18;;;;;;;;:34;;;;;;;;;71126:30;;;;;;:44;;;71243:30;;:17;:30;;;;;:43;;;71004:328;-1:-1:-1;71428:26:0;;;;:17;:26;;;;;;;;71421:33;;;-1:-1:-1;;;;;71472:18:0;;;;;:12;:18;;;;;:34;;;;;;;71465:41;70526:988::o;71809:1079::-;72087:10;:17;72062:22;;72087:21;;72107:1;;72087:21;:::i;:::-;72119:18;72140:24;;;:15;:24;;;;;;72513:10;:26;;72062:46;;-1:-1:-1;72140:24:0;;72062:46;;72513:26;;;;;;:::i;:::-;;;;;;;;;72491:48;;72577:11;72552:10;72563;72552:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;72657:28;;;:15;:28;;;;;;;:41;;;72829:24;;;;;72822:31;72864:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;71880:1008;;;71809:1079;:::o;69313:221::-;69398:14;69415:20;69432:2;69415:16;:20::i;:::-;-1:-1:-1;;;;;69446:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;69491:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;69313:221:0:o;57849:942::-;-1:-1:-1;;;;;57929:16:0;;57921:61;;;;-1:-1:-1;;;57921:61:0;;55377:2:1;57921:61:0;;;55359:21:1;;;55396:18;;;55389:30;55455:34;55435:18;;;55428:62;55507:18;;57921:61:0;55175:356:1;57921:61:0;58002:16;58010:7;58002;:16::i;:::-;58001:17;57993:58;;;;-1:-1:-1;;;57993:58:0;;55738:2:1;57993:58:0;;;55720:21:1;55777:2;55757:18;;;55750:30;55816;55796:18;;;55789:58;55864:18;;57993:58:0;55536:352:1;57993:58:0;58064:48;58093:1;58097:2;58101:7;58110:1;58064:20;:48::i;:::-;58211:16;58219:7;58211;:16::i;:::-;58210:17;58202:58;;;;-1:-1:-1;;;58202:58:0;;55738:2:1;58202:58:0;;;55720:21:1;55777:2;55757:18;;;55750:30;55816;55796:18;;;55789:58;55864:18;;58202:58:0;55536:352:1;58202:58:0;-1:-1:-1;;;;;58609:13:0;;;;;;:9;:13;;;;;;;;:18;;58626:1;58609:18;;;58651:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;58651:21:0;;;;;58690:33;58659:7;;58609:13;;58690:33;;58609:13;;58690:33;94090:307:::1;93974:430:::0;:::o;78103:1520::-;78234:7;;79168:66;79155:79;;79151:163;;;-1:-1:-1;79267:1:0;;-1:-1:-1;79271:30:0;79251:51;;79151:163;79428:24;;;79411:14;79428:24;;;;;;;;;56120:25:1;;;56193:4;56181:17;;56161:18;;;56154:45;;;;56215:18;;;56208:34;;;56258:18;;;56251:34;;;79428:24:0;;56092:19:1;;79428:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;79428:24:0;;-1:-1:-1;;79428:24:0;;;-1:-1:-1;;;;;;;79467:20:0;;79463:103;;79520:1;79524:29;79504:50;;;;;;;79463:103;79586:6;-1:-1:-1;79594:20:0;;-1:-1:-1;78103:1520:0;;;;;;;;:::o;73495:521::-;73573:20;73564:5;:29;;;;;;;;:::i;:::-;;73560:449;;73495:521;:::o;73560:449::-;73671:29;73662:5;:38;;;;;;;;:::i;:::-;;73658:351;;73717:34;;-1:-1:-1;;;73717:34:0;;56630:2:1;73717:34:0;;;56612:21:1;56669:2;56649:18;;;56642:30;56708:26;56688:18;;;56681:54;56752:18;;73717:34:0;56428:348:1;73658:351:0;73782:35;73773:5;:44;;;;;;;;:::i;:::-;;73769:240;;73834:41;;-1:-1:-1;;;73834:41:0;;56983:2:1;73834:41:0;;;56965:21:1;57022:2;57002:18;;;56995:30;57061:33;57041:18;;;57034:61;57112:18;;73834:41:0;56781:355:1;73769:240:0;73906:30;73897:5;:39;;;;;;;;:::i;:::-;;73893:116;;73953:44;;-1:-1:-1;;;73953:44:0;;57343:2:1;73953:44:0;;;57325:21:1;57382:2;57362:18;;;57355:30;57421:34;57401:18;;;57394:62;-1:-1:-1;;;57472:18:1;;;57465:32;57514:19;;73953:44:0;57141:398:1;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:131::-;-1:-1:-1;;;;;667:31:1;;657:42;;647:70;;713:1;710;703:12;728:247;787:6;840:2;828:9;819:7;815:23;811:32;808:52;;;856:1;853;846:12;808:52;895:9;882:23;914:31;939:5;914:31;:::i;980:250::-;1065:1;1075:113;1089:6;1086:1;1083:13;1075:113;;;1165:11;;;1159:18;1146:11;;;1139:39;1111:2;1104:10;1075:113;;;-1:-1:-1;;1222:1:1;1204:16;;1197:27;980:250::o;1235:282::-;1288:3;1326:5;1320:12;1353:6;1348:3;1341:19;1369:76;1438:6;1431:4;1426:3;1422:14;1415:4;1408:5;1404:16;1369:76;:::i;:::-;1499:2;1478:15;-1:-1:-1;;1474:29:1;1465:39;;;;1506:4;1461:50;;1235:282;-1:-1:-1;;1235:282:1:o;1522:231::-;1671:2;1660:9;1653:21;1634:4;1691:56;1743:2;1732:9;1728:18;1720:6;1691:56;:::i;1758:180::-;1817:6;1870:2;1858:9;1849:7;1845:23;1841:32;1838:52;;;1886:1;1883;1876:12;1838:52;-1:-1:-1;1909:23:1;;1758:180;-1:-1:-1;1758:180:1:o;2151:315::-;2219:6;2227;2280:2;2268:9;2259:7;2255:23;2251:32;2248:52;;;2296:1;2293;2286:12;2248:52;2335:9;2322:23;2354:31;2379:5;2354:31;:::i;:::-;2404:5;2456:2;2441:18;;;;2428:32;;-1:-1:-1;;;2151:315:1:o;2471:127::-;2532:10;2527:3;2523:20;2520:1;2513:31;2563:4;2560:1;2553:15;2587:4;2584:1;2577:15;2603:253;2675:2;2669:9;2717:4;2705:17;;-1:-1:-1;;;;;2737:34:1;;2773:22;;;2734:62;2731:88;;;2799:18;;:::i;:::-;2835:2;2828:22;2603:253;:::o;2861:::-;2933:2;2927:9;2975:4;2963:17;;-1:-1:-1;;;;;2995:34:1;;3031:22;;;2992:62;2989:88;;;3057:18;;:::i;3119:253::-;3191:2;3185:9;3233:4;3221:17;;-1:-1:-1;;;;;3253:34:1;;3289:22;;;3250:62;3247:88;;;3315:18;;:::i;3377:275::-;3448:2;3442:9;3513:2;3494:13;;-1:-1:-1;;3490:27:1;3478:40;;-1:-1:-1;;;;;3533:34:1;;3569:22;;;3530:62;3527:88;;;3595:18;;:::i;:::-;3631:2;3624:22;3377:275;;-1:-1:-1;3377:275:1:o;3657:407::-;3722:5;-1:-1:-1;;;;;3748:6:1;3745:30;3742:56;;;3778:18;;:::i;:::-;3816:57;3861:2;3840:15;;-1:-1:-1;;3836:29:1;3867:4;3832:40;3816:57;:::i;:::-;3807:66;;3896:6;3889:5;3882:21;3936:3;3927:6;3922:3;3918:16;3915:25;3912:45;;;3953:1;3950;3943:12;3912:45;4002:6;3997:3;3990:4;3983:5;3979:16;3966:43;4056:1;4049:4;4040:6;4033:5;4029:18;4025:29;4018:40;3657:407;;;;;:::o;4069:222::-;4112:5;4165:3;4158:4;4150:6;4146:17;4142:27;4132:55;;4183:1;4180;4173:12;4132:55;4205:80;4281:3;4272:6;4259:20;4252:4;4244:6;4240:17;4205:80;:::i;4296:390::-;4374:6;4382;4435:2;4423:9;4414:7;4410:23;4406:32;4403:52;;;4451:1;4448;4441:12;4403:52;4487:9;4474:23;4464:33;;4548:2;4537:9;4533:18;4520:32;-1:-1:-1;;;;;4567:6:1;4564:30;4561:50;;;4607:1;4604;4597:12;4561:50;4630;4672:7;4663:6;4652:9;4648:22;4630:50;:::i;:::-;4620:60;;;4296:390;;;;;:::o;4691:199::-;4767:4;-1:-1:-1;;;;;4792:6:1;4789:30;4786:56;;;4822:18;;:::i;:::-;-1:-1:-1;4867:1:1;4863:14;4879:4;4859:25;;4691:199::o;4895:2131::-;5013:6;5044:2;5087;5075:9;5066:7;5062:23;5058:32;5055:52;;;5103:1;5100;5093:12;5055:52;5143:9;5130:23;-1:-1:-1;;;;;5213:2:1;5205:6;5202:14;5199:34;;;5229:1;5226;5219:12;5199:34;5267:6;5256:9;5252:22;5242:32;;5312:7;5305:4;5301:2;5297:13;5293:27;5283:55;;5334:1;5331;5324:12;5283:55;5370:2;5357:16;5393:76;5409:59;5465:2;5409:59;:::i;:::-;5393:76;:::i;:::-;5503:15;;;5585:1;5581:10;;;;5573:19;;5569:28;;;5534:12;;;;5609:19;;;5606:39;;;5641:1;5638;5631:12;5606:39;5673:2;5669;5665:11;5685:1311;5701:6;5696:3;5693:15;5685:1311;;;5787:3;5774:17;5823:2;5810:11;5807:19;5804:109;;;5867:1;5896:2;5892;5885:14;5804:109;5936:20;;5979:4;6007:16;;;-1:-1:-1;;6003:30:1;5999:39;-1:-1:-1;5996:129:1;;;6079:1;6108:2;6104;6097:14;5996:129;6151:22;;:::i;:::-;6221:2;6217;6213:11;6200:25;6193:5;6186:40;6249:2;6308;6304;6300:11;6287:25;6282:2;6275:5;6271:14;6264:49;6337:2;6388:3;6384:2;6380:12;6367:26;6406:33;6431:7;6406:33;:::i;:::-;6475:7;6470:2;6463:5;6459:14;6452:31;;6507:3;6496:14;;6559:3;6555:2;6551:12;6538:26;6577:33;6602:7;6577:33;:::i;:::-;6630:15;;;6623:32;6697:11;;;6684:25;;6725:16;;;6722:109;;;6783:1;6813:3;6808;6801:16;6722:109;6868:54;6914:7;6909:2;6898:8;6894:2;6890:17;6886:26;6868:54;:::i;:::-;6851:15;;;6844:79;6936:18;;-1:-1:-1;;6974:12:1;;;;5718;;5685:1311;;;-1:-1:-1;7015:5:1;4895:2131;-1:-1:-1;;;;;;;;4895:2131:1:o;7213:456::-;7290:6;7298;7306;7359:2;7347:9;7338:7;7334:23;7330:32;7327:52;;;7375:1;7372;7365:12;7327:52;7414:9;7401:23;7433:31;7458:5;7433:31;:::i;:::-;7483:5;-1:-1:-1;7540:2:1;7525:18;;7512:32;7553:33;7512:32;7553:33;:::i;:::-;7213:456;;7605:7;;-1:-1:-1;;;7659:2:1;7644:18;;;;7631:32;;7213:456::o;7674:248::-;7742:6;7750;7803:2;7791:9;7782:7;7778:23;7774:32;7771:52;;;7819:1;7816;7809:12;7771:52;-1:-1:-1;;7842:23:1;;;7912:2;7897:18;;;7884:32;;-1:-1:-1;7674:248:1:o;8206:405::-;8403:2;8392:9;8385:21;8366:4;8429:56;8481:2;8470:9;8466:18;8458:6;8429:56;:::i;:::-;8533:9;8525:6;8521:22;8516:2;8505:9;8501:18;8494:50;8561:44;8598:6;8590;8561:44;:::i;:::-;8553:52;8206:405;-1:-1:-1;;;;;8206:405:1:o;8616:931::-;8670:5;8718:4;8706:9;8701:3;8697:19;8693:30;8690:50;;;8736:1;8733;8726:12;8690:50;8758:22;;:::i;:::-;8749:31;;8816:9;8803:23;-1:-1:-1;;;;;8886:2:1;8878:6;8875:14;8872:34;;;8902:1;8899;8892:12;8872:34;8929:46;8971:3;8962:6;8951:9;8947:22;8929:46;:::i;:::-;8922:5;8915:61;9029:2;9018:9;9014:18;9001:32;8985:48;;9058:2;9048:8;9045:16;9042:36;;;9074:1;9071;9064:12;9042:36;9110:48;9154:3;9143:8;9132:9;9128:24;9110:48;:::i;:::-;9105:2;9098:5;9094:14;9087:72;9212:2;9201:9;9197:18;9184:32;9168:48;;9241:2;9231:8;9228:16;9225:36;;;9257:1;9254;9247:12;9225:36;;9293:48;9337:3;9326:8;9315:9;9311:24;9293:48;:::i;:::-;9288:2;9281:5;9277:14;9270:72;;9402:2;9391:9;9387:18;9374:32;9369:2;9362:5;9358:14;9351:56;9468:3;9457:9;9453:19;9440:33;9434:3;9427:5;9423:15;9416:58;9535:3;9524:9;9520:19;9507:33;9501:3;9494:5;9490:15;9483:58;8616:931;;;;:::o;9552:1172::-;9661:6;9692:2;9735;9723:9;9714:7;9710:23;9706:32;9703:52;;;9751:1;9748;9741:12;9703:52;9791:9;9778:23;-1:-1:-1;;;;;9861:2:1;9853:6;9850:14;9847:34;;;9877:1;9874;9867:12;9847:34;9915:6;9904:9;9900:22;9890:32;;9960:7;9953:4;9949:2;9945:13;9941:27;9931:55;;9982:1;9979;9972:12;9931:55;10018:2;10005:16;10041:76;10057:59;10113:2;10057:59;:::i;10041:76::-;10151:15;;;10233:1;10229:10;;;;10221:19;;10217:28;;;10182:12;;;;10257:19;;;10254:39;;;10289:1;10286;10279:12;10254:39;10321:2;10317;10313:11;10333:361;10349:6;10344:3;10341:15;10333:361;;;10435:3;10422:17;10471:2;10458:11;10455:19;10452:109;;;10515:1;10544:2;10540;10533:14;10452:109;10586:65;10643:7;10638:2;10624:11;10620:2;10616:20;10612:29;10586:65;:::i;:::-;10574:78;;-1:-1:-1;10672:12:1;;;;10366;;10333:361;;10729:796;11058:3;11047:9;11040:22;11021:4;11085:57;11137:3;11126:9;11122:19;11114:6;11085:57;:::i;:::-;11190:9;11182:6;11178:22;11173:2;11162:9;11158:18;11151:50;11224:44;11261:6;11253;11224:44;:::i;:::-;11210:58;;11316:9;11308:6;11304:22;11299:2;11288:9;11284:18;11277:50;11344:44;11381:6;11373;11344:44;:::i;:::-;11419:2;11404:18;;11397:34;;;;-1:-1:-1;;11462:3:1;11447:19;;11440:35;;;;11506:3;11491:19;;;11484:35;11336:52;10729:796;-1:-1:-1;;;10729:796:1:o;11530:611::-;11627:6;11635;11643;11696:2;11684:9;11675:7;11671:23;11667:32;11664:52;;;11712:1;11709;11702:12;11664:52;11748:9;11735:23;11725:33;;11809:2;11798:9;11794:18;11781:32;-1:-1:-1;;;;;11873:2:1;11865:6;11862:14;11859:34;;;11889:1;11886;11879:12;11859:34;11912:50;11954:7;11945:6;11934:9;11930:22;11912:50;:::i;:::-;11902:60;;12015:2;12004:9;12000:18;11987:32;11971:48;;12044:2;12034:8;12031:16;12028:36;;;12060:1;12057;12050:12;12028:36;;12083:52;12127:7;12116:8;12105:9;12101:24;12083:52;:::i;:::-;12073:62;;;11530:611;;;;;:::o;12146:302::-;12323:6;12312:9;12305:25;12366:2;12361;12350:9;12346:18;12339:30;12286:4;12386:56;12438:2;12427:9;12423:18;12415:6;12386:56;:::i;12453:766::-;12575:6;12583;12591;12644:2;12632:9;12623:7;12619:23;12615:32;12612:52;;;12660:1;12657;12650:12;12612:52;12700:9;12687:23;-1:-1:-1;;;;;12770:2:1;12762:6;12759:14;12756:34;;;12786:1;12783;12776:12;12756:34;12809:58;12859:7;12850:6;12839:9;12835:22;12809:58;:::i;:::-;12799:68;;12920:2;12909:9;12905:18;12892:32;12876:48;;12949:2;12939:8;12936:16;12933:36;;;12965:1;12962;12955:12;13224:322;13293:6;13346:2;13334:9;13325:7;13321:23;13317:32;13314:52;;;13362:1;13359;13352:12;13314:52;13402:9;13389:23;-1:-1:-1;;;;;13427:6:1;13424:30;13421:50;;;13467:1;13464;13457:12;13421:50;13490;13532:7;13523:6;13512:9;13508:22;13490:50;:::i;13551:2030::-;13673:6;13704:2;13747;13735:9;13726:7;13722:23;13718:32;13715:52;;;13763:1;13760;13753:12;13715:52;13803:9;13790:23;-1:-1:-1;;;;;13828:6:1;13825:30;13822:50;;;13868:1;13865;13858:12;13822:50;13891:22;;13944:4;13936:13;;13932:27;-1:-1:-1;13922:55:1;;13973:1;13970;13963:12;13922:55;14009:2;13996:16;14032:76;14048:59;14104:2;14048:59;:::i;14032:76::-;14142:15;;;14204:4;14243:11;;;14235:20;;14231:29;;;14173:12;;;;14130:3;14272:19;;;14269:39;;;14304:1;14301;14294:12;14269:39;14328:11;;;;14348:1203;14364:6;14359:3;14356:15;14348:1203;;;14444:2;14438:3;14429:7;14425:17;14421:26;14418:116;;;14488:1;14517:2;14513;14506:14;14418:116;14560:22;;:::i;:::-;14623:3;14610:17;14640:33;14665:7;14640:33;:::i;:::-;14686:22;;14749:12;;;14736:26;14775:33;14736:26;14775:33;:::i;:::-;14828:14;;;14821:31;14875:2;14926:12;;;14913:26;14897:14;;;14890:50;14963:2;15014:12;;;15001:26;14985:14;;;14978:50;15051:3;15103:12;;;15090:26;15074:14;;;15067:50;15140:3;15192:12;;;15179:26;15163:14;;;15156:50;15230:3;15274:13;;;15261:27;15336:4;15323:18;;15311:31;;15301:132;;15385:1;15415:3;15410;15403:16;15301:132;15453:15;;;15446:32;15491:18;;14381:12;;;;15529;;;;14348:1203;;;-1:-1:-1;15570:5:1;13551:2030;-1:-1:-1;;;;;;;13551:2030:1:o;15586:118::-;15672:5;15665:13;15658:21;15651:5;15648:32;15638:60;;15694:1;15691;15684:12;15709:382;15774:6;15782;15835:2;15823:9;15814:7;15810:23;15806:32;15803:52;;;15851:1;15848;15841:12;15803:52;15890:9;15877:23;15909:31;15934:5;15909:31;:::i;:::-;15959:5;-1:-1:-1;16016:2:1;16001:18;;15988:32;16029:30;15988:32;16029:30;:::i;:::-;16078:7;16068:17;;;15709:382;;;;;:::o;16096:795::-;16191:6;16199;16207;16215;16268:3;16256:9;16247:7;16243:23;16239:33;16236:53;;;16285:1;16282;16275:12;16236:53;16324:9;16311:23;16343:31;16368:5;16343:31;:::i;:::-;16393:5;-1:-1:-1;16450:2:1;16435:18;;16422:32;16463:33;16422:32;16463:33;:::i;:::-;16515:7;-1:-1:-1;16569:2:1;16554:18;;16541:32;;-1:-1:-1;16624:2:1;16609:18;;16596:32;-1:-1:-1;;;;;16640:30:1;;16637:50;;;16683:1;16680;16673:12;16637:50;16706:22;;16759:4;16751:13;;16747:27;-1:-1:-1;16737:55:1;;16788:1;16785;16778:12;16737:55;16811:74;16877:7;16872:2;16859:16;16854:2;16850;16846:11;16811:74;:::i;:::-;16801:84;;;16096:795;;;;;;;:::o;16896:388::-;16964:6;16972;17025:2;17013:9;17004:7;17000:23;16996:32;16993:52;;;17041:1;17038;17031:12;16993:52;17080:9;17067:23;17099:31;17124:5;17099:31;:::i;:::-;17149:5;-1:-1:-1;17206:2:1;17191:18;;17178:32;17219:33;17178:32;17219:33;:::i;17528:907::-;17612:6;17643:2;17686;17674:9;17665:7;17661:23;17657:32;17654:52;;;17702:1;17699;17692:12;17654:52;17742:9;17729:23;-1:-1:-1;;;;;17767:6:1;17764:30;17761:50;;;17807:1;17804;17797:12;17761:50;17830:22;;17883:4;17875:13;;17871:27;-1:-1:-1;17861:55:1;;17912:1;17909;17902:12;17861:55;17948:2;17935:16;17971:76;17987:59;18043:2;17987:59;:::i;17971:76::-;18081:15;;;18163:1;18159:10;;;;18151:19;;18147:28;;;18112:12;;;;18187:19;;;18184:39;;;18219:1;18216;18209:12;18184:39;18243:11;;;;18263:142;18279:6;18274:3;18271:15;18263:142;;;18345:17;;18333:30;;18296:12;;;;18383;;;;18263:142;;;18424:5;17528:907;-1:-1:-1;;;;;;;17528:907:1:o;18440:380::-;18519:1;18515:12;;;;18562;;;18583:61;;18637:4;18629:6;18625:17;18615:27;;18583:61;18690:2;18682:6;18679:14;18659:18;18656:38;18653:161;;18736:10;18731:3;18727:20;18724:1;18717:31;18771:4;18768:1;18761:15;18799:4;18796:1;18789:15;18653:161;;18440:380;;;:::o;19182:198::-;19224:3;19262:5;19256:12;19277:65;19335:6;19330:3;19323:4;19316:5;19312:16;19277:65;:::i;:::-;19358:16;;;;;19182:198;-1:-1:-1;;19182:198:1:o;19385:289::-;19516:3;19554:6;19548:13;19570:66;19629:6;19624:3;19617:4;19609:6;19605:17;19570:66;:::i;:::-;19652:16;;;;;19385:289;-1:-1:-1;;19385:289:1:o;20156:842::-;20284:3;20313:1;20346:6;20340:13;20376:36;20402:9;20376:36;:::i;:::-;20431:1;20448:18;;;20475:133;;;;20622:1;20617:356;;;;20441:532;;20475:133;-1:-1:-1;;20508:24:1;;20496:37;;20581:14;;20574:22;20562:35;;20553:45;;;-1:-1:-1;20475:133:1;;20617:356;20648:6;20645:1;20638:17;20678:4;20723:2;20720:1;20710:16;20748:1;20762:165;20776:6;20773:1;20770:13;20762:165;;;20854:14;;20841:11;;;20834:35;20897:16;;;;20791:10;;20762:165;;;20766:3;;;20956:6;20951:3;20947:16;20940:23;;20441:532;-1:-1:-1;20989:3:1;;20156:842;-1:-1:-1;;;;;;20156:842:1:o;21003:545::-;21105:2;21100:3;21097:11;21094:448;;;21141:1;21166:5;21162:2;21155:17;21211:4;21207:2;21197:19;21281:2;21269:10;21265:19;21262:1;21258:27;21252:4;21248:38;21317:4;21305:10;21302:20;21299:47;;;-1:-1:-1;21340:4:1;21299:47;21395:2;21390:3;21386:12;21383:1;21379:20;21373:4;21369:31;21359:41;;21450:82;21468:2;21461:5;21458:13;21450:82;;;21513:17;;;21494:1;21483:13;21450:82;;21724:1352;21850:3;21844:10;-1:-1:-1;;;;;21869:6:1;21866:30;21863:56;;;21899:18;;:::i;:::-;21928:97;22018:6;21978:38;22010:4;22004:11;21978:38;:::i;:::-;21972:4;21928:97;:::i;:::-;22080:4;;22144:2;22133:14;;22161:1;22156:663;;;;22863:1;22880:6;22877:89;;;-1:-1:-1;22932:19:1;;;22926:26;22877:89;-1:-1:-1;;21681:1:1;21677:11;;;21673:24;21669:29;21659:40;21705:1;21701:11;;;21656:57;22979:81;;22126:944;;22156:663;20103:1;20096:14;;;20140:4;20127:18;;-1:-1:-1;;22192:20:1;;;22310:236;22324:7;22321:1;22318:14;22310:236;;;22413:19;;;22407:26;22392:42;;22505:27;;;;22473:1;22461:14;;;;22340:19;;22310:236;;;22314:3;22574:6;22565:7;22562:19;22559:201;;;22635:19;;;22629:26;-1:-1:-1;;22718:1:1;22714:14;;;22730:3;22710:24;22706:37;22702:42;22687:58;22672:74;;22559:201;-1:-1:-1;;;;;22806:1:1;22790:14;;;22786:22;22773:36;;-1:-1:-1;21724:1352:1:o;23081:127::-;23142:10;23137:3;23133:20;23130:1;23123:31;23173:4;23170:1;23163:15;23197:4;23194:1;23187:15;23213:127;23274:10;23269:3;23265:20;23262:1;23255:31;23305:4;23302:1;23295:15;23329:4;23326:1;23319:15;23345:135;23384:3;23405:17;;;23402:43;;23425:18;;:::i;:::-;-1:-1:-1;23472:1:1;23461:13;;23345:135::o;23903:168::-;23976:9;;;24007;;24024:15;;;24018:22;;24004:37;23994:71;;24045:18;;:::i;24208:217::-;24248:1;24274;24264:132;;24318:10;24313:3;24309:20;24306:1;24299:31;24353:4;24350:1;24343:15;24381:4;24378:1;24371:15;24264:132;-1:-1:-1;24410:9:1;;24208:217::o;27991:125::-;28056:9;;;28077:10;;;28074:36;;;28090:18;;:::i;28121:128::-;28188:9;;;28209:11;;;28206:37;;;28223:18;;:::i;28254:431::-;-1:-1:-1;;;28511:3:1;28504:16;28486:3;28549:6;28543:13;28565:74;28632:6;28628:1;28623:3;28619:11;28612:4;28604:6;28600:17;28565:74;:::i;:::-;28659:16;;;;28677:1;28655:24;;28254:431;-1:-1:-1;;28254:431:1:o;29927:400::-;30129:2;30111:21;;;30168:2;30148:18;;;30141:30;30207:34;30202:2;30187:18;;30180:62;-1:-1:-1;;;30273:2:1;30258:18;;30251:34;30317:3;30302:19;;29927:400::o;30332:410::-;30534:2;30516:21;;;30573:2;30553:18;;;30546:30;30612:34;30607:2;30592:18;;30585:62;-1:-1:-1;;;30678:2:1;30663:18;;30656:44;30732:3;30717:19;;30332:410::o;31417:245::-;31484:6;31537:2;31525:9;31516:7;31512:23;31508:32;31505:52;;;31553:1;31550;31543:12;31505:52;31585:9;31579:16;31604:28;31626:5;31604:28;:::i;34864:409::-;35066:2;35048:21;;;35105:2;35085:18;;;35078:30;35144:34;35139:2;35124:18;;35117:62;-1:-1:-1;;;35210:2:1;35195:18;;35188:43;35263:3;35248:19;;34864:409::o;38475:640::-;38755:3;38793:6;38787:13;38809:66;38868:6;38863:3;38856:4;38848:6;38844:17;38809:66;:::i;:::-;-1:-1:-1;;;38897:16:1;;;38922:18;;;38965:13;;38987:78;38965:13;39052:1;39041:13;;39034:4;39022:17;;38987:78;:::i;:::-;39085:20;39107:1;39081:28;;38475:640;-1:-1:-1;;;;38475:640:1:o;39290:2182::-;-1:-1:-1;;;40285:39:1;;40347:13;;40267:3;;40369:74;40347:13;40432:1;40423:11;;40416:4;40404:17;;40369:74;:::i;:::-;-1:-1:-1;;;40502:1:1;40462:16;;;40494:10;;;40487:54;40566:13;;40588:76;40566:13;40650:2;40642:11;;40635:4;40623:17;;40588:76;:::i;:::-;-1:-1:-1;;;40724:2:1;40683:17;;;;40716:11;;;40709:59;40793:13;;40815:76;40793:13;40877:2;40869:11;;40862:4;40850:17;;40815:76;:::i;:::-;-1:-1:-1;;;40951:2:1;40910:17;;;;40943:11;;;40936:67;41028:13;;41050:76;41028:13;41112:2;41104:11;;41097:4;41085:17;;41050:76;:::i;:::-;-1:-1:-1;;;41186:2:1;41145:17;;;;41178:11;;;41171:72;41268:13;;41290:76;41268:13;41352:2;41344:11;;41337:4;41325:17;;41290:76;:::i;:::-;41382:84;41408:57;41461:2;41450:8;41446:2;41442:17;41438:26;-1:-1:-1;;;39185:66:1;;39276:2;39267:12;;39120:165;41408:57;41400:6;41382:84;:::i;:::-;41375:91;39290:2182;-1:-1:-1;;;;;;;;;;39290:2182:1:o;41477:1401::-;42005:3;42043:6;42037:13;42059:66;42118:6;42113:3;42106:4;42098:6;42094:17;42059:66;:::i;:::-;42156:6;42151:3;42147:16;42134:29;;42186:66;42179:5;42172:81;42295:42;42291:2;42287:51;42280:4;42273:5;42269:16;42262:77;42370:6;42364:13;42386:79;42456:8;42451:2;42444:5;42440:14;42433:4;42425:6;42421:17;42386:79;:::i;:::-;42533:66;42528:2;42484:20;;;;42520:11;;;42513:87;-1:-1:-1;;;42624:2:1;42616:11;;42609:33;42667:13;;42689:76;42667:13;42751:2;42743:11;;42736:4;42724:17;;42689:76;:::i;:::-;-1:-1:-1;;;42825:2:1;42784:17;;;;42817:11;;;42810:35;42869:2;42861:11;;41477:1401;-1:-1:-1;;;;;41477:1401:1:o;42883:461::-;43145:31;43140:3;43133:44;43115:3;43206:6;43200:13;43222:75;43290:6;43285:2;43280:3;43276:12;43269:4;43261:6;43257:17;43222:75;:::i;:::-;43317:16;;;;43335:2;43313:25;;42883:461;-1:-1:-1;;42883:461:1:o;43349:496::-;43528:3;43566:6;43560:13;43582:66;43641:6;43636:3;43629:4;43621:6;43617:17;43582:66;:::i;:::-;43711:13;;43670:16;;;;43733:70;43711:13;43670:16;43780:4;43768:17;;43733:70;:::i;:::-;43819:20;;43349:496;-1:-1:-1;;;;43349:496:1:o;44812:127::-;44873:10;44868:3;44864:20;44861:1;44854:31;44904:4;44901:1;44894:15;44928:4;44925:1;44918:15;44944:414;45146:2;45128:21;;;45185:2;45165:18;;;45158:30;45224:34;45219:2;45204:18;;45197:62;-1:-1:-1;;;45290:2:1;45275:18;;45268:48;45348:3;45333:19;;44944:414::o;45363:401::-;45565:2;45547:21;;;45604:2;45584:18;;;45577:30;45643:34;45638:2;45623:18;;45616:62;-1:-1:-1;;;45709:2:1;45694:18;;45687:35;45754:3;45739:19;;45363:401::o;46528:1021::-;46955:3;46993:6;46987:13;47009:66;47068:6;47063:3;47056:4;47048:6;47044:17;47009:66;:::i;:::-;47138:13;;47097:16;;;;47160:70;47138:13;47097:16;47207:4;47195:17;;47160:70;:::i;:::-;-1:-1:-1;;;47252:20:1;;47281:29;;;47335:13;;47357:78;47335:13;47422:1;47411:13;;47404:4;47392:17;;47357:78;:::i;:::-;-1:-1:-1;;;47498:1:1;47454:20;;;;47490:10;;;47483:34;47541:1;47533:10;;46528:1021;-1:-1:-1;;;;;46528:1021:1:o;47554:450::-;47784:3;47822:6;47816:13;47838:66;47897:6;47892:3;47885:4;47877:6;47873:17;47838:66;:::i;:::-;-1:-1:-1;;;47926:16:1;;47951:18;;;-1:-1:-1;47996:1:1;47985:13;;47554:450;-1:-1:-1;47554:450:1:o;48009:251::-;48079:6;48132:2;48120:9;48111:7;48107:23;48103:32;48100:52;;;48148:1;48145;48138:12;48100:52;48180:9;48174:16;48199:31;48224:5;48199:31;:::i;48265:995::-;-1:-1:-1;;;48765:49:1;;48837:13;;48747:3;;48859:75;48837:13;48922:2;48913:12;;48906:4;48894:17;;48859:75;:::i;:::-;-1:-1:-1;;;48993:2:1;48953:16;;;48985:11;;;48978:57;49060:13;;49082:76;49060:13;49144:2;49136:11;;49129:4;49117:17;;49082:76;:::i;:::-;-1:-1:-1;;;49218:2:1;49177:17;;;;49210:11;;;49203:24;49251:2;49243:11;;48265:995;-1:-1:-1;;;;48265:995:1:o;49443:3659::-;49955:66;49950:3;49943:79;50052:34;50047:2;50042:3;50038:12;50031:56;-1:-1:-1;;;50112:2:1;50107:3;50103:12;50096:30;49925:3;50155:6;50149:13;50171:73;50237:6;50232:2;50227:3;50223:12;50218:2;50210:6;50206:15;50171:73;:::i;:::-;50308:34;50303:2;50263:16;;;50295:11;;;50288:55;50373:66;50367:3;50359:12;;50352:88;50470:34;50464:3;50456:12;;50449:56;50535:66;50529:3;50521:12;;50514:88;50632:66;50626:3;50618:12;;50611:88;50729:34;50723:3;50715:12;;50708:56;50794:34;50788:3;50780:12;;50773:56;50859:34;50853:3;50845:12;;50838:56;50924:34;50918:3;50910:12;;50903:56;50989:34;50983:3;50975:12;;50968:56;51054:34;51048:3;51040:12;;51033:56;51119:34;51113:3;51105:12;;51098:56;51184:34;51178:3;51170:12;;51163:56;51249:66;51243:3;51235:12;;51228:88;51346:66;51340:3;51332:12;;51325:88;51443:66;51437:3;51429:12;;51422:88;51540:66;51534:3;51526:12;;51519:88;51637:66;51631:3;51623:12;;51616:88;51734:66;51728:3;51720:12;;51713:88;51831:66;51825:3;51817:12;;51810:88;51928:66;51922:3;51914:12;;51907:88;52025:66;52019:3;52011:12;;52004:88;52122:66;52116:3;52108:12;;52101:88;52219:66;52213:3;52205:12;;52198:88;52316:66;52310:3;52302:12;;52295:88;52413:34;52407:3;52399:12;;52392:56;52478:66;52472:3;52464:12;;52457:88;52575:34;52569:3;52561:12;;52554:56;52640:66;52634:3;52626:12;;52619:88;52737:66;52731:3;52723:12;;52716:88;52835:34;52828:4;52820:13;;52813:57;52901:66;52894:4;52886:13;;52879:89;-1:-1:-1;;;52992:4:1;52984:13;;52977:37;53030:66;53055:40;53089:4;53081:13;;53073:6;53055:40;:::i;:::-;49337:66;49325:79;;49429:2;49420:12;;49265:173;53529:500;-1:-1:-1;;;;;53798:15:1;;;53780:34;;53850:15;;53845:2;53830:18;;53823:43;53897:2;53882:18;;53875:34;;;53945:3;53940:2;53925:18;;53918:31;;;53723:4;;53966:57;;54003:19;;53995:6;53966:57;:::i;54034:249::-;54103:6;54156:2;54144:9;54135:7;54131:23;54127:32;54124:52;;;54172:1;54169;54162:12;54124:52;54204:9;54198:16;54223:30;54247:5;54223:30;:::i;54673:136::-;54712:3;54740:5;54730:39;;54749:18;;:::i;:::-;-1:-1:-1;;;54785:18:1;;54673:136::o;56296:127::-;56357:10;56352:3;56348:20;56345:1;56338:31;56388:4;56385:1;56378:15;56412:4;56409:1;56402:15

Swarm Source

ipfs://42d0608f6bdeba088885bbc80c16f7e3dcf49b66daa3e70507924c01e202d7ef
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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