ERC-1155
Source Code
Overview
Max Total Supply
23
Holders
2
Market
Onchain Market Cap
-
Circulating Supply Market Cap
-
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
Contract Name:
KitsuBaddies_1
Compiler Version
v0.8.30+commit.73712a01
Contract Source Code (Solidity)
/**
*Submitted for verification at KatanaScan.com on 2025-10-24
*/
// File: @openzeppelin/contracts/access/IAccessControl.sol
// OpenZeppelin Contracts (last updated v5.4.0) (access/IAccessControl.sol)
pragma solidity >=0.8.4;
/**
* @dev External interface of AccessControl declared to support ERC-165 detection.
*/
interface IAccessControl {
/**
* @dev The `account` is missing a role.
*/
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
/**
* @dev The caller of a function is not the expected one.
*
* NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
*/
error AccessControlBadConfirmation();
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted to signal this.
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).
* Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*/
function renounceRole(bytes32 role, address callerConfirmation) external;
}
// File: @openzeppelin/contracts/utils/Context.sol
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @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;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
// File: @openzeppelin/contracts/utils/introspection/IERC165.sol
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* 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[ERC 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/utils/introspection/ERC165.sol
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC-165 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);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
// File: @openzeppelin/contracts/access/AccessControl.sol
// OpenZeppelin Contracts (last updated v5.4.0) (access/AccessControl.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```solidity
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```solidity
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
* to enforce additional security measures for this role.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address account => bool) hasRole;
bytes32 adminRole;
}
mapping(bytes32 role => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with an {AccessControlUnauthorizedAccount} error including the required role.
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual returns (bool) {
return _roles[role].hasRole[account];
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
* is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
* is missing `role`.
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert AccessControlUnauthorizedAccount(account, role);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address callerConfirmation) public virtual {
if (callerConfirmation != _msgSender()) {
revert AccessControlBadConfirmation();
}
_revokeRole(role, callerConfirmation);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
if (!hasRole(role, account)) {
_roles[role].hasRole[account] = true;
emit RoleGranted(role, account, _msgSender());
return true;
} else {
return false;
}
}
/**
* @dev Attempts to revoke `role` from `account` and returns a boolean indicating if `role` was revoked.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
if (hasRole(role, account)) {
_roles[role].hasRole[account] = false;
emit RoleRevoked(role, account, _msgSender());
return true;
} else {
return false;
}
}
}
// File: @openzeppelin/contracts/token/ERC1155/IERC1155.sol
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC1155/IERC1155.sol)
pragma solidity >=0.6.2;
/**
* @dev Required interface of an ERC-1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[ERC].
*/
interface IERC1155 is IERC165 {
/**
* @dev Emitted when `value` amount of tokens of type `id` are transferred from `from` to `to` by `operator`.
*/
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
/**
* @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
* transfers.
*/
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
/**
* @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
* `approved`.
*/
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
/**
* @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
*
* If an {URI} event was emitted for `id`, the standard
* https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
* returned by {IERC1155MetadataURI-uri}.
*/
event URI(string value, uint256 indexed id);
/**
* @dev Returns the value of tokens of token type `id` owned by `account`.
*/
function balanceOf(address account, uint256 id) external view returns (uint256);
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(
address[] calldata accounts,
uint256[] calldata ids
) external view returns (uint256[] memory);
/**
* @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the zero address.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address account, address operator) external view returns (bool);
/**
* @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`.
*
* WARNING: This function can potentially allow a reentrancy attack when transferring tokens
* to an untrusted contract, when invoking {IERC1155Receiver-onERC1155Received} on the receiver.
* Ensure to follow the checks-effects-interactions pattern and consider employing
* reentrancy guards when interacting with untrusted contracts.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
* - `from` must have a balance of tokens of type `id` of at least `value` amount.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external;
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
*
* WARNING: This function can potentially allow a reentrancy attack when transferring tokens
* to an untrusted contract, when invoking {IERC1155Receiver-onERC1155BatchReceived} on the receiver.
* Ensure to follow the checks-effects-interactions pattern and consider employing
* reentrancy guards when interacting with untrusted contracts.
*
* Emits either a {TransferSingle} or a {TransferBatch} event, depending on the length of the array arguments.
*
* Requirements:
*
* - `ids` and `values` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external;
}
// File: @openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC1155/extensions/IERC1155MetadataURI.sol)
pragma solidity >=0.6.2;
/**
* @dev Interface of the optional ERC1155MetadataExtension interface, as defined
* in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[ERC].
*/
interface IERC1155MetadataURI is IERC1155 {
/**
* @dev Returns the URI for token type `id`.
*
* If the `\{id\}` substring is present in the URI, it must be replaced by
* clients with the actual token type ID.
*/
function uri(uint256 id) external view returns (string memory);
}
// File: @openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC1155/IERC1155Receiver.sol)
pragma solidity >=0.6.2;
/**
* @dev Interface that must be implemented by smart contracts in order to receive
* ERC-1155 token transfers.
*/
interface IERC1155Receiver is IERC165 {
/**
* @dev Handles the receipt of a single ERC-1155 token type. This function is
* called at the end of a `safeTransferFrom` after the balance has been updated.
*
* NOTE: To accept the transfer, this must return
* `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
* (i.e. 0xf23a6e61, or its own function selector).
*
* @param operator The address which initiated the transfer (i.e. msg.sender)
* @param from The address which previously owned the token
* @param id The ID of the token being transferred
* @param value The amount of tokens being transferred
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
*/
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
/**
* @dev Handles the receipt of a multiple ERC-1155 token types. This function
* is called at the end of a `safeBatchTransferFrom` after the balances have
* been updated.
*
* NOTE: To accept the transfer(s), this must return
* `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
* (i.e. 0xbc197c81, or its own function selector).
*
* @param operator The address which initiated the batch transfer (i.e. msg.sender)
* @param from The address which previously owned the token
* @param ids An array containing ids of each token being transferred (order and length must match values array)
* @param values An array containing amounts of each token being transferred (order and length must match ids array)
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
*/
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}
// File: @openzeppelin/contracts/interfaces/draft-IERC6093.sol
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/draft-IERC6093.sol)
pragma solidity >=0.8.4;
/**
* @dev Standard ERC-20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
*/
interface IERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC-721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
*/
interface IERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC-1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
*/
interface IERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/
error ERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}
// File: @openzeppelin/contracts/token/ERC1155/utils/ERC1155Utils.sol
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC1155/utils/ERC1155Utils.sol)
pragma solidity ^0.8.20;
/**
* @dev Library that provide common ERC-1155 utility functions.
*
* See https://eips.ethereum.org/EIPS/eip-1155[ERC-1155].
*
* _Available since v5.1._
*/
library ERC1155Utils {
/**
* @dev Performs an acceptance check for the provided `operator` by calling {IERC1155Receiver-onERC1155Received}
* on the `to` address. The `operator` is generally the address that initiated the token transfer (i.e. `msg.sender`).
*
* The acceptance call is not executed and treated as a no-op if the target address doesn't contain code (i.e. an EOA).
* Otherwise, the recipient must implement {IERC1155Receiver-onERC1155Received} and return the acceptance magic value to accept
* the transfer.
*/
function checkOnERC1155Received(
address operator,
address from,
address to,
uint256 id,
uint256 value,
bytes memory data
) internal {
if (to.code.length > 0) {
try IERC1155Receiver(to).onERC1155Received(operator, from, id, value, data) returns (bytes4 response) {
if (response != IERC1155Receiver.onERC1155Received.selector) {
// Tokens rejected
revert IERC1155Errors.ERC1155InvalidReceiver(to);
}
} catch (bytes memory reason) {
if (reason.length == 0) {
// non-IERC1155Receiver implementer
revert IERC1155Errors.ERC1155InvalidReceiver(to);
} else {
assembly ("memory-safe") {
revert(add(reason, 0x20), mload(reason))
}
}
}
}
}
/**
* @dev Performs a batch acceptance check for the provided `operator` by calling {IERC1155Receiver-onERC1155BatchReceived}
* on the `to` address. The `operator` is generally the address that initiated the token transfer (i.e. `msg.sender`).
*
* The acceptance call is not executed and treated as a no-op if the target address doesn't contain code (i.e. an EOA).
* Otherwise, the recipient must implement {IERC1155Receiver-onERC1155Received} and return the acceptance magic value to accept
* the transfer.
*/
function checkOnERC1155BatchReceived(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory values,
bytes memory data
) internal {
if (to.code.length > 0) {
try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, values, data) returns (
bytes4 response
) {
if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
// Tokens rejected
revert IERC1155Errors.ERC1155InvalidReceiver(to);
}
} catch (bytes memory reason) {
if (reason.length == 0) {
// non-IERC1155Receiver implementer
revert IERC1155Errors.ERC1155InvalidReceiver(to);
} else {
assembly ("memory-safe") {
revert(add(reason, 0x20), mload(reason))
}
}
}
}
}
}
// File: @openzeppelin/contracts/utils/Comparators.sol
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Comparators.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides a set of functions to compare values.
*
* _Available since v5.1._
*/
library Comparators {
function lt(uint256 a, uint256 b) internal pure returns (bool) {
return a < b;
}
function gt(uint256 a, uint256 b) internal pure returns (bool) {
return a > b;
}
}
// File: @openzeppelin/contracts/utils/SlotDerivation.sol
// OpenZeppelin Contracts (last updated v5.3.0) (utils/SlotDerivation.sol)
// This file was procedurally generated from scripts/generate/templates/SlotDerivation.js.
pragma solidity ^0.8.20;
/**
* @dev Library for computing storage (and transient storage) locations from namespaces and deriving slots
* corresponding to standard patterns. The derivation method for array and mapping matches the storage layout used by
* the solidity language / compiler.
*
* See https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays[Solidity docs for mappings and dynamic arrays.].
*
* Example usage:
* ```solidity
* contract Example {
* // Add the library methods
* using StorageSlot for bytes32;
* using SlotDerivation for bytes32;
*
* // Declare a namespace
* string private constant _NAMESPACE = "<namespace>"; // eg. OpenZeppelin.Slot
*
* function setValueInNamespace(uint256 key, address newValue) internal {
* _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value = newValue;
* }
*
* function getValueInNamespace(uint256 key) internal view returns (address) {
* return _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value;
* }
* }
* ```
*
* TIP: Consider using this library along with {StorageSlot}.
*
* NOTE: This library provides a way to manipulate storage locations in a non-standard way. Tooling for checking
* upgrade safety will ignore the slots accessed through this library.
*
* _Available since v5.1._
*/
library SlotDerivation {
/**
* @dev Derive an ERC-7201 slot from a string (namespace).
*/
function erc7201Slot(string memory namespace) internal pure returns (bytes32 slot) {
assembly ("memory-safe") {
mstore(0x00, sub(keccak256(add(namespace, 0x20), mload(namespace)), 1))
slot := and(keccak256(0x00, 0x20), not(0xff))
}
}
/**
* @dev Add an offset to a slot to get the n-th element of a structure or an array.
*/
function offset(bytes32 slot, uint256 pos) internal pure returns (bytes32 result) {
unchecked {
return bytes32(uint256(slot) + pos);
}
}
/**
* @dev Derive the location of the first element in an array from the slot where the length is stored.
*/
function deriveArray(bytes32 slot) internal pure returns (bytes32 result) {
assembly ("memory-safe") {
mstore(0x00, slot)
result := keccak256(0x00, 0x20)
}
}
/**
* @dev Derive the location of a mapping element from the key.
*/
function deriveMapping(bytes32 slot, address key) internal pure returns (bytes32 result) {
assembly ("memory-safe") {
mstore(0x00, and(key, shr(96, not(0))))
mstore(0x20, slot)
result := keccak256(0x00, 0x40)
}
}
/**
* @dev Derive the location of a mapping element from the key.
*/
function deriveMapping(bytes32 slot, bool key) internal pure returns (bytes32 result) {
assembly ("memory-safe") {
mstore(0x00, iszero(iszero(key)))
mstore(0x20, slot)
result := keccak256(0x00, 0x40)
}
}
/**
* @dev Derive the location of a mapping element from the key.
*/
function deriveMapping(bytes32 slot, bytes32 key) internal pure returns (bytes32 result) {
assembly ("memory-safe") {
mstore(0x00, key)
mstore(0x20, slot)
result := keccak256(0x00, 0x40)
}
}
/**
* @dev Derive the location of a mapping element from the key.
*/
function deriveMapping(bytes32 slot, uint256 key) internal pure returns (bytes32 result) {
assembly ("memory-safe") {
mstore(0x00, key)
mstore(0x20, slot)
result := keccak256(0x00, 0x40)
}
}
/**
* @dev Derive the location of a mapping element from the key.
*/
function deriveMapping(bytes32 slot, int256 key) internal pure returns (bytes32 result) {
assembly ("memory-safe") {
mstore(0x00, key)
mstore(0x20, slot)
result := keccak256(0x00, 0x40)
}
}
/**
* @dev Derive the location of a mapping element from the key.
*/
function deriveMapping(bytes32 slot, string memory key) internal pure returns (bytes32 result) {
assembly ("memory-safe") {
let length := mload(key)
let begin := add(key, 0x20)
let end := add(begin, length)
let cache := mload(end)
mstore(end, slot)
result := keccak256(begin, add(length, 0x20))
mstore(end, cache)
}
}
/**
* @dev Derive the location of a mapping element from the key.
*/
function deriveMapping(bytes32 slot, bytes memory key) internal pure returns (bytes32 result) {
assembly ("memory-safe") {
let length := mload(key)
let begin := add(key, 0x20)
let end := add(begin, length)
let cache := mload(end)
mstore(end, slot)
result := keccak256(begin, add(length, 0x20))
mstore(end, cache)
}
}
}
// File: @openzeppelin/contracts/utils/StorageSlot.sol
// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
pragma solidity ^0.8.20;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC-1967 implementation slot:
* ```solidity
* contract ERC1967 {
* // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(newImplementation.code.length > 0);
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*
* TIP: Consider using this library along with {SlotDerivation}.
*/
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
struct Int256Slot {
int256 value;
}
struct StringSlot {
string value;
}
struct BytesSlot {
bytes value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `Int256Slot` with member `value` located at `slot`.
*/
function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `StringSlot` with member `value` located at `slot`.
*/
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` representation of the string storage pointer `store`.
*/
function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
assembly ("memory-safe") {
r.slot := store.slot
}
}
/**
* @dev Returns a `BytesSlot` with member `value` located at `slot`.
*/
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
*/
function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
assembly ("memory-safe") {
r.slot := store.slot
}
}
}
// File: @openzeppelin/contracts/utils/Panic.sol
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)
pragma solidity ^0.8.20;
/**
* @dev Helper library for emitting standardized panic codes.
*
* ```solidity
* contract Example {
* using Panic for uint256;
*
* // Use any of the declared internal constants
* function foo() { Panic.GENERIC.panic(); }
*
* // Alternatively
* function foo() { Panic.panic(Panic.GENERIC); }
* }
* ```
*
* Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].
*
* _Available since v5.1._
*/
// slither-disable-next-line unused-state
library Panic {
/// @dev generic / unspecified error
uint256 internal constant GENERIC = 0x00;
/// @dev used by the assert() builtin
uint256 internal constant ASSERT = 0x01;
/// @dev arithmetic underflow or overflow
uint256 internal constant UNDER_OVERFLOW = 0x11;
/// @dev division or modulo by zero
uint256 internal constant DIVISION_BY_ZERO = 0x12;
/// @dev enum conversion error
uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;
/// @dev invalid encoding in storage
uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;
/// @dev empty array pop
uint256 internal constant EMPTY_ARRAY_POP = 0x31;
/// @dev array out of bounds access
uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;
/// @dev resource error (too large allocation or too large array)
uint256 internal constant RESOURCE_ERROR = 0x41;
/// @dev calling invalid internal function
uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;
/// @dev Reverts with a panic code. Recommended to use with
/// the internal constants with predefined codes.
function panic(uint256 code) internal pure {
assembly ("memory-safe") {
mstore(0x00, 0x4e487b71)
mstore(0x20, code)
revert(0x1c, 0x24)
}
}
}
// File: @openzeppelin/contracts/utils/math/SafeCast.sol
// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.20;
/**
* @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeCast {
/**
* @dev Value doesn't fit in an uint of `bits` size.
*/
error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);
/**
* @dev An int value doesn't fit in an uint of `bits` size.
*/
error SafeCastOverflowedIntToUint(int256 value);
/**
* @dev Value doesn't fit in an int of `bits` size.
*/
error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);
/**
* @dev An uint value doesn't fit in an int of `bits` size.
*/
error SafeCastOverflowedUintToInt(uint256 value);
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*/
function toUint248(uint256 value) internal pure returns (uint248) {
if (value > type(uint248).max) {
revert SafeCastOverflowedUintDowncast(248, value);
}
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*/
function toUint240(uint256 value) internal pure returns (uint240) {
if (value > type(uint240).max) {
revert SafeCastOverflowedUintDowncast(240, value);
}
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*/
function toUint232(uint256 value) internal pure returns (uint232) {
if (value > type(uint232).max) {
revert SafeCastOverflowedUintDowncast(232, value);
}
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*/
function toUint224(uint256 value) internal pure returns (uint224) {
if (value > type(uint224).max) {
revert SafeCastOverflowedUintDowncast(224, value);
}
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*/
function toUint216(uint256 value) internal pure returns (uint216) {
if (value > type(uint216).max) {
revert SafeCastOverflowedUintDowncast(216, value);
}
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*/
function toUint208(uint256 value) internal pure returns (uint208) {
if (value > type(uint208).max) {
revert SafeCastOverflowedUintDowncast(208, value);
}
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*/
function toUint200(uint256 value) internal pure returns (uint200) {
if (value > type(uint200).max) {
revert SafeCastOverflowedUintDowncast(200, value);
}
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*/
function toUint192(uint256 value) internal pure returns (uint192) {
if (value > type(uint192).max) {
revert SafeCastOverflowedUintDowncast(192, value);
}
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*/
function toUint184(uint256 value) internal pure returns (uint184) {
if (value > type(uint184).max) {
revert SafeCastOverflowedUintDowncast(184, value);
}
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*/
function toUint176(uint256 value) internal pure returns (uint176) {
if (value > type(uint176).max) {
revert SafeCastOverflowedUintDowncast(176, value);
}
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*/
function toUint168(uint256 value) internal pure returns (uint168) {
if (value > type(uint168).max) {
revert SafeCastOverflowedUintDowncast(168, value);
}
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*/
function toUint160(uint256 value) internal pure returns (uint160) {
if (value > type(uint160).max) {
revert SafeCastOverflowedUintDowncast(160, value);
}
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*/
function toUint152(uint256 value) internal pure returns (uint152) {
if (value > type(uint152).max) {
revert SafeCastOverflowedUintDowncast(152, value);
}
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*/
function toUint144(uint256 value) internal pure returns (uint144) {
if (value > type(uint144).max) {
revert SafeCastOverflowedUintDowncast(144, value);
}
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*/
function toUint136(uint256 value) internal pure returns (uint136) {
if (value > type(uint136).max) {
revert SafeCastOverflowedUintDowncast(136, value);
}
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toUint128(uint256 value) internal pure returns (uint128) {
if (value > type(uint128).max) {
revert SafeCastOverflowedUintDowncast(128, value);
}
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*/
function toUint120(uint256 value) internal pure returns (uint120) {
if (value > type(uint120).max) {
revert SafeCastOverflowedUintDowncast(120, value);
}
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*/
function toUint112(uint256 value) internal pure returns (uint112) {
if (value > type(uint112).max) {
revert SafeCastOverflowedUintDowncast(112, value);
}
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*/
function toUint104(uint256 value) internal pure returns (uint104) {
if (value > type(uint104).max) {
revert SafeCastOverflowedUintDowncast(104, value);
}
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*/
function toUint96(uint256 value) internal pure returns (uint96) {
if (value > type(uint96).max) {
revert SafeCastOverflowedUintDowncast(96, value);
}
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*/
function toUint88(uint256 value) internal pure returns (uint88) {
if (value > type(uint88).max) {
revert SafeCastOverflowedUintDowncast(88, value);
}
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*/
function toUint80(uint256 value) internal pure returns (uint80) {
if (value > type(uint80).max) {
revert SafeCastOverflowedUintDowncast(80, value);
}
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*/
function toUint72(uint256 value) internal pure returns (uint72) {
if (value > type(uint72).max) {
revert SafeCastOverflowedUintDowncast(72, value);
}
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toUint64(uint256 value) internal pure returns (uint64) {
if (value > type(uint64).max) {
revert SafeCastOverflowedUintDowncast(64, value);
}
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*/
function toUint56(uint256 value) internal pure returns (uint56) {
if (value > type(uint56).max) {
revert SafeCastOverflowedUintDowncast(56, value);
}
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*/
function toUint48(uint256 value) internal pure returns (uint48) {
if (value > type(uint48).max) {
revert SafeCastOverflowedUintDowncast(48, value);
}
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*/
function toUint40(uint256 value) internal pure returns (uint40) {
if (value > type(uint40).max) {
revert SafeCastOverflowedUintDowncast(40, value);
}
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toUint32(uint256 value) internal pure returns (uint32) {
if (value > type(uint32).max) {
revert SafeCastOverflowedUintDowncast(32, value);
}
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*/
function toUint24(uint256 value) internal pure returns (uint24) {
if (value > type(uint24).max) {
revert SafeCastOverflowedUintDowncast(24, value);
}
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toUint16(uint256 value) internal pure returns (uint16) {
if (value > type(uint16).max) {
revert SafeCastOverflowedUintDowncast(16, value);
}
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*/
function toUint8(uint256 value) internal pure returns (uint8) {
if (value > type(uint8).max) {
revert SafeCastOverflowedUintDowncast(8, value);
}
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*/
function toUint256(int256 value) internal pure returns (uint256) {
if (value < 0) {
revert SafeCastOverflowedIntToUint(value);
}
return uint256(value);
}
/**
* @dev Returns the downcasted int248 from int256, reverting on
* overflow (when the input is less than smallest int248 or
* greater than largest int248).
*
* Counterpart to Solidity's `int248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(248, value);
}
}
/**
* @dev Returns the downcasted int240 from int256, reverting on
* overflow (when the input is less than smallest int240 or
* greater than largest int240).
*
* Counterpart to Solidity's `int240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(240, value);
}
}
/**
* @dev Returns the downcasted int232 from int256, reverting on
* overflow (when the input is less than smallest int232 or
* greater than largest int232).
*
* Counterpart to Solidity's `int232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(232, value);
}
}
/**
* @dev Returns the downcasted int224 from int256, reverting on
* overflow (when the input is less than smallest int224 or
* greater than largest int224).
*
* Counterpart to Solidity's `int224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(224, value);
}
}
/**
* @dev Returns the downcasted int216 from int256, reverting on
* overflow (when the input is less than smallest int216 or
* greater than largest int216).
*
* Counterpart to Solidity's `int216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(216, value);
}
}
/**
* @dev Returns the downcasted int208 from int256, reverting on
* overflow (when the input is less than smallest int208 or
* greater than largest int208).
*
* Counterpart to Solidity's `int208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(208, value);
}
}
/**
* @dev Returns the downcasted int200 from int256, reverting on
* overflow (when the input is less than smallest int200 or
* greater than largest int200).
*
* Counterpart to Solidity's `int200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(200, value);
}
}
/**
* @dev Returns the downcasted int192 from int256, reverting on
* overflow (when the input is less than smallest int192 or
* greater than largest int192).
*
* Counterpart to Solidity's `int192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(192, value);
}
}
/**
* @dev Returns the downcasted int184 from int256, reverting on
* overflow (when the input is less than smallest int184 or
* greater than largest int184).
*
* Counterpart to Solidity's `int184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(184, value);
}
}
/**
* @dev Returns the downcasted int176 from int256, reverting on
* overflow (when the input is less than smallest int176 or
* greater than largest int176).
*
* Counterpart to Solidity's `int176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(176, value);
}
}
/**
* @dev Returns the downcasted int168 from int256, reverting on
* overflow (when the input is less than smallest int168 or
* greater than largest int168).
*
* Counterpart to Solidity's `int168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(168, value);
}
}
/**
* @dev Returns the downcasted int160 from int256, reverting on
* overflow (when the input is less than smallest int160 or
* greater than largest int160).
*
* Counterpart to Solidity's `int160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(160, value);
}
}
/**
* @dev Returns the downcasted int152 from int256, reverting on
* overflow (when the input is less than smallest int152 or
* greater than largest int152).
*
* Counterpart to Solidity's `int152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(152, value);
}
}
/**
* @dev Returns the downcasted int144 from int256, reverting on
* overflow (when the input is less than smallest int144 or
* greater than largest int144).
*
* Counterpart to Solidity's `int144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(144, value);
}
}
/**
* @dev Returns the downcasted int136 from int256, reverting on
* overflow (when the input is less than smallest int136 or
* greater than largest int136).
*
* Counterpart to Solidity's `int136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(136, value);
}
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(128, value);
}
}
/**
* @dev Returns the downcasted int120 from int256, reverting on
* overflow (when the input is less than smallest int120 or
* greater than largest int120).
*
* Counterpart to Solidity's `int120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(120, value);
}
}
/**
* @dev Returns the downcasted int112 from int256, reverting on
* overflow (when the input is less than smallest int112 or
* greater than largest int112).
*
* Counterpart to Solidity's `int112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(112, value);
}
}
/**
* @dev Returns the downcasted int104 from int256, reverting on
* overflow (when the input is less than smallest int104 or
* greater than largest int104).
*
* Counterpart to Solidity's `int104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(104, value);
}
}
/**
* @dev Returns the downcasted int96 from int256, reverting on
* overflow (when the input is less than smallest int96 or
* greater than largest int96).
*
* Counterpart to Solidity's `int96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(96, value);
}
}
/**
* @dev Returns the downcasted int88 from int256, reverting on
* overflow (when the input is less than smallest int88 or
* greater than largest int88).
*
* Counterpart to Solidity's `int88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(88, value);
}
}
/**
* @dev Returns the downcasted int80 from int256, reverting on
* overflow (when the input is less than smallest int80 or
* greater than largest int80).
*
* Counterpart to Solidity's `int80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(80, value);
}
}
/**
* @dev Returns the downcasted int72 from int256, reverting on
* overflow (when the input is less than smallest int72 or
* greater than largest int72).
*
* Counterpart to Solidity's `int72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(72, value);
}
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(64, value);
}
}
/**
* @dev Returns the downcasted int56 from int256, reverting on
* overflow (when the input is less than smallest int56 or
* greater than largest int56).
*
* Counterpart to Solidity's `int56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(56, value);
}
}
/**
* @dev Returns the downcasted int48 from int256, reverting on
* overflow (when the input is less than smallest int48 or
* greater than largest int48).
*
* Counterpart to Solidity's `int48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(48, value);
}
}
/**
* @dev Returns the downcasted int40 from int256, reverting on
* overflow (when the input is less than smallest int40 or
* greater than largest int40).
*
* Counterpart to Solidity's `int40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(40, value);
}
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(32, value);
}
}
/**
* @dev Returns the downcasted int24 from int256, reverting on
* overflow (when the input is less than smallest int24 or
* greater than largest int24).
*
* Counterpart to Solidity's `int24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(24, value);
}
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(16, value);
}
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(8, value);
}
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
if (value > uint256(type(int256).max)) {
revert SafeCastOverflowedUintToInt(value);
}
return int256(value);
}
/**
* @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.
*/
function toUint(bool b) internal pure returns (uint256 u) {
assembly ("memory-safe") {
u := iszero(iszero(b))
}
}
}
// File: @openzeppelin/contracts/utils/math/Math.sol
// OpenZeppelin Contracts (last updated v5.3.0) (utils/math/Math.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Floor, // Toward negative infinity
Ceil, // Toward positive infinity
Trunc, // Toward zero
Expand // Away from zero
}
/**
* @dev Return the 512-bit addition of two uint256.
*
* The result is stored in two 256 variables such that sum = high * 2²⁵⁶ + low.
*/
function add512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {
assembly ("memory-safe") {
low := add(a, b)
high := lt(low, a)
}
}
/**
* @dev Return the 512-bit multiplication of two uint256.
*
* The result is stored in two 256 variables such that product = high * 2²⁵⁶ + low.
*/
function mul512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {
// 512-bit multiply [high low] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use
// the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = high * 2²⁵⁶ + low.
assembly ("memory-safe") {
let mm := mulmod(a, b, not(0))
low := mul(a, b)
high := sub(sub(mm, low), lt(mm, low))
}
}
/**
* @dev Returns the addition of two unsigned integers, with a success flag (no overflow).
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
uint256 c = a + b;
success = c >= a;
result = c * SafeCast.toUint(success);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with a success flag (no overflow).
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
uint256 c = a - b;
success = c <= a;
result = c * SafeCast.toUint(success);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow).
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
uint256 c = a * b;
assembly ("memory-safe") {
// Only true when the multiplication doesn't overflow
// (c / a == b) || (a == 0)
success := or(eq(div(c, a), b), iszero(a))
}
// equivalent to: success ? c : 0
result = c * SafeCast.toUint(success);
}
}
/**
* @dev Returns the division of two unsigned integers, with a success flag (no division by zero).
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
success = b > 0;
assembly ("memory-safe") {
// The `DIV` opcode returns zero when the denominator is 0.
result := div(a, b)
}
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
success = b > 0;
assembly ("memory-safe") {
// The `MOD` opcode returns zero when the denominator is 0.
result := mod(a, b)
}
}
}
/**
* @dev Unsigned saturating addition, bounds to `2²⁵⁶ - 1` instead of overflowing.
*/
function saturatingAdd(uint256 a, uint256 b) internal pure returns (uint256) {
(bool success, uint256 result) = tryAdd(a, b);
return ternary(success, result, type(uint256).max);
}
/**
* @dev Unsigned saturating subtraction, bounds to zero instead of overflowing.
*/
function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) {
(, uint256 result) = trySub(a, b);
return result;
}
/**
* @dev Unsigned saturating multiplication, bounds to `2²⁵⁶ - 1` instead of overflowing.
*/
function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) {
(bool success, uint256 result) = tryMul(a, b);
return ternary(success, result, type(uint256).max);
}
/**
* @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.
*
* IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.
* However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute
* one branch when needed, making this function more expensive.
*/
function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {
unchecked {
// branchless ternary works because:
// b ^ (a ^ b) == a
// b ^ 0 == b
return b ^ ((a ^ b) * SafeCast.toUint(condition));
}
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return ternary(a > b, a, b);
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return ternary(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 towards infinity instead
* of rounding towards zero.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
if (b == 0) {
// Guarantee the same behavior as in a regular Solidity division.
Panic.panic(Panic.DIVISION_BY_ZERO);
}
// The following calculation ensures accurate ceiling division without overflow.
// Since a is non-zero, (a - 1) / b will not overflow.
// The largest possible result occurs when (a - 1) / b is type(uint256).max,
// but the largest value we can obtain is type(uint256).max - 1, which happens
// when a = type(uint256).max and b = 1.
unchecked {
return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);
}
}
/**
* @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
* denominator == 0.
*
* 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 {
(uint256 high, uint256 low) = mul512(x, y);
// Handle non-overflow cases, 256 by 256 division.
if (high == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return low / denominator;
}
// Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.
if (denominator <= high) {
Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));
}
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [high low].
uint256 remainder;
assembly ("memory-safe") {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
high := sub(high, gt(remainder, low))
low := sub(low, 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.
uint256 twos = denominator & (0 - denominator);
assembly ("memory-safe") {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [high low] by twos.
low := div(low, twos)
// Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from high into low.
low |= high * twos;
// Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such
// that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv ≡ 1 mod 2⁴.
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⁸
inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶
inverse *= 2 - denominator * inverse; // inverse mod 2³²
inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴
inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸
inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶
// 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²⁵⁶. Since the preconditions guarantee that the outcome is
// less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and high
// is no longer required.
result = low * inverse;
return result;
}
}
/**
* @dev 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) {
return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);
}
/**
* @dev Calculates floor(x * y >> n) with full precision. Throws if result overflows a uint256.
*/
function mulShr(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 result) {
unchecked {
(uint256 high, uint256 low) = mul512(x, y);
if (high >= 1 << n) {
Panic.panic(Panic.UNDER_OVERFLOW);
}
return (high << (256 - n)) | (low >> n);
}
}
/**
* @dev Calculates x * y >> n with full precision, following the selected rounding direction.
*/
function mulShr(uint256 x, uint256 y, uint8 n, Rounding rounding) internal pure returns (uint256) {
return mulShr(x, y, n) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, 1 << n) > 0);
}
/**
* @dev Calculate the modular multiplicative inverse of a number in Z/nZ.
*
* If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.
* If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.
*
* If the input value is not inversible, 0 is returned.
*
* NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the
* inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.
*/
function invMod(uint256 a, uint256 n) internal pure returns (uint256) {
unchecked {
if (n == 0) return 0;
// The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)
// Used to compute integers x and y such that: ax + ny = gcd(a, n).
// When the gcd is 1, then the inverse of a modulo n exists and it's x.
// ax + ny = 1
// ax = 1 + (-y)n
// ax ≡ 1 (mod n) # x is the inverse of a modulo n
// If the remainder is 0 the gcd is n right away.
uint256 remainder = a % n;
uint256 gcd = n;
// Therefore the initial coefficients are:
// ax + ny = gcd(a, n) = n
// 0a + 1n = n
int256 x = 0;
int256 y = 1;
while (remainder != 0) {
uint256 quotient = gcd / remainder;
(gcd, remainder) = (
// The old remainder is the next gcd to try.
remainder,
// Compute the next remainder.
// Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd
// where gcd is at most n (capped to type(uint256).max)
gcd - remainder * quotient
);
(x, y) = (
// Increment the coefficient of a.
y,
// Decrement the coefficient of n.
// Can overflow, but the result is casted to uint256 so that the
// next value of y is "wrapped around" to a value between 0 and n - 1.
x - y * int256(quotient)
);
}
if (gcd != 1) return 0; // No inverse exists.
return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.
}
}
/**
* @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.
*
* From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is
* prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that
* `a**(p-2)` is the modular multiplicative inverse of a in Fp.
*
* NOTE: this function does NOT check that `p` is a prime greater than `2`.
*/
function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {
unchecked {
return Math.modExp(a, p - 2, p);
}
}
/**
* @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)
*
* Requirements:
* - modulus can't be zero
* - underlying staticcall to precompile must succeed
*
* IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make
* sure the chain you're using it on supports the precompiled contract for modular exponentiation
* at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,
* the underlying function will succeed given the lack of a revert, but the result may be incorrectly
* interpreted as 0.
*/
function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {
(bool success, uint256 result) = tryModExp(b, e, m);
if (!success) {
Panic.panic(Panic.DIVISION_BY_ZERO);
}
return result;
}
/**
* @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).
* It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying
* to operate modulo 0 or if the underlying precompile reverted.
*
* IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain
* you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in
* https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack
* of a revert, but the result may be incorrectly interpreted as 0.
*/
function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {
if (m == 0) return (false, 0);
assembly ("memory-safe") {
let ptr := mload(0x40)
// | Offset | Content | Content (Hex) |
// |-----------|------------|--------------------------------------------------------------------|
// | 0x00:0x1f | size of b | 0x0000000000000000000000000000000000000000000000000000000000000020 |
// | 0x20:0x3f | size of e | 0x0000000000000000000000000000000000000000000000000000000000000020 |
// | 0x40:0x5f | size of m | 0x0000000000000000000000000000000000000000000000000000000000000020 |
// | 0x60:0x7f | value of b | 0x<.............................................................b> |
// | 0x80:0x9f | value of e | 0x<.............................................................e> |
// | 0xa0:0xbf | value of m | 0x<.............................................................m> |
mstore(ptr, 0x20)
mstore(add(ptr, 0x20), 0x20)
mstore(add(ptr, 0x40), 0x20)
mstore(add(ptr, 0x60), b)
mstore(add(ptr, 0x80), e)
mstore(add(ptr, 0xa0), m)
// Given the result < m, it's guaranteed to fit in 32 bytes,
// so we can use the memory scratch space located at offset 0.
success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)
result := mload(0x00)
}
}
/**
* @dev Variant of {modExp} that supports inputs of arbitrary length.
*/
function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {
(bool success, bytes memory result) = tryModExp(b, e, m);
if (!success) {
Panic.panic(Panic.DIVISION_BY_ZERO);
}
return result;
}
/**
* @dev Variant of {tryModExp} that supports inputs of arbitrary length.
*/
function tryModExp(
bytes memory b,
bytes memory e,
bytes memory m
) internal view returns (bool success, bytes memory result) {
if (_zeroBytes(m)) return (false, new bytes(0));
uint256 mLen = m.length;
// Encode call args in result and move the free memory pointer
result = abi.encodePacked(b.length, e.length, mLen, b, e, m);
assembly ("memory-safe") {
let dataPtr := add(result, 0x20)
// Write result on top of args to avoid allocating extra memory.
success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)
// Overwrite the length.
// result.length > returndatasize() is guaranteed because returndatasize() == m.length
mstore(result, mLen)
// Set the memory pointer after the returned data.
mstore(0x40, add(dataPtr, mLen))
}
}
/**
* @dev Returns whether the provided byte array is zero.
*/
function _zeroBytes(bytes memory byteArray) private pure returns (bool) {
for (uint256 i = 0; i < byteArray.length; ++i) {
if (byteArray[i] != 0) {
return false;
}
}
return true;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
* towards zero.
*
* This method is based on Newton's method for computing square roots; the algorithm is restricted to only
* using integer operations.
*/
function sqrt(uint256 a) internal pure returns (uint256) {
unchecked {
// Take care of easy edge cases when a == 0 or a == 1
if (a <= 1) {
return a;
}
// In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a
// sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between
// the current value as `ε_n = | x_n - sqrt(a) |`.
//
// For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root
// of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is
// bigger than any uint256.
//
// By noticing that
// `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`
// we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar
// to the msb function.
uint256 aa = a;
uint256 xn = 1;
if (aa >= (1 << 128)) {
aa >>= 128;
xn <<= 64;
}
if (aa >= (1 << 64)) {
aa >>= 64;
xn <<= 32;
}
if (aa >= (1 << 32)) {
aa >>= 32;
xn <<= 16;
}
if (aa >= (1 << 16)) {
aa >>= 16;
xn <<= 8;
}
if (aa >= (1 << 8)) {
aa >>= 8;
xn <<= 4;
}
if (aa >= (1 << 4)) {
aa >>= 4;
xn <<= 2;
}
if (aa >= (1 << 2)) {
xn <<= 1;
}
// We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).
//
// We can refine our estimation by noticing that the middle of that interval minimizes the error.
// If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).
// This is going to be our x_0 (and ε_0)
xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)
// From here, Newton's method give us:
// x_{n+1} = (x_n + a / x_n) / 2
//
// One should note that:
// x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a
// = ((x_n² + a) / (2 * x_n))² - a
// = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a
// = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)
// = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)
// = (x_n² - a)² / (2 * x_n)²
// = ((x_n² - a) / (2 * x_n))²
// ≥ 0
// Which proves that for all n ≥ 1, sqrt(a) ≤ x_n
//
// This gives us the proof of quadratic convergence of the sequence:
// ε_{n+1} = | x_{n+1} - sqrt(a) |
// = | (x_n + a / x_n) / 2 - sqrt(a) |
// = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |
// = | (x_n - sqrt(a))² / (2 * x_n) |
// = | ε_n² / (2 * x_n) |
// = ε_n² / | (2 * x_n) |
//
// For the first iteration, we have a special case where x_0 is known:
// ε_1 = ε_0² / | (2 * x_0) |
// ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))
// ≤ 2**(2*e-4) / (3 * 2**(e-1))
// ≤ 2**(e-3) / 3
// ≤ 2**(e-3-log2(3))
// ≤ 2**(e-4.5)
//
// For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:
// ε_{n+1} = ε_n² / | (2 * x_n) |
// ≤ (2**(e-k))² / (2 * 2**(e-1))
// ≤ 2**(2*e-2*k) / 2**e
// ≤ 2**(e-2*k)
xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5) -- special case, see above
xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9) -- general case with k = 4.5
xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18) -- general case with k = 9
xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36) -- general case with k = 18
xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72) -- general case with k = 36
xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144) -- general case with k = 72
// Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision
// ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either
// sqrt(a) or sqrt(a) + 1.
return xn - SafeCast.toUint(xn > a / xn);
}
}
/**
* @dev 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);
}
}
/**
* @dev Return the log in base 2 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/
function log2(uint256 x) internal pure returns (uint256 r) {
// If value has upper 128 bits set, log2 result is at least 128
r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;
// If upper 64 bits of 128-bit half set, add 64 to result
r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;
// If upper 32 bits of 64-bit half set, add 32 to result
r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;
// If upper 16 bits of 32-bit half set, add 16 to result
r |= SafeCast.toUint((x >> r) > 0xffff) << 4;
// If upper 8 bits of 16-bit half set, add 8 to result
r |= SafeCast.toUint((x >> r) > 0xff) << 3;
// If upper 4 bits of 8-bit half set, add 4 to result
r |= SafeCast.toUint((x >> r) > 0xf) << 2;
// Shifts value right by the current result and use it as an index into this lookup table:
//
// | x (4 bits) | index | table[index] = MSB position |
// |------------|---------|-----------------------------|
// | 0000 | 0 | table[0] = 0 |
// | 0001 | 1 | table[1] = 0 |
// | 0010 | 2 | table[2] = 1 |
// | 0011 | 3 | table[3] = 1 |
// | 0100 | 4 | table[4] = 2 |
// | 0101 | 5 | table[5] = 2 |
// | 0110 | 6 | table[6] = 2 |
// | 0111 | 7 | table[7] = 2 |
// | 1000 | 8 | table[8] = 3 |
// | 1001 | 9 | table[9] = 3 |
// | 1010 | 10 | table[10] = 3 |
// | 1011 | 11 | table[11] = 3 |
// | 1100 | 12 | table[12] = 3 |
// | 1101 | 13 | table[13] = 3 |
// | 1110 | 14 | table[14] = 3 |
// | 1111 | 15 | table[15] = 3 |
//
// The lookup table is represented as a 32-byte value with the MSB positions for 0-15 in the last 16 bytes.
assembly ("memory-safe") {
r := or(r, byte(shr(r, x), 0x0000010102020202030303030303030300000000000000000000000000000000))
}
}
/**
* @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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);
}
}
/**
* @dev Return the log in base 10 of a positive value rounded towards zero.
* 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);
}
}
/**
* @dev Return the log in base 256 of a positive value rounded towards zero.
* 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 x) internal pure returns (uint256 r) {
// If value has upper 128 bits set, log2 result is at least 128
r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;
// If upper 64 bits of 128-bit half set, add 64 to result
r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;
// If upper 32 bits of 64-bit half set, add 32 to result
r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;
// If upper 16 bits of 32-bit half set, add 16 to result
r |= SafeCast.toUint((x >> r) > 0xffff) << 4;
// Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8
return (r >> 3) | SafeCast.toUint((x >> r) > 0xff);
}
/**
* @dev Return the log in base 256, 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);
}
}
/**
* @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
*/
function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
return uint8(rounding) % 2 == 1;
}
}
// File: @openzeppelin/contracts/utils/Arrays.sol
// OpenZeppelin Contracts (last updated v5.4.0) (utils/Arrays.sol)
// This file was procedurally generated from scripts/generate/templates/Arrays.js.
pragma solidity ^0.8.20;
/**
* @dev Collection of functions related to array types.
*/
library Arrays {
using SlotDerivation for bytes32;
using StorageSlot for bytes32;
/**
* @dev Sort an array of uint256 (in memory) following the provided comparator function.
*
* This function does the sorting "in place", meaning that it overrides the input. The object is returned for
* convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
*
* NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the
* array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful
* when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
* consume more gas than is available in a block, leading to potential DoS.
*
* IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.
*/
function sort(
uint256[] memory array,
function(uint256, uint256) pure returns (bool) comp
) internal pure returns (uint256[] memory) {
_quickSort(_begin(array), _end(array), comp);
return array;
}
/**
* @dev Variant of {sort} that sorts an array of uint256 in increasing order.
*/
function sort(uint256[] memory array) internal pure returns (uint256[] memory) {
sort(array, Comparators.lt);
return array;
}
/**
* @dev Sort an array of address (in memory) following the provided comparator function.
*
* This function does the sorting "in place", meaning that it overrides the input. The object is returned for
* convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
*
* NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the
* array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful
* when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
* consume more gas than is available in a block, leading to potential DoS.
*
* IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.
*/
function sort(
address[] memory array,
function(address, address) pure returns (bool) comp
) internal pure returns (address[] memory) {
sort(_castToUint256Array(array), _castToUint256Comp(comp));
return array;
}
/**
* @dev Variant of {sort} that sorts an array of address in increasing order.
*/
function sort(address[] memory array) internal pure returns (address[] memory) {
sort(_castToUint256Array(array), Comparators.lt);
return array;
}
/**
* @dev Sort an array of bytes32 (in memory) following the provided comparator function.
*
* This function does the sorting "in place", meaning that it overrides the input. The object is returned for
* convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
*
* NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the
* array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful
* when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
* consume more gas than is available in a block, leading to potential DoS.
*
* IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.
*/
function sort(
bytes32[] memory array,
function(bytes32, bytes32) pure returns (bool) comp
) internal pure returns (bytes32[] memory) {
sort(_castToUint256Array(array), _castToUint256Comp(comp));
return array;
}
/**
* @dev Variant of {sort} that sorts an array of bytes32 in increasing order.
*/
function sort(bytes32[] memory array) internal pure returns (bytes32[] memory) {
sort(_castToUint256Array(array), Comparators.lt);
return array;
}
/**
* @dev Performs a quick sort of a segment of memory. The segment sorted starts at `begin` (inclusive), and stops
* at end (exclusive). Sorting follows the `comp` comparator.
*
* Invariant: `begin <= end`. This is the case when initially called by {sort} and is preserved in subcalls.
*
* IMPORTANT: Memory locations between `begin` and `end` are not validated/zeroed. This function should
* be used only if the limits are within a memory array.
*/
function _quickSort(uint256 begin, uint256 end, function(uint256, uint256) pure returns (bool) comp) private pure {
unchecked {
if (end - begin < 0x40) return;
// Use first element as pivot
uint256 pivot = _mload(begin);
// Position where the pivot should be at the end of the loop
uint256 pos = begin;
for (uint256 it = begin + 0x20; it < end; it += 0x20) {
if (comp(_mload(it), pivot)) {
// If the value stored at the iterator's position comes before the pivot, we increment the
// position of the pivot and move the value there.
pos += 0x20;
_swap(pos, it);
}
}
_swap(begin, pos); // Swap pivot into place
_quickSort(begin, pos, comp); // Sort the left side of the pivot
_quickSort(pos + 0x20, end, comp); // Sort the right side of the pivot
}
}
/**
* @dev Pointer to the memory location of the first element of `array`.
*/
function _begin(uint256[] memory array) private pure returns (uint256 ptr) {
assembly ("memory-safe") {
ptr := add(array, 0x20)
}
}
/**
* @dev Pointer to the memory location of the first memory word (32bytes) after `array`. This is the memory word
* that comes just after the last element of the array.
*/
function _end(uint256[] memory array) private pure returns (uint256 ptr) {
unchecked {
return _begin(array) + array.length * 0x20;
}
}
/**
* @dev Load memory word (as a uint256) at location `ptr`.
*/
function _mload(uint256 ptr) private pure returns (uint256 value) {
assembly {
value := mload(ptr)
}
}
/**
* @dev Swaps the elements memory location `ptr1` and `ptr2`.
*/
function _swap(uint256 ptr1, uint256 ptr2) private pure {
assembly {
let value1 := mload(ptr1)
let value2 := mload(ptr2)
mstore(ptr1, value2)
mstore(ptr2, value1)
}
}
/// @dev Helper: low level cast address memory array to uint256 memory array
function _castToUint256Array(address[] memory input) private pure returns (uint256[] memory output) {
assembly {
output := input
}
}
/// @dev Helper: low level cast bytes32 memory array to uint256 memory array
function _castToUint256Array(bytes32[] memory input) private pure returns (uint256[] memory output) {
assembly {
output := input
}
}
/// @dev Helper: low level cast address comp function to uint256 comp function
function _castToUint256Comp(
function(address, address) pure returns (bool) input
) private pure returns (function(uint256, uint256) pure returns (bool) output) {
assembly {
output := input
}
}
/// @dev Helper: low level cast bytes32 comp function to uint256 comp function
function _castToUint256Comp(
function(bytes32, bytes32) pure returns (bool) input
) private pure returns (function(uint256, uint256) pure returns (bool) output) {
assembly {
output := input
}
}
/**
* @dev Searches a sorted `array` and returns the first index that contains
* a value greater or equal to `element`. If no such index exists (i.e. all
* values in the array are strictly less than `element`), the array length is
* returned. Time complexity O(log n).
*
* NOTE: The `array` is expected to be sorted in ascending order, and to
* contain no repeated elements.
*
* IMPORTANT: Deprecated. This implementation behaves as {lowerBound} but lacks
* support for repeated elements in the array. The {lowerBound} function should
* be used instead.
*/
function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
uint256 low = 0;
uint256 high = array.length;
if (high == 0) {
return 0;
}
while (low < high) {
uint256 mid = Math.average(low, high);
// Note that mid will always be strictly less than high (i.e. it will be a valid array index)
// because Math.average rounds towards zero (it does integer division with truncation).
if (unsafeAccess(array, mid).value > element) {
high = mid;
} else {
low = mid + 1;
}
}
// At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.
if (low > 0 && unsafeAccess(array, low - 1).value == element) {
return low - 1;
} else {
return low;
}
}
/**
* @dev Searches an `array` sorted in ascending order and returns the first
* index that contains a value greater or equal than `element`. If no such index
* exists (i.e. all values in the array are strictly less than `element`), the array
* length is returned. Time complexity O(log n).
*
* See C++'s https://en.cppreference.com/w/cpp/algorithm/lower_bound[lower_bound].
*/
function lowerBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
uint256 low = 0;
uint256 high = array.length;
if (high == 0) {
return 0;
}
while (low < high) {
uint256 mid = Math.average(low, high);
// Note that mid will always be strictly less than high (i.e. it will be a valid array index)
// because Math.average rounds towards zero (it does integer division with truncation).
if (unsafeAccess(array, mid).value < element) {
// this cannot overflow because mid < high
unchecked {
low = mid + 1;
}
} else {
high = mid;
}
}
return low;
}
/**
* @dev Searches an `array` sorted in ascending order and returns the first
* index that contains a value strictly greater than `element`. If no such index
* exists (i.e. all values in the array are strictly less than `element`), the array
* length is returned. Time complexity O(log n).
*
* See C++'s https://en.cppreference.com/w/cpp/algorithm/upper_bound[upper_bound].
*/
function upperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
uint256 low = 0;
uint256 high = array.length;
if (high == 0) {
return 0;
}
while (low < high) {
uint256 mid = Math.average(low, high);
// Note that mid will always be strictly less than high (i.e. it will be a valid array index)
// because Math.average rounds towards zero (it does integer division with truncation).
if (unsafeAccess(array, mid).value > element) {
high = mid;
} else {
// this cannot overflow because mid < high
unchecked {
low = mid + 1;
}
}
}
return low;
}
/**
* @dev Same as {lowerBound}, but with an array in memory.
*/
function lowerBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {
uint256 low = 0;
uint256 high = array.length;
if (high == 0) {
return 0;
}
while (low < high) {
uint256 mid = Math.average(low, high);
// Note that mid will always be strictly less than high (i.e. it will be a valid array index)
// because Math.average rounds towards zero (it does integer division with truncation).
if (unsafeMemoryAccess(array, mid) < element) {
// this cannot overflow because mid < high
unchecked {
low = mid + 1;
}
} else {
high = mid;
}
}
return low;
}
/**
* @dev Same as {upperBound}, but with an array in memory.
*/
function upperBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {
uint256 low = 0;
uint256 high = array.length;
if (high == 0) {
return 0;
}
while (low < high) {
uint256 mid = Math.average(low, high);
// Note that mid will always be strictly less than high (i.e. it will be a valid array index)
// because Math.average rounds towards zero (it does integer division with truncation).
if (unsafeMemoryAccess(array, mid) > element) {
high = mid;
} else {
// this cannot overflow because mid < high
unchecked {
low = mid + 1;
}
}
}
return low;
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeAccess(address[] storage arr, uint256 pos) internal pure returns (StorageSlot.AddressSlot storage) {
bytes32 slot;
assembly ("memory-safe") {
slot := arr.slot
}
return slot.deriveArray().offset(pos).getAddressSlot();
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeAccess(bytes32[] storage arr, uint256 pos) internal pure returns (StorageSlot.Bytes32Slot storage) {
bytes32 slot;
assembly ("memory-safe") {
slot := arr.slot
}
return slot.deriveArray().offset(pos).getBytes32Slot();
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeAccess(uint256[] storage arr, uint256 pos) internal pure returns (StorageSlot.Uint256Slot storage) {
bytes32 slot;
assembly ("memory-safe") {
slot := arr.slot
}
return slot.deriveArray().offset(pos).getUint256Slot();
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeAccess(bytes[] storage arr, uint256 pos) internal pure returns (StorageSlot.BytesSlot storage) {
bytes32 slot;
assembly ("memory-safe") {
slot := arr.slot
}
return slot.deriveArray().offset(pos).getBytesSlot();
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeAccess(string[] storage arr, uint256 pos) internal pure returns (StorageSlot.StringSlot storage) {
bytes32 slot;
assembly ("memory-safe") {
slot := arr.slot
}
return slot.deriveArray().offset(pos).getStringSlot();
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeMemoryAccess(address[] memory arr, uint256 pos) internal pure returns (address res) {
assembly {
res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
}
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeMemoryAccess(bytes32[] memory arr, uint256 pos) internal pure returns (bytes32 res) {
assembly {
res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
}
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeMemoryAccess(uint256[] memory arr, uint256 pos) internal pure returns (uint256 res) {
assembly {
res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
}
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeMemoryAccess(bytes[] memory arr, uint256 pos) internal pure returns (bytes memory res) {
assembly {
res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
}
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeMemoryAccess(string[] memory arr, uint256 pos) internal pure returns (string memory res) {
assembly {
res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
}
}
/**
* @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
*
* WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
*/
function unsafeSetLength(address[] storage array, uint256 len) internal {
assembly ("memory-safe") {
sstore(array.slot, len)
}
}
/**
* @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
*
* WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
*/
function unsafeSetLength(bytes32[] storage array, uint256 len) internal {
assembly ("memory-safe") {
sstore(array.slot, len)
}
}
/**
* @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
*
* WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
*/
function unsafeSetLength(uint256[] storage array, uint256 len) internal {
assembly ("memory-safe") {
sstore(array.slot, len)
}
}
/**
* @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
*
* WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
*/
function unsafeSetLength(bytes[] storage array, uint256 len) internal {
assembly ("memory-safe") {
sstore(array.slot, len)
}
}
/**
* @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
*
* WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
*/
function unsafeSetLength(string[] storage array, uint256 len) internal {
assembly ("memory-safe") {
sstore(array.slot, len)
}
}
}
// File: @openzeppelin/contracts/token/ERC1155/ERC1155.sol
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC1155/ERC1155.sol)
pragma solidity ^0.8.20;
/**
* @dev Implementation of the basic standard multi-token.
* See https://eips.ethereum.org/EIPS/eip-1155
* Originally based on code by Enjin: https://github.com/enjin/erc-1155
*/
abstract contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI, IERC1155Errors {
using Arrays for uint256[];
using Arrays for address[];
mapping(uint256 id => mapping(address account => uint256)) private _balances;
mapping(address account => mapping(address operator => bool)) private _operatorApprovals;
// Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
string private _uri;
/**
* @dev See {_setURI}.
*/
constructor(string memory uri_) {
_setURI(uri_);
}
/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC1155).interfaceId ||
interfaceId == type(IERC1155MetadataURI).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC1155MetadataURI-uri}.
*
* This implementation returns the same URI for *all* token types. It relies
* on the token type ID substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the ERC].
*
* Clients calling this function must replace the `\{id\}` substring with the
* actual token type ID.
*/
function uri(uint256 /* id */) public view virtual returns (string memory) {
return _uri;
}
/// @inheritdoc IERC1155
function balanceOf(address account, uint256 id) public view virtual returns (uint256) {
return _balances[id][account];
}
/**
* @dev See {IERC1155-balanceOfBatch}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(
address[] memory accounts,
uint256[] memory ids
) public view virtual returns (uint256[] memory) {
if (accounts.length != ids.length) {
revert ERC1155InvalidArrayLength(ids.length, accounts.length);
}
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts.unsafeMemoryAccess(i), ids.unsafeMemoryAccess(i));
}
return batchBalances;
}
/// @inheritdoc IERC1155
function setApprovalForAll(address operator, bool approved) public virtual {
_setApprovalForAll(_msgSender(), operator, approved);
}
/// @inheritdoc IERC1155
function isApprovedForAll(address account, address operator) public view virtual returns (bool) {
return _operatorApprovals[account][operator];
}
/// @inheritdoc IERC1155
function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes memory data) public virtual {
address sender = _msgSender();
if (from != sender && !isApprovedForAll(from, sender)) {
revert ERC1155MissingApprovalForAll(sender, from);
}
_safeTransferFrom(from, to, id, value, data);
}
/// @inheritdoc IERC1155
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory values,
bytes memory data
) public virtual {
address sender = _msgSender();
if (from != sender && !isApprovedForAll(from, sender)) {
revert ERC1155MissingApprovalForAll(sender, from);
}
_safeBatchTransferFrom(from, to, ids, values, data);
}
/**
* @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`. Will mint (or burn) if `from`
* (or `to`) is the zero address.
*
* Emits a {TransferSingle} event if the arrays contain one element, and {TransferBatch} otherwise.
*
* Requirements:
*
* - If `to` refers to a smart contract, it must implement either {IERC1155Receiver-onERC1155Received}
* or {IERC1155Receiver-onERC1155BatchReceived} and return the acceptance magic value.
* - `ids` and `values` must have the same length.
*
* NOTE: The ERC-1155 acceptance check is not performed in this function. See {_updateWithAcceptanceCheck} instead.
*/
function _update(address from, address to, uint256[] memory ids, uint256[] memory values) internal virtual {
if (ids.length != values.length) {
revert ERC1155InvalidArrayLength(ids.length, values.length);
}
address operator = _msgSender();
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids.unsafeMemoryAccess(i);
uint256 value = values.unsafeMemoryAccess(i);
if (from != address(0)) {
uint256 fromBalance = _balances[id][from];
if (fromBalance < value) {
revert ERC1155InsufficientBalance(from, fromBalance, value, id);
}
unchecked {
// Overflow not possible: value <= fromBalance
_balances[id][from] = fromBalance - value;
}
}
if (to != address(0)) {
_balances[id][to] += value;
}
}
if (ids.length == 1) {
uint256 id = ids.unsafeMemoryAccess(0);
uint256 value = values.unsafeMemoryAccess(0);
emit TransferSingle(operator, from, to, id, value);
} else {
emit TransferBatch(operator, from, to, ids, values);
}
}
/**
* @dev Version of {_update} that performs the token acceptance check by calling
* {IERC1155Receiver-onERC1155Received} or {IERC1155Receiver-onERC1155BatchReceived} on the receiver address if it
* contains code (eg. is a smart contract at the moment of execution).
*
* IMPORTANT: Overriding this function is discouraged because it poses a reentrancy risk from the receiver. So any
* update to the contract state after this function would break the check-effect-interaction pattern. Consider
* overriding {_update} instead.
*/
function _updateWithAcceptanceCheck(
address from,
address to,
uint256[] memory ids,
uint256[] memory values,
bytes memory data
) internal virtual {
_update(from, to, ids, values);
if (to != address(0)) {
address operator = _msgSender();
if (ids.length == 1) {
uint256 id = ids.unsafeMemoryAccess(0);
uint256 value = values.unsafeMemoryAccess(0);
ERC1155Utils.checkOnERC1155Received(operator, from, to, id, value, data);
} else {
ERC1155Utils.checkOnERC1155BatchReceived(operator, from, to, ids, values, data);
}
}
}
/**
* @dev Transfers a `value` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `from` must have a balance of tokens of type `id` of at least `value` amount.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes memory data) internal {
if (to == address(0)) {
revert ERC1155InvalidReceiver(address(0));
}
if (from == address(0)) {
revert ERC1155InvalidSender(address(0));
}
(uint256[] memory ids, uint256[] memory values) = _asSingletonArrays(id, value);
_updateWithAcceptanceCheck(from, to, ids, values, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
* - `ids` and `values` must have the same length.
*/
function _safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory values,
bytes memory data
) internal {
if (to == address(0)) {
revert ERC1155InvalidReceiver(address(0));
}
if (from == address(0)) {
revert ERC1155InvalidSender(address(0));
}
_updateWithAcceptanceCheck(from, to, ids, values, data);
}
/**
* @dev Sets a new URI for all token types, by relying on the token type ID
* substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the ERC].
*
* By this mechanism, any occurrence of the `\{id\}` substring in either the
* URI or any of the values in the JSON file at said URI will be replaced by
* clients with the token type ID.
*
* For example, the `https://token-cdn-domain/\{id\}.json` URI would be
* interpreted by clients as
* `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
* for token type ID 0x4cce0.
*
* See {uri}.
*
* Because these URIs cannot be meaningfully represented by the {URI} event,
* this function emits no events.
*/
function _setURI(string memory newuri) internal virtual {
_uri = newuri;
}
/**
* @dev Creates a `value` amount of tokens of type `id`, and assigns them to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _mint(address to, uint256 id, uint256 value, bytes memory data) internal {
if (to == address(0)) {
revert ERC1155InvalidReceiver(address(0));
}
(uint256[] memory ids, uint256[] memory values) = _asSingletonArrays(id, value);
_updateWithAcceptanceCheck(address(0), to, ids, values, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `values` must have the same length.
* - `to` cannot be the zero address.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function _mintBatch(address to, uint256[] memory ids, uint256[] memory values, bytes memory data) internal {
if (to == address(0)) {
revert ERC1155InvalidReceiver(address(0));
}
_updateWithAcceptanceCheck(address(0), to, ids, values, data);
}
/**
* @dev Destroys a `value` amount of tokens of type `id` from `from`
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `from` must have at least `value` amount of tokens of type `id`.
*/
function _burn(address from, uint256 id, uint256 value) internal {
if (from == address(0)) {
revert ERC1155InvalidSender(address(0));
}
(uint256[] memory ids, uint256[] memory values) = _asSingletonArrays(id, value);
_updateWithAcceptanceCheck(from, address(0), ids, values, "");
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `from` must have at least `value` amount of tokens of type `id`.
* - `ids` and `values` must have the same length.
*/
function _burnBatch(address from, uint256[] memory ids, uint256[] memory values) internal {
if (from == address(0)) {
revert ERC1155InvalidSender(address(0));
}
_updateWithAcceptanceCheck(from, address(0), ids, values, "");
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the zero address.
*/
function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {
if (operator == address(0)) {
revert ERC1155InvalidOperator(address(0));
}
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Creates an array in memory with only one value for each of the elements provided.
*/
function _asSingletonArrays(
uint256 element1,
uint256 element2
) private pure returns (uint256[] memory array1, uint256[] memory array2) {
assembly ("memory-safe") {
// Load the free memory pointer
array1 := mload(0x40)
// Set array length to 1
mstore(array1, 1)
// Store the single element at the next word after the length (where content starts)
mstore(add(array1, 0x20), element1)
// Repeat for next array locating it right after the first array
array2 := add(array1, 0x40)
mstore(array2, 1)
mstore(add(array2, 0x20), element2)
// Update the free memory pointer by pointing after the second array
mstore(0x40, add(array2, 0x40))
}
}
}
// File: @openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/extensions/ERC1155Burnable.sol)
pragma solidity ^0.8.20;
/**
* @dev Extension of {ERC1155} that allows token holders to destroy both their
* own tokens and those that they have been approved to use.
*/
abstract contract ERC1155Burnable is ERC1155 {
function burn(address account, uint256 id, uint256 value) public virtual {
if (account != _msgSender() && !isApprovedForAll(account, _msgSender())) {
revert ERC1155MissingApprovalForAll(_msgSender(), account);
}
_burn(account, id, value);
}
function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {
if (account != _msgSender() && !isApprovedForAll(account, _msgSender())) {
revert ERC1155MissingApprovalForAll(_msgSender(), account);
}
_burnBatch(account, ids, values);
}
}
// File: @openzeppelin/contracts/utils/Pausable.sol
// OpenZeppelin Contracts (last updated v5.3.0) (utils/Pausable.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
bool private _paused;
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
/**
* @dev The operation failed because the contract is paused.
*/
error EnforcedPause();
/**
* @dev The operation failed because the contract is not paused.
*/
error ExpectedPause();
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
if (paused()) {
revert EnforcedPause();
}
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
if (!paused()) {
revert ExpectedPause();
}
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
// File: @openzeppelin/contracts/token/ERC1155/extensions/ERC1155Pausable.sol
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC1155/extensions/ERC1155Pausable.sol)
pragma solidity ^0.8.20;
/**
* @dev ERC-1155 token with pausable token transfers, minting and burning.
*
* Useful for scenarios such as preventing trades until the end of an evaluation
* period, or having an emergency switch for freezing all token transfers in the
* event of a large bug.
*
* IMPORTANT: This contract does not include public pause and unpause functions. In
* addition to inheriting this contract, you must define both functions, invoking the
* {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate
* access control, e.g. using {AccessControl} or {Ownable}. Not doing so will
* make the contract pause mechanism of the contract unreachable, and thus unusable.
*/
abstract contract ERC1155Pausable is ERC1155, Pausable {
/**
* @dev See {ERC1155-_update}.
*
* Requirements:
*
* - the contract must not be paused.
*/
function _update(
address from,
address to,
uint256[] memory ids,
uint256[] memory values
) internal virtual override whenNotPaused {
super._update(from, to, ids, values);
}
}
// File: @openzeppelin/contracts/token/ERC1155/extensions/ERC1155Supply.sol
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC1155/extensions/ERC1155Supply.sol)
pragma solidity ^0.8.20;
/**
* @dev Extension of ERC-1155 that adds tracking of total supply per id.
*
* Useful for scenarios where Fungible and Non-fungible tokens have to be
* clearly identified. Note: While a totalSupply of 1 might mean the
* corresponding is an NFT, there is no guarantees that no other token with the
* same id are not going to be minted.
*
* NOTE: This contract implies a global limit of 2**256 - 1 to the number of tokens
* that can be minted.
*
* CAUTION: This extension should not be added in an upgrade to an already deployed contract.
*/
abstract contract ERC1155Supply is ERC1155 {
using Arrays for uint256[];
mapping(uint256 id => uint256) private _totalSupply;
uint256 private _totalSupplyAll;
/**
* @dev Total value of tokens in with a given id.
*/
function totalSupply(uint256 id) public view virtual returns (uint256) {
return _totalSupply[id];
}
/**
* @dev Total value of tokens.
*/
function totalSupply() public view virtual returns (uint256) {
return _totalSupplyAll;
}
/**
* @dev Indicates whether any token exist with a given id, or not.
*/
function exists(uint256 id) public view virtual returns (bool) {
return totalSupply(id) > 0;
}
/// @inheritdoc ERC1155
function _update(
address from,
address to,
uint256[] memory ids,
uint256[] memory values
) internal virtual override {
super._update(from, to, ids, values);
if (from == address(0)) {
uint256 totalMintValue = 0;
for (uint256 i = 0; i < ids.length; ++i) {
uint256 value = values.unsafeMemoryAccess(i);
// Overflow check required: The rest of the code assumes that totalSupply never overflows
_totalSupply[ids.unsafeMemoryAccess(i)] += value;
totalMintValue += value;
}
// Overflow check required: The rest of the code assumes that totalSupplyAll never overflows
_totalSupplyAll += totalMintValue;
}
if (to == address(0)) {
uint256 totalBurnValue = 0;
for (uint256 i = 0; i < ids.length; ++i) {
uint256 value = values.unsafeMemoryAccess(i);
unchecked {
// Overflow not possible: values[i] <= balanceOf(from, ids[i]) <= totalSupply(ids[i])
_totalSupply[ids.unsafeMemoryAccess(i)] -= value;
// Overflow not possible: sum_i(values[i]) <= sum_i(totalSupply(ids[i])) <= totalSupplyAll
totalBurnValue += value;
}
}
unchecked {
// Overflow not possible: totalBurnValue = sum_i(values[i]) <= sum_i(totalSupply(ids[i])) <= totalSupplyAll
_totalSupplyAll -= totalBurnValue;
}
}
}
}
// File: contract-8846e8ea97.sol
pragma solidity ^0.8.27;
/**
* @title KitsuBaddies_1
* @notice ERC1155 collection with per-collection supply caps and compact ID packing.
* @dev
* - IDs encode a `(collectionId, itemSeq)` pair as `(collectionId << 224) | itemSeq`.
* - Per-collection supply is tracked in `collectionSupply` and adjusted on mint/burn in `_update`.
* - URI resolution supports per-collection base URIs via `collectionBaseURI[collectionId]` and
* falls back to the global ERC1155 base URI when not set.
* - Access restricted by `DEFAULT_ADMIN_ROLE` and `MINTER_ROLE`.
* - Built on OpenZeppelin Contracts v5.4: ERC1155, Pausable, Burnable, Supply, AccessControl.
*/
contract KitsuBaddies_1 is ERC1155, AccessControl, ERC1155Pausable, ERC1155Burnable, ERC1155Supply {
/// @notice Role identifier that allows minting new tokens.
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
/// @notice Maximum number of distinct collections supported (0-indexed).
uint256 public constant MAX_COLLECTIONS = 10;
/// @notice Ensures `collectionId` is within the valid range `[0, MAX_COLLECTIONS)`.
/// @param collectionId The collection identifier to validate.
modifier validCollection(uint256 collectionId) {
require(collectionId < MAX_COLLECTIONS, "invalid collection");
_;
}
/// @dev ID packing scheme: `id = (collectionId << 224) | itemSeq`.
uint256 private constant SHIFT = 224;
/// @dev Next sequential item index per collection. Grows monotonically on mints.
mapping(uint256 => uint256) private _nextItemSeq;
/// @notice Optional per-collection hard cap (0 means unlimited).
mapping(uint256 => uint256) public collectionCap;
/// @notice Current minted supply per collection (burns decrement this counter).
mapping(uint256 => uint256) public collectionSupply;
/// @notice Optional per-collection base URI overriding the global ERC1155 base URI.
mapping(uint256 => string) public collectionBaseURI;
/// @notice Emitted when a new token type is created within a collection.
/// @param collectionId The collection to which the type belongs.
/// @param itemSeq The sequence number within the collection.
/// @param id The fully packed token ID.
event TypeCreated(uint256 indexed collectionId, uint256 indexed itemSeq, uint256 id);
/**
* @notice Deploy the contract with an initial base URI.
* @param uri_ The initial global ERC1155 base URI.
* @dev Grants `DEFAULT_ADMIN_ROLE` and `MINTER_ROLE` to the deployer.
* Sets a hard cap of 100 for collection index 9 (the 10th collection).
*/
constructor(string memory uri_) ERC1155(uri_) {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(MINTER_ROLE, msg.sender);
collectionCap[9] = 100; //collection 10 is hc to 100.
}
/**
* @notice Update the global ERC1155 base URI.
* @param newuri The new base URI to set.
* @dev Restricted to `DEFAULT_ADMIN_ROLE`.
*/
function setURI(string memory newuri) external onlyRole(DEFAULT_ADMIN_ROLE) {
_setURI(newuri);
}
/**
* @notice Set the base URI for a specific collection.
* @param collectionId The target collection ID.
* @param newBase The new base URI to use for `collectionId`.
* @dev Restricted to `DEFAULT_ADMIN_ROLE`.
*/
function setCollectionBaseURI(uint256 collectionId, string calldata newBase)
external
onlyRole(DEFAULT_ADMIN_ROLE)
validCollection(collectionId)
{
collectionBaseURI[collectionId] = newBase;
}
/**
* @notice Set base URIs for multiple collections in a single call.
* @param collectionIds The list of collection IDs to update.
* @param bases The list of base URIs matching `collectionIds` one-to-one.
* @dev Reverts if the array lengths differ. Restricted to `DEFAULT_ADMIN_ROLE`.
*/
function setCollectionBaseURIs(uint256[] calldata collectionIds, string[] calldata bases)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
require(collectionIds.length == bases.length, "length mismatch");
for (uint256 i; i < collectionIds.length; i++) {
require(collectionIds[i] < MAX_COLLECTIONS, "invalid collection");
collectionBaseURI[collectionIds[i]] = bases[i];
}
}
/**
* @notice Set or update the cap for a collection.
* @param collectionId The target collection ID.
* @param cap The new cap (0 for unlimited). Must be >= current supply.
* @dev Restricted to `DEFAULT_ADMIN_ROLE`.
*/
function setCollectionCap(uint256 collectionId, uint256 cap)
external
onlyRole(DEFAULT_ADMIN_ROLE)
validCollection(collectionId)
{
require(cap == 0 || collectionSupply[collectionId] <= cap, "cap < current supply");
collectionCap[collectionId] = cap;
}
/**
* @notice Set or update caps for multiple collections.
* @param collectionIds The list of collection IDs to update.
* @param caps The list of caps matching `collectionIds` one-to-one (0 for unlimited).
* @dev Each cap must be >= the collection's current supply. Restricted to `DEFAULT_ADMIN_ROLE`.
*/
function setCollectionCaps(uint256[] calldata collectionIds, uint256[] calldata caps)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
require(collectionIds.length == caps.length, "length mismatch");
for (uint256 i; i < collectionIds.length; i++) {
uint256 cid = collectionIds[i];
require(cid < MAX_COLLECTIONS, "invalid collection");
require(caps[i] == 0 || collectionSupply[cid] <= caps[i], "cap < current supply");
collectionCap[cid] = caps[i];
}
}
/// @notice Pause all token transfers, mints, and burns.
/// @dev Restricted to `DEFAULT_ADMIN_ROLE`.
function pause() external onlyRole(DEFAULT_ADMIN_ROLE) { _pause(); }
/// @notice Unpause the contract.
/// @dev Restricted to `DEFAULT_ADMIN_ROLE`.
function unpause() external onlyRole(DEFAULT_ADMIN_ROLE) { _unpause(); }
/**
* @notice Pack `(collectionId, itemSeq)` into a single token id.
* @param collectionId The collection identifier.
* @param itemSeq The sequence number within the collection.
* @return The packed token id.
*/
function _packId(uint256 collectionId, uint256 itemSeq) internal pure returns (uint256) {
return (collectionId << SHIFT) | itemSeq;
}
/**
* @notice Unpack a token id into its `(collectionId, itemSeq)` components.
* @param id The packed token id.
* @return collectionId The collection identifier component.
* @return itemSeq The sequence number within the collection.
*/
function unpackId(uint256 id) public pure returns (uint256 collectionId, uint256 itemSeq) {
collectionId = id >> SHIFT;
itemSeq = id & ((uint256(1) << SHIFT) - 1);
}
/**
* @notice Get the next sequence number that will be assigned in a collection.
* @param collectionId The collection identifier.
* @return The next `itemSeq` value.
*/
function nextItemSeq(uint256 collectionId) external view returns (uint256) {
return _nextItemSeq[collectionId];
}
/**
* @dev Reverts if minting `addAmount` would exceed the collection cap.
* @param collectionId The collection identifier.
* @param addAmount The number of tokens to be added.
*/
function _checkCollectionCap(uint256 collectionId, uint256 addAmount) internal view {
uint256 cap = collectionCap[collectionId];
if (cap == 0) return; // unlimited
require(collectionSupply[collectionId] + addAmount <= cap, "collection cap exceeded");
}
/**
* @notice Mint a new token of amount 1 within a collection to `to`.
* @param collectionId The target collection ID.
* @param to The recipient address.
* @param data Additional data with no specified format, sent in the mint call.
* @return id The newly created packed token id.
* @dev Restricted to `MINTER_ROLE`. Respects per-collection caps.
*/
function mint(
uint256 collectionId,
address to,
bytes memory data
) public onlyRole(MINTER_ROLE) validCollection(collectionId) returns (uint256 id) {
_checkCollectionCap(collectionId, 1);
uint256 itemSeq = _nextItemSeq[collectionId]++;
id = _packId(collectionId, itemSeq);
_mint(to, id, 1, data);
emit TypeCreated(collectionId, itemSeq, id);
}
/**
* @notice Batch mint `amount` new token ids (each with amount 1) within a collection to `to`.
* @param collectionId The target collection ID.
* @param to The recipient address.
* @param amount How many distinct token ids to create.
* @param data Additional data with no specified format, sent in the mint call.
* @return ids The list of newly created packed token ids.
* @dev Restricted to `MINTER_ROLE`. Respects per-collection caps.
*/
function mintBatch(
uint256 collectionId,
address to,
uint256 amount, // how many NFTs to create
bytes memory data
) public onlyRole(MINTER_ROLE) validCollection(collectionId) returns (uint256[] memory ids) {
require(amount > 0, "amount = 0");
_checkCollectionCap(collectionId, amount);
ids = new uint256[](amount);
uint256[] memory amounts = new uint256[](amount);
uint256 startSeq = _nextItemSeq[collectionId];
for (uint256 i; i < amount; i++) {
uint256 id = _packId(collectionId, startSeq + i);
ids[i] = id;
amounts[i] = 1;
}
_nextItemSeq[collectionId] = startSeq + amount;
_mintBatch(to, ids, amounts, data);
for (uint256 i; i < amount; i++) {
emit TypeCreated(collectionId, startSeq + i, ids[i]);
}
}
/**
* @notice Resolve the metadata URI for a token id.
* @param id The packed token id.
* @return The metadata URI string.
* @dev If a per-collection base URI exists, returns it; otherwise defers to the global base URI.
*/
function uri(uint256 id) public view override returns (string memory) {
(uint256 cId, ) = unpackId(id);
string memory base = collectionBaseURI[cId];
if (bytes(base).length > 0) return base;
return super.uri(id);
}
/**
* @dev Hook that updates per-collection supply on mint and burn, then defers to parents.
* @param from The address tokens are transferred from.
* @param to The address tokens are transferred to.
* @param ids The list of token ids affected.
* @param values The list of amounts corresponding to `ids`.
*/
function _update(address from, address to, uint256[] memory ids, uint256[] memory values)
internal
override(ERC1155, ERC1155Pausable, ERC1155Supply)
{
// Mint: from == address(0) => increment
// Burn: to == address(0) => decrement
if (from == address(0) || to == address(0)) {
for (uint256 i; i < ids.length; i++) {
(uint256 cId, ) = unpackId(ids[i]);
uint256 qty = values[i];
if (from == address(0)) {
// mint
collectionSupply[cId] += qty;
} else if (to == address(0)) {
// burn
collectionSupply[cId] -= qty;
}
}
}
super._update(from, to, ids, values);
}
/**
* @inheritdoc ERC1155
*/
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC1155, AccessControl)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"string","name":"uri_","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC1155InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC1155InvalidApprover","type":"error"},{"inputs":[{"internalType":"uint256","name":"idsLength","type":"uint256"},{"internalType":"uint256","name":"valuesLength","type":"uint256"}],"name":"ERC1155InvalidArrayLength","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC1155InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC1155InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC1155InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC1155MissingApprovalForAll","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"collectionId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"itemSeq","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"TypeCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_COLLECTIONS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"burnBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"collectionBaseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"collectionCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"collectionSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"collectionId","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mint","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"collectionId","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mintBatch","outputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"collectionId","type":"uint256"}],"name":"nextItemSeq","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"collectionId","type":"uint256"},{"internalType":"string","name":"newBase","type":"string"}],"name":"setCollectionBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"collectionIds","type":"uint256[]"},{"internalType":"string[]","name":"bases","type":"string[]"}],"name":"setCollectionBaseURIs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"collectionId","type":"uint256"},{"internalType":"uint256","name":"cap","type":"uint256"}],"name":"setCollectionCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"collectionIds","type":"uint256[]"},{"internalType":"uint256[]","name":"caps","type":"uint256[]"}],"name":"setCollectionCaps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newuri","type":"string"}],"name":"setURI","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":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"unpackId","outputs":[{"internalType":"uint256","name":"collectionId","type":"uint256"},{"internalType":"uint256","name":"itemSeq","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561000f575f5ffd5b50604051614d7a380380614d7a83398181016040528101906100319190610365565b80610041816100a460201b60201c565b506100545f5f1b336100b760201b60201c565b506100857f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336100b760201b60201c565b50606460085f600981526020019081526020015f20819055505061068b565b80600290816100b391906105bc565b5050565b5f6100c883836101ad60201b60201c565b6101a357600160035f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555061014061021160201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4600190506101a7565b5f90505b92915050565b5f60035f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f33905090565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61027782610231565b810181811067ffffffffffffffff8211171561029657610295610241565b5b80604052505050565b5f6102a8610218565b90506102b4828261026e565b919050565b5f67ffffffffffffffff8211156102d3576102d2610241565b5b6102dc82610231565b9050602081019050919050565b8281835e5f83830152505050565b5f610309610304846102b9565b61029f565b9050828152602081018484840111156103255761032461022d565b5b6103308482856102e9565b509392505050565b5f82601f83011261034c5761034b610229565b5b815161035c8482602086016102f7565b91505092915050565b5f6020828403121561037a57610379610221565b5b5f82015167ffffffffffffffff81111561039757610396610225565b5b6103a384828501610338565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806103fa57607f821691505b60208210810361040d5761040c6103b6565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261046f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610434565b6104798683610434565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6104bd6104b86104b384610491565b61049a565b610491565b9050919050565b5f819050919050565b6104d6836104a3565b6104ea6104e2826104c4565b848454610440565b825550505050565b5f5f905090565b6105016104f2565b61050c8184846104cd565b505050565b5b8181101561052f576105245f826104f9565b600181019050610512565b5050565b601f8211156105745761054581610413565b61054e84610425565b8101602085101561055d578190505b61057161056985610425565b830182610511565b50505b505050565b5f82821c905092915050565b5f6105945f1984600802610579565b1980831691505092915050565b5f6105ac8383610585565b9150826002028217905092915050565b6105c5826103ac565b67ffffffffffffffff8111156105de576105dd610241565b5b6105e882546103e3565b6105f3828285610533565b5f60209050601f831160018114610624575f8415610612578287015190505b61061c85826105a1565b865550610683565b601f19841661063286610413565b5f5b8281101561065957848901518255600182019150602085019450602081019050610634565b868310156106765784890151610672601f891682610585565b8355505b6001600288020188555050505b505050505050565b6146e2806106985f395ff3fe608060405234801561000f575f5ffd5b5060043610610219575f3560e01c80637f067b6711610123578063bd85b039116100ab578063d547741f1161007a578063d547741f14610680578063de9dd04c1461069c578063e985e9c5146106cc578063f242432a146106fc578063f5298aca1461071857610219565b8063bd85b039146105d2578063c5ee7b3c14610602578063ce756c5714610632578063d53913931461066257610219565b806391d14854116100f257806391d148541461051b57806399425dcc1461054b5780639ad706931461057c578063a217fddf14610598578063a22cb465146105b657610219565b80637f067b67146104a75780638456cb59146104c5578063876a9ce7146104cf57806390669908146104ff57610219565b80632f2ff15d116101a65780634f558e79116101755780634f558e79146103f15780635c975abb146104215780636b20c4541461043f57806373c025191461045b578063765008021461048b57610219565b80632f2ff15d1461037f57806336568abe1461039b5780633f4ba83a146103b75780634e1273f4146103c157610219565b806318160ddd116101ed57806318160ddd146102c95780631ae21c74146102e7578063248a9ca314610317578063274dd8ce146103475780632eb2c2d61461036357610219565b8062fdd58e1461021d57806301ffc9a71461024d57806302fe53051461027d5780630e89341c14610299575b5f5ffd5b61023760048036038101906102329190612f4c565b610734565b6040516102449190612f99565b60405180910390f35b61026760048036038101906102629190613007565b610789565b604051610274919061304c565b60405180910390f35b610297600480360381019061029291906131a1565b61079a565b005b6102b360048036038101906102ae91906131e8565b6107b3565b6040516102c09190613273565b60405180910390f35b6102d1610883565b6040516102de9190612f99565b60405180910390f35b61030160048036038101906102fc91906131e8565b61088c565b60405161030e9190612f99565b60405180910390f35b610331600480360381019061032c91906132c6565b6108a1565b60405161033e9190613300565b60405180910390f35b610361600480360381019061035c9190613376565b6108be565b005b61037d60048036038101906103789190613552565b610a54565b005b6103996004803603810190610394919061361d565b610afb565b005b6103b560048036038101906103b0919061361d565b610b1d565b005b6103bf610b98565b005b6103db60048036038101906103d6919061371b565b610baf565b6040516103e89190613848565b60405180910390f35b61040b600480360381019061040691906131e8565b610cb9565b604051610418919061304c565b60405180910390f35b610429610ccc565b604051610436919061304c565b60405180910390f35b61045960048036038101906104549190613868565b610ce1565b005b610475600480360381019061047091906138f0565b610d8d565b6040516104829190612f99565b60405180910390f35b6104a560048036038101906104a091906139b1565b610e8b565b005b6104af610f03565b6040516104bc9190612f99565b60405180910390f35b6104cd610f08565b005b6104e960048036038101906104e491906131e8565b610f1f565b6040516104f69190613273565b60405180910390f35b61051960048036038101906105149190613a63565b610fba565b005b6105356004803603810190610530919061361d565b6110e9565b604051610542919061304c565b60405180910390f35b610565600480360381019061056091906131e8565b61114d565b604051610573929190613ae1565b60405180910390f35b61059660048036038101906105919190613b08565b611171565b005b6105a061123b565b6040516105ad9190613300565b60405180910390f35b6105d060048036038101906105cb9190613b70565b611241565b005b6105ec60048036038101906105e791906131e8565b611257565b6040516105f99190612f99565b60405180910390f35b61061c60048036038101906106179190613bae565b611271565b6040516106299190613848565b60405180910390f35b61064c600480360381019061064791906131e8565b6114fa565b6040516106599190612f99565b60405180910390f35b61066a611514565b6040516106779190613300565b60405180910390f35b61069a6004803603810190610695919061361d565b611538565b005b6106b660048036038101906106b191906131e8565b61155a565b6040516106c39190612f99565b60405180910390f35b6106e660048036038101906106e19190613c2e565b61156f565b6040516106f3919061304c565b60405180910390f35b61071660048036038101906107119190613c6c565b6115fd565b005b610732600480360381019061072d9190613cff565b6116a4565b005b5f5f5f8381526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f61079382611750565b9050919050565b5f5f1b6107a6816117c9565b6107af826117dd565b5050565b60605f6107bf8361114d565b5090505f600a5f8381526020019081526020015f2080546107df90613d7c565b80601f016020809104026020016040519081016040528092919081815260200182805461080b90613d7c565b80156108565780601f1061082d57610100808354040283529160200191610856565b820191905f5260205f20905b81548152906001019060200180831161083957829003601f168201915b505050505090505f8151111561087057809250505061087e565b610879846117f0565b925050505b919050565b5f600654905090565b6009602052805f5260405f205f915090505481565b5f60035f8381526020019081526020015f20600101549050919050565b5f5f1b6108ca816117c9565b828290508585905014610912576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090990613df6565b60405180910390fd5b5f5b85859050811015610a4c575f86868381811061093357610932613e14565b5b905060200201359050600a811061097f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097690613e8b565b60405180910390fd5b5f85858481811061099357610992613e14565b5b9050602002013514806109d057508484838181106109b4576109b3613e14565b5b9050602002013560095f8381526020019081526020015f205411155b610a0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0690613ef3565b60405180910390fd5b848483818110610a2257610a21613e14565b5b9050602002013560085f8381526020019081526020015f2081905550508080600101915050610914565b505050505050565b5f610a5d611882565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614158015610aa25750610aa0868261156f565b155b15610ae65780866040517fe237d922000000000000000000000000000000000000000000000000000000008152600401610add929190613f20565b60405180910390fd5b610af38686868686611889565b505050505050565b610b04826108a1565b610b0d816117c9565b610b17838361197d565b50505050565b610b25611882565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b89576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b938282611a67565b505050565b5f5f1b610ba4816117c9565b610bac611b51565b50565b60608151835114610bfb57815183516040517f5b059991000000000000000000000000000000000000000000000000000000008152600401610bf2929190613ae1565b60405180910390fd5b5f835167ffffffffffffffff811115610c1757610c1661307d565b5b604051908082528060200260200182016040528015610c455781602001602082028036833780820191505090505b5090505f5f90505b8451811015610cae57610c84610c6c8287611bb290919063ffffffff16565b610c7f8387611bc590919063ffffffff16565b610734565b828281518110610c9757610c96613e14565b5b602002602001018181525050806001019050610c4d565b508091505092915050565b5f5f610cc483611257565b119050919050565b5f60045f9054906101000a900460ff16905090565b610ce9611882565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015610d325750610d3083610d2b611882565b61156f565b155b15610d7d57610d3f611882565b836040517fe237d922000000000000000000000000000000000000000000000000000000008152600401610d74929190613f20565b60405180910390fd5b610d88838383611bd8565b505050565b5f7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610db8816117c9565b84600a8110610dfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df390613e8b565b60405180910390fd5b610e07866001611c68565b5f60075f8881526020019081526020015f205f815480929190610e2990613f74565b919050559050610e398782611cef565b9350610e488685600188611cff565b80877fd0f72bb70ee0c436a349142b3b216da1d26789b338e820ba70c61d2ed47b183586604051610e799190612f99565b60405180910390a35050509392505050565b5f5f1b610e97816117c9565b83600a8110610edb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed290613e8b565b60405180910390fd5b8383600a5f8881526020019081526020015f209182610efb929190614165565b505050505050565b600a81565b5f5f1b610f14816117c9565b610f1c611d94565b50565b600a602052805f5260405f205f915090508054610f3b90613d7c565b80601f0160208091040260200160405190810160405280929190818152602001828054610f6790613d7c565b8015610fb25780601f10610f8957610100808354040283529160200191610fb2565b820191905f5260205f20905b815481529060010190602001808311610f9557829003601f168201915b505050505081565b5f5f1b610fc6816117c9565b82829050858590501461100e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161100590613df6565b60405180910390fd5b5f5b858590508110156110e157600a8686838181106110305761102f613e14565b5b9050602002013510611077576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106e90613e8b565b60405180910390fd5b83838281811061108a57611089613e14565b5b905060200281019061109c919061423e565b600a5f8989868181106110b2576110b1613e14565b5b9050602002013581526020019081526020015f2091826110d3929190614165565b508080600101915050611010565b505050505050565b5f60035f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f5f60e083901c9150600160e06001901b61116891906142a0565b83169050915091565b5f5f1b61117d816117c9565b82600a81106111c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111b890613e8b565b60405180910390fd5b5f8314806111e057508260095f8681526020019081526020015f205411155b61121f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121690613ef3565b60405180910390fd5b8260085f8681526020019081526020015f208190555050505050565b5f5f1b81565b61125361124c611882565b8383611df6565b5050565b5f60055f8381526020019081526020015f20549050919050565b60607f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661129d816117c9565b85600a81106112e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d890613e8b565b60405180910390fd5b5f8511611323576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131a9061431d565b60405180910390fd5b61132d8786611c68565b8467ffffffffffffffff8111156113475761134661307d565b5b6040519080825280602002602001820160405280156113755781602001602082028036833780820191505090505b5092505f8567ffffffffffffffff8111156113935761139261307d565b5b6040519080825280602002602001820160405280156113c15781602001602082028036833780820191505090505b5090505f60075f8a81526020019081526020015f205490505f5b8781101561144a575f6113f98b83856113f4919061433b565b611cef565b90508087838151811061140f5761140e613e14565b5b60200260200101818152505060018483815181106114305761142f613e14565b5b6020026020010181815250505080806001019150506113db565b508681611457919061433b565b60075f8b81526020019081526020015f208190555061147888868489611f5f565b5f5b878110156114ed57808261148e919061433b565b8a7fd0f72bb70ee0c436a349142b3b216da1d26789b338e820ba70c61d2ed47b18358884815181106114c3576114c2613e14565b5b60200260200101516040516114d89190612f99565b60405180910390a3808060010191505061147a565b5050505050949350505050565b5f60075f8381526020019081526020015f20549050919050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b611541826108a1565b61154a816117c9565b6115548383611a67565b50505050565b6008602052805f5260405f205f915090505481565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f611606611882565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561164b5750611649868261156f565b155b1561168f5780866040517fe237d922000000000000000000000000000000000000000000000000000000008152600401611686929190613f20565b60405180910390fd5b61169c8686868686611fe2565b505050505050565b6116ac611882565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156116f557506116f3836116ee611882565b61156f565b155b1561174057611702611882565b836040517fe237d922000000000000000000000000000000000000000000000000000000008152600401611737929190613f20565b60405180910390fd5b61174b8383836120e8565b505050565b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806117c257506117c18261218a565b5b9050919050565b6117da816117d5611882565b61226b565b50565b80600290816117ec919061436e565b5050565b6060600280546117ff90613d7c565b80601f016020809104026020016040519081016040528092919081815260200182805461182b90613d7c565b80156118765780601f1061184d57610100808354040283529160200191611876565b820191905f5260205f20905b81548152906001019060200180831161185957829003601f168201915b50505050509050919050565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036118f9575f6040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016118f0919061443d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611969575f6040517f01a83514000000000000000000000000000000000000000000000000000000008152600401611960919061443d565b60405180910390fd5b61197685858585856122bc565b5050505050565b5f61198883836110e9565b611a5d57600160035f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506119fa611882565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019050611a61565b5f90505b92915050565b5f611a7283836110e9565b15611b47575f60035f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550611ae4611882565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a460019050611b4b565b5f90505b92915050565b611b59612368565b5f60045f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa611b9b611882565b604051611ba8919061443d565b60405180910390a1565b5f60208202602084010151905092915050565b5f60208202602084010151905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611c48575f6040517f01a83514000000000000000000000000000000000000000000000000000000008152600401611c3f919061443d565b60405180910390fd5b611c63835f848460405180602001604052805f8152506122bc565b505050565b5f60085f8481526020019081526020015f205490505f8103611c8a5750611ceb565b808260095f8681526020019081526020015f2054611ca8919061433b565b1115611ce9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce0906144a0565b60405180910390fd5b505b5050565b5f8160e084901b17905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611d6f575f6040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401611d66919061443d565b60405180910390fd5b5f5f611d7b85856123a8565b91509150611d8c5f878484876122bc565b505050505050565b611d9c6123d8565b600160045f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611ddf611882565b604051611dec919061443d565b60405180910390a1565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611e66575f6040517fced3e100000000000000000000000000000000000000000000000000000000008152600401611e5d919061443d565b60405180910390fd5b8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611f52919061304c565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611fcf575f6040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401611fc6919061443d565b60405180910390fd5b611fdc5f858585856122bc565b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612052575f6040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401612049919061443d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036120c2575f6040517f01a835140000000000000000000000000000000000000000000000000000000081526004016120b9919061443d565b60405180910390fd5b5f5f6120ce85856123a8565b915091506120df87878484876122bc565b50505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612158575f6040517f01a8351400000000000000000000000000000000000000000000000000000000815260040161214f919061443d565b60405180910390fd5b5f5f61216484846123a8565b91509150612183855f848460405180602001604052805f8152506122bc565b5050505050565b5f7fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061225457507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80612264575061226382612419565b5b9050919050565b61227582826110e9565b6122b85780826040517fe2517d3f0000000000000000000000000000000000000000000000000000000081526004016122af9291906144be565b60405180910390fd5b5050565b6122c885858585612482565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614612361575f612304611882565b90506001845103612350575f6123235f86611bc590919063ffffffff16565b90505f6123395f86611bc590919063ffffffff16565b905061234983898985858961261a565b505061235f565b61235e8187878787876127c9565b5b505b5050505050565b612370610ccc565b6123a6576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60608060405191506001825283602083015260408201905060018152826020820152604081016040529250929050565b6123e0610ccc565b15612417576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806124e757505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b15612608575f5b8251811015612606575f61251b84838151811061250e5761250d613e14565b5b602002602001015161114d565b5090505f83838151811061253257612531613e14565b5b602002602001015190505f73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff160361259b578060095f8481526020019081526020015f205f82825461258f919061433b565b925050819055506125f7565b5f73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16036125f6578060095f8481526020019081526020015f205f8282546125ee91906142a0565b925050819055505b5b505080806001019150506124ee565b505b61261484848484612978565b50505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b11156127c1578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b815260040161267a959493929190614537565b6020604051808303815f875af19250505080156126b557506040513d601f19601f820116820180604052508101906126b291906145a3565b60015b612736573d805f81146126e3576040519150601f19603f3d011682016040523d82523d5f602084013e6126e8565b606091505b505f81510361272e57846040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401612725919061443d565b60405180910390fd5b805160208201fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146127bf57846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016127b6919061443d565b60405180910390fd5b505b505050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b1115612970578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b81526004016128299594939291906145ce565b6020604051808303815f875af192505050801561286457506040513d601f19601f8201168201806040525081019061286191906145a3565b60015b6128e5573d805f8114612892576040519150601f19603f3d011682016040523d82523d5f602084013e612897565b606091505b505f8151036128dd57846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016128d4919061443d565b60405180910390fd5b805160208201fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461296e57846040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401612965919061443d565b60405180910390fd5b505b505050505050565b61298484848484612b01565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612a4d575f5f90505f5f90505b8351811015612a32575f6129dd8285611bc590919063ffffffff16565b90508060055f6129f68589611bc590919063ffffffff16565b81526020019081526020015f205f828254612a11919061433b565b925050819055508083612a24919061433b565b9250508060010190506129c0565b508060065f828254612a44919061433b565b92505081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612afb575f5f90505f5f90505b8351811015612ae9575f612aa68285611bc590919063ffffffff16565b90508060055f612abf8589611bc590919063ffffffff16565b81526020019081526020015f205f8282540392505081905550808301925050806001019050612a89565b508060065f8282540392505081905550505b50505050565b612b096123d8565b612b1584848484612b1b565b50505050565b8051825114612b6557815181516040517f5b059991000000000000000000000000000000000000000000000000000000008152600401612b5c929190613ae1565b60405180910390fd5b5f612b6e611882565b90505f5f90505b8351811015612d6d575f612b928286611bc590919063ffffffff16565b90505f612ba88386611bc590919063ffffffff16565b90505f73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614612ccb575f5f5f8481526020019081526020015f205f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015612c7757888183856040517f03dee4c5000000000000000000000000000000000000000000000000000000008152600401612c6e9493929190614634565b60405180910390fd5b8181035f5f8581526020019081526020015f205f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614612d6057805f5f8481526020019081526020015f205f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612d58919061433b565b925050819055505b5050806001019050612b75565b506001835103612e28575f612d8b5f85611bc590919063ffffffff16565b90505f612da15f85611bc590919063ffffffff16565b90508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051612e19929190613ae1565b60405180910390a45050612ea7565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051612e9e929190614677565b60405180910390a45b5050505050565b5f604051905090565b5f5ffd5b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612ee882612ebf565b9050919050565b612ef881612ede565b8114612f02575f5ffd5b50565b5f81359050612f1381612eef565b92915050565b5f819050919050565b612f2b81612f19565b8114612f35575f5ffd5b50565b5f81359050612f4681612f22565b92915050565b5f5f60408385031215612f6257612f61612eb7565b5b5f612f6f85828601612f05565b9250506020612f8085828601612f38565b9150509250929050565b612f9381612f19565b82525050565b5f602082019050612fac5f830184612f8a565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fe681612fb2565b8114612ff0575f5ffd5b50565b5f8135905061300181612fdd565b92915050565b5f6020828403121561301c5761301b612eb7565b5b5f61302984828501612ff3565b91505092915050565b5f8115159050919050565b61304681613032565b82525050565b5f60208201905061305f5f83018461303d565b92915050565b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6130b38261306d565b810181811067ffffffffffffffff821117156130d2576130d161307d565b5b80604052505050565b5f6130e4612eae565b90506130f082826130aa565b919050565b5f67ffffffffffffffff82111561310f5761310e61307d565b5b6131188261306d565b9050602081019050919050565b828183375f83830152505050565b5f613145613140846130f5565b6130db565b90508281526020810184848401111561316157613160613069565b5b61316c848285613125565b509392505050565b5f82601f83011261318857613187613065565b5b8135613198848260208601613133565b91505092915050565b5f602082840312156131b6576131b5612eb7565b5b5f82013567ffffffffffffffff8111156131d3576131d2612ebb565b5b6131df84828501613174565b91505092915050565b5f602082840312156131fd576131fc612eb7565b5b5f61320a84828501612f38565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61324582613213565b61324f818561321d565b935061325f81856020860161322d565b6132688161306d565b840191505092915050565b5f6020820190508181035f83015261328b818461323b565b905092915050565b5f819050919050565b6132a581613293565b81146132af575f5ffd5b50565b5f813590506132c08161329c565b92915050565b5f602082840312156132db576132da612eb7565b5b5f6132e8848285016132b2565b91505092915050565b6132fa81613293565b82525050565b5f6020820190506133135f8301846132f1565b92915050565b5f5ffd5b5f5ffd5b5f5f83601f84011261333657613335613065565b5b8235905067ffffffffffffffff81111561335357613352613319565b5b60208301915083602082028301111561336f5761336e61331d565b5b9250929050565b5f5f5f5f6040858703121561338e5761338d612eb7565b5b5f85013567ffffffffffffffff8111156133ab576133aa612ebb565b5b6133b787828801613321565b9450945050602085013567ffffffffffffffff8111156133da576133d9612ebb565b5b6133e687828801613321565b925092505092959194509250565b5f67ffffffffffffffff82111561340e5761340d61307d565b5b602082029050602081019050919050565b5f61343161342c846133f4565b6130db565b905080838252602082019050602084028301858111156134545761345361331d565b5b835b8181101561347d57806134698882612f38565b845260208401935050602081019050613456565b5050509392505050565b5f82601f83011261349b5761349a613065565b5b81356134ab84826020860161341f565b91505092915050565b5f67ffffffffffffffff8211156134ce576134cd61307d565b5b6134d78261306d565b9050602081019050919050565b5f6134f66134f1846134b4565b6130db565b90508281526020810184848401111561351257613511613069565b5b61351d848285613125565b509392505050565b5f82601f83011261353957613538613065565b5b81356135498482602086016134e4565b91505092915050565b5f5f5f5f5f60a0868803121561356b5761356a612eb7565b5b5f61357888828901612f05565b955050602061358988828901612f05565b945050604086013567ffffffffffffffff8111156135aa576135a9612ebb565b5b6135b688828901613487565b935050606086013567ffffffffffffffff8111156135d7576135d6612ebb565b5b6135e388828901613487565b925050608086013567ffffffffffffffff81111561360457613603612ebb565b5b61361088828901613525565b9150509295509295909350565b5f5f6040838503121561363357613632612eb7565b5b5f613640858286016132b2565b925050602061365185828601612f05565b9150509250929050565b5f67ffffffffffffffff8211156136755761367461307d565b5b602082029050602081019050919050565b5f6136986136938461365b565b6130db565b905080838252602082019050602084028301858111156136bb576136ba61331d565b5b835b818110156136e457806136d08882612f05565b8452602084019350506020810190506136bd565b5050509392505050565b5f82601f83011261370257613701613065565b5b8135613712848260208601613686565b91505092915050565b5f5f6040838503121561373157613730612eb7565b5b5f83013567ffffffffffffffff81111561374e5761374d612ebb565b5b61375a858286016136ee565b925050602083013567ffffffffffffffff81111561377b5761377a612ebb565b5b61378785828601613487565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6137c381612f19565b82525050565b5f6137d483836137ba565b60208301905092915050565b5f602082019050919050565b5f6137f682613791565b613800818561379b565b935061380b836137ab565b805f5b8381101561383b57815161382288826137c9565b975061382d836137e0565b92505060018101905061380e565b5085935050505092915050565b5f6020820190508181035f83015261386081846137ec565b905092915050565b5f5f5f6060848603121561387f5761387e612eb7565b5b5f61388c86828701612f05565b935050602084013567ffffffffffffffff8111156138ad576138ac612ebb565b5b6138b986828701613487565b925050604084013567ffffffffffffffff8111156138da576138d9612ebb565b5b6138e686828701613487565b9150509250925092565b5f5f5f6060848603121561390757613906612eb7565b5b5f61391486828701612f38565b935050602061392586828701612f05565b925050604084013567ffffffffffffffff81111561394657613945612ebb565b5b61395286828701613525565b9150509250925092565b5f5f83601f84011261397157613970613065565b5b8235905067ffffffffffffffff81111561398e5761398d613319565b5b6020830191508360018202830111156139aa576139a961331d565b5b9250929050565b5f5f5f604084860312156139c8576139c7612eb7565b5b5f6139d586828701612f38565b935050602084013567ffffffffffffffff8111156139f6576139f5612ebb565b5b613a028682870161395c565b92509250509250925092565b5f5f83601f840112613a2357613a22613065565b5b8235905067ffffffffffffffff811115613a4057613a3f613319565b5b602083019150836020820283011115613a5c57613a5b61331d565b5b9250929050565b5f5f5f5f60408587031215613a7b57613a7a612eb7565b5b5f85013567ffffffffffffffff811115613a9857613a97612ebb565b5b613aa487828801613321565b9450945050602085013567ffffffffffffffff811115613ac757613ac6612ebb565b5b613ad387828801613a0e565b925092505092959194509250565b5f604082019050613af45f830185612f8a565b613b016020830184612f8a565b9392505050565b5f5f60408385031215613b1e57613b1d612eb7565b5b5f613b2b85828601612f38565b9250506020613b3c85828601612f38565b9150509250929050565b613b4f81613032565b8114613b59575f5ffd5b50565b5f81359050613b6a81613b46565b92915050565b5f5f60408385031215613b8657613b85612eb7565b5b5f613b9385828601612f05565b9250506020613ba485828601613b5c565b9150509250929050565b5f5f5f5f60808587031215613bc657613bc5612eb7565b5b5f613bd387828801612f38565b9450506020613be487828801612f05565b9350506040613bf587828801612f38565b925050606085013567ffffffffffffffff811115613c1657613c15612ebb565b5b613c2287828801613525565b91505092959194509250565b5f5f60408385031215613c4457613c43612eb7565b5b5f613c5185828601612f05565b9250506020613c6285828601612f05565b9150509250929050565b5f5f5f5f5f60a08688031215613c8557613c84612eb7565b5b5f613c9288828901612f05565b9550506020613ca388828901612f05565b9450506040613cb488828901612f38565b9350506060613cc588828901612f38565b925050608086013567ffffffffffffffff811115613ce657613ce5612ebb565b5b613cf288828901613525565b9150509295509295909350565b5f5f5f60608486031215613d1657613d15612eb7565b5b5f613d2386828701612f05565b9350506020613d3486828701612f38565b9250506040613d4586828701612f38565b9150509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680613d9357607f821691505b602082108103613da657613da5613d4f565b5b50919050565b7f6c656e677468206d69736d6174636800000000000000000000000000000000005f82015250565b5f613de0600f8361321d565b9150613deb82613dac565b602082019050919050565b5f6020820190508181035f830152613e0d81613dd4565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f696e76616c696420636f6c6c656374696f6e00000000000000000000000000005f82015250565b5f613e7560128361321d565b9150613e8082613e41565b602082019050919050565b5f6020820190508181035f830152613ea281613e69565b9050919050565b7f636170203c2063757272656e7420737570706c790000000000000000000000005f82015250565b5f613edd60148361321d565b9150613ee882613ea9565b602082019050919050565b5f6020820190508181035f830152613f0a81613ed1565b9050919050565b613f1a81612ede565b82525050565b5f604082019050613f335f830185613f11565b613f406020830184613f11565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f613f7e82612f19565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fb057613faf613f47565b5b600182019050919050565b5f82905092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026140217fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613fe6565b61402b8683613fe6565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61406661406161405c84612f19565b614043565b612f19565b9050919050565b5f819050919050565b61407f8361404c565b61409361408b8261406d565b848454613ff2565b825550505050565b5f5f905090565b6140aa61409b565b6140b5818484614076565b505050565b5b818110156140d8576140cd5f826140a2565b6001810190506140bb565b5050565b601f82111561411d576140ee81613fc5565b6140f784613fd7565b81016020851015614106578190505b61411a61411285613fd7565b8301826140ba565b50505b505050565b5f82821c905092915050565b5f61413d5f1984600802614122565b1980831691505092915050565b5f614155838361412e565b9150826002028217905092915050565b61416f8383613fbb565b67ffffffffffffffff8111156141885761418761307d565b5b6141928254613d7c565b61419d8282856140dc565b5f601f8311600181146141ca575f84156141b8578287013590505b6141c2858261414a565b865550614229565b601f1984166141d886613fc5565b5f5b828110156141ff578489013582556001820191506020850194506020810190506141da565b8683101561421c5784890135614218601f89168261412e565b8355505b6001600288020188555050505b50505050505050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f8335600160200384360303811261425a57614259614232565b5b80840192508235915067ffffffffffffffff82111561427c5761427b614236565b5b6020830192506001820236038313156142985761429761423a565b5b509250929050565b5f6142aa82612f19565b91506142b583612f19565b92508282039050818111156142cd576142cc613f47565b5b92915050565b7f616d6f756e74203d2030000000000000000000000000000000000000000000005f82015250565b5f614307600a8361321d565b9150614312826142d3565b602082019050919050565b5f6020820190508181035f830152614334816142fb565b9050919050565b5f61434582612f19565b915061435083612f19565b925082820190508082111561436857614367613f47565b5b92915050565b61437782613213565b67ffffffffffffffff8111156143905761438f61307d565b5b61439a8254613d7c565b6143a58282856140dc565b5f60209050601f8311600181146143d6575f84156143c4578287015190505b6143ce858261414a565b865550614435565b601f1984166143e486613fc5565b5f5b8281101561440b578489015182556001820191506020850194506020810190506143e6565b868310156144285784890151614424601f89168261412e565b8355505b6001600288020188555050505b505050505050565b5f6020820190506144505f830184613f11565b92915050565b7f636f6c6c656374696f6e206361702065786365656465640000000000000000005f82015250565b5f61448a60178361321d565b915061449582614456565b602082019050919050565b5f6020820190508181035f8301526144b78161447e565b9050919050565b5f6040820190506144d15f830185613f11565b6144de60208301846132f1565b9392505050565b5f81519050919050565b5f82825260208201905092915050565b5f614509826144e5565b61451381856144ef565b935061452381856020860161322d565b61452c8161306d565b840191505092915050565b5f60a08201905061454a5f830188613f11565b6145576020830187613f11565b6145646040830186612f8a565b6145716060830185612f8a565b818103608083015261458381846144ff565b90509695505050505050565b5f8151905061459d81612fdd565b92915050565b5f602082840312156145b8576145b7612eb7565b5b5f6145c58482850161458f565b91505092915050565b5f60a0820190506145e15f830188613f11565b6145ee6020830187613f11565b818103604083015261460081866137ec565b9050818103606083015261461481856137ec565b9050818103608083015261462881846144ff565b90509695505050505050565b5f6080820190506146475f830187613f11565b6146546020830186612f8a565b6146616040830185612f8a565b61466e6060830184612f8a565b95945050505050565b5f6040820190508181035f83015261468f81856137ec565b905081810360208301526146a381846137ec565b9050939250505056fea2646970667358221220a1c7fa091824256d3619d0815864392d017db5d89333b746fc0914b15853693864736f6c634300081e00330000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004268747470733a2f2f6b697473756e696e652e696f2f6e6674735f636f6c6c65637469626c65732f657263313135352f6261646469655f64656661756c742e6a736f6e000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561000f575f5ffd5b5060043610610219575f3560e01c80637f067b6711610123578063bd85b039116100ab578063d547741f1161007a578063d547741f14610680578063de9dd04c1461069c578063e985e9c5146106cc578063f242432a146106fc578063f5298aca1461071857610219565b8063bd85b039146105d2578063c5ee7b3c14610602578063ce756c5714610632578063d53913931461066257610219565b806391d14854116100f257806391d148541461051b57806399425dcc1461054b5780639ad706931461057c578063a217fddf14610598578063a22cb465146105b657610219565b80637f067b67146104a75780638456cb59146104c5578063876a9ce7146104cf57806390669908146104ff57610219565b80632f2ff15d116101a65780634f558e79116101755780634f558e79146103f15780635c975abb146104215780636b20c4541461043f57806373c025191461045b578063765008021461048b57610219565b80632f2ff15d1461037f57806336568abe1461039b5780633f4ba83a146103b75780634e1273f4146103c157610219565b806318160ddd116101ed57806318160ddd146102c95780631ae21c74146102e7578063248a9ca314610317578063274dd8ce146103475780632eb2c2d61461036357610219565b8062fdd58e1461021d57806301ffc9a71461024d57806302fe53051461027d5780630e89341c14610299575b5f5ffd5b61023760048036038101906102329190612f4c565b610734565b6040516102449190612f99565b60405180910390f35b61026760048036038101906102629190613007565b610789565b604051610274919061304c565b60405180910390f35b610297600480360381019061029291906131a1565b61079a565b005b6102b360048036038101906102ae91906131e8565b6107b3565b6040516102c09190613273565b60405180910390f35b6102d1610883565b6040516102de9190612f99565b60405180910390f35b61030160048036038101906102fc91906131e8565b61088c565b60405161030e9190612f99565b60405180910390f35b610331600480360381019061032c91906132c6565b6108a1565b60405161033e9190613300565b60405180910390f35b610361600480360381019061035c9190613376565b6108be565b005b61037d60048036038101906103789190613552565b610a54565b005b6103996004803603810190610394919061361d565b610afb565b005b6103b560048036038101906103b0919061361d565b610b1d565b005b6103bf610b98565b005b6103db60048036038101906103d6919061371b565b610baf565b6040516103e89190613848565b60405180910390f35b61040b600480360381019061040691906131e8565b610cb9565b604051610418919061304c565b60405180910390f35b610429610ccc565b604051610436919061304c565b60405180910390f35b61045960048036038101906104549190613868565b610ce1565b005b610475600480360381019061047091906138f0565b610d8d565b6040516104829190612f99565b60405180910390f35b6104a560048036038101906104a091906139b1565b610e8b565b005b6104af610f03565b6040516104bc9190612f99565b60405180910390f35b6104cd610f08565b005b6104e960048036038101906104e491906131e8565b610f1f565b6040516104f69190613273565b60405180910390f35b61051960048036038101906105149190613a63565b610fba565b005b6105356004803603810190610530919061361d565b6110e9565b604051610542919061304c565b60405180910390f35b610565600480360381019061056091906131e8565b61114d565b604051610573929190613ae1565b60405180910390f35b61059660048036038101906105919190613b08565b611171565b005b6105a061123b565b6040516105ad9190613300565b60405180910390f35b6105d060048036038101906105cb9190613b70565b611241565b005b6105ec60048036038101906105e791906131e8565b611257565b6040516105f99190612f99565b60405180910390f35b61061c60048036038101906106179190613bae565b611271565b6040516106299190613848565b60405180910390f35b61064c600480360381019061064791906131e8565b6114fa565b6040516106599190612f99565b60405180910390f35b61066a611514565b6040516106779190613300565b60405180910390f35b61069a6004803603810190610695919061361d565b611538565b005b6106b660048036038101906106b191906131e8565b61155a565b6040516106c39190612f99565b60405180910390f35b6106e660048036038101906106e19190613c2e565b61156f565b6040516106f3919061304c565b60405180910390f35b61071660048036038101906107119190613c6c565b6115fd565b005b610732600480360381019061072d9190613cff565b6116a4565b005b5f5f5f8381526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f61079382611750565b9050919050565b5f5f1b6107a6816117c9565b6107af826117dd565b5050565b60605f6107bf8361114d565b5090505f600a5f8381526020019081526020015f2080546107df90613d7c565b80601f016020809104026020016040519081016040528092919081815260200182805461080b90613d7c565b80156108565780601f1061082d57610100808354040283529160200191610856565b820191905f5260205f20905b81548152906001019060200180831161083957829003601f168201915b505050505090505f8151111561087057809250505061087e565b610879846117f0565b925050505b919050565b5f600654905090565b6009602052805f5260405f205f915090505481565b5f60035f8381526020019081526020015f20600101549050919050565b5f5f1b6108ca816117c9565b828290508585905014610912576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090990613df6565b60405180910390fd5b5f5b85859050811015610a4c575f86868381811061093357610932613e14565b5b905060200201359050600a811061097f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097690613e8b565b60405180910390fd5b5f85858481811061099357610992613e14565b5b9050602002013514806109d057508484838181106109b4576109b3613e14565b5b9050602002013560095f8381526020019081526020015f205411155b610a0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0690613ef3565b60405180910390fd5b848483818110610a2257610a21613e14565b5b9050602002013560085f8381526020019081526020015f2081905550508080600101915050610914565b505050505050565b5f610a5d611882565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614158015610aa25750610aa0868261156f565b155b15610ae65780866040517fe237d922000000000000000000000000000000000000000000000000000000008152600401610add929190613f20565b60405180910390fd5b610af38686868686611889565b505050505050565b610b04826108a1565b610b0d816117c9565b610b17838361197d565b50505050565b610b25611882565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b89576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b938282611a67565b505050565b5f5f1b610ba4816117c9565b610bac611b51565b50565b60608151835114610bfb57815183516040517f5b059991000000000000000000000000000000000000000000000000000000008152600401610bf2929190613ae1565b60405180910390fd5b5f835167ffffffffffffffff811115610c1757610c1661307d565b5b604051908082528060200260200182016040528015610c455781602001602082028036833780820191505090505b5090505f5f90505b8451811015610cae57610c84610c6c8287611bb290919063ffffffff16565b610c7f8387611bc590919063ffffffff16565b610734565b828281518110610c9757610c96613e14565b5b602002602001018181525050806001019050610c4d565b508091505092915050565b5f5f610cc483611257565b119050919050565b5f60045f9054906101000a900460ff16905090565b610ce9611882565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015610d325750610d3083610d2b611882565b61156f565b155b15610d7d57610d3f611882565b836040517fe237d922000000000000000000000000000000000000000000000000000000008152600401610d74929190613f20565b60405180910390fd5b610d88838383611bd8565b505050565b5f7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610db8816117c9565b84600a8110610dfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df390613e8b565b60405180910390fd5b610e07866001611c68565b5f60075f8881526020019081526020015f205f815480929190610e2990613f74565b919050559050610e398782611cef565b9350610e488685600188611cff565b80877fd0f72bb70ee0c436a349142b3b216da1d26789b338e820ba70c61d2ed47b183586604051610e799190612f99565b60405180910390a35050509392505050565b5f5f1b610e97816117c9565b83600a8110610edb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed290613e8b565b60405180910390fd5b8383600a5f8881526020019081526020015f209182610efb929190614165565b505050505050565b600a81565b5f5f1b610f14816117c9565b610f1c611d94565b50565b600a602052805f5260405f205f915090508054610f3b90613d7c565b80601f0160208091040260200160405190810160405280929190818152602001828054610f6790613d7c565b8015610fb25780601f10610f8957610100808354040283529160200191610fb2565b820191905f5260205f20905b815481529060010190602001808311610f9557829003601f168201915b505050505081565b5f5f1b610fc6816117c9565b82829050858590501461100e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161100590613df6565b60405180910390fd5b5f5b858590508110156110e157600a8686838181106110305761102f613e14565b5b9050602002013510611077576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106e90613e8b565b60405180910390fd5b83838281811061108a57611089613e14565b5b905060200281019061109c919061423e565b600a5f8989868181106110b2576110b1613e14565b5b9050602002013581526020019081526020015f2091826110d3929190614165565b508080600101915050611010565b505050505050565b5f60035f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f5f60e083901c9150600160e06001901b61116891906142a0565b83169050915091565b5f5f1b61117d816117c9565b82600a81106111c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111b890613e8b565b60405180910390fd5b5f8314806111e057508260095f8681526020019081526020015f205411155b61121f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121690613ef3565b60405180910390fd5b8260085f8681526020019081526020015f208190555050505050565b5f5f1b81565b61125361124c611882565b8383611df6565b5050565b5f60055f8381526020019081526020015f20549050919050565b60607f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661129d816117c9565b85600a81106112e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d890613e8b565b60405180910390fd5b5f8511611323576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131a9061431d565b60405180910390fd5b61132d8786611c68565b8467ffffffffffffffff8111156113475761134661307d565b5b6040519080825280602002602001820160405280156113755781602001602082028036833780820191505090505b5092505f8567ffffffffffffffff8111156113935761139261307d565b5b6040519080825280602002602001820160405280156113c15781602001602082028036833780820191505090505b5090505f60075f8a81526020019081526020015f205490505f5b8781101561144a575f6113f98b83856113f4919061433b565b611cef565b90508087838151811061140f5761140e613e14565b5b60200260200101818152505060018483815181106114305761142f613e14565b5b6020026020010181815250505080806001019150506113db565b508681611457919061433b565b60075f8b81526020019081526020015f208190555061147888868489611f5f565b5f5b878110156114ed57808261148e919061433b565b8a7fd0f72bb70ee0c436a349142b3b216da1d26789b338e820ba70c61d2ed47b18358884815181106114c3576114c2613e14565b5b60200260200101516040516114d89190612f99565b60405180910390a3808060010191505061147a565b5050505050949350505050565b5f60075f8381526020019081526020015f20549050919050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b611541826108a1565b61154a816117c9565b6115548383611a67565b50505050565b6008602052805f5260405f205f915090505481565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f611606611882565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415801561164b5750611649868261156f565b155b1561168f5780866040517fe237d922000000000000000000000000000000000000000000000000000000008152600401611686929190613f20565b60405180910390fd5b61169c8686868686611fe2565b505050505050565b6116ac611882565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156116f557506116f3836116ee611882565b61156f565b155b1561174057611702611882565b836040517fe237d922000000000000000000000000000000000000000000000000000000008152600401611737929190613f20565b60405180910390fd5b61174b8383836120e8565b505050565b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806117c257506117c18261218a565b5b9050919050565b6117da816117d5611882565b61226b565b50565b80600290816117ec919061436e565b5050565b6060600280546117ff90613d7c565b80601f016020809104026020016040519081016040528092919081815260200182805461182b90613d7c565b80156118765780601f1061184d57610100808354040283529160200191611876565b820191905f5260205f20905b81548152906001019060200180831161185957829003601f168201915b50505050509050919050565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036118f9575f6040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016118f0919061443d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611969575f6040517f01a83514000000000000000000000000000000000000000000000000000000008152600401611960919061443d565b60405180910390fd5b61197685858585856122bc565b5050505050565b5f61198883836110e9565b611a5d57600160035f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506119fa611882565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019050611a61565b5f90505b92915050565b5f611a7283836110e9565b15611b47575f60035f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550611ae4611882565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a460019050611b4b565b5f90505b92915050565b611b59612368565b5f60045f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa611b9b611882565b604051611ba8919061443d565b60405180910390a1565b5f60208202602084010151905092915050565b5f60208202602084010151905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611c48575f6040517f01a83514000000000000000000000000000000000000000000000000000000008152600401611c3f919061443d565b60405180910390fd5b611c63835f848460405180602001604052805f8152506122bc565b505050565b5f60085f8481526020019081526020015f205490505f8103611c8a5750611ceb565b808260095f8681526020019081526020015f2054611ca8919061433b565b1115611ce9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce0906144a0565b60405180910390fd5b505b5050565b5f8160e084901b17905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611d6f575f6040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401611d66919061443d565b60405180910390fd5b5f5f611d7b85856123a8565b91509150611d8c5f878484876122bc565b505050505050565b611d9c6123d8565b600160045f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611ddf611882565b604051611dec919061443d565b60405180910390a1565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611e66575f6040517fced3e100000000000000000000000000000000000000000000000000000000008152600401611e5d919061443d565b60405180910390fd5b8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611f52919061304c565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611fcf575f6040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401611fc6919061443d565b60405180910390fd5b611fdc5f858585856122bc565b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612052575f6040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401612049919061443d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036120c2575f6040517f01a835140000000000000000000000000000000000000000000000000000000081526004016120b9919061443d565b60405180910390fd5b5f5f6120ce85856123a8565b915091506120df87878484876122bc565b50505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612158575f6040517f01a8351400000000000000000000000000000000000000000000000000000000815260040161214f919061443d565b60405180910390fd5b5f5f61216484846123a8565b91509150612183855f848460405180602001604052805f8152506122bc565b5050505050565b5f7fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061225457507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80612264575061226382612419565b5b9050919050565b61227582826110e9565b6122b85780826040517fe2517d3f0000000000000000000000000000000000000000000000000000000081526004016122af9291906144be565b60405180910390fd5b5050565b6122c885858585612482565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614612361575f612304611882565b90506001845103612350575f6123235f86611bc590919063ffffffff16565b90505f6123395f86611bc590919063ffffffff16565b905061234983898985858961261a565b505061235f565b61235e8187878787876127c9565b5b505b5050505050565b612370610ccc565b6123a6576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60608060405191506001825283602083015260408201905060018152826020820152604081016040529250929050565b6123e0610ccc565b15612417576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806124e757505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b15612608575f5b8251811015612606575f61251b84838151811061250e5761250d613e14565b5b602002602001015161114d565b5090505f83838151811061253257612531613e14565b5b602002602001015190505f73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff160361259b578060095f8481526020019081526020015f205f82825461258f919061433b565b925050819055506125f7565b5f73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16036125f6578060095f8481526020019081526020015f205f8282546125ee91906142a0565b925050819055505b5b505080806001019150506124ee565b505b61261484848484612978565b50505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b11156127c1578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b815260040161267a959493929190614537565b6020604051808303815f875af19250505080156126b557506040513d601f19601f820116820180604052508101906126b291906145a3565b60015b612736573d805f81146126e3576040519150601f19603f3d011682016040523d82523d5f602084013e6126e8565b606091505b505f81510361272e57846040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401612725919061443d565b60405180910390fd5b805160208201fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146127bf57846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016127b6919061443d565b60405180910390fd5b505b505050505050565b5f8473ffffffffffffffffffffffffffffffffffffffff163b1115612970578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b81526004016128299594939291906145ce565b6020604051808303815f875af192505050801561286457506040513d601f19601f8201168201806040525081019061286191906145a3565b60015b6128e5573d805f8114612892576040519150601f19603f3d011682016040523d82523d5f602084013e612897565b606091505b505f8151036128dd57846040517f57f447ce0000000000000000000000000000000000000000000000000000000081526004016128d4919061443d565b60405180910390fd5b805160208201fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461296e57846040517f57f447ce000000000000000000000000000000000000000000000000000000008152600401612965919061443d565b60405180910390fd5b505b505050505050565b61298484848484612b01565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612a4d575f5f90505f5f90505b8351811015612a32575f6129dd8285611bc590919063ffffffff16565b90508060055f6129f68589611bc590919063ffffffff16565b81526020019081526020015f205f828254612a11919061433b565b925050819055508083612a24919061433b565b9250508060010190506129c0565b508060065f828254612a44919061433b565b92505081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612afb575f5f90505f5f90505b8351811015612ae9575f612aa68285611bc590919063ffffffff16565b90508060055f612abf8589611bc590919063ffffffff16565b81526020019081526020015f205f8282540392505081905550808301925050806001019050612a89565b508060065f8282540392505081905550505b50505050565b612b096123d8565b612b1584848484612b1b565b50505050565b8051825114612b6557815181516040517f5b059991000000000000000000000000000000000000000000000000000000008152600401612b5c929190613ae1565b60405180910390fd5b5f612b6e611882565b90505f5f90505b8351811015612d6d575f612b928286611bc590919063ffffffff16565b90505f612ba88386611bc590919063ffffffff16565b90505f73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614612ccb575f5f5f8481526020019081526020015f205f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015612c7757888183856040517f03dee4c5000000000000000000000000000000000000000000000000000000008152600401612c6e9493929190614634565b60405180910390fd5b8181035f5f8581526020019081526020015f205f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614612d6057805f5f8481526020019081526020015f205f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254612d58919061433b565b925050819055505b5050806001019050612b75565b506001835103612e28575f612d8b5f85611bc590919063ffffffff16565b90505f612da15f85611bc590919063ffffffff16565b90508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051612e19929190613ae1565b60405180910390a45050612ea7565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051612e9e929190614677565b60405180910390a45b5050505050565b5f604051905090565b5f5ffd5b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612ee882612ebf565b9050919050565b612ef881612ede565b8114612f02575f5ffd5b50565b5f81359050612f1381612eef565b92915050565b5f819050919050565b612f2b81612f19565b8114612f35575f5ffd5b50565b5f81359050612f4681612f22565b92915050565b5f5f60408385031215612f6257612f61612eb7565b5b5f612f6f85828601612f05565b9250506020612f8085828601612f38565b9150509250929050565b612f9381612f19565b82525050565b5f602082019050612fac5f830184612f8a565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fe681612fb2565b8114612ff0575f5ffd5b50565b5f8135905061300181612fdd565b92915050565b5f6020828403121561301c5761301b612eb7565b5b5f61302984828501612ff3565b91505092915050565b5f8115159050919050565b61304681613032565b82525050565b5f60208201905061305f5f83018461303d565b92915050565b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6130b38261306d565b810181811067ffffffffffffffff821117156130d2576130d161307d565b5b80604052505050565b5f6130e4612eae565b90506130f082826130aa565b919050565b5f67ffffffffffffffff82111561310f5761310e61307d565b5b6131188261306d565b9050602081019050919050565b828183375f83830152505050565b5f613145613140846130f5565b6130db565b90508281526020810184848401111561316157613160613069565b5b61316c848285613125565b509392505050565b5f82601f83011261318857613187613065565b5b8135613198848260208601613133565b91505092915050565b5f602082840312156131b6576131b5612eb7565b5b5f82013567ffffffffffffffff8111156131d3576131d2612ebb565b5b6131df84828501613174565b91505092915050565b5f602082840312156131fd576131fc612eb7565b5b5f61320a84828501612f38565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61324582613213565b61324f818561321d565b935061325f81856020860161322d565b6132688161306d565b840191505092915050565b5f6020820190508181035f83015261328b818461323b565b905092915050565b5f819050919050565b6132a581613293565b81146132af575f5ffd5b50565b5f813590506132c08161329c565b92915050565b5f602082840312156132db576132da612eb7565b5b5f6132e8848285016132b2565b91505092915050565b6132fa81613293565b82525050565b5f6020820190506133135f8301846132f1565b92915050565b5f5ffd5b5f5ffd5b5f5f83601f84011261333657613335613065565b5b8235905067ffffffffffffffff81111561335357613352613319565b5b60208301915083602082028301111561336f5761336e61331d565b5b9250929050565b5f5f5f5f6040858703121561338e5761338d612eb7565b5b5f85013567ffffffffffffffff8111156133ab576133aa612ebb565b5b6133b787828801613321565b9450945050602085013567ffffffffffffffff8111156133da576133d9612ebb565b5b6133e687828801613321565b925092505092959194509250565b5f67ffffffffffffffff82111561340e5761340d61307d565b5b602082029050602081019050919050565b5f61343161342c846133f4565b6130db565b905080838252602082019050602084028301858111156134545761345361331d565b5b835b8181101561347d57806134698882612f38565b845260208401935050602081019050613456565b5050509392505050565b5f82601f83011261349b5761349a613065565b5b81356134ab84826020860161341f565b91505092915050565b5f67ffffffffffffffff8211156134ce576134cd61307d565b5b6134d78261306d565b9050602081019050919050565b5f6134f66134f1846134b4565b6130db565b90508281526020810184848401111561351257613511613069565b5b61351d848285613125565b509392505050565b5f82601f83011261353957613538613065565b5b81356135498482602086016134e4565b91505092915050565b5f5f5f5f5f60a0868803121561356b5761356a612eb7565b5b5f61357888828901612f05565b955050602061358988828901612f05565b945050604086013567ffffffffffffffff8111156135aa576135a9612ebb565b5b6135b688828901613487565b935050606086013567ffffffffffffffff8111156135d7576135d6612ebb565b5b6135e388828901613487565b925050608086013567ffffffffffffffff81111561360457613603612ebb565b5b61361088828901613525565b9150509295509295909350565b5f5f6040838503121561363357613632612eb7565b5b5f613640858286016132b2565b925050602061365185828601612f05565b9150509250929050565b5f67ffffffffffffffff8211156136755761367461307d565b5b602082029050602081019050919050565b5f6136986136938461365b565b6130db565b905080838252602082019050602084028301858111156136bb576136ba61331d565b5b835b818110156136e457806136d08882612f05565b8452602084019350506020810190506136bd565b5050509392505050565b5f82601f83011261370257613701613065565b5b8135613712848260208601613686565b91505092915050565b5f5f6040838503121561373157613730612eb7565b5b5f83013567ffffffffffffffff81111561374e5761374d612ebb565b5b61375a858286016136ee565b925050602083013567ffffffffffffffff81111561377b5761377a612ebb565b5b61378785828601613487565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6137c381612f19565b82525050565b5f6137d483836137ba565b60208301905092915050565b5f602082019050919050565b5f6137f682613791565b613800818561379b565b935061380b836137ab565b805f5b8381101561383b57815161382288826137c9565b975061382d836137e0565b92505060018101905061380e565b5085935050505092915050565b5f6020820190508181035f83015261386081846137ec565b905092915050565b5f5f5f6060848603121561387f5761387e612eb7565b5b5f61388c86828701612f05565b935050602084013567ffffffffffffffff8111156138ad576138ac612ebb565b5b6138b986828701613487565b925050604084013567ffffffffffffffff8111156138da576138d9612ebb565b5b6138e686828701613487565b9150509250925092565b5f5f5f6060848603121561390757613906612eb7565b5b5f61391486828701612f38565b935050602061392586828701612f05565b925050604084013567ffffffffffffffff81111561394657613945612ebb565b5b61395286828701613525565b9150509250925092565b5f5f83601f84011261397157613970613065565b5b8235905067ffffffffffffffff81111561398e5761398d613319565b5b6020830191508360018202830111156139aa576139a961331d565b5b9250929050565b5f5f5f604084860312156139c8576139c7612eb7565b5b5f6139d586828701612f38565b935050602084013567ffffffffffffffff8111156139f6576139f5612ebb565b5b613a028682870161395c565b92509250509250925092565b5f5f83601f840112613a2357613a22613065565b5b8235905067ffffffffffffffff811115613a4057613a3f613319565b5b602083019150836020820283011115613a5c57613a5b61331d565b5b9250929050565b5f5f5f5f60408587031215613a7b57613a7a612eb7565b5b5f85013567ffffffffffffffff811115613a9857613a97612ebb565b5b613aa487828801613321565b9450945050602085013567ffffffffffffffff811115613ac757613ac6612ebb565b5b613ad387828801613a0e565b925092505092959194509250565b5f604082019050613af45f830185612f8a565b613b016020830184612f8a565b9392505050565b5f5f60408385031215613b1e57613b1d612eb7565b5b5f613b2b85828601612f38565b9250506020613b3c85828601612f38565b9150509250929050565b613b4f81613032565b8114613b59575f5ffd5b50565b5f81359050613b6a81613b46565b92915050565b5f5f60408385031215613b8657613b85612eb7565b5b5f613b9385828601612f05565b9250506020613ba485828601613b5c565b9150509250929050565b5f5f5f5f60808587031215613bc657613bc5612eb7565b5b5f613bd387828801612f38565b9450506020613be487828801612f05565b9350506040613bf587828801612f38565b925050606085013567ffffffffffffffff811115613c1657613c15612ebb565b5b613c2287828801613525565b91505092959194509250565b5f5f60408385031215613c4457613c43612eb7565b5b5f613c5185828601612f05565b9250506020613c6285828601612f05565b9150509250929050565b5f5f5f5f5f60a08688031215613c8557613c84612eb7565b5b5f613c9288828901612f05565b9550506020613ca388828901612f05565b9450506040613cb488828901612f38565b9350506060613cc588828901612f38565b925050608086013567ffffffffffffffff811115613ce657613ce5612ebb565b5b613cf288828901613525565b9150509295509295909350565b5f5f5f60608486031215613d1657613d15612eb7565b5b5f613d2386828701612f05565b9350506020613d3486828701612f38565b9250506040613d4586828701612f38565b9150509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680613d9357607f821691505b602082108103613da657613da5613d4f565b5b50919050565b7f6c656e677468206d69736d6174636800000000000000000000000000000000005f82015250565b5f613de0600f8361321d565b9150613deb82613dac565b602082019050919050565b5f6020820190508181035f830152613e0d81613dd4565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f696e76616c696420636f6c6c656374696f6e00000000000000000000000000005f82015250565b5f613e7560128361321d565b9150613e8082613e41565b602082019050919050565b5f6020820190508181035f830152613ea281613e69565b9050919050565b7f636170203c2063757272656e7420737570706c790000000000000000000000005f82015250565b5f613edd60148361321d565b9150613ee882613ea9565b602082019050919050565b5f6020820190508181035f830152613f0a81613ed1565b9050919050565b613f1a81612ede565b82525050565b5f604082019050613f335f830185613f11565b613f406020830184613f11565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f613f7e82612f19565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fb057613faf613f47565b5b600182019050919050565b5f82905092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026140217fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613fe6565b61402b8683613fe6565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61406661406161405c84612f19565b614043565b612f19565b9050919050565b5f819050919050565b61407f8361404c565b61409361408b8261406d565b848454613ff2565b825550505050565b5f5f905090565b6140aa61409b565b6140b5818484614076565b505050565b5b818110156140d8576140cd5f826140a2565b6001810190506140bb565b5050565b601f82111561411d576140ee81613fc5565b6140f784613fd7565b81016020851015614106578190505b61411a61411285613fd7565b8301826140ba565b50505b505050565b5f82821c905092915050565b5f61413d5f1984600802614122565b1980831691505092915050565b5f614155838361412e565b9150826002028217905092915050565b61416f8383613fbb565b67ffffffffffffffff8111156141885761418761307d565b5b6141928254613d7c565b61419d8282856140dc565b5f601f8311600181146141ca575f84156141b8578287013590505b6141c2858261414a565b865550614229565b601f1984166141d886613fc5565b5f5b828110156141ff578489013582556001820191506020850194506020810190506141da565b8683101561421c5784890135614218601f89168261412e565b8355505b6001600288020188555050505b50505050505050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f8335600160200384360303811261425a57614259614232565b5b80840192508235915067ffffffffffffffff82111561427c5761427b614236565b5b6020830192506001820236038313156142985761429761423a565b5b509250929050565b5f6142aa82612f19565b91506142b583612f19565b92508282039050818111156142cd576142cc613f47565b5b92915050565b7f616d6f756e74203d2030000000000000000000000000000000000000000000005f82015250565b5f614307600a8361321d565b9150614312826142d3565b602082019050919050565b5f6020820190508181035f830152614334816142fb565b9050919050565b5f61434582612f19565b915061435083612f19565b925082820190508082111561436857614367613f47565b5b92915050565b61437782613213565b67ffffffffffffffff8111156143905761438f61307d565b5b61439a8254613d7c565b6143a58282856140dc565b5f60209050601f8311600181146143d6575f84156143c4578287015190505b6143ce858261414a565b865550614435565b601f1984166143e486613fc5565b5f5b8281101561440b578489015182556001820191506020850194506020810190506143e6565b868310156144285784890151614424601f89168261412e565b8355505b6001600288020188555050505b505050505050565b5f6020820190506144505f830184613f11565b92915050565b7f636f6c6c656374696f6e206361702065786365656465640000000000000000005f82015250565b5f61448a60178361321d565b915061449582614456565b602082019050919050565b5f6020820190508181035f8301526144b78161447e565b9050919050565b5f6040820190506144d15f830185613f11565b6144de60208301846132f1565b9392505050565b5f81519050919050565b5f82825260208201905092915050565b5f614509826144e5565b61451381856144ef565b935061452381856020860161322d565b61452c8161306d565b840191505092915050565b5f60a08201905061454a5f830188613f11565b6145576020830187613f11565b6145646040830186612f8a565b6145716060830185612f8a565b818103608083015261458381846144ff565b90509695505050505050565b5f8151905061459d81612fdd565b92915050565b5f602082840312156145b8576145b7612eb7565b5b5f6145c58482850161458f565b91505092915050565b5f60a0820190506145e15f830188613f11565b6145ee6020830187613f11565b818103604083015261460081866137ec565b9050818103606083015261461481856137ec565b9050818103608083015261462881846144ff565b90509695505050505050565b5f6080820190506146475f830187613f11565b6146546020830186612f8a565b6146616040830185612f8a565b61466e6060830184612f8a565b95945050505050565b5f6040820190508181035f83015261468f81856137ec565b905081810360208301526146a381846137ec565b9050939250505056fea2646970667358221220a1c7fa091824256d3619d0815864392d017db5d89333b746fc0914b15853693864736f6c634300081e0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004268747470733a2f2f6b697473756e696e652e696f2f6e6674735f636f6c6c65637469626c65732f657263313135352f6261646469655f64656661756c742e6a736f6e000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : uri_ (string): https://kitsunine.io/nfts_collectibles/erc1155/baddie_default.json
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000042
Arg [2] : 68747470733a2f2f6b697473756e696e652e696f2f6e6674735f636f6c6c6563
Arg [3] : 7469626c65732f657263313135352f6261646469655f64656661756c742e6a73
Arg [4] : 6f6e000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
158051:11551:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;136476:134;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;169389:210;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;160464:110;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;167890:254;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;155349:102;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;159206:51;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10081:122;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;162763:549;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;138157:441;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;10513:138;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;11650:251;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;163595:72;;;:::i;:::-;;136776:567;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;155549:108;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;151766:86;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;149671:319;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;165785:426;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;160830:237;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;158372:44;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;163432:68;;;:::i;:::-;;159356:51;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;161399:444;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;9097:138;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;164352:188;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;162109:306;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;8444:49;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;137381:146;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;155174:113;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;166714:910;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;164747:127;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;158222:62;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10944:140;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;159065:48;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;137565:159;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;137762:357;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;149376:287;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;136476:134;136553:7;136580:9;:13;136590:2;136580:13;;;;;;;;;;;:22;136594:7;136580:22;;;;;;;;;;;;;;;;136573:29;;136476:134;;;;:::o;169389:210::-;169526:4;169555:36;169579:11;169555:23;:36::i;:::-;169548:43;;169389:210;;;:::o;160464:110::-;8489:4;160520:18;;8728:16;8739:4;8728:10;:16::i;:::-;160551:15:::1;160559:6;160551:7;:15::i;:::-;160464:110:::0;;:::o;167890:254::-;167945:13;167972:11;167989:12;167998:2;167989:8;:12::i;:::-;167971:30;;;168012:18;168033:17;:22;168051:3;168033:22;;;;;;;;;;;168012:43;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;168091:1;168076:4;168070:18;:22;168066:39;;;168101:4;168094:11;;;;;;168066:39;168123:13;168133:2;168123:9;:13::i;:::-;168116:20;;;;167890:254;;;;:::o;155349:102::-;155401:7;155428:15;;155421:22;;155349:102;:::o;159206:51::-;;;;;;;;;;;;;;;;;:::o;10081:122::-;10146:7;10173:6;:12;10180:4;10173:12;;;;;;;;;;;:22;;;10166:29;;10081:122;;;:::o;162763:549::-;8489:4;162885:18;;8728:16;8739:4;8728:10;:16::i;:::-;162953:4:::1;;:11;;162929:13;;:20;;:35;162921:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;163000:9;162995:310;163015:13;;:20;;163011:1;:24;162995:310;;;163057:11;163071:13;;163085:1;163071:16;;;;;;;:::i;:::-;;;;;;;;163057:30;;158414:2;163110:3;:21;163102:52;;;;;;;;;;;;:::i;:::-;;;;;;;;;163188:1;163177:4;;163182:1;163177:7;;;;;;;:::i;:::-;;;;;;;;:12;:48;;;;163218:4;;163223:1;163218:7;;;;;;;:::i;:::-;;;;;;;;163193:16;:21;163210:3;163193:21;;;;;;;;;;;;:32;;163177:48;163169:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;163286:4;;163291:1;163286:7;;;;;;;:::i;:::-;;;;;;;;163265:13;:18;163279:3;163265:18;;;;;;;;;;;:28;;;;163042:263;163037:3;;;;;;;162995:310;;;;162763:549:::0;;;;;:::o;138157:441::-;138358:14;138375:12;:10;:12::i;:::-;138358:29;;138410:6;138402:14;;:4;:14;;;;:49;;;;;138421:30;138438:4;138444:6;138421:16;:30::i;:::-;138420:31;138402:49;138398:131;;;138504:6;138512:4;138475:42;;;;;;;;;;;;:::i;:::-;;;;;;;;138398:131;138539:51;138562:4;138568:2;138572:3;138577:6;138585:4;138539:22;:51::i;:::-;138347:251;138157:441;;;;;:::o;10513:138::-;10587:18;10600:4;10587:12;:18::i;:::-;8728:16;8739:4;8728:10;:16::i;:::-;10618:25:::1;10629:4;10635:7;10618:10;:25::i;:::-;;10513:138:::0;;;:::o;11650:251::-;11766:12;:10;:12::i;:::-;11744:34;;:18;:34;;;11740:104;;11802:30;;;;;;;;;;;;;;11740:104;11856:37;11868:4;11874:18;11856:11;:37::i;:::-;;11650:251;;:::o;163595:72::-;8489:4;163632:18;;8728:16;8739:4;8728:10;:16::i;:::-;163654:10:::1;:8;:10::i;:::-;163595:72:::0;:::o;136776:567::-;136903:16;136955:3;:10;136936:8;:15;:29;136932:123;;137015:3;:10;137027:8;:15;136989:54;;;;;;;;;;;;:::i;:::-;;;;;;;;136932:123;137067:30;137114:8;:15;137100:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;137067:63;;137148:9;137160:1;137148:13;;137143:160;137167:8;:15;137163:1;:19;137143:160;;;137223:68;137233:30;137261:1;137233:8;:27;;:30;;;;:::i;:::-;137265:25;137288:1;137265:3;:22;;:25;;;;:::i;:::-;137223:9;:68::i;:::-;137204:13;137218:1;137204:16;;;;;;;;:::i;:::-;;;;;;;:87;;;;;137184:3;;;;;137143:160;;;;137322:13;137315:20;;;136776:567;;;;:::o;155549:108::-;155606:4;155648:1;155630:15;155642:2;155630:11;:15::i;:::-;:19;155623:26;;155549:108;;;:::o;151766:86::-;151813:4;151837:7;;;;;;;;;;;151830:14;;151766:86;:::o;149671:319::-;149795:12;:10;:12::i;:::-;149784:23;;:7;:23;;;;:67;;;;;149812:39;149829:7;149838:12;:10;:12::i;:::-;149812:16;:39::i;:::-;149811:40;149784:67;149780:158;;;149904:12;:10;:12::i;:::-;149918:7;149875:51;;;;;;;;;;;;:::i;:::-;;;;;;;;149780:158;149950:32;149961:7;149970:3;149975:6;149950:10;:32::i;:::-;149671:319;;;:::o;165785:426::-;165954:10;158260:24;8728:16;8739:4;8728:10;:16::i;:::-;165931:12:::1;158414:2;158649:12;:30;158641:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;165977:36:::2;165997:12;166011:1;165977:19;:36::i;:::-;166024:15;166042:12;:26;166055:12;166042:26;;;;;;;;;;;;:28;;;;;;;;;:::i;:::-;;;;;166024:46;;166086:30;166094:12;166108:7;166086;:30::i;:::-;166081:35;;166127:22;166133:2;166137;166141:1;166144:4;166127:5;:22::i;:::-;166191:7;166177:12;166165:38;166200:2;166165:38;;;;;;:::i;:::-;;;;;;;;165966:245;8755:1:::1;165785:426:::0;;;;;;:::o;160830:237::-;8489:4;160943:18;;8728:16;8739:4;8728:10;:16::i;:::-;160988:12:::1;158414:2;158649:12;:30;158641:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;161052:7:::2;;161018:17;:31;161036:12;161018:31;;;;;;;;;;;:41;;;;;;;:::i;:::-;;8755:1:::1;160830:237:::0;;;;:::o;158372:44::-;158414:2;158372:44;:::o;163432:68::-;8489:4;163467:18;;8728:16;8739:4;8728:10;:16::i;:::-;163489:8:::1;:6;:8::i;:::-;163432:68:::0;:::o;159356:51::-;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;161399:444::-;8489:4;161525:18;;8728:16;8739:4;8728:10;:16::i;:::-;161593:5:::1;;:12;;161569:13;;:20;;:36;161561:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;161641:9;161636:200;161656:13;;:20;;161652:1;:24;161636:200;;;158414:2;161706:13;;161720:1;161706:16;;;;;;;:::i;:::-;;;;;;;;:34;161698:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;161816:5;;161822:1;161816:8;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;161778:17;:35;161796:13;;161810:1;161796:16;;;;;;;:::i;:::-;;;;;;;;161778:35;;;;;;;;;;;:46;;;;;;;:::i;:::-;;161678:3;;;;;;;161636:200;;;;161399:444:::0;;;;;:::o;9097:138::-;9174:4;9198:6;:12;9205:4;9198:12;;;;;;;;;;;:20;;:29;9219:7;9198:29;;;;;;;;;;;;;;;;;;;;;;;;;9191:36;;9097:138;;;;:::o;164352:188::-;164403:20;164425:15;158836:3;164468:2;:11;;164453:26;;164530:1;158836:3;164515:1;164507:19;;164506:25;;;;:::i;:::-;164500:2;:32;164490:42;;164352:188;;;:::o;162109:306::-;8489:4;162206:18;;8728:16;8739:4;8728:10;:16::i;:::-;162251:12:::1;158414:2;158649:12;:30;158641:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;162296:1:::2;162289:3;:8;:49;;;;162335:3;162301:16;:30;162318:12;162301:30;;;;;;;;;;;;:37;;162289:49;162281:82;;;;;;;;;;;;:::i;:::-;;;;;;;;;162404:3;162374:13;:27;162388:12;162374:27;;;;;;;;;;;:33;;;;8755:1:::1;162109:306:::0;;;:::o;8444:49::-;8489:4;8444:49;;;:::o;137381:146::-;137467:52;137486:12;:10;:12::i;:::-;137500:8;137510;137467:18;:52::i;:::-;137381:146;;:::o;155174:113::-;155236:7;155263:12;:16;155276:2;155263:16;;;;;;;;;;;;155256:23;;155174:113;;;:::o;166714:910::-;166940:20;158260:24;8728:16;8739:4;8728:10;:16::i;:::-;166917:12:::1;158414:2;158649:12;:30;158641:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;166990:1:::2;166981:6;:10;166973:33;;;;;;;;;;;;:::i;:::-;;;;;;;;;167017:41;167037:12;167051:6;167017:19;:41::i;:::-;167091:6;167077:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;167071:27;;167109:24;167150:6;167136:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;167109:48;;167170:16;167189:12;:26;167202:12;167189:26;;;;;;;;;;;;167170:45;;167231:9;167226:163;167246:6;167242:1;:10;167226:163;;;167274:10;167287:35;167295:12;167320:1;167309:8;:12;;;;:::i;:::-;167287:7;:35::i;:::-;167274:48;;167346:2;167337:3;167341:1;167337:6;;;;;;;;:::i;:::-;;;;;;;:11;;;::::0;::::2;167376:1;167363:7;167371:1;167363:10;;;;;;;;:::i;:::-;;;;;;;:14;;;::::0;::::2;167259:130;167254:3;;;;;;;167226:163;;;;167439:6;167428:8;:17;;;;:::i;:::-;167399:12;:26;167412:12;167399:26;;;;;;;;;;;:46;;;;167458:34;167469:2;167473:3;167478:7;167487:4;167458:10;:34::i;:::-;167510:9;167505:112;167525:6;167521:1;:10;167505:112;;;167595:1;167584:8;:12;;;;:::i;:::-;167570;167558:47;167598:3;167602:1;167598:6;;;;;;;;:::i;:::-;;;;;;;;167558:47;;;;;;:::i;:::-;;;;;;;;167533:3;;;;;;;167505:112;;;;166962:662;;8755:1:::1;166714:910:::0;;;;;;;:::o;164747:127::-;164813:7;164840:12;:26;164853:12;164840:26;;;;;;;;;;;;164833:33;;164747:127;;;:::o;158222:62::-;158260:24;158222:62;:::o;10944:140::-;11019:18;11032:4;11019:12;:18::i;:::-;8728:16;8739:4;8728:10;:16::i;:::-;11050:26:::1;11062:4;11068:7;11050:11;:26::i;:::-;;10944:140:::0;;;:::o;159065:48::-;;;;;;;;;;;;;;;;;:::o;137565:159::-;137655:4;137679:18;:27;137698:7;137679:27;;;;;;;;;;;;;;;:37;137707:8;137679:37;;;;;;;;;;;;;;;;;;;;;;;;;137672:44;;137565:159;;;;:::o;137762:357::-;137886:14;137903:12;:10;:12::i;:::-;137886:29;;137938:6;137930:14;;:4;:14;;;;:49;;;;;137949:30;137966:4;137972:6;137949:16;:30::i;:::-;137948:31;137930:49;137926:131;;;138032:6;138040:4;138003:42;;;;;;;;;;;;:::i;:::-;;;;;;;;137926:131;138067:44;138085:4;138091:2;138095;138099:5;138106:4;138067:17;:44::i;:::-;137875:244;137762:357;;;;;:::o;149376:287::-;149475:12;:10;:12::i;:::-;149464:23;;:7;:23;;;;:67;;;;;149492:39;149509:7;149518:12;:10;:12::i;:::-;149492:16;:39::i;:::-;149491:40;149464:67;149460:158;;;149584:12;:10;:12::i;:::-;149598:7;149555:51;;;;;;;;;;;;:::i;:::-;;;;;;;;149460:158;149630:25;149636:7;149645:2;149649:5;149630;:25::i;:::-;149376:287;;;:::o;8801:204::-;8886:4;8925:32;8910:47;;;:11;:47;;;;:87;;;;8961:36;8985:11;8961:23;:36::i;:::-;8910:87;8903:94;;8801:204;;;:::o;9450:105::-;9517:30;9528:4;9534:12;:10;:12::i;:::-;9517:10;:30::i;:::-;9450:105;:::o;144597:88::-;144671:6;144664:4;:13;;;;;;:::i;:::-;;144597:88;:::o;136333:105::-;136393:13;136426:4;136419:11;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;136333:105;;;:::o;4169:98::-;4222:7;4249:10;4242:17;;4169:98;:::o;143295:459::-;143509:1;143495:16;;:2;:16;;;143491:90;;143566:1;143535:34;;;;;;;;;;;:::i;:::-;;;;;;;;143491:90;143611:1;143595:18;;:4;:18;;;143591:90;;143666:1;143637:32;;;;;;;;;;;:::i;:::-;;;;;;;;143591:90;143691:55;143718:4;143724:2;143728:3;143733:6;143741:4;143691:26;:55::i;:::-;143295:459;;;;;:::o;12527:324::-;12604:4;12626:22;12634:4;12640:7;12626;:22::i;:::-;12621:223;;12697:4;12665:6;:12;12672:4;12665:12;;;;;;;;;;;:20;;:29;12686:7;12665:29;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;12748:12;:10;:12::i;:::-;12721:40;;12739:7;12721:40;;12733:4;12721:40;;;;;;;;;;12783:4;12776:11;;;;12621:223;12827:5;12820:12;;12527:324;;;;;:::o;13097:325::-;13175:4;13196:22;13204:4;13210:7;13196;:22::i;:::-;13192:223;;;13267:5;13235:6;:12;13242:4;13235:12;;;;;;;;;;;:20;;:29;13256:7;13235:29;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;13319:12;:10;:12::i;:::-;13292:40;;13310:7;13292:40;;13304:4;13292:40;;;;;;;;;;13354:4;13347:11;;;;13192:223;13398:5;13391:12;;13097:325;;;;;:::o;152667:120::-;151630:16;:14;:16::i;:::-;152736:5:::1;152726:7;;:15;;;;;;;;;;;;;;;;;;152757:22;152766:12;:10;:12::i;:::-;152757:22;;;;;;:::i;:::-;;;;;;;;152667:120::o:0;130670:201::-;130756:11;130846:4;130841:3;130837:14;130830:4;130825:3;130821:14;130817:35;130811:42;130804:49;;130670:201;;;;:::o;131490:::-;131576:11;131666:4;131661:3;131657:14;131650:4;131645:3;131641:14;131637:35;131631:42;131624:49;;131490:201;;;;:::o;147170:270::-;147291:1;147275:18;;:4;:18;;;147271:90;;147346:1;147317:32;;;;;;;;;;;:::i;:::-;;;;;;;;147271:90;147371:61;147398:4;147412:1;147416:3;147421:6;147371:61;;;;;;;;;;;;:26;:61::i;:::-;147170:270;;;:::o;165095:284::-;165190:11;165204:13;:27;165218:12;165204:27;;;;;;;;;;;;165190:41;;165253:1;165246:3;:8;165242:21;;165256:7;;;165242:21;165340:3;165327:9;165294:16;:30;165311:12;165294:30;;;;;;;;;;;;:42;;;;:::i;:::-;:49;;165286:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;165179:200;165095:284;;;:::o;163926:147::-;164005:7;164058;158836:3;164033:12;:21;;164032:33;164025:40;;163926:147;;;;:::o;145076:352::-;145187:1;145173:16;;:2;:16;;;145169:90;;145244:1;145213:34;;;;;;;;;;;:::i;:::-;;;;;;;;145169:90;145270:20;145292:23;145319:29;145338:2;145342:5;145319:18;:29::i;:::-;145269:79;;;;145359:61;145394:1;145398:2;145402:3;145407:6;145415:4;145359:26;:61::i;:::-;145158:270;;145076:352;;;;:::o;152408:118::-;151371:19;:17;:19::i;:::-;152478:4:::1;152468:7;;:14;;;;;;;;;;;;;;;;;;152498:20;152505:12;:10;:12::i;:::-;152498:20;;;;;;:::i;:::-;;;;;;;;152408:118::o:0;147670:321::-;147798:1;147778:22;;:8;:22;;;147774:96;;147855:1;147824:34;;;;;;;;;;;:::i;:::-;;;;;;;;147774:96;147918:8;147880:18;:25;147899:5;147880:25;;;;;;;;;;;;;;;:35;147906:8;147880:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;147964:8;147942:41;;147957:5;147942:41;;;147974:8;147942:41;;;;;;:::i;:::-;;;;;;;;147670:321;;;:::o;145873:287::-;146009:1;145995:16;;:2;:16;;;145991:90;;146066:1;146035:34;;;;;;;;;;;:::i;:::-;;;;;;;;145991:90;146091:61;146126:1;146130:2;146134:3;146139:6;146147:4;146091:26;:61::i;:::-;145873:287;;;;:::o;142409:472::-;142546:1;142532:16;;:2;:16;;;142528:90;;142603:1;142572:34;;;;;;;;;;;:::i;:::-;;;;;;;;142528:90;142648:1;142632:18;;:4;:18;;;142628:90;;142703:1;142674:32;;;;;;;;;;;:::i;:::-;;;;;;;;142628:90;142729:20;142751:23;142778:29;142797:2;142801:5;142778:18;:29::i;:::-;142728:79;;;;142818:55;142845:4;142851:2;142855:3;142860:6;142868:4;142818:26;:55::i;:::-;142517:364;;142409:472;;;;;:::o;146466:335::-;146562:1;146546:18;;:4;:18;;;146542:90;;146617:1;146588:32;;;;;;;;;;;:::i;:::-;;;;;;;;146542:90;146643:20;146665:23;146692:29;146711:2;146715:5;146692:18;:29::i;:::-;146642:79;;;;146732:61;146759:4;146773:1;146777:3;146782:6;146732:61;;;;;;;;;;;;:26;:61::i;:::-;146531:270;;146466:335;;;:::o;135612:310::-;135714:4;135766:26;135751:41;;;:11;:41;;;;:110;;;;135824:37;135809:52;;;:11;:52;;;;135751:110;:163;;;;135878:36;135902:11;135878:23;:36::i;:::-;135751:163;135731:183;;135612:310;;;:::o;9691:201::-;9780:22;9788:4;9794:7;9780;:22::i;:::-;9775:110;;9859:7;9868:4;9826:47;;;;;;;;;;;;:::i;:::-;;;;;;;;9775:110;9691:201;;:::o;141220:718::-;141428:30;141436:4;141442:2;141446:3;141451:6;141428:7;:30::i;:::-;141487:1;141473:16;;:2;:16;;;141469:462;;141506:16;141525:12;:10;:12::i;:::-;141506:31;;141570:1;141556:3;:10;:15;141552:368;;141592:10;141605:25;141628:1;141605:3;:22;;:25;;;;:::i;:::-;141592:38;;141649:13;141665:28;141691:1;141665:6;:25;;:28;;;;:::i;:::-;141649:44;;141712:72;141748:8;141758:4;141764:2;141768;141772:5;141779:4;141712:35;:72::i;:::-;141573:227;;141552:368;;;141825:79;141866:8;141876:4;141882:2;141886:3;141891:6;141899:4;141825:40;:79::i;:::-;141552:368;141491:440;141469:462;141220:718;;;;;:::o;152134:130::-;152198:8;:6;:8::i;:::-;152193:64;;152230:15;;;;;;;;;;;;;;152193:64;152134:130::o;148112:842::-;148223:23;148248;148385:4;148379:11;148369:21;;148457:1;148449:6;148442:17;148597:8;148590:4;148582:6;148578:17;148571:35;148722:4;148714:6;148710:17;148700:27;;148756:1;148748:6;148741:17;148798:8;148791:4;148783:6;148779:17;148772:35;148930:4;148922:6;148918:17;148912:4;148905:31;148112:842;;;;;:::o;151925:132::-;151991:8;:6;:8::i;:::-;151987:63;;;152023:15;;;;;;;;;;;;;;151987:63;151925:132::o;6172:148::-;6248:4;6287:25;6272:40;;;:11;:40;;;;6265:47;;6172:148;;;:::o;168500:835::-;168809:1;168793:18;;:4;:18;;;:38;;;;168829:1;168815:16;;:2;:16;;;168793:38;168789:490;;;168853:9;168848:420;168868:3;:10;168864:1;:14;168848:420;;;168905:11;168922:16;168931:3;168935:1;168931:6;;;;;;;;:::i;:::-;;;;;;;;168922:8;:16::i;:::-;168904:34;;;168957:11;168971:6;168978:1;168971:9;;;;;;;;:::i;:::-;;;;;;;;168957:23;;169021:1;169005:18;;:4;:18;;;169001:252;;169102:3;169077:16;:21;169094:3;169077:21;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;;;;;169001:252;;;169149:1;169135:16;;:2;:16;;;169131:122;;169230:3;169205:16;:21;169222:3;169205:21;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;;;;;169131:122;169001:252;168885:383;;168880:3;;;;;;;168848:420;;;;168789:490;169291:36;169305:4;169311:2;169315:3;169320:6;169291:13;:36::i;:::-;168500:835;;;;:::o;29297:986::-;29521:1;29504:2;:14;;;:18;29500:776;;;29560:2;29543:38;;;29582:8;29592:4;29598:2;29602:5;29609:4;29543:71;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;29539:726;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29936:1;29919:6;:13;:18;29915:335;;30064:2;30026:41;;;;;;;;;;;:::i;:::-;;;;;;;;29915:335;30200:6;30194:13;30187:4;30179:6;30175:17;30168:40;29539:726;29676:43;;;29664:55;;;:8;:55;;;;29660:192;;29829:2;29791:41;;;;;;;;;;;:::i;:::-;;;;;;;;29660:192;29615:252;29500:776;29297:986;;;;;;:::o;30849:1055::-;31098:1;31081:2;:14;;;:18;31077:820;;;31137:2;31120:43;;;31164:8;31174:4;31180:3;31185:6;31193:4;31120:78;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;31116:770;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31557:1;31540:6;:13;:18;31536:335;;31685:2;31647:41;;;;;;;;;;;:::i;:::-;;;;;;;;31536:335;31821:6;31815:13;31808:4;31800:6;31796:17;31789:40;31116:770;31292:48;;;31280:60;;;:8;:60;;;;31276:197;;31450:2;31412:41;;;;;;;;;;;:::i;:::-;;;;;;;;31276:197;31199:289;31077:820;30849:1055;;;;;;:::o;155694:1631::-;155864:36;155878:4;155884:2;155888:3;155893:6;155864:13;:36::i;:::-;155933:1;155917:18;;:4;:18;;;155913:581;;155952:22;155977:1;155952:26;;155998:9;156010:1;155998:13;;155993:336;156017:3;:10;156013:1;:14;155993:336;;;156053:13;156069:28;156095:1;156069:6;:25;;:28;;;;:::i;:::-;156053:44;;156266:5;156223:12;:39;156236:25;156259:1;156236:3;:22;;:25;;;;:::i;:::-;156223:39;;;;;;;;;;;;:48;;;;;;;:::i;:::-;;;;;;;;156308:5;156290:23;;;;;:::i;:::-;;;156034:295;156029:3;;;;;155993:336;;;;156468:14;156449:15;;:33;;;;;;;:::i;:::-;;;;;;;;155937:557;155913:581;156524:1;156510:16;;:2;:16;;;156506:812;;156543:22;156568:1;156543:26;;156589:9;156601:1;156589:13;;156584:506;156608:3;:10;156604:1;:14;156584:506;;;156644:13;156660:28;156686:1;156660:6;:25;;:28;;;;:::i;:::-;156644:44;;156892:5;156849:12;:39;156862:25;156885:1;156862:3;:22;;:25;;;;:::i;:::-;156849:39;;;;;;;;;;;;:48;;;;;;;;;;;157050:5;157032:23;;;;156625:465;156620:3;;;;;156584:506;;;;157277:14;157258:15;;:33;;;;;;;;;;;156528:790;156506:812;155694:1631;;;;:::o;153908:228::-;151371:19;:17;:19::i;:::-;154092:36:::1;154106:4;154112:2;154116:3;154121:6;154092:13;:36::i;:::-;153908:228:::0;;;;:::o;139315:1315::-;139451:6;:13;139437:3;:10;:27;139433:119;;139514:3;:10;139526:6;:13;139488:52;;;;;;;;;;;;:::i;:::-;;;;;;;;139433:119;139564:16;139583:12;:10;:12::i;:::-;139564:31;;139613:9;139625:1;139613:13;;139608:709;139632:3;:10;139628:1;:14;139608:709;;;139664:10;139677:25;139700:1;139677:3;:22;;:25;;;;:::i;:::-;139664:38;;139717:13;139733:28;139759:1;139733:6;:25;;:28;;;;:::i;:::-;139717:44;;139798:1;139782:18;;:4;:18;;;139778:429;;139821:19;139843:9;:13;139853:2;139843:13;;;;;;;;;;;:19;139857:4;139843:19;;;;;;;;;;;;;;;;139821:41;;139899:5;139885:11;:19;139881:131;;;139963:4;139969:11;139982:5;139989:2;139936:56;;;;;;;;;;;;;;:::i;:::-;;;;;;;;139881:131;140167:5;140153:11;:19;140131:9;:13;140141:2;140131:13;;;;;;;;;;;:19;140145:4;140131:19;;;;;;;;;;;;;;;:41;;;;139802:405;139778:429;140241:1;140227:16;;:2;:16;;;140223:83;;140285:5;140264:9;:13;140274:2;140264:13;;;;;;;;;;;:17;140278:2;140264:17;;;;;;;;;;;;;;;;:26;;;;;;;:::i;:::-;;;;;;;;140223:83;139649:668;;139644:3;;;;;139608:709;;;;140347:1;140333:3;:10;:15;140329:294;;140365:10;140378:25;140401:1;140378:3;:22;;:25;;;;:::i;:::-;140365:38;;140418:13;140434:28;140460:1;140434:6;:25;;:28;;;;:::i;:::-;140418:44;;140513:2;140482:45;;140507:4;140482:45;;140497:8;140482:45;;;140517:2;140521:5;140482:45;;;;;;;:::i;:::-;;;;;;;;140350:189;;140329:294;;;140595:2;140565:46;;140589:4;140565:46;;140579:8;140565:46;;;140599:3;140604:6;140565:46;;;;;;;:::i;:::-;;;;;;;;140329:294;139422:1208;139315:1315;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:126;371:7;411:42;404:5;400:54;389:65;;334:126;;;:::o;466:96::-;503:7;532:24;550:5;532:24;:::i;:::-;521:35;;466:96;;;:::o;568:122::-;641:24;659:5;641:24;:::i;:::-;634:5;631:35;621:63;;680:1;677;670:12;621:63;568:122;:::o;696:139::-;742:5;780:6;767:20;758:29;;796:33;823:5;796:33;:::i;:::-;696:139;;;;:::o;841:77::-;878:7;907:5;896:16;;841:77;;;:::o;924:122::-;997:24;1015:5;997:24;:::i;:::-;990:5;987:35;977:63;;1036:1;1033;1026:12;977:63;924:122;:::o;1052:139::-;1098:5;1136:6;1123:20;1114:29;;1152:33;1179:5;1152:33;:::i;:::-;1052:139;;;;:::o;1197:474::-;1265:6;1273;1322:2;1310:9;1301:7;1297:23;1293:32;1290:119;;;1328:79;;:::i;:::-;1290:119;1448:1;1473:53;1518:7;1509:6;1498:9;1494:22;1473:53;:::i;:::-;1463:63;;1419:117;1575:2;1601:53;1646:7;1637:6;1626:9;1622:22;1601:53;:::i;:::-;1591:63;;1546:118;1197:474;;;;;:::o;1677:118::-;1764:24;1782:5;1764:24;:::i;:::-;1759:3;1752:37;1677:118;;:::o;1801:222::-;1894:4;1932:2;1921:9;1917:18;1909:26;;1945:71;2013:1;2002:9;1998:17;1989:6;1945:71;:::i;:::-;1801:222;;;;:::o;2029:149::-;2065:7;2105:66;2098:5;2094:78;2083:89;;2029:149;;;:::o;2184:120::-;2256:23;2273:5;2256:23;:::i;:::-;2249:5;2246:34;2236:62;;2294:1;2291;2284:12;2236:62;2184:120;:::o;2310:137::-;2355:5;2393:6;2380:20;2371:29;;2409:32;2435:5;2409:32;:::i;:::-;2310:137;;;;:::o;2453:327::-;2511:6;2560:2;2548:9;2539:7;2535:23;2531:32;2528:119;;;2566:79;;:::i;:::-;2528:119;2686:1;2711:52;2755:7;2746:6;2735:9;2731:22;2711:52;:::i;:::-;2701:62;;2657:116;2453:327;;;;:::o;2786:90::-;2820:7;2863:5;2856:13;2849:21;2838:32;;2786:90;;;:::o;2882:109::-;2963:21;2978:5;2963:21;:::i;:::-;2958:3;2951:34;2882:109;;:::o;2997:210::-;3084:4;3122:2;3111:9;3107:18;3099:26;;3135:65;3197:1;3186:9;3182:17;3173:6;3135:65;:::i;:::-;2997:210;;;;:::o;3213:117::-;3322:1;3319;3312:12;3336:117;3445:1;3442;3435:12;3459:102;3500:6;3551:2;3547:7;3542:2;3535:5;3531:14;3527:28;3517:38;;3459:102;;;:::o;3567:180::-;3615:77;3612:1;3605:88;3712:4;3709:1;3702:15;3736:4;3733:1;3726:15;3753:281;3836:27;3858:4;3836:27;:::i;:::-;3828:6;3824:40;3966:6;3954:10;3951:22;3930:18;3918:10;3915:34;3912:62;3909:88;;;3977:18;;:::i;:::-;3909:88;4017:10;4013:2;4006:22;3796:238;3753:281;;:::o;4040:129::-;4074:6;4101:20;;:::i;:::-;4091:30;;4130:33;4158:4;4150:6;4130:33;:::i;:::-;4040:129;;;:::o;4175:308::-;4237:4;4327:18;4319:6;4316:30;4313:56;;;4349:18;;:::i;:::-;4313:56;4387:29;4409:6;4387:29;:::i;:::-;4379:37;;4471:4;4465;4461:15;4453:23;;4175:308;;;:::o;4489:148::-;4587:6;4582:3;4577;4564:30;4628:1;4619:6;4614:3;4610:16;4603:27;4489:148;;;:::o;4643:425::-;4721:5;4746:66;4762:49;4804:6;4762:49;:::i;:::-;4746:66;:::i;:::-;4737:75;;4835:6;4828:5;4821:21;4873:4;4866:5;4862:16;4911:3;4902:6;4897:3;4893:16;4890:25;4887:112;;;4918:79;;:::i;:::-;4887:112;5008:54;5055:6;5050:3;5045;5008:54;:::i;:::-;4727:341;4643:425;;;;;:::o;5088:340::-;5144:5;5193:3;5186:4;5178:6;5174:17;5170:27;5160:122;;5201:79;;:::i;:::-;5160:122;5318:6;5305:20;5343:79;5418:3;5410:6;5403:4;5395:6;5391:17;5343:79;:::i;:::-;5334:88;;5150:278;5088:340;;;;:::o;5434:509::-;5503:6;5552:2;5540:9;5531:7;5527:23;5523:32;5520:119;;;5558:79;;:::i;:::-;5520:119;5706:1;5695:9;5691:17;5678:31;5736:18;5728:6;5725:30;5722:117;;;5758:79;;:::i;:::-;5722:117;5863:63;5918:7;5909:6;5898:9;5894:22;5863:63;:::i;:::-;5853:73;;5649:287;5434:509;;;;:::o;5949:329::-;6008:6;6057:2;6045:9;6036:7;6032:23;6028:32;6025:119;;;6063:79;;:::i;:::-;6025:119;6183:1;6208:53;6253:7;6244:6;6233:9;6229:22;6208:53;:::i;:::-;6198:63;;6154:117;5949:329;;;;:::o;6284:99::-;6336:6;6370:5;6364:12;6354:22;;6284:99;;;:::o;6389:169::-;6473:11;6507:6;6502:3;6495:19;6547:4;6542:3;6538:14;6523:29;;6389:169;;;;:::o;6564:139::-;6653:6;6648:3;6643;6637:23;6694:1;6685:6;6680:3;6676:16;6669:27;6564:139;;;:::o;6709:377::-;6797:3;6825:39;6858:5;6825:39;:::i;:::-;6880:71;6944:6;6939:3;6880:71;:::i;:::-;6873:78;;6960:65;7018:6;7013:3;7006:4;6999:5;6995:16;6960:65;:::i;:::-;7050:29;7072:6;7050:29;:::i;:::-;7045:3;7041:39;7034:46;;6801:285;6709:377;;;;:::o;7092:313::-;7205:4;7243:2;7232:9;7228:18;7220:26;;7292:9;7286:4;7282:20;7278:1;7267:9;7263:17;7256:47;7320:78;7393:4;7384:6;7320:78;:::i;:::-;7312:86;;7092:313;;;;:::o;7411:77::-;7448:7;7477:5;7466:16;;7411:77;;;:::o;7494:122::-;7567:24;7585:5;7567:24;:::i;:::-;7560:5;7557:35;7547:63;;7606:1;7603;7596:12;7547:63;7494:122;:::o;7622:139::-;7668:5;7706:6;7693:20;7684:29;;7722:33;7749:5;7722:33;:::i;:::-;7622:139;;;;:::o;7767:329::-;7826:6;7875:2;7863:9;7854:7;7850:23;7846:32;7843:119;;;7881:79;;:::i;:::-;7843:119;8001:1;8026:53;8071:7;8062:6;8051:9;8047:22;8026:53;:::i;:::-;8016:63;;7972:117;7767:329;;;;:::o;8102:118::-;8189:24;8207:5;8189:24;:::i;:::-;8184:3;8177:37;8102:118;;:::o;8226:222::-;8319:4;8357:2;8346:9;8342:18;8334:26;;8370:71;8438:1;8427:9;8423:17;8414:6;8370:71;:::i;:::-;8226:222;;;;:::o;8454:117::-;8563:1;8560;8553:12;8577:117;8686:1;8683;8676:12;8717:568;8790:8;8800:6;8850:3;8843:4;8835:6;8831:17;8827:27;8817:122;;8858:79;;:::i;:::-;8817:122;8971:6;8958:20;8948:30;;9001:18;8993:6;8990:30;8987:117;;;9023:79;;:::i;:::-;8987:117;9137:4;9129:6;9125:17;9113:29;;9191:3;9183:4;9175:6;9171:17;9161:8;9157:32;9154:41;9151:128;;;9198:79;;:::i;:::-;9151:128;8717:568;;;;;:::o;9291:934::-;9413:6;9421;9429;9437;9486:2;9474:9;9465:7;9461:23;9457:32;9454:119;;;9492:79;;:::i;:::-;9454:119;9640:1;9629:9;9625:17;9612:31;9670:18;9662:6;9659:30;9656:117;;;9692:79;;:::i;:::-;9656:117;9805:80;9877:7;9868:6;9857:9;9853:22;9805:80;:::i;:::-;9787:98;;;;9583:312;9962:2;9951:9;9947:18;9934:32;9993:18;9985:6;9982:30;9979:117;;;10015:79;;:::i;:::-;9979:117;10128:80;10200:7;10191:6;10180:9;10176:22;10128:80;:::i;:::-;10110:98;;;;9905:313;9291:934;;;;;;;:::o;10231:311::-;10308:4;10398:18;10390:6;10387:30;10384:56;;;10420:18;;:::i;:::-;10384:56;10470:4;10462:6;10458:17;10450:25;;10530:4;10524;10520:15;10512:23;;10231:311;;;:::o;10565:710::-;10661:5;10686:81;10702:64;10759:6;10702:64;:::i;:::-;10686:81;:::i;:::-;10677:90;;10787:5;10816:6;10809:5;10802:21;10850:4;10843:5;10839:16;10832:23;;10903:4;10895:6;10891:17;10883:6;10879:30;10932:3;10924:6;10921:15;10918:122;;;10951:79;;:::i;:::-;10918:122;11066:6;11049:220;11083:6;11078:3;11075:15;11049:220;;;11158:3;11187:37;11220:3;11208:10;11187:37;:::i;:::-;11182:3;11175:50;11254:4;11249:3;11245:14;11238:21;;11125:144;11109:4;11104:3;11100:14;11093:21;;11049:220;;;11053:21;10667:608;;10565:710;;;;;:::o;11298:370::-;11369:5;11418:3;11411:4;11403:6;11399:17;11395:27;11385:122;;11426:79;;:::i;:::-;11385:122;11543:6;11530:20;11568:94;11658:3;11650:6;11643:4;11635:6;11631:17;11568:94;:::i;:::-;11559:103;;11375:293;11298:370;;;;:::o;11674:307::-;11735:4;11825:18;11817:6;11814:30;11811:56;;;11847:18;;:::i;:::-;11811:56;11885:29;11907:6;11885:29;:::i;:::-;11877:37;;11969:4;11963;11959:15;11951:23;;11674:307;;;:::o;11987:423::-;12064:5;12089:65;12105:48;12146:6;12105:48;:::i;:::-;12089:65;:::i;:::-;12080:74;;12177:6;12170:5;12163:21;12215:4;12208:5;12204:16;12253:3;12244:6;12239:3;12235:16;12232:25;12229:112;;;12260:79;;:::i;:::-;12229:112;12350:54;12397:6;12392:3;12387;12350:54;:::i;:::-;12070:340;11987:423;;;;;:::o;12429:338::-;12484:5;12533:3;12526:4;12518:6;12514:17;12510:27;12500:122;;12541:79;;:::i;:::-;12500:122;12658:6;12645:20;12683:78;12757:3;12749:6;12742:4;12734:6;12730:17;12683:78;:::i;:::-;12674:87;;12490:277;12429:338;;;;:::o;12773:1509::-;12927:6;12935;12943;12951;12959;13008:3;12996:9;12987:7;12983:23;12979:33;12976:120;;;13015:79;;:::i;:::-;12976:120;13135:1;13160:53;13205:7;13196:6;13185:9;13181:22;13160:53;:::i;:::-;13150:63;;13106:117;13262:2;13288:53;13333:7;13324:6;13313:9;13309:22;13288:53;:::i;:::-;13278:63;;13233:118;13418:2;13407:9;13403:18;13390:32;13449:18;13441:6;13438:30;13435:117;;;13471:79;;:::i;:::-;13435:117;13576:78;13646:7;13637:6;13626:9;13622:22;13576:78;:::i;:::-;13566:88;;13361:303;13731:2;13720:9;13716:18;13703:32;13762:18;13754:6;13751:30;13748:117;;;13784:79;;:::i;:::-;13748:117;13889:78;13959:7;13950:6;13939:9;13935:22;13889:78;:::i;:::-;13879:88;;13674:303;14044:3;14033:9;14029:19;14016:33;14076:18;14068:6;14065:30;14062:117;;;14098:79;;:::i;:::-;14062:117;14203:62;14257:7;14248:6;14237:9;14233:22;14203:62;:::i;:::-;14193:72;;13987:288;12773:1509;;;;;;;;:::o;14288:474::-;14356:6;14364;14413:2;14401:9;14392:7;14388:23;14384:32;14381:119;;;14419:79;;:::i;:::-;14381:119;14539:1;14564:53;14609:7;14600:6;14589:9;14585:22;14564:53;:::i;:::-;14554:63;;14510:117;14666:2;14692:53;14737:7;14728:6;14717:9;14713:22;14692:53;:::i;:::-;14682:63;;14637:118;14288:474;;;;;:::o;14768:311::-;14845:4;14935:18;14927:6;14924:30;14921:56;;;14957:18;;:::i;:::-;14921:56;15007:4;14999:6;14995:17;14987:25;;15067:4;15061;15057:15;15049:23;;14768:311;;;:::o;15102:710::-;15198:5;15223:81;15239:64;15296:6;15239:64;:::i;:::-;15223:81;:::i;:::-;15214:90;;15324:5;15353:6;15346:5;15339:21;15387:4;15380:5;15376:16;15369:23;;15440:4;15432:6;15428:17;15420:6;15416:30;15469:3;15461:6;15458:15;15455:122;;;15488:79;;:::i;:::-;15455:122;15603:6;15586:220;15620:6;15615:3;15612:15;15586:220;;;15695:3;15724:37;15757:3;15745:10;15724:37;:::i;:::-;15719:3;15712:50;15791:4;15786:3;15782:14;15775:21;;15662:144;15646:4;15641:3;15637:14;15630:21;;15586:220;;;15590:21;15204:608;;15102:710;;;;;:::o;15835:370::-;15906:5;15955:3;15948:4;15940:6;15936:17;15932:27;15922:122;;15963:79;;:::i;:::-;15922:122;16080:6;16067:20;16105:94;16195:3;16187:6;16180:4;16172:6;16168:17;16105:94;:::i;:::-;16096:103;;15912:293;15835:370;;;;:::o;16211:894::-;16329:6;16337;16386:2;16374:9;16365:7;16361:23;16357:32;16354:119;;;16392:79;;:::i;:::-;16354:119;16540:1;16529:9;16525:17;16512:31;16570:18;16562:6;16559:30;16556:117;;;16592:79;;:::i;:::-;16556:117;16697:78;16767:7;16758:6;16747:9;16743:22;16697:78;:::i;:::-;16687:88;;16483:302;16852:2;16841:9;16837:18;16824:32;16883:18;16875:6;16872:30;16869:117;;;16905:79;;:::i;:::-;16869:117;17010:78;17080:7;17071:6;17060:9;17056:22;17010:78;:::i;:::-;17000:88;;16795:303;16211:894;;;;;:::o;17111:114::-;17178:6;17212:5;17206:12;17196:22;;17111:114;;;:::o;17231:184::-;17330:11;17364:6;17359:3;17352:19;17404:4;17399:3;17395:14;17380:29;;17231:184;;;;:::o;17421:132::-;17488:4;17511:3;17503:11;;17541:4;17536:3;17532:14;17524:22;;17421:132;;;:::o;17559:108::-;17636:24;17654:5;17636:24;:::i;:::-;17631:3;17624:37;17559:108;;:::o;17673:179::-;17742:10;17763:46;17805:3;17797:6;17763:46;:::i;:::-;17841:4;17836:3;17832:14;17818:28;;17673:179;;;;:::o;17858:113::-;17928:4;17960;17955:3;17951:14;17943:22;;17858:113;;;:::o;18007:732::-;18126:3;18155:54;18203:5;18155:54;:::i;:::-;18225:86;18304:6;18299:3;18225:86;:::i;:::-;18218:93;;18335:56;18385:5;18335:56;:::i;:::-;18414:7;18445:1;18430:284;18455:6;18452:1;18449:13;18430:284;;;18531:6;18525:13;18558:63;18617:3;18602:13;18558:63;:::i;:::-;18551:70;;18644:60;18697:6;18644:60;:::i;:::-;18634:70;;18490:224;18477:1;18474;18470:9;18465:14;;18430:284;;;18434:14;18730:3;18723:10;;18131:608;;;18007:732;;;;:::o;18745:373::-;18888:4;18926:2;18915:9;18911:18;18903:26;;18975:9;18969:4;18965:20;18961:1;18950:9;18946:17;18939:47;19003:108;19106:4;19097:6;19003:108;:::i;:::-;18995:116;;18745:373;;;;:::o;19124:1039::-;19251:6;19259;19267;19316:2;19304:9;19295:7;19291:23;19287:32;19284:119;;;19322:79;;:::i;:::-;19284:119;19442:1;19467:53;19512:7;19503:6;19492:9;19488:22;19467:53;:::i;:::-;19457:63;;19413:117;19597:2;19586:9;19582:18;19569:32;19628:18;19620:6;19617:30;19614:117;;;19650:79;;:::i;:::-;19614:117;19755:78;19825:7;19816:6;19805:9;19801:22;19755:78;:::i;:::-;19745:88;;19540:303;19910:2;19899:9;19895:18;19882:32;19941:18;19933:6;19930:30;19927:117;;;19963:79;;:::i;:::-;19927:117;20068:78;20138:7;20129:6;20118:9;20114:22;20068:78;:::i;:::-;20058:88;;19853:303;19124:1039;;;;;:::o;20169:797::-;20255:6;20263;20271;20320:2;20308:9;20299:7;20295:23;20291:32;20288:119;;;20326:79;;:::i;:::-;20288:119;20446:1;20471:53;20516:7;20507:6;20496:9;20492:22;20471:53;:::i;:::-;20461:63;;20417:117;20573:2;20599:53;20644:7;20635:6;20624:9;20620:22;20599:53;:::i;:::-;20589:63;;20544:118;20729:2;20718:9;20714:18;20701:32;20760:18;20752:6;20749:30;20746:117;;;20782:79;;:::i;:::-;20746:117;20887:62;20941:7;20932:6;20921:9;20917:22;20887:62;:::i;:::-;20877:72;;20672:287;20169:797;;;;;:::o;20986:553::-;21044:8;21054:6;21104:3;21097:4;21089:6;21085:17;21081:27;21071:122;;21112:79;;:::i;:::-;21071:122;21225:6;21212:20;21202:30;;21255:18;21247:6;21244:30;21241:117;;;21277:79;;:::i;:::-;21241:117;21391:4;21383:6;21379:17;21367:29;;21445:3;21437:4;21429:6;21425:17;21415:8;21411:32;21408:41;21405:128;;;21452:79;;:::i;:::-;21405:128;20986:553;;;;;:::o;21545:674::-;21625:6;21633;21641;21690:2;21678:9;21669:7;21665:23;21661:32;21658:119;;;21696:79;;:::i;:::-;21658:119;21816:1;21841:53;21886:7;21877:6;21866:9;21862:22;21841:53;:::i;:::-;21831:63;;21787:117;21971:2;21960:9;21956:18;21943:32;22002:18;21994:6;21991:30;21988:117;;;22024:79;;:::i;:::-;21988:117;22137:65;22194:7;22185:6;22174:9;22170:22;22137:65;:::i;:::-;22119:83;;;;21914:298;21545:674;;;;;:::o;22241:580::-;22326:8;22336:6;22386:3;22379:4;22371:6;22367:17;22363:27;22353:122;;22394:79;;:::i;:::-;22353:122;22507:6;22494:20;22484:30;;22537:18;22529:6;22526:30;22523:117;;;22559:79;;:::i;:::-;22523:117;22673:4;22665:6;22661:17;22649:29;;22727:3;22719:4;22711:6;22707:17;22697:8;22693:32;22690:41;22687:128;;;22734:79;;:::i;:::-;22687:128;22241:580;;;;;:::o;22827:958::-;22961:6;22969;22977;22985;23034:2;23022:9;23013:7;23009:23;23005:32;23002:119;;;23040:79;;:::i;:::-;23002:119;23188:1;23177:9;23173:17;23160:31;23218:18;23210:6;23207:30;23204:117;;;23240:79;;:::i;:::-;23204:117;23353:80;23425:7;23416:6;23405:9;23401:22;23353:80;:::i;:::-;23335:98;;;;23131:312;23510:2;23499:9;23495:18;23482:32;23541:18;23533:6;23530:30;23527:117;;;23563:79;;:::i;:::-;23527:117;23676:92;23760:7;23751:6;23740:9;23736:22;23676:92;:::i;:::-;23658:110;;;;23453:325;22827:958;;;;;;;:::o;23791:332::-;23912:4;23950:2;23939:9;23935:18;23927:26;;23963:71;24031:1;24020:9;24016:17;24007:6;23963:71;:::i;:::-;24044:72;24112:2;24101:9;24097:18;24088:6;24044:72;:::i;:::-;23791:332;;;;;:::o;24129:474::-;24197:6;24205;24254:2;24242:9;24233:7;24229:23;24225:32;24222:119;;;24260:79;;:::i;:::-;24222:119;24380:1;24405:53;24450:7;24441:6;24430:9;24426:22;24405:53;:::i;:::-;24395:63;;24351:117;24507:2;24533:53;24578:7;24569:6;24558:9;24554:22;24533:53;:::i;:::-;24523:63;;24478:118;24129:474;;;;;:::o;24609:116::-;24679:21;24694:5;24679:21;:::i;:::-;24672:5;24669:32;24659:60;;24715:1;24712;24705:12;24659:60;24609:116;:::o;24731:133::-;24774:5;24812:6;24799:20;24790:29;;24828:30;24852:5;24828:30;:::i;:::-;24731:133;;;;:::o;24870:468::-;24935:6;24943;24992:2;24980:9;24971:7;24967:23;24963:32;24960:119;;;24998:79;;:::i;:::-;24960:119;25118:1;25143:53;25188:7;25179:6;25168:9;25164:22;25143:53;:::i;:::-;25133:63;;25089:117;25245:2;25271:50;25313:7;25304:6;25293:9;25289:22;25271:50;:::i;:::-;25261:60;;25216:115;24870:468;;;;;:::o;25344:943::-;25439:6;25447;25455;25463;25512:3;25500:9;25491:7;25487:23;25483:33;25480:120;;;25519:79;;:::i;:::-;25480:120;25639:1;25664:53;25709:7;25700:6;25689:9;25685:22;25664:53;:::i;:::-;25654:63;;25610:117;25766:2;25792:53;25837:7;25828:6;25817:9;25813:22;25792:53;:::i;:::-;25782:63;;25737:118;25894:2;25920:53;25965:7;25956:6;25945:9;25941:22;25920:53;:::i;:::-;25910:63;;25865:118;26050:2;26039:9;26035:18;26022:32;26081:18;26073:6;26070:30;26067:117;;;26103:79;;:::i;:::-;26067:117;26208:62;26262:7;26253:6;26242:9;26238:22;26208:62;:::i;:::-;26198:72;;25993:287;25344:943;;;;;;;:::o;26293:474::-;26361:6;26369;26418:2;26406:9;26397:7;26393:23;26389:32;26386:119;;;26424:79;;:::i;:::-;26386:119;26544:1;26569:53;26614:7;26605:6;26594:9;26590:22;26569:53;:::i;:::-;26559:63;;26515:117;26671:2;26697:53;26742:7;26733:6;26722:9;26718:22;26697:53;:::i;:::-;26687:63;;26642:118;26293:474;;;;;:::o;26773:1089::-;26877:6;26885;26893;26901;26909;26958:3;26946:9;26937:7;26933:23;26929:33;26926:120;;;26965:79;;:::i;:::-;26926:120;27085:1;27110:53;27155:7;27146:6;27135:9;27131:22;27110:53;:::i;:::-;27100:63;;27056:117;27212:2;27238:53;27283:7;27274:6;27263:9;27259:22;27238:53;:::i;:::-;27228:63;;27183:118;27340:2;27366:53;27411:7;27402:6;27391:9;27387:22;27366:53;:::i;:::-;27356:63;;27311:118;27468:2;27494:53;27539:7;27530:6;27519:9;27515:22;27494:53;:::i;:::-;27484:63;;27439:118;27624:3;27613:9;27609:19;27596:33;27656:18;27648:6;27645:30;27642:117;;;27678:79;;:::i;:::-;27642:117;27783:62;27837:7;27828:6;27817:9;27813:22;27783:62;:::i;:::-;27773:72;;27567:288;26773:1089;;;;;;;;:::o;27868:619::-;27945:6;27953;27961;28010:2;27998:9;27989:7;27985:23;27981:32;27978:119;;;28016:79;;:::i;:::-;27978:119;28136:1;28161:53;28206:7;28197:6;28186:9;28182:22;28161:53;:::i;:::-;28151:63;;28107:117;28263:2;28289:53;28334:7;28325:6;28314:9;28310:22;28289:53;:::i;:::-;28279:63;;28234:118;28391:2;28417:53;28462:7;28453:6;28442:9;28438:22;28417:53;:::i;:::-;28407:63;;28362:118;27868:619;;;;;:::o;28493:180::-;28541:77;28538:1;28531:88;28638:4;28635:1;28628:15;28662:4;28659:1;28652:15;28679:320;28723:6;28760:1;28754:4;28750:12;28740:22;;28807:1;28801:4;28797:12;28828:18;28818:81;;28884:4;28876:6;28872:17;28862:27;;28818:81;28946:2;28938:6;28935:14;28915:18;28912:38;28909:84;;28965:18;;:::i;:::-;28909:84;28730:269;28679:320;;;:::o;29005:165::-;29145:17;29141:1;29133:6;29129:14;29122:41;29005:165;:::o;29176:366::-;29318:3;29339:67;29403:2;29398:3;29339:67;:::i;:::-;29332:74;;29415:93;29504:3;29415:93;:::i;:::-;29533:2;29528:3;29524:12;29517:19;;29176:366;;;:::o;29548:419::-;29714:4;29752:2;29741:9;29737:18;29729:26;;29801:9;29795:4;29791:20;29787:1;29776:9;29772:17;29765:47;29829:131;29955:4;29829:131;:::i;:::-;29821:139;;29548:419;;;:::o;29973:180::-;30021:77;30018:1;30011:88;30118:4;30115:1;30108:15;30142:4;30139:1;30132:15;30159:168;30299:20;30295:1;30287:6;30283:14;30276:44;30159:168;:::o;30333:366::-;30475:3;30496:67;30560:2;30555:3;30496:67;:::i;:::-;30489:74;;30572:93;30661:3;30572:93;:::i;:::-;30690:2;30685:3;30681:12;30674:19;;30333:366;;;:::o;30705:419::-;30871:4;30909:2;30898:9;30894:18;30886:26;;30958:9;30952:4;30948:20;30944:1;30933:9;30929:17;30922:47;30986:131;31112:4;30986:131;:::i;:::-;30978:139;;30705:419;;;:::o;31130:170::-;31270:22;31266:1;31258:6;31254:14;31247:46;31130:170;:::o;31306:366::-;31448:3;31469:67;31533:2;31528:3;31469:67;:::i;:::-;31462:74;;31545:93;31634:3;31545:93;:::i;:::-;31663:2;31658:3;31654:12;31647:19;;31306:366;;;:::o;31678:419::-;31844:4;31882:2;31871:9;31867:18;31859:26;;31931:9;31925:4;31921:20;31917:1;31906:9;31902:17;31895:47;31959:131;32085:4;31959:131;:::i;:::-;31951:139;;31678:419;;;:::o;32103:118::-;32190:24;32208:5;32190:24;:::i;:::-;32185:3;32178:37;32103:118;;:::o;32227:332::-;32348:4;32386:2;32375:9;32371:18;32363:26;;32399:71;32467:1;32456:9;32452:17;32443:6;32399:71;:::i;:::-;32480:72;32548:2;32537:9;32533:18;32524:6;32480:72;:::i;:::-;32227:332;;;;;:::o;32565:180::-;32613:77;32610:1;32603:88;32710:4;32707:1;32700:15;32734:4;32731:1;32724:15;32751:233;32790:3;32813:24;32831:5;32813:24;:::i;:::-;32804:33;;32859:66;32852:5;32849:77;32846:103;;32929:18;;:::i;:::-;32846:103;32976:1;32969:5;32965:13;32958:20;;32751:233;;;:::o;32990:97::-;33049:6;33077:3;33067:13;;32990:97;;;;:::o;33093:141::-;33142:4;33165:3;33157:11;;33188:3;33185:1;33178:14;33222:4;33219:1;33209:18;33201:26;;33093:141;;;:::o;33240:93::-;33277:6;33324:2;33319;33312:5;33308:14;33304:23;33294:33;;33240:93;;;:::o;33339:107::-;33383:8;33433:5;33427:4;33423:16;33402:37;;33339:107;;;;:::o;33452:393::-;33521:6;33571:1;33559:10;33555:18;33594:97;33624:66;33613:9;33594:97;:::i;:::-;33712:39;33742:8;33731:9;33712:39;:::i;:::-;33700:51;;33784:4;33780:9;33773:5;33769:21;33760:30;;33833:4;33823:8;33819:19;33812:5;33809:30;33799:40;;33528:317;;33452:393;;;;;:::o;33851:60::-;33879:3;33900:5;33893:12;;33851:60;;;:::o;33917:142::-;33967:9;34000:53;34018:34;34027:24;34045:5;34027:24;:::i;:::-;34018:34;:::i;:::-;34000:53;:::i;:::-;33987:66;;33917:142;;;:::o;34065:75::-;34108:3;34129:5;34122:12;;34065:75;;;:::o;34146:269::-;34256:39;34287:7;34256:39;:::i;:::-;34317:91;34366:41;34390:16;34366:41;:::i;:::-;34358:6;34351:4;34345:11;34317:91;:::i;:::-;34311:4;34304:105;34222:193;34146:269;;;:::o;34421:73::-;34466:3;34487:1;34480:8;;34421:73;:::o;34500:189::-;34577:32;;:::i;:::-;34618:65;34676:6;34668;34662:4;34618:65;:::i;:::-;34553:136;34500:189;;:::o;34695:186::-;34755:120;34772:3;34765:5;34762:14;34755:120;;;34826:39;34863:1;34856:5;34826:39;:::i;:::-;34799:1;34792:5;34788:13;34779:22;;34755:120;;;34695:186;;:::o;34887:543::-;34988:2;34983:3;34980:11;34977:446;;;35022:38;35054:5;35022:38;:::i;:::-;35106:29;35124:10;35106:29;:::i;:::-;35096:8;35092:44;35289:2;35277:10;35274:18;35271:49;;;35310:8;35295:23;;35271:49;35333:80;35389:22;35407:3;35389:22;:::i;:::-;35379:8;35375:37;35362:11;35333:80;:::i;:::-;34992:431;;34977:446;34887:543;;;:::o;35436:117::-;35490:8;35540:5;35534:4;35530:16;35509:37;;35436:117;;;;:::o;35559:169::-;35603:6;35636:51;35684:1;35680:6;35672:5;35669:1;35665:13;35636:51;:::i;:::-;35632:56;35717:4;35711;35707:15;35697:25;;35610:118;35559:169;;;;:::o;35733:295::-;35809:4;35955:29;35980:3;35974:4;35955:29;:::i;:::-;35947:37;;36017:3;36014:1;36010:11;36004:4;36001:21;35993:29;;35733:295;;;;:::o;36033:1403::-;36157:44;36197:3;36192;36157:44;:::i;:::-;36266:18;36258:6;36255:30;36252:56;;;36288:18;;:::i;:::-;36252:56;36332:38;36364:4;36358:11;36332:38;:::i;:::-;36417:67;36477:6;36469;36463:4;36417:67;:::i;:::-;36511:1;36540:2;36532:6;36529:14;36557:1;36552:632;;;;37228:1;37245:6;37242:84;;;37301:9;37296:3;37292:19;37279:33;37270:42;;37242:84;37352:67;37412:6;37405:5;37352:67;:::i;:::-;37346:4;37339:81;37201:229;36522:908;;36552:632;36604:4;36600:9;36592:6;36588:22;36638:37;36670:4;36638:37;:::i;:::-;36697:1;36711:215;36725:7;36722:1;36719:14;36711:215;;;36811:9;36806:3;36802:19;36789:33;36781:6;36774:49;36862:1;36854:6;36850:14;36840:24;;36909:2;36898:9;36894:18;36881:31;;36748:4;36745:1;36741:12;36736:17;;36711:215;;;36954:6;36945:7;36942:19;36939:186;;;37019:9;37014:3;37010:19;36997:33;37062:48;37104:4;37096:6;37092:17;37081:9;37062:48;:::i;:::-;37054:6;37047:64;36962:163;36939:186;37171:1;37167;37159:6;37155:14;37151:22;37145:4;37138:36;36559:625;;;36522:908;;36132:1304;;;36033:1403;;;:::o;37442:117::-;37551:1;37548;37541:12;37565:117;37674:1;37671;37664:12;37688:117;37797:1;37794;37787:12;37811:725;37889:4;37895:6;37951:11;37938:25;38051:1;38045:4;38041:12;38030:8;38014:14;38010:29;38006:48;37986:18;37982:73;37972:168;;38059:79;;:::i;:::-;37972:168;38171:18;38161:8;38157:33;38149:41;;38223:4;38210:18;38200:28;;38251:18;38243:6;38240:30;38237:117;;;38273:79;;:::i;:::-;38237:117;38381:2;38375:4;38371:13;38363:21;;38438:4;38430:6;38426:17;38410:14;38406:38;38400:4;38396:49;38393:136;;;38448:79;;:::i;:::-;38393:136;37902:634;37811:725;;;;;:::o;38542:194::-;38582:4;38602:20;38620:1;38602:20;:::i;:::-;38597:25;;38636:20;38654:1;38636:20;:::i;:::-;38631:25;;38680:1;38677;38673:9;38665:17;;38704:1;38698:4;38695:11;38692:37;;;38709:18;;:::i;:::-;38692:37;38542:194;;;;:::o;38742:160::-;38882:12;38878:1;38870:6;38866:14;38859:36;38742:160;:::o;38908:366::-;39050:3;39071:67;39135:2;39130:3;39071:67;:::i;:::-;39064:74;;39147:93;39236:3;39147:93;:::i;:::-;39265:2;39260:3;39256:12;39249:19;;38908:366;;;:::o;39280:419::-;39446:4;39484:2;39473:9;39469:18;39461:26;;39533:9;39527:4;39523:20;39519:1;39508:9;39504:17;39497:47;39561:131;39687:4;39561:131;:::i;:::-;39553:139;;39280:419;;;:::o;39705:191::-;39745:3;39764:20;39782:1;39764:20;:::i;:::-;39759:25;;39798:20;39816:1;39798:20;:::i;:::-;39793:25;;39841:1;39838;39834:9;39827:16;;39862:3;39859:1;39856:10;39853:36;;;39869:18;;:::i;:::-;39853:36;39705:191;;;;:::o;39902:1395::-;40019:37;40052:3;40019:37;:::i;:::-;40121:18;40113:6;40110:30;40107:56;;;40143:18;;:::i;:::-;40107:56;40187:38;40219:4;40213:11;40187:38;:::i;:::-;40272:67;40332:6;40324;40318:4;40272:67;:::i;:::-;40366:1;40390:4;40377:17;;40422:2;40414:6;40411:14;40439:1;40434:618;;;;41096:1;41113:6;41110:77;;;41162:9;41157:3;41153:19;41147:26;41138:35;;41110:77;41213:67;41273:6;41266:5;41213:67;:::i;:::-;41207:4;41200:81;41069:222;40404:887;;40434:618;40486:4;40482:9;40474:6;40470:22;40520:37;40552:4;40520:37;:::i;:::-;40579:1;40593:208;40607:7;40604:1;40601:14;40593:208;;;40686:9;40681:3;40677:19;40671:26;40663:6;40656:42;40737:1;40729:6;40725:14;40715:24;;40784:2;40773:9;40769:18;40756:31;;40630:4;40627:1;40623:12;40618:17;;40593:208;;;40829:6;40820:7;40817:19;40814:179;;;40887:9;40882:3;40878:19;40872:26;40930:48;40972:4;40964:6;40960:17;40949:9;40930:48;:::i;:::-;40922:6;40915:64;40837:156;40814:179;41039:1;41035;41027:6;41023:14;41019:22;41013:4;41006:36;40441:611;;;40404:887;;39994:1303;;;39902:1395;;:::o;41303:222::-;41396:4;41434:2;41423:9;41419:18;41411:26;;41447:71;41515:1;41504:9;41500:17;41491:6;41447:71;:::i;:::-;41303:222;;;;:::o;41531:173::-;41671:25;41667:1;41659:6;41655:14;41648:49;41531:173;:::o;41710:366::-;41852:3;41873:67;41937:2;41932:3;41873:67;:::i;:::-;41866:74;;41949:93;42038:3;41949:93;:::i;:::-;42067:2;42062:3;42058:12;42051:19;;41710:366;;;:::o;42082:419::-;42248:4;42286:2;42275:9;42271:18;42263:26;;42335:9;42329:4;42325:20;42321:1;42310:9;42306:17;42299:47;42363:131;42489:4;42363:131;:::i;:::-;42355:139;;42082:419;;;:::o;42507:332::-;42628:4;42666:2;42655:9;42651:18;42643:26;;42679:71;42747:1;42736:9;42732:17;42723:6;42679:71;:::i;:::-;42760:72;42828:2;42817:9;42813:18;42804:6;42760:72;:::i;:::-;42507:332;;;;;:::o;42845:98::-;42896:6;42930:5;42924:12;42914:22;;42845:98;;;:::o;42949:168::-;43032:11;43066:6;43061:3;43054:19;43106:4;43101:3;43097:14;43082:29;;42949:168;;;;:::o;43123:373::-;43209:3;43237:38;43269:5;43237:38;:::i;:::-;43291:70;43354:6;43349:3;43291:70;:::i;:::-;43284:77;;43370:65;43428:6;43423:3;43416:4;43409:5;43405:16;43370:65;:::i;:::-;43460:29;43482:6;43460:29;:::i;:::-;43455:3;43451:39;43444:46;;43213:283;43123:373;;;;:::o;43502:751::-;43725:4;43763:3;43752:9;43748:19;43740:27;;43777:71;43845:1;43834:9;43830:17;43821:6;43777:71;:::i;:::-;43858:72;43926:2;43915:9;43911:18;43902:6;43858:72;:::i;:::-;43940;44008:2;43997:9;43993:18;43984:6;43940:72;:::i;:::-;44022;44090:2;44079:9;44075:18;44066:6;44022:72;:::i;:::-;44142:9;44136:4;44132:20;44126:3;44115:9;44111:19;44104:49;44170:76;44241:4;44232:6;44170:76;:::i;:::-;44162:84;;43502:751;;;;;;;;:::o;44259:141::-;44315:5;44346:6;44340:13;44331:22;;44362:32;44388:5;44362:32;:::i;:::-;44259:141;;;;:::o;44406:349::-;44475:6;44524:2;44512:9;44503:7;44499:23;44495:32;44492:119;;;44530:79;;:::i;:::-;44492:119;44650:1;44675:63;44730:7;44721:6;44710:9;44706:22;44675:63;:::i;:::-;44665:73;;44621:127;44406:349;;;;:::o;44761:1053::-;45084:4;45122:3;45111:9;45107:19;45099:27;;45136:71;45204:1;45193:9;45189:17;45180:6;45136:71;:::i;:::-;45217:72;45285:2;45274:9;45270:18;45261:6;45217:72;:::i;:::-;45336:9;45330:4;45326:20;45321:2;45310:9;45306:18;45299:48;45364:108;45467:4;45458:6;45364:108;:::i;:::-;45356:116;;45519:9;45513:4;45509:20;45504:2;45493:9;45489:18;45482:48;45547:108;45650:4;45641:6;45547:108;:::i;:::-;45539:116;;45703:9;45697:4;45693:20;45687:3;45676:9;45672:19;45665:49;45731:76;45802:4;45793:6;45731:76;:::i;:::-;45723:84;;44761:1053;;;;;;;;:::o;45820:553::-;45997:4;46035:3;46024:9;46020:19;46012:27;;46049:71;46117:1;46106:9;46102:17;46093:6;46049:71;:::i;:::-;46130:72;46198:2;46187:9;46183:18;46174:6;46130:72;:::i;:::-;46212;46280:2;46269:9;46265:18;46256:6;46212:72;:::i;:::-;46294;46362:2;46351:9;46347:18;46338:6;46294:72;:::i;:::-;45820:553;;;;;;;:::o;46379:634::-;46600:4;46638:2;46627:9;46623:18;46615:26;;46687:9;46681:4;46677:20;46673:1;46662:9;46658:17;46651:47;46715:108;46818:4;46809:6;46715:108;:::i;:::-;46707:116;;46870:9;46864:4;46860:20;46855:2;46844:9;46840:18;46833:48;46898:108;47001:4;46992:6;46898:108;:::i;:::-;46890:116;;46379:634;;;;;:::o
Swarm Source
ipfs://a1c7fa091824256d3619d0815864392d017db5d89333b746fc0914b158536938
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.