ETH Price: $3,400.84 (+2.13%)

Token

ElmonXStore (ElmonXStore)
 

Overview

Max Total Supply

360 ElmonXStore

Holders

85

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
elmonx.eth
0x59de7273191e6bf1907d614e94ecfbe8e5fb7318
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
ElmonXStore

Compiler Version
v0.8.26+commit.8a97fa7a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2024-09-13
*/

// 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: @limitbreak/creator-token-standards/src/access/OwnablePermissions.sol


pragma solidity ^0.8.4;


abstract contract OwnablePermissions is Context {
    function _requireCallerIsContractOwner() internal view virtual;
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;


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

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

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

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

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

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

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

// File: @limitbreak/creator-token-standards/src/access/OwnableBasic.sol



pragma solidity ^0.8.4;



abstract contract OwnableBasic is OwnablePermissions, Ownable {
    function _requireCallerIsContractOwner() internal view virtual override {
        _checkOwner();
    }
}

// File: @limitbreak/creator-token-standards/src/utils/AutomaticValidatorTransferApproval.sol


pragma solidity ^0.8.4;


/**
 * @title AutomaticValidatorTransferApproval
 * @author Limit Break, Inc.
 * @notice Base contract mix-in that provides boilerplate code giving the contract owner the
 *         option to automatically approve a 721-C transfer validator implementation for transfers.
 */
abstract contract AutomaticValidatorTransferApproval is OwnablePermissions {

    /// @dev Emitted when the automatic approval flag is modified by the creator.
    event AutomaticApprovalOfTransferValidatorSet(bool autoApproved);

    /// @dev If true, the collection's transfer validator is automatically approved to transfer holder's tokens.
    bool public autoApproveTransfersFromValidator;

    /**
     * @notice Sets if the transfer validator is automatically approved as an operator for all token owners.
     * 
     * @dev    Throws when the caller is not the contract owner.
     * 
     * @param autoApprove If true, the collection's transfer validator will be automatically approved to
     *                    transfer holder's tokens.
     */
    function setAutomaticApprovalOfTransfersFromValidator(bool autoApprove) external {
        _requireCallerIsContractOwner();
        autoApproveTransfersFromValidator = autoApprove;
        emit AutomaticApprovalOfTransferValidatorSet(autoApprove);
    }
}
// File: @limitbreak/creator-token-standards/src/interfaces/ICreatorToken.sol


pragma solidity ^0.8.4;

interface ICreatorToken {
    event TransferValidatorUpdated(address oldValidator, address newValidator);
    function getTransferValidator() external view returns (address validator);
    function setTransferValidator(address validator) external;
    function getTransferValidationFunction() external view returns (bytes4 functionSignature, bool isViewFunction);
}
// File: @limitbreak/creator-token-standards/src/interfaces/ICreatorTokenLegacy.sol


pragma solidity ^0.8.4;

interface ICreatorTokenLegacy {
    event TransferValidatorUpdated(address oldValidator, address newValidator);
    function getTransferValidator() external view returns (address validator);
    function setTransferValidator(address validator) external;
}

// File: @limitbreak/creator-token-standards/src/interfaces/ITransferValidator.sol


pragma solidity ^0.8.4;

interface ITransferValidator {
    function applyCollectionTransferPolicy(address caller, address from, address to) external view;
    function validateTransfer(address caller, address from, address to) external view;
    function validateTransfer(address caller, address from, address to, uint256 tokenId) external view;
    function validateTransfer(address caller, address from, address to, uint256 tokenId, uint256 amount) external;

    function beforeAuthorizedTransfer(address operator, address token, uint256 tokenId) external;
    function afterAuthorizedTransfer(address token, uint256 tokenId) external;
    function beforeAuthorizedTransfer(address operator, address token) external;
    function afterAuthorizedTransfer(address token) external;
    function beforeAuthorizedTransfer(address token, uint256 tokenId) external;
    function beforeAuthorizedTransferWithAmount(address token, uint256 tokenId, uint256 amount) external;
    function afterAuthorizedTransferWithAmount(address token, uint256 tokenId) external;
}
// File: @limitbreak/creator-token-standards/src/utils/TransferValidation.sol


pragma solidity ^0.8.4;


/**
 * @title TransferValidation
 * @author Limit Break, Inc.
 * @notice A mix-in that can be combined with ERC-721 contracts to provide more granular hooks.
 * Openzeppelin's ERC721 contract only provides hooks for before and after transfer.  This allows
 * developers to validate or customize transfers within the context of a mint, a burn, or a transfer.
 */
abstract contract TransferValidation is Context {
    
    /// @dev Thrown when the from and to address are both the zero address.
    error ShouldNotMintToBurnAddress();

    /*************************************************************************/
    /*                      Transfers Without Amounts                        */
    /*************************************************************************/

    /// @dev Inheriting contracts should call this function in the _beforeTokenTransfer function to get more granular hooks.
    function _validateBeforeTransfer(address from, address to, uint256 tokenId) internal virtual {
        bool fromZeroAddress = from == address(0);
        bool toZeroAddress = to == address(0);

        if(fromZeroAddress && toZeroAddress) {
            revert ShouldNotMintToBurnAddress();
        } else if(fromZeroAddress) {
            _preValidateMint(_msgSender(), to, tokenId, msg.value);
        } else if(toZeroAddress) {
            _preValidateBurn(_msgSender(), from, tokenId, msg.value);
        } else {
            _preValidateTransfer(_msgSender(), from, to, tokenId, msg.value);
        }
    }

    /// @dev Inheriting contracts should call this function in the _afterTokenTransfer function to get more granular hooks.
    function _validateAfterTransfer(address from, address to, uint256 tokenId) internal virtual {
        bool fromZeroAddress = from == address(0);
        bool toZeroAddress = to == address(0);

        if(fromZeroAddress && toZeroAddress) {
            revert ShouldNotMintToBurnAddress();
        } else if(fromZeroAddress) {
            _postValidateMint(_msgSender(), to, tokenId, msg.value);
        } else if(toZeroAddress) {
            _postValidateBurn(_msgSender(), from, tokenId, msg.value);
        } else {
            _postValidateTransfer(_msgSender(), from, to, tokenId, msg.value);
        }
    }

    /// @dev Optional validation hook that fires before a mint
    function _preValidateMint(address caller, address to, uint256 tokenId, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires after a mint
    function _postValidateMint(address caller, address to, uint256 tokenId, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires before a burn
    function _preValidateBurn(address caller, address from, uint256 tokenId, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires after a burn
    function _postValidateBurn(address caller, address from, uint256 tokenId, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires before a transfer
    function _preValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires after a transfer
    function _postValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 value) internal virtual {}

    /*************************************************************************/
    /*                         Transfers With Amounts                        */
    /*************************************************************************/

    /// @dev Inheriting contracts should call this function in the _beforeTokenTransfer function to get more granular hooks.
    function _validateBeforeTransfer(address from, address to, uint256 tokenId, uint256 amount) internal virtual {
        bool fromZeroAddress = from == address(0);
        bool toZeroAddress = to == address(0);

        if(fromZeroAddress && toZeroAddress) {
            revert ShouldNotMintToBurnAddress();
        } else if(fromZeroAddress) {
            _preValidateMint(_msgSender(), to, tokenId, amount, msg.value);
        } else if(toZeroAddress) {
            _preValidateBurn(_msgSender(), from, tokenId, amount, msg.value);
        } else {
            _preValidateTransfer(_msgSender(), from, to, tokenId, amount, msg.value);
        }
    }

    /// @dev Inheriting contracts should call this function in the _afterTokenTransfer function to get more granular hooks.
    function _validateAfterTransfer(address from, address to, uint256 tokenId, uint256 amount) internal virtual {
        bool fromZeroAddress = from == address(0);
        bool toZeroAddress = to == address(0);

        if(fromZeroAddress && toZeroAddress) {
            revert ShouldNotMintToBurnAddress();
        } else if(fromZeroAddress) {
            _postValidateMint(_msgSender(), to, tokenId, amount, msg.value);
        } else if(toZeroAddress) {
            _postValidateBurn(_msgSender(), from, tokenId, amount, msg.value);
        } else {
            _postValidateTransfer(_msgSender(), from, to, tokenId, amount, msg.value);
        }
    }

    /// @dev Optional validation hook that fires before a mint
    function _preValidateMint(address caller, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires after a mint
    function _postValidateMint(address caller, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires before a burn
    function _preValidateBurn(address caller, address from, uint256 tokenId, uint256 amount, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires after a burn
    function _postValidateBurn(address caller, address from, uint256 tokenId, uint256 amount, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires before a transfer
    function _preValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires after a transfer
    function _postValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {}
}

// File: @limitbreak/creator-token-standards/src/interfaces/ITransferValidatorSetTokenType.sol


pragma solidity ^0.8.4;

interface ITransferValidatorSetTokenType {
    function setTokenTypeOfCollection(address collection, uint16 tokenType) external;
}
// File: @limitbreak/creator-token-standards/src/utils/CreatorTokenBase.sol


pragma solidity ^0.8.4;







/**
 * @title CreatorTokenBase
 * @author Limit Break, Inc.
 * @notice CreatorTokenBaseV3 is an abstract contract that provides basic functionality for managing token 
 * transfer policies through an implementation of ICreatorTokenTransferValidator/ICreatorTokenTransferValidatorV2/ICreatorTokenTransferValidatorV3. 
 * This contract is intended to be used as a base for creator-specific token contracts, enabling customizable transfer 
 * restrictions and security policies.
 *
 * <h4>Features:</h4>
 * <ul>Ownable: This contract can have an owner who can set and update the transfer validator.</ul>
 * <ul>TransferValidation: Implements the basic token transfer validation interface.</ul>
 *
 * <h4>Benefits:</h4>
 * <ul>Provides a flexible and modular way to implement custom token transfer restrictions and security policies.</ul>
 * <ul>Allows creators to enforce policies such as account and codehash blacklists, whitelists, and graylists.</ul>
 * <ul>Can be easily integrated into other token contracts as a base contract.</ul>
 *
 * <h4>Intended Usage:</h4>
 * <ul>Use as a base contract for creator token implementations that require advanced transfer restrictions and 
 *   security policies.</ul>
 * <ul>Set and update the ICreatorTokenTransferValidator implementation contract to enforce desired policies for the 
 *   creator token.</ul>
 *
 * <h4>Compatibility:</h4>
 * <ul>Backward and Forward Compatible - V1/V2/V3 Creator Token Base will work with V1/V2/V3 Transfer Validators.</ul>
 */
abstract contract CreatorTokenBase is OwnablePermissions, TransferValidation, ICreatorToken {

    /// @dev Thrown when setting a transfer validator address that has no deployed code.
    error CreatorTokenBase__InvalidTransferValidatorContract();

    /// @dev The default transfer validator that will be used if no transfer validator has been set by the creator.
    address public constant DEFAULT_TRANSFER_VALIDATOR = address(0x721C0078c2328597Ca70F5451ffF5A7B38D4E947);

    /// @dev Used to determine if the default transfer validator is applied.
    /// @dev Set to true when the creator sets a transfer validator address.
    bool private isValidatorInitialized;
    /// @dev Address of the transfer validator to apply to transactions.
    address private transferValidator;

    constructor() {
        _emitDefaultTransferValidator();
        _registerTokenType(DEFAULT_TRANSFER_VALIDATOR);
    }

    /**
     * @notice Sets the transfer validator for the token contract.
     *
     * @dev    Throws when provided validator contract is not the zero address and does not have code.
     * @dev    Throws when the caller is not the contract owner.
     *
     * @dev    <h4>Postconditions:</h4>
     *         1. The transferValidator address is updated.
     *         2. The `TransferValidatorUpdated` event is emitted.
     *
     * @param transferValidator_ The address of the transfer validator contract.
     */
    function setTransferValidator(address transferValidator_) public {
        _requireCallerIsContractOwner();

        bool isValidTransferValidator = transferValidator_.code.length > 0;

        if(transferValidator_ != address(0) && !isValidTransferValidator) {
            revert CreatorTokenBase__InvalidTransferValidatorContract();
        }

        emit TransferValidatorUpdated(address(getTransferValidator()), transferValidator_);

        isValidatorInitialized = true;
        transferValidator = transferValidator_;

        _registerTokenType(transferValidator_);
    }

    /**
     * @notice Returns the transfer validator contract address for this token contract.
     */
    function getTransferValidator() public view override returns (address validator) {
        validator = transferValidator;

        if (validator == address(0)) {
            if (!isValidatorInitialized) {
                validator = DEFAULT_TRANSFER_VALIDATOR;
            }
        }
    }

    /**
     * @dev Pre-validates a token transfer, reverting if the transfer is not allowed by this token's security policy.
     *      Inheriting contracts are responsible for overriding the _beforeTokenTransfer function, or its equivalent
     *      and calling _validateBeforeTransfer so that checks can be properly applied during token transfers.
     *
     * @dev Be aware that if the msg.sender is the transfer validator, the transfer is automatically permitted, as the
     *      transfer validator is expected to pre-validate the transfer.
     *
     * @dev Throws when the transfer doesn't comply with the collection's transfer policy, if the transferValidator is
     *      set to a non-zero address.
     *
     * @param caller  The address of the caller.
     * @param from    The address of the sender.
     * @param to      The address of the receiver.
     * @param tokenId The token id being transferred.
     */
    function _preValidateTransfer(
        address caller, 
        address from, 
        address to, 
        uint256 tokenId, 
        uint256 /*value*/) internal virtual override {
        address validator = getTransferValidator();

        if (validator != address(0)) {
            if (msg.sender == validator) {
                return;
            }

            ITransferValidator(validator).validateTransfer(caller, from, to, tokenId);
        }
    }

    /**
     * @dev Pre-validates a token transfer, reverting if the transfer is not allowed by this token's security policy.
     *      Inheriting contracts are responsible for overriding the _beforeTokenTransfer function, or its equivalent
     *      and calling _validateBeforeTransfer so that checks can be properly applied during token transfers.
     *
     * @dev Be aware that if the msg.sender is the transfer validator, the transfer is automatically permitted, as the
     *      transfer validator is expected to pre-validate the transfer.
     * 
     * @dev Used for ERC20 and ERC1155 token transfers which have an amount value to validate in the transfer validator.
     * @dev The `tokenId` for ERC20 tokens should be set to `0`.
     *
     * @dev Throws when the transfer doesn't comply with the collection's transfer policy, if the transferValidator is
     *      set to a non-zero address.
     *
     * @param caller  The address of the caller.
     * @param from    The address of the sender.
     * @param to      The address of the receiver.
     * @param tokenId The token id being transferred.
     * @param amount  The amount of token being transferred.
     */
    function _preValidateTransfer(
        address caller, 
        address from, 
        address to, 
        uint256 tokenId, 
        uint256 amount,
        uint256 /*value*/) internal virtual override {
        address validator = getTransferValidator();

        if (validator != address(0)) {
            if (msg.sender == validator) {
                return;
            }

            ITransferValidator(validator).validateTransfer(caller, from, to, tokenId, amount);
        }
    }

    function _tokenType() internal virtual pure returns(uint16);

    function _registerTokenType(address validator) internal {
        if (validator != address(0)) {
            uint256 validatorCodeSize;
            assembly {
                validatorCodeSize := extcodesize(validator)
            }
            if(validatorCodeSize > 0) {
                try ITransferValidatorSetTokenType(validator).setTokenTypeOfCollection(address(this), _tokenType()) {
                } catch { }
            }
        }
    }

    /**
     * @dev  Used during contract deployment for constructable and cloneable creator tokens
     * @dev  to emit the `TransferValidatorUpdated` event signaling the validator for the contract
     * @dev  is the default transfer validator.
     */
    function _emitDefaultTransferValidator() internal {
        emit TransferValidatorUpdated(address(0), DEFAULT_TRANSFER_VALIDATOR);
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

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

// File: @openzeppelin/contracts/token/ERC1155/IERC1155.sol


// OpenZeppelin Contracts (last updated v5.0.1) (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.20;


/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 */
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`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    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 caller.
     */
    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 {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 {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/IERC1155Receiver.sol


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/IERC1155Receiver.sol)

pragma solidity ^0.8.20;


/**
 * @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 ERC1155 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 ERC1155 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/token/ERC1155/extensions/IERC1155MetadataURI.sol


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/extensions/IERC1155MetadataURI.sol)

pragma solidity ^0.8.20;


/**
 * @dev Interface of the optional ERC1155MetadataExtension interface, as defined
 * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
 */
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/utils/introspection/ERC165.sol


// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)

pragma solidity ^0.8.20;


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

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


// OpenZeppelin Contracts (last updated v5.0.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 ERC1967 implementation slot:
 * ```solidity
 * contract ERC1967 {
 *     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;
 *     }
 * }
 * ```
 */
library StorageSlot {
    struct AddressSlot {
        address value;
    }

    struct BooleanSlot {
        bool value;
    }

    struct Bytes32Slot {
        bytes32 value;
    }

    struct Uint256Slot {
        uint256 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) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
     */
    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
     */
    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
     */
    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `StringSlot` with member `value` located at `slot`.
     */
    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            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) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := store.slot
        }
    }

    /**
     * @dev Returns an `BytesSlot` with member `value` located at `slot`.
     */
    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            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) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := store.slot
        }
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)

pragma solidity ^0.8.20;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Muldiv operation overflow.
     */
    error MathOverflowedMulDiv();

    enum Rounding {
        Floor, // Toward negative infinity
        Ceil, // Toward positive infinity
        Trunc, // Toward zero
        Expand // Away from zero
    }

    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

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

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

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

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds 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.
            return a / b;
        }

        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

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

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 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 prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            if (denominator <= prod1) {
                revert MathOverflowedMulDiv();
            }

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

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

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

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

            uint256 twos = denominator & (0 - denominator);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @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 + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @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 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 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 + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
        }
    }

    /**
     * @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.0.0) (utils/Arrays.sol)

pragma solidity ^0.8.20;



/**
 * @dev Collection of functions related to array types.
 */
library Arrays {
    using StorageSlot for bytes32;

    /**
     * @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).
     *
     * `array` is expected to be sorted in ascending order, and to contain no
     * repeated elements.
     */
    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 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;
        // We use assembly to calculate the storage slot of the element at index `pos` of the dynamic array `arr`
        // following https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays.

        /// @solidity memory-safe-assembly
        assembly {
            mstore(0, arr.slot)
            slot := add(keccak256(0, 0x20), pos)
        }
        return slot.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;
        // We use assembly to calculate the storage slot of the element at index `pos` of the dynamic array `arr`
        // following https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays.

        /// @solidity memory-safe-assembly
        assembly {
            mstore(0, arr.slot)
            slot := add(keccak256(0, 0x20), pos)
        }
        return slot.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;
        // We use assembly to calculate the storage slot of the element at index `pos` of the dynamic array `arr`
        // following https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays.

        /// @solidity memory-safe-assembly
        assembly {
            mstore(0, arr.slot)
            slot := add(keccak256(0, 0x20), pos)
        }
        return slot.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 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(address[] memory arr, uint256 pos) internal pure returns (address res) {
        assembly {
            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
        }
    }
}

// File: @openzeppelin/contracts/interfaces/draft-IERC6093.sol


// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;

/**
 * @dev Standard ERC20 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 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 ERC721 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.
 */
interface IERC721Errors {
    /**
     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-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 ERC1155 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 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/ERC1155.sol


// OpenZeppelin Contracts (last updated v5.0.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_);
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    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 EIP].
     *
     * 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;
    }

    /**
     * @dev See {IERC1155-balanceOf}.
     */
    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;
    }

    /**
     * @dev See {IERC1155-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

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

    /**
     * @dev See {IERC1155-safeTransferFrom}.
     */
    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);
    }

    /**
     * @dev See {IERC1155-safeBatchTransferFrom}.
     */
    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);
                _doSafeTransferAcceptanceCheck(operator, from, to, id, value, data);
            } else {
                _doSafeBatchTransferAcceptanceCheck(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 EIP].
     *
     * 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 Performs an acceptance check by calling {IERC1155-onERC1155Received} on the `to` address
     * if it contains code at the moment of execution.
     */
    function _doSafeTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256 value,
        bytes memory data
    ) private {
        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 ERC1155InvalidReceiver(to);
                }
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    // non-ERC1155Receiver implementer
                    revert ERC1155InvalidReceiver(to);
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        }
    }

    /**
     * @dev Performs a batch acceptance check by calling {IERC1155-onERC1155BatchReceived} on the `to` address
     * if it contains code at the moment of execution.
     */
    function _doSafeBatchTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory values,
        bytes memory data
    ) private {
        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 ERC1155InvalidReceiver(to);
                }
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    // non-ERC1155Receiver implementer
                    revert ERC1155InvalidReceiver(to);
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        }
    }

    /**
     * @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) {
        /// @solidity memory-safe-assembly
        assembly {
            // 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: @limitbreak/creator-token-standards/src/token/erc1155/ERC1155OpenZeppelin.sol



pragma solidity ^0.8.4;



abstract contract ERC1155OpenZeppelinBase is ERC1155 {

}

abstract contract ERC1155OpenZeppelin is ERC1155OpenZeppelinBase {
    constructor(string memory uri_) ERC1155(uri_) {}
}

abstract contract ERC1155OpenZeppelinInitializable is OwnablePermissions, ERC1155OpenZeppelinBase {

    error ERC1155OpenZeppelinInitializable__AlreadyInitializedERC1155();

    bool private _erc1155Initialized;

    function initializeERC1155(string memory uri_) public virtual {
        _requireCallerIsContractOwner();

        if(_erc1155Initialized) {
            revert ERC1155OpenZeppelinInitializable__AlreadyInitializedERC1155();
        }

        _erc1155Initialized = true;

        _setURI(uri_);
    }
}
// File: @limitbreak/permit-c/src/Constants.sol


pragma solidity ^0.8.4;

/// @dev Constant bytes32 value of 0x000...000
bytes32 constant ZERO_BYTES32 = bytes32(0);

/// @dev Constant value of 0
uint256 constant ZERO = 0;
/// @dev Constant value of 1
uint256 constant ONE = 1;

/// @dev Constant value representing an open order in storage
uint8 constant ORDER_STATE_OPEN = 0;
/// @dev Constant value representing a filled order in storage
uint8 constant ORDER_STATE_FILLED = 1;
/// @dev Constant value representing a cancelled order in storage
uint8 constant ORDER_STATE_CANCELLED = 2;

/// @dev Constant value representing the ERC721 token type for signatures and transfer hooks
uint256 constant TOKEN_TYPE_ERC721 = 721;
/// @dev Constant value representing the ERC1155 token type for signatures and transfer hooks
uint256 constant TOKEN_TYPE_ERC1155 = 1155;
/// @dev Constant value representing the ERC20 token type for signatures and transfer hooks
uint256 constant TOKEN_TYPE_ERC20 = 20;

/// @dev Constant value to mask the upper bits of a signature that uses a packed `vs` value to extract `s`
bytes32 constant UPPER_BIT_MASK = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;

/// @dev EIP-712 typehash used for validating signature based stored approvals
bytes32 constant UPDATE_APPROVAL_TYPEHASH =
    keccak256("UpdateApprovalBySignature(uint256 tokenType,address token,uint256 id,uint256 amount,uint256 nonce,address operator,uint256 approvalExpiration,uint256 sigDeadline,uint256 masterNonce)");

/// @dev EIP-712 typehash used for validating a single use permit without additional data
bytes32 constant SINGLE_USE_PERMIT_TYPEHASH =
    keccak256("PermitTransferFrom(uint256 tokenType,address token,uint256 id,uint256 amount,uint256 nonce,address operator,uint256 expiration,uint256 masterNonce)");

/// @dev EIP-712 typehash used for validating a single use permit with additional data
string constant SINGLE_USE_PERMIT_TRANSFER_ADVANCED_TYPEHASH_STUB =
    "PermitTransferFromWithAdditionalData(uint256 tokenType,address token,uint256 id,uint256 amount,uint256 nonce,address operator,uint256 expiration,uint256 masterNonce,";

/// @dev EIP-712 typehash used for validating an order permit that updates storage as it fills
string constant PERMIT_ORDER_ADVANCED_TYPEHASH_STUB =
    "PermitOrderWithAdditionalData(uint256 tokenType,address token,uint256 id,uint256 amount,uint256 salt,address operator,uint256 expiration,uint256 masterNonce,";

/// @dev Pausable flag for stored approval transfers of ERC721 assets
uint256 constant PAUSABLE_APPROVAL_TRANSFER_FROM_ERC721 = 1 << 0;
/// @dev Pausable flag for stored approval transfers of ERC1155 assets
uint256 constant PAUSABLE_APPROVAL_TRANSFER_FROM_ERC1155 = 1 << 1;
/// @dev Pausable flag for stored approval transfers of ERC20 assets
uint256 constant PAUSABLE_APPROVAL_TRANSFER_FROM_ERC20 = 1 << 2;

/// @dev Pausable flag for single use permit transfers of ERC721 assets
uint256 constant PAUSABLE_PERMITTED_TRANSFER_FROM_ERC721 = 1 << 3;
/// @dev Pausable flag for single use permit transfers of ERC1155 assets
uint256 constant PAUSABLE_PERMITTED_TRANSFER_FROM_ERC1155 = 1 << 4;
/// @dev Pausable flag for single use permit transfers of ERC20 assets
uint256 constant PAUSABLE_PERMITTED_TRANSFER_FROM_ERC20 = 1 << 5;

/// @dev Pausable flag for order fill transfers of ERC1155 assets
uint256 constant PAUSABLE_ORDER_TRANSFER_FROM_ERC1155 = 1 << 6;
/// @dev Pausable flag for order fill transfers of ERC20 assets
uint256 constant PAUSABLE_ORDER_TRANSFER_FROM_ERC20 = 1 << 7;
// File: @limitbreak/creator-token-standards/src/erc1155c/ERC1155C.sol


pragma solidity ^0.8.4;





/**
 * @title ERC1155C
 * @author Limit Break, Inc.
 * @notice Extends OpenZeppelin's ERC1155 implementation with Creator Token functionality, which
 *         allows the contract owner to update the transfer validation logic by managing a security policy in
 *         an external transfer validation security policy registry.  See {CreatorTokenTransferValidator}.
 */
abstract contract ERC1155C is ERC1155OpenZeppelin, CreatorTokenBase, AutomaticValidatorTransferApproval {
    
    /**
     * @notice Overrides behavior of isApprovedFor all such that if an operator is not explicitly approved
     *         for all, the contract owner can optionally auto-approve the 721-C transfer validator for transfers.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool isApproved) {
        isApproved = super.isApprovedForAll(owner, operator);

        if (!isApproved) {
            if (autoApproveTransfersFromValidator) {
                isApproved = operator == address(getTransferValidator());
            }
        }
    }

    /**
     * @notice Indicates whether the contract implements the specified interface.
     * @dev Overrides supportsInterface in ERC165.
     * @param interfaceId The interface id
     * @return true if the contract implements the specified interface, false otherwise
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return 
        interfaceId == type(ICreatorToken).interfaceId || 
        interfaceId == type(ICreatorTokenLegacy).interfaceId || 
        super.supportsInterface(interfaceId);
    }

    /**
     * @notice Returns the function selector for the transfer validator's validation function to be called 
     * @notice for transaction simulation. 
     */
    function getTransferValidationFunction() external pure returns (bytes4 functionSignature, bool isViewFunction) {
        functionSignature = bytes4(keccak256("validateTransfer(address,address,address,uint256,uint256)"));
        isViewFunction = false;
    }

    /// @dev Ties the open-zeppelin _beforeTokenTransfer hook to more granular transfer validation logic
    function _beforeTokenTransfer(
        address /*operator*/,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory /*data*/
    ) internal virtual {
        uint256 idsArrayLength = ids.length;
        for (uint256 i = 0; i < idsArrayLength;) {
            _validateBeforeTransfer(from, to, ids[i], amounts[i]);

            unchecked {
                ++i;
            }
        }
    }

    /// @dev Ties the open-zeppelin _afterTokenTransfer hook to more granular transfer validation logic
    function _afterTokenTransfer(
        address /*operator*/,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory /*data*/
    ) internal virtual {
        uint256 idsArrayLength = ids.length;
        for (uint256 i = 0; i < idsArrayLength;) {
            _validateAfterTransfer(from, to, ids[i], amounts[i]);

            unchecked {
                ++i;
            }
        }
    }

    function _tokenType() internal pure override returns(uint16) {
        return uint16(TOKEN_TYPE_ERC1155);
    }
}

/**
 * @title ERC1155CInitializable
 * @author Limit Break, Inc.
 * @notice Initializable implementation of ERC1155C to allow for EIP-1167 proxy clones.
 */
abstract contract ERC1155CInitializable is ERC1155OpenZeppelinInitializable, CreatorTokenBase, AutomaticValidatorTransferApproval {

    function initializeERC1155(string memory uri_) public override {
        super.initializeERC1155(uri_);

        _emitDefaultTransferValidator();
        _registerTokenType(getTransferValidator());
    }

    /**
     * @notice Overrides behavior of isApprovedFor all such that if an operator is not explicitly approved
     *         for all, the contract owner can optionally auto-approve the 721-C transfer validator for transfers.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool isApproved) {
        isApproved = super.isApprovedForAll(owner, operator);

        if (!isApproved) {
            if (autoApproveTransfersFromValidator) {
                isApproved = operator == address(getTransferValidator());
            }
        }
    }

    /**
     * @notice Indicates whether the contract implements the specified interface.
     * @dev Overrides supportsInterface in ERC165.
     * @param interfaceId The interface id
     * @return true if the contract implements the specified interface, false otherwise
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return 
        interfaceId == type(ICreatorToken).interfaceId || 
        interfaceId == type(ICreatorTokenLegacy).interfaceId || 
        super.supportsInterface(interfaceId);
    }

    /**
     * @notice Returns the function selector for the transfer validator's validation function to be called 
     * @notice for transaction simulation. 
     */
    function getTransferValidationFunction() external pure returns (bytes4 functionSignature, bool isViewFunction) {
        functionSignature = bytes4(keccak256("validateTransfer(address,address,address,uint256,uint256)"));
        isViewFunction = false;
    }

    /// @dev Ties the open-zeppelin _beforeTokenTransfer hook to more granular transfer validation logic
    function _beforeTokenTransfer(
        address /*operator*/,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory /*data*/
    ) internal virtual {
        uint256 idsArrayLength = ids.length;
        for (uint256 i = 0; i < idsArrayLength;) {
            _validateBeforeTransfer(from, to, ids[i], amounts[i]);

            unchecked {
                ++i;
            }
        }
    }

    /// @dev Ties the open-zeppelin _afterTokenTransfer hook to more granular transfer validation logic
    function _afterTokenTransfer(
        address /*operator*/,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory /*data*/
    ) internal virtual {
        uint256 idsArrayLength = ids.length;
        for (uint256 i = 0; i < idsArrayLength;) {
            _validateAfterTransfer(from, to, ids[i], amounts[i]);

            unchecked {
                ++i;
            }
        }
    }

    function _tokenType() internal pure override returns(uint16) {
        return uint16(TOKEN_TYPE_ERC1155);
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.20;


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

// File: @openzeppelin/contracts/token/common/ERC2981.sol


// OpenZeppelin Contracts (last updated v5.0.0) (token/common/ERC2981.sol)

pragma solidity ^0.8.20;



/**
 * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
 *
 * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
 * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
 *
 * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
 * fee is specified in basis points by default.
 *
 * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
 * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
 * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
 */
abstract contract ERC2981 is IERC2981, ERC165 {
    struct RoyaltyInfo {
        address receiver;
        uint96 royaltyFraction;
    }

    RoyaltyInfo private _defaultRoyaltyInfo;
    mapping(uint256 tokenId => RoyaltyInfo) private _tokenRoyaltyInfo;

    /**
     * @dev The default royalty set is invalid (eg. (numerator / denominator) >= 1).
     */
    error ERC2981InvalidDefaultRoyalty(uint256 numerator, uint256 denominator);

    /**
     * @dev The default royalty receiver is invalid.
     */
    error ERC2981InvalidDefaultRoyaltyReceiver(address receiver);

    /**
     * @dev The royalty set for an specific `tokenId` is invalid (eg. (numerator / denominator) >= 1).
     */
    error ERC2981InvalidTokenRoyalty(uint256 tokenId, uint256 numerator, uint256 denominator);

    /**
     * @dev The royalty receiver for `tokenId` is invalid.
     */
    error ERC2981InvalidTokenRoyaltyReceiver(uint256 tokenId, address receiver);

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

    /**
     * @inheritdoc IERC2981
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual returns (address, uint256) {
        RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId];

        if (royalty.receiver == address(0)) {
            royalty = _defaultRoyaltyInfo;
        }

        uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator();

        return (royalty.receiver, royaltyAmount);
    }

    /**
     * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
     * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
     * override.
     */
    function _feeDenominator() internal pure virtual returns (uint96) {
        return 10000;
    }

    /**
     * @dev Sets the royalty information that all ids in this contract will default to.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
        uint256 denominator = _feeDenominator();
        if (feeNumerator > denominator) {
            // Royalty fee will exceed the sale price
            revert ERC2981InvalidDefaultRoyalty(feeNumerator, denominator);
        }
        if (receiver == address(0)) {
            revert ERC2981InvalidDefaultRoyaltyReceiver(address(0));
        }

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Removes default royalty information.
     */
    function _deleteDefaultRoyalty() internal virtual {
        delete _defaultRoyaltyInfo;
    }

    /**
     * @dev Sets the royalty information for a specific token id, overriding the global default.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {
        uint256 denominator = _feeDenominator();
        if (feeNumerator > denominator) {
            // Royalty fee will exceed the sale price
            revert ERC2981InvalidTokenRoyalty(tokenId, feeNumerator, denominator);
        }
        if (receiver == address(0)) {
            revert ERC2981InvalidTokenRoyaltyReceiver(tokenId, address(0));
        }

        _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Resets royalty information for the token id back to the global default.
     */
    function _resetTokenRoyalty(uint256 tokenId) internal virtual {
        delete _tokenRoyaltyInfo[tokenId];
    }
}

// File: @limitbreak/creator-token-standards/src/programmable-royalties/BasicRoyalties.sol


pragma solidity ^0.8.4;


/**
 * @title BasicRoyaltiesBase
 * @author Limit Break, Inc.
 * @dev Base functionality of an NFT mix-in contract implementing the most basic form of programmable royalties.
 */
abstract contract BasicRoyaltiesBase is ERC2981 {

    event DefaultRoyaltySet(address indexed receiver, uint96 feeNumerator);
    event TokenRoyaltySet(uint256 indexed tokenId, address indexed receiver, uint96 feeNumerator);

    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual override {
        super._setDefaultRoyalty(receiver, feeNumerator);
        emit DefaultRoyaltySet(receiver, feeNumerator);
    }

    function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual override {
        super._setTokenRoyalty(tokenId, receiver, feeNumerator);
        emit TokenRoyaltySet(tokenId, receiver, feeNumerator);
    }
}

/**
 * @title BasicRoyalties
 * @author Limit Break, Inc.
 * @notice Constructable BasicRoyalties Contract implementation.
 */
abstract contract BasicRoyalties is BasicRoyaltiesBase {
    constructor(address receiver, uint96 feeNumerator) {
        _setDefaultRoyalty(receiver, feeNumerator);
    }
}

/**
 * @title BasicRoyaltiesInitializable
 * @author Limit Break, Inc.
 * @notice Initializable BasicRoyalties Contract implementation to allow for EIP-1167 clones. 
 */
abstract contract BasicRoyaltiesInitializable is BasicRoyaltiesBase {}
// File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol


// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.20;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The tree and the proofs can be generated using our
 * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
 * You will find a quickstart guide in the readme.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the Merkle tree could be reinterpreted as a leaf value.
 * OpenZeppelin's JavaScript library generates Merkle trees that are safe
 * against this attack out of the box.
 */
library MerkleProof {
    /**
     *@dev The multiproof provided is not valid.
     */
    error MerkleProofInvalidMultiproof();

    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Calldata version of {verify}
     */
    function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Calldata version of {processProof}
     */
    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.
     */
    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Calldata version of {multiProofVerify}
     *
     * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.
     */
    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
     * respectively.
     *
     * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the Merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 proofLen = proof.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        if (leavesLen + proofLen != totalHashes + 1) {
            revert MerkleProofInvalidMultiproof();
        }

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i]
                ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
                : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            if (proofPos != proofLen) {
                revert MerkleProofInvalidMultiproof();
            }
            unchecked {
                return hashes[totalHashes - 1];
            }
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}.
     *
     * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the Merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 proofLen = proof.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        if (leavesLen + proofLen != totalHashes + 1) {
            revert MerkleProofInvalidMultiproof();
        }

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i]
                ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
                : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            if (proofPos != proofLen) {
                revert MerkleProofInvalidMultiproof();
            }
            unchecked {
                return hashes[totalHashes - 1];
            }
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Sorts the pair (a, b) and hashes the result.
     */
    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    /**
     * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory.
     */
    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

// File: @openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol


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

pragma solidity ^0.8.0;

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

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

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

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

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

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

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // 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 prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Return the log in base 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 + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}

// File: @openzeppelin/contracts-upgradeable/utils/math/SignedMathUpgradeable.sol


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

pragma solidity ^0.8.0;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMathUpgradeable {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

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

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}

// File: @openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol


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

pragma solidity ^0.8.0;



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

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

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toString(int256 value) internal pure returns (string memory) {
        return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMathUpgradeable.abs(value))));
    }

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

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

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

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

// File: elmonxstore.sol


pragma solidity ^0.8.20;







abstract contract mytoken {
    function burn(
        address from,
        uint256 id,
        uint256 value
    ) external  {}

    function balanceOf(address account, uint256 id)
        external
        view
        returns (uint256) {}
}

error WithdrawFailed();
error TimeNotStarted();

contract ElmonXStore is ERC1155C, OwnableBasic, BasicRoyalties {

    event Minted(uint256 id, uint256 amount, address receiver);

    string public name = "ElmonXStore";
    string public symbol = "ElmonXStore";
    string baseURI;
    bytes32 public merkleRoot;

    struct idRecord {
        uint256 id;
        uint256 mintPrice;
        uint256 editions;
        uint256 minted;
        uint256 mintPerWallet;
        uint256 startTime;
        uint256 endTime;
        address fundReceiver;
        bool enableMint;
    }

    struct idType {
        address burningContract;
        bool isPublic;
        bool isWhiteList;
        bool craft;
        bool isLimited;
    }

    mapping(uint256 => idRecord) public idR;
    mapping(uint256 => idType) public idT;

    constructor(
        address royaltyReceiver_,
        uint96 royaltyFeeNumerator_,
        address initialOwner
    ) ERC1155OpenZeppelin("") Ownable(initialOwner) 
    BasicRoyalties(royaltyReceiver_, royaltyFeeNumerator_)
    {  }

    function setURI(string memory newuri) public onlyOwner {
        baseURI = newuri;
    }

    function setMerkleRoot(bytes32 _merkleRoot) external onlyOwner {
        merkleRoot = _merkleRoot;
    }

    function setConfigPublic(
        uint256[] memory _ids,
        uint256[] memory _mintPrices,
        uint256[] memory _editions,
        uint256[] memory _mintPerWallets,
        address[] memory _receiver,
        bool[] memory _enableMints
    ) external onlyOwner {
        require(
            _ids.length == _mintPrices.length &&
                _ids.length == _editions.length &&
                _ids.length == _mintPerWallets.length &&
                _ids.length == _enableMints.length &&
                _ids.length == _receiver.length,
            "Array lengths do not match"
        );

        for (uint256 i = 0; i < _ids.length; i++) {
            uint256 id = _ids[i];
            idR[id].id = id;
            idR[id].mintPrice = _mintPrices[i];
            idR[id].editions = _editions[i];
            idR[id].mintPerWallet = _mintPerWallets[i];
            idR[id].fundReceiver = _receiver[i];
            idR[id].enableMint = _enableMints[i];
            idT[id].isPublic = true;
        }
    }

    function setConfigLimitedEditions(
        uint256[] memory _ids,
        uint256[] memory _mintPrices,
        uint256[] memory _editions,
        uint256[] memory _mintPerWallets,
        uint256[] memory _startTimes,
        uint256[] memory _endTimes,
        bool[] memory _enableMints,
        address[] memory _receiver
    ) external onlyOwner {
        require(
            _ids.length == _mintPrices.length &&
                _ids.length == _editions.length &&
                _ids.length == _mintPerWallets.length &&
                _ids.length == _startTimes.length &&
                _ids.length == _endTimes.length &&
                _ids.length == _enableMints.length&&
                _ids.length == _receiver.length,
            "Array lengths do not match"
        );

        for (uint256 i = 0; i < _ids.length; i++) {
            uint256 id = _ids[i];
            idR[id].id = id;
            idR[id].mintPrice = _mintPrices[i];
            idR[id].editions = _editions[i];
            idR[id].mintPerWallet = _mintPerWallets[i];
            idR[id].startTime = _startTimes[i];
            idR[id].endTime = _endTimes[i];
            idR[id].enableMint = _enableMints[i];
            idR[id].fundReceiver = _receiver[i];
            idT[id].isLimited = true;
        }
    }

    function setConfigCraft(
        uint256[] memory _ids,
        uint256[] memory _mintPrices,
        uint256[] memory _editions,
        uint256[] memory _mintPerWallets,
        address[] memory _receiver,
        bool[] memory _enableMints,
        address[] memory burning
    ) external onlyOwner {
        require(
            _ids.length == _mintPrices.length &&
                _ids.length == _editions.length &&
                _ids.length == _mintPerWallets.length &&
                _ids.length == _enableMints.length&&
                _ids.length == _receiver.length,
            "Array lengths do not match"
        );

        for (uint256 i = 0; i < _ids.length; i++) {
            uint256 id = _ids[i];
            idR[id].id = id;
            idR[id].mintPrice = _mintPrices[i];
            idR[id].editions = _editions[i];
            idR[id].mintPerWallet = _mintPerWallets[i];
            idR[id].enableMint = _enableMints[i];
            idR[id].fundReceiver = _receiver[i];
            idT[id].craft = true;
            idT[id].burningContract = burning[i];
        }
    }

    function setConfigWhiteList(
        uint256[] memory _ids,
        uint256[] memory _mintPrices,
        uint256[] memory _editions,
        uint256[] memory _mintPerWallets,
        address[] memory _receiver,
        bool[] memory _enableMints
    ) external onlyOwner {
        require(
            _ids.length == _mintPrices.length &&
                _ids.length == _editions.length &&
                _ids.length == _mintPerWallets.length &&
                _ids.length == _enableMints.length&&
                _ids.length == _receiver.length,
            "Array lengths do not match"
        );

        for (uint256 i = 0; i < _ids.length; i++) {
            uint256 id = _ids[i];
            idR[id].id = id;
            idR[id].mintPrice = _mintPrices[i];
            idR[id].editions = _editions[i];
            idR[id].mintPerWallet = _mintPerWallets[i];
            idR[id].fundReceiver = _receiver[i];
            idR[id].enableMint = _enableMints[i];
            idT[id].isWhiteList = true;
        }
    }

    function reserve(
        address account,
        uint256[] memory ids,
        uint256[] memory amounts
    ) external onlyOwner {
        require(
            ids.length == amounts.length,
            "Please enter correct length and correct id"
        );
        for (uint256 i = 0; i < ids.length; i++) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];
            require(
                idR[id].minted + amount <= idR[id].editions,
                "Supply exceeds"
            );
            // Mint the tokens
            _mint(account, id, amount, "0x");

            // Update the minted count
            idR[id].minted += amount;

            emit Minted(id, amount, account);
        }
    }

    function publicMint(
        address account,
        uint256[] memory ids,
        uint256[] memory amounts
    ) external payable {
        require(
            ids.length == amounts.length,
            "Please enter correct length for ids and amounts"
        );
        uint256 totalCost;
        for (uint256 i = 0; i < ids.length; i++) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];
            require(
                idT[id].isPublic == true,
                "Not a Public Drop"
            );
            require(idR[id].enableMint == true, "Minting is not enabled yet");
            require(
                idR[id].minted + amounts[i] <= idR[id].editions,
                "Supply exceeds"
            );
            require(
            idR[id].mintPerWallet > 0 ?
            balanceOf(account, id) + amount <= idR[id].mintPerWallet :
            true,
            "minting limit exceed"
            );
            totalCost += idR[id].mintPrice * amount;
            require(msg.value >= totalCost, "Insufficient payment");
            payable(idR[id].fundReceiver).transfer(totalCost);

            _mint(account, id, amount, "0x");
            idR[id].minted += amount;

            emit Minted(id, amount, account);
        }
        if (msg.value > totalCost) {
            payable(msg.sender).transfer(msg.value - totalCost);
        }
    }

    function mintLimited(
        address account,
        uint256[] memory ids,
        uint256[] memory amounts
    ) external payable {
        require(
            ids.length == amounts.length,
            "Please enter correct length for ids and amounts"
        );
        uint256 totalCost;
        for (uint256 i = 0; i < ids.length; i++) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];
            require(
                idT[id].isLimited == true,
                "Not a Limited Drop"
            );
            require(idR[id].enableMint == true, "Minting is not enabled yet");
            require(
                idR[id].minted + amounts[i] <= idR[id].editions,
                "Supply exceeds"
            );
            require(
            idR[id].mintPerWallet > 0 ?
            balanceOf(account, id) + amount <= idR[id].mintPerWallet :
            true,
            "minting limit exceed"
            );
            if (idR[id].startTime > 0 && idR[id].endTime > 0) {
                require(
                    block.timestamp >= idR[id].startTime,
                    "Not Started yet"
                );
                require(
                    block.timestamp <= idR[id].endTime,
                    "minting time end"
                );
            }
            totalCost += idR[id].mintPrice * amount;
            require(msg.value >= totalCost, "Insufficient payment");
            payable(idR[id].fundReceiver).transfer(totalCost);

            _mint(account, id, amount, "0x");
            idR[id].minted += amount;
            emit Minted(id, amount, account);
        }
        if (msg.value > totalCost) {
            payable(msg.sender).transfer(msg.value - totalCost);
        }
    }

    function whiteListMint(
        address account,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes32[] memory merkleProof
    ) external payable {
        require(
            ids.length == amounts.length,
            "Please enter correct length for ids and amounts"
        );
        uint256 totalCost;
        for (uint256 i = 0; i < ids.length; i++) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];
            require(
                idT[id].isWhiteList == true,
                "Not Whitelist Drop"
            );
            require(idR[id].enableMint == true, "Minting is not enabled yet");
            require(
                idR[id].minted + amount <= idR[id].editions,
                "Supply exceeds"
            );
            bytes32 node = keccak256(abi.encodePacked(account));
            require(
                MerkleProof.verify(merkleProof, merkleRoot, node),
                "Invalid Whitelist Proof."
            );

            require(
            idR[id].mintPerWallet > 0 ?
            balanceOf(account, id) + amount <= idR[id].mintPerWallet :
            true,
            "minting limit exceed"
            );
            
            totalCost += idR[id].mintPrice * amount;
            require(msg.value >= totalCost, "Insufficient payment");
            payable(idR[id].fundReceiver).transfer(totalCost);

            _mint(account, id, amount, "0x");
            idR[id].minted += amount;
            emit Minted(id, amount, account);
        }
        if (msg.value > totalCost) {
            payable(msg.sender).transfer(msg.value - totalCost);
        }
    }

    function craftToken(uint256[] memory ids, uint256[] memory amounts) external payable{
        uint256 totalCost;
        require(
            ids.length == amounts.length,
            "Please enter correct length for ids and amounts"
        );
        for (uint256 i = 0; i < ids.length; ++i) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];
            require(
                    idT[id].craft == true,
                "Not Crafting Drop"
            );
            require(idR[id].enableMint == true, "Minting is not enabled yet");
            require(
                idR[id].minted + amount <= idR[id].editions,
                "Supply exceeds"
            );
            require(
            idR[id].mintPerWallet > 0 ?
            balanceOf(msg.sender, id) + amount <= idR[id].mintPerWallet :
            true,
            "minting limit exceed"
            );
            mytoken bContract = mytoken(idT[id].burningContract);
            require(
                bContract.balanceOf(msg.sender, id) > 0,
                "Doesn't own the token"
            ); // Check if the user own one of the ERC-1155
    
            totalCost += idR[id].mintPrice * amount;
            require(msg.value >= totalCost, "Insufficient payment");
            payable(idR[id].fundReceiver).transfer(totalCost);
            bContract.burn(msg.sender, id, amount); // Burn one the ERC-1155 token

            _mint(msg.sender, id, amount, "0x");

            emit Minted(id, amount, msg.sender);
        }
        if (msg.value > totalCost) {
            payable(msg.sender).transfer(msg.value - totalCost);
        }
    }

    function totalSupply(uint256 id) public view returns (uint256) {
        return idR[id].editions;
    }

    function totalMinted(uint256 _id) public view returns (uint256) {
        return idR[_id].minted;
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC1155C, ERC2981)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }

        function setDefaultRoyalty(address receiver, uint96 feeNumerator) public onlyOwner {
        _requireCallerIsContractOwner();
        _setDefaultRoyalty(receiver, feeNumerator);
    }

    function setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) public onlyOwner{
        _requireCallerIsContractOwner();
        _setTokenRoyalty(tokenId, receiver, feeNumerator);
    }

    function uri(uint256 _id) public view override returns (string memory) {
        return
            bytes(baseURI).length > 0
                ? string(
                    abi.encodePacked(baseURI, StringsUpgradeable.toString(_id))
                )
                : "";
    }

    function withdraw() external onlyOwner {
        (bool success, ) = payable(msg.sender).call{
            value: address(this).balance
        }("");
        if (!success) revert WithdrawFailed();
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"royaltyReceiver_","type":"address"},{"internalType":"uint96","name":"royaltyFeeNumerator_","type":"uint96"},{"internalType":"address","name":"initialOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CreatorTokenBase__InvalidTransferValidatorContract","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":[{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidDefaultRoyalty","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidDefaultRoyaltyReceiver","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidTokenRoyalty","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidTokenRoyaltyReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ShouldNotMintToBurnAddress","type":"error"},{"inputs":[],"name":"WithdrawFailed","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":"bool","name":"autoApproved","type":"bool"}],"name":"AutomaticApprovalOfTransferValidatorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"DefaultRoyaltySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"TokenRoyaltySet","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":false,"internalType":"address","name":"oldValidator","type":"address"},{"indexed":false,"internalType":"address","name":"newValidator","type":"address"}],"name":"TransferValidatorUpdated","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"},{"inputs":[],"name":"DEFAULT_TRANSFER_VALIDATOR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"autoApproveTransfersFromValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"craftToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"getTransferValidationFunction","outputs":[{"internalType":"bytes4","name":"functionSignature","type":"bytes4"},{"internalType":"bool","name":"isViewFunction","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getTransferValidator","outputs":[{"internalType":"address","name":"validator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"idR","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"mintPrice","type":"uint256"},{"internalType":"uint256","name":"editions","type":"uint256"},{"internalType":"uint256","name":"minted","type":"uint256"},{"internalType":"uint256","name":"mintPerWallet","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"address","name":"fundReceiver","type":"address"},{"internalType":"bool","name":"enableMint","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"idT","outputs":[{"internalType":"address","name":"burningContract","type":"address"},{"internalType":"bool","name":"isPublic","type":"bool"},{"internalType":"bool","name":"isWhiteList","type":"bool"},{"internalType":"bool","name":"craft","type":"bool"},{"internalType":"bool","name":"isLimited","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"isApproved","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"mintLimited","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"reserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"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":"bool","name":"autoApprove","type":"bool"}],"name":"setAutomaticApprovalOfTransfersFromValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_mintPrices","type":"uint256[]"},{"internalType":"uint256[]","name":"_editions","type":"uint256[]"},{"internalType":"uint256[]","name":"_mintPerWallets","type":"uint256[]"},{"internalType":"address[]","name":"_receiver","type":"address[]"},{"internalType":"bool[]","name":"_enableMints","type":"bool[]"},{"internalType":"address[]","name":"burning","type":"address[]"}],"name":"setConfigCraft","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_mintPrices","type":"uint256[]"},{"internalType":"uint256[]","name":"_editions","type":"uint256[]"},{"internalType":"uint256[]","name":"_mintPerWallets","type":"uint256[]"},{"internalType":"uint256[]","name":"_startTimes","type":"uint256[]"},{"internalType":"uint256[]","name":"_endTimes","type":"uint256[]"},{"internalType":"bool[]","name":"_enableMints","type":"bool[]"},{"internalType":"address[]","name":"_receiver","type":"address[]"}],"name":"setConfigLimitedEditions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_mintPrices","type":"uint256[]"},{"internalType":"uint256[]","name":"_editions","type":"uint256[]"},{"internalType":"uint256[]","name":"_mintPerWallets","type":"uint256[]"},{"internalType":"address[]","name":"_receiver","type":"address[]"},{"internalType":"bool[]","name":"_enableMints","type":"bool[]"}],"name":"setConfigPublic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_mintPrices","type":"uint256[]"},{"internalType":"uint256[]","name":"_editions","type":"uint256[]"},{"internalType":"uint256[]","name":"_mintPerWallets","type":"uint256[]"},{"internalType":"address[]","name":"_receiver","type":"address[]"},{"internalType":"bool[]","name":"_enableMints","type":"bool[]"}],"name":"setConfigWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setTokenRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"transferValidator_","type":"address"}],"name":"setTransferValidator","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":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"totalMinted","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":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"whiteListMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c0604052600b60809081526a456c6d6f6e5853746f726560a81b60a05260079061002a90826103d8565b5060408051808201909152600b81526a456c6d6f6e5853746f726560a81b602082015260089061005a90826103d8565b50348015610066575f80fd5b506040516147ca3803806147ca833981016040819052610085916104ad565b82828260405180602001604052805f815250806100a78161011b60201b60201c565b506100b2905061012b565b6100cf73721c0078c2328597ca70f5451fff5a7b38d4e947610179565b6001600160a01b0381166100fd57604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b610106816101f8565b506101118282610249565b50505050506104fb565b600261012782826103d8565b5050565b604080515f815273721c0078c2328597ca70f5451fff5a7b38d4e94760208201527fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac910160405180910390a1565b6001600160a01b038116156101f557803b8015610127576040805163fb2de5d760e01b8152306004820152610483602482015290516001600160a01b0384169163fb2de5d7916044808301925f92919082900301818387803b1580156101dd575f80fd5b505af19250505080156101ee575060015b1561012757505b50565b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b610253828261029e565b6040516001600160601b03821681526001600160a01b038316907f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef9060200160405180910390a25050565b6127106001600160601b0382168110156102dd57604051636f483d0960e01b81526001600160601b0383166004820152602481018290526044016100f4565b6001600160a01b03831661030657604051635b6cc80560e11b81525f60048201526024016100f4565b50604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600555565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061036857607f821691505b60208210810361038657634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156103d357805f5260205f20601f840160051c810160208510156103b15750805b601f840160051c820191505b818110156103d0575f81556001016103bd565b50505b505050565b81516001600160401b038111156103f1576103f1610340565b610405816103ff8454610354565b8461038c565b6020601f821160018114610437575f83156104205750848201515b5f19600385901b1c1916600184901b1784556103d0565b5f84815260208120601f198516915b828110156104665787850151825560209485019460019092019101610446565b508482101561048357868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b80516001600160a01b03811681146104a8575f80fd5b919050565b5f805f606084860312156104bf575f80fd5b6104c884610492565b60208501519093506001600160601b03811681146104e4575f80fd5b91506104f260408501610492565b90509250925092565b6142c2806105085f395ff3fe608060405260043610610227575f3560e01c80635944c75311610129578063a7c570a5116100a8578063ded0ec121161006d578063ded0ec12146107a0578063e985e9c5146107b3578063f242432a146107d2578063f2fde38b146107f1578063fb7b453914610810575f80fd5b8063a7c570a51461070e578063a9fc664e1461072d578063bd85b0391461074c578063c493c32c1461077a578063d753eeea1461078d575f80fd5b80638da5cb5b116100ee5780638da5cb5b1461067157806395d89b411461068e5780639d7f4ebf146106a25780639e05d240146106d0578063a22cb465146106ef575f80fd5b80635944c753146105ec5780636221d13c1461060b578063715018a61461062b5780637cb647591461063f578063862dadf41461065e575f80fd5b8063122d6a87116101b55780632eb4a7ab1161017a5780632eb4a7ab146105595780633ccfd60b1461056e5780634010ff55146105825780634e1273f4146105a15780634e8cdb7e146105cd575f80fd5b8063122d6a87146103855780631586db9b1461041d5780631e3f27da146104dd5780632a55205a146104fc5780632eb2c2d61461053a575f80fd5b806304634d8d116101fb57806304634d8d146102ec57806306fdde031461030b578063098144d41461032c5780630d705df6146103405780630e89341c14610366575f80fd5b8062fdd58e1461022b578063014635461461025d57806301ffc9a71461029c57806302fe5305146102cb575b5f80fd5b348015610236575f80fd5b5061024a6102453660046132c7565b61082f565b6040519081526020015b60405180910390f35b348015610268575f80fd5b5061028473721c0078c2328597ca70f5451fff5a7b38d4e94781565b6040516001600160a01b039091168152602001610254565b3480156102a7575f80fd5b506102bb6102b6366004613304565b610856565b6040519015158152602001610254565b3480156102d6575f80fd5b506102ea6102e53660046133bb565b610860565b005b3480156102f7575f80fd5b506102ea61030636600461341d565b610878565b348015610316575f80fd5b5061031f610892565b604051610254919061347c565b348015610337575f80fd5b5061028461091e565b34801561034b575f80fd5b5060408051631854b24160e01b81525f602082015201610254565b348015610371575f80fd5b5061031f61038036600461348e565b610958565b348015610390575f80fd5b506103e361039f36600461348e565b600c6020525f90815260409020546001600160a01b0381169060ff600160a01b8204811691600160a81b8104821691600160b01b8204811691600160b81b90041685565b604080516001600160a01b03909616865293151560208601529115159284019290925290151560608301521515608082015260a001610254565b348015610428575f80fd5b5061048e61043736600461348e565b600b6020525f9081526040902080546001820154600283015460038401546004850154600586015460068701546007909701549596949593949293919290916001600160a01b03811690600160a01b900460ff1689565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c08401526001600160a01b031660e0830152151561010082015261012001610254565b3480156104e8575f80fd5b506102ea6104f7366004613531565b6109b4565b348015610507575f80fd5b5061051b6105163660046135a3565b610b36565b604080516001600160a01b039093168352602083019190915201610254565b348015610545575f80fd5b506102ea6105543660046135e1565b610be0565b348015610564575f80fd5b5061024a600a5481565b348015610579575f80fd5b506102ea610c47565b34801561058d575f80fd5b506102ea61059c366004613760565b610cb8565b3480156105ac575f80fd5b506105c06105bb3660046138ba565b610f27565b6040516102549190613957565b3480156105d8575f80fd5b506102ea6105e7366004613969565b610ff1565b3480156105f7575f80fd5b506102ea610606366004613a6f565b6111de565b348015610616575f80fd5b506003546102bb90600160a81b900460ff1681565b348015610636575f80fd5b506102ea6111fe565b34801561064a575f80fd5b506102ea61065936600461348e565b611211565b6102ea61066c366004613531565b61121e565b34801561067c575f80fd5b506004546001600160a01b0316610284565b348015610699575f80fd5b5061031f61161b565b3480156106ad575f80fd5b5061024a6106bc36600461348e565b5f908152600b602052604090206003015490565b3480156106db575f80fd5b506102ea6106ea366004613aa8565b611628565b3480156106fa575f80fd5b506102ea610709366004613ac1565b611688565b348015610719575f80fd5b506102ea610728366004613ae9565b611693565b348015610738575f80fd5b506102ea610747366004613c19565b6118ce565b348015610757575f80fd5b5061024a61076636600461348e565b5f908152600b602052604090206002015490565b6102ea610788366004613c32565b611987565b6102ea61079b366004613531565b611d7d565b6102ea6107ae366004613c64565b61205e565b3480156107be575f80fd5b506102bb6107cd366004613d57565b6123e6565b3480156107dd575f80fd5b506102ea6107ec366004613d7f565b612449565b3480156107fc575f80fd5b506102ea61080b366004613c19565b6124a8565b34801561081b575f80fd5b506102ea61082a366004613969565b6124e2565b5f818152602081815260408083206001600160a01b03861684529091529020545b92915050565b5f610850826126cf565b6108686126f3565b60096108748282613e4e565b5050565b6108806126f3565b610888612720565b6108748282612728565b6007805461089f90613dd2565b80601f01602080910402602001604051908101604052809291908181526020018280546108cb90613dd2565b80156109165780601f106108ed57610100808354040283529160200191610916565b820191905f5260205f20905b8154815290600101906020018083116108f957829003601f168201915b505050505081565b60035461010090046001600160a01b0316806109555760035460ff16610955575073721c0078c2328597ca70f5451fff5a7b38d4e9475b90565b60605f6009805461096890613dd2565b9050116109835760405180602001604052805f815250610850565b600961098e8361277d565b60405160200161099f929190613f08565b60405160208183030381529060405292915050565b6109bc6126f3565b8051825114610a255760405162461bcd60e51b815260206004820152602a60248201527f506c6561736520656e74657220636f7272656374206c656e67746820616e642060448201526918dbdc9c9958dd081a5960b21b60648201526084015b60405180910390fd5b5f5b8251811015610b30575f838281518110610a4357610a43613f88565b602002602001015190505f838381518110610a6057610a60613f88565b6020908102919091018101515f848152600b9092526040909120600281015460039091015491925090610a94908390613fb0565b1115610ab25760405162461bcd60e51b8152600401610a1c90613fc3565b610ad886838360405180604001604052806002815260200161060f60f31b81525061280c565b5f828152600b602052604081206003018054839290610af8908490613fb0565b90915550506040515f8051602061426d83398151915290610b1e90849084908a90613feb565b60405180910390a15050600101610a27565b50505050565b5f8281526006602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610baa5750604080518082019091526005546001600160a01b0381168252600160a01b90046001600160601b031660208201525b60208101515f9061271090610bc8906001600160601b03168761400a565b610bd29190614021565b915196919550909350505050565b336001600160a01b0386168114801590610c015750610bff86826123e6565b155b15610c325760405163711bec9160e11b81526001600160a01b03808316600483015287166024820152604401610a1c565b610c3f8686868686612867565b505050505050565b610c4f6126f3565b6040515f90339047908381818185875af1925050503d805f8114610c8e576040519150601f19603f3d011682016040523d82523d5f602084013e610c93565b606091505b5050905080610cb557604051631d42c86760e21b815260040160405180910390fd5b50565b610cc06126f3565b86518851148015610cd2575085518851145b8015610cdf575084518851145b8015610cec575083518851145b8015610cf9575082518851145b8015610d06575081518851145b8015610d13575080518851145b610d2f5760405162461bcd60e51b8152600401610a1c90614040565b5f5b8851811015610f1c575f898281518110610d4d57610d4d613f88565b6020026020010151905080600b5f8381526020019081526020015f205f0181905550888281518110610d8157610d81613f88565b6020026020010151600b5f8381526020019081526020015f2060010181905550878281518110610db357610db3613f88565b6020026020010151600b5f8381526020019081526020015f2060020181905550868281518110610de557610de5613f88565b6020026020010151600b5f8381526020019081526020015f2060040181905550858281518110610e1757610e17613f88565b6020026020010151600b5f8381526020019081526020015f2060050181905550848281518110610e4957610e49613f88565b6020026020010151600b5f8381526020019081526020015f2060060181905550838281518110610e7b57610e7b613f88565b6020026020010151600b5f8381526020019081526020015f2060070160146101000a81548160ff021916908315150217905550828281518110610ec057610ec0613f88565b6020908102919091018101515f928352600b8252604080842060070180546001600160a01b039093166001600160a01b031990931692909217909155600c9091529020805460ff60b81b1916600160b81b179055600101610d31565b505050505050505050565b60608151835114610f585781518351604051635b05999160e01b815260048101929092526024820152604401610a1c565b5f83516001600160401b03811115610f7257610f7261331f565b604051908082528060200260200182016040528015610f9b578160200160208202803683370190505b5090505f5b8451811015610fe957602080820286010151610fc49060208084028701015161082f565b828281518110610fd657610fd6613f88565b6020908102919091010152600101610fa0565b509392505050565b610ff96126f3565b8451865114801561100b575083518651145b8015611018575082518651145b8015611025575080518651145b8015611032575081518651145b61104e5760405162461bcd60e51b8152600401610a1c90614040565b5f5b86518110156111d5575f87828151811061106c5761106c613f88565b6020026020010151905080600b5f8381526020019081526020015f205f01819055508682815181106110a0576110a0613f88565b6020026020010151600b5f8381526020019081526020015f20600101819055508582815181106110d2576110d2613f88565b6020026020010151600b5f8381526020019081526020015f206002018190555084828151811061110457611104613f88565b6020026020010151600b5f8381526020019081526020015f206004018190555083828151811061113657611136613f88565b6020026020010151600b5f8381526020019081526020015f206007015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555082828151811061118757611187613f88565b6020908102919091018101515f928352600b825260408084206007018054921515600160a01b90810260ff60a01b1994851617909155600c9093529092208054909216179055600101611050565b50505050505050565b6111e66126f3565b6111ee612720565b6111f98383836128c5565b505050565b6112066126f3565b61120f5f61291f565b565b6112196126f3565b600a55565b805182511461123f5760405162461bcd60e51b8152600401610a1c90614077565b5f805b83518110156115d8575f84828151811061125e5761125e613f88565b602002602001015190505f84838151811061127b5761127b613f88565b60200260200101519050600c5f8381526020019081526020015f205f0160179054906101000a900460ff16151560011515146112ee5760405162461bcd60e51b815260206004820152601260248201527104e6f742061204c696d697465642044726f760741b6044820152606401610a1c565b5f828152600b6020526040902060070154600160a01b900460ff16151560011461132a5760405162461bcd60e51b8152600401610a1c906140c6565b5f828152600b6020526040902060020154855186908590811061134f5761134f613f88565b6020026020010151600b5f8581526020019081526020015f20600301546113769190613fb0565b11156113945760405162461bcd60e51b8152600401610a1c90613fc3565b5f828152600b60205260409020600401546113b05760016113d9565b5f828152600b6020526040902060040154816113cc898561082f565b6113d69190613fb0565b11155b6113f55760405162461bcd60e51b8152600401610a1c906140fd565b5f828152600b60205260409020600501541580159061142357505f828152600b602052604090206006015415155b156114cd575f828152600b602052604090206005015442101561147a5760405162461bcd60e51b815260206004820152600f60248201526e139bdd0814dd185c9d1959081e595d608a1b6044820152606401610a1c565b5f828152600b60205260409020600601544211156114cd5760405162461bcd60e51b815260206004820152601060248201526f1b5a5b9d1a5b99c81d1a5b5948195b9960821b6044820152606401610a1c565b5f828152600b60205260409020600101546114e990829061400a565b6114f39085613fb0565b9350833410156115155760405162461bcd60e51b8152600401610a1c9061412b565b5f828152600b60205260408082206007015490516001600160a01b039091169186156108fc02918791818181858888f19350505050158015611559573d5f803e3d5ffd5b5061158087838360405180604001604052806002815260200161060f60f31b81525061280c565b5f828152600b6020526040812060030180548392906115a0908490613fb0565b90915550506040515f8051602061426d833981519152906115c690849084908b90613feb565b60405180910390a15050600101611242565b5080341115610b3057336108fc6115ef8334614159565b6040518115909202915f818181858888f19350505050158015611614573d5f803e3d5ffd5b5050505050565b6008805461089f90613dd2565b611630612720565b60038054821515600160a81b0260ff60a81b199091161790556040517f6787c7f9a80aa0f5ceddab2c54f1f5169c0b88e75dd5e19d5e858a64144c7dbc9061167d90831515815260200190565b60405180910390a150565b610874338383612970565b61169b6126f3565b855187511480156116ad575084518751145b80156116ba575083518751145b80156116c7575081518751145b80156116d4575082518751145b6116f05760405162461bcd60e51b8152600401610a1c90614040565b5f5b87518110156118c4575f88828151811061170e5761170e613f88565b6020026020010151905080600b5f8381526020019081526020015f205f018190555087828151811061174257611742613f88565b6020026020010151600b5f8381526020019081526020015f206001018190555086828151811061177457611774613f88565b6020026020010151600b5f8381526020019081526020015f20600201819055508582815181106117a6576117a6613f88565b6020026020010151600b5f8381526020019081526020015f20600401819055508382815181106117d8576117d8613f88565b6020026020010151600b5f8381526020019081526020015f2060070160146101000a81548160ff02191690831515021790555084828151811061181d5761181d613f88565b6020908102919091018101515f838152600b8352604080822060070180546001600160a01b039094166001600160a01b031990941693909317909255600c9092529020805460ff60b01b1916600160b01b179055825183908390811061188557611885613f88565b6020908102919091018101515f928352600c909152604090912080546001600160a01b0319166001600160a01b039092169190911790556001016116f2565b5050505050505050565b6118d6612720565b6001600160a01b038116803b151590158015906118f1575080155b1561190f576040516332483afb60e01b815260040160405180910390fd5b7fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac61193861091e565b604080516001600160a01b03928316815291851660208301520160405180910390a1600380546001600160a01b038416610100026001600160a81b0319909116176001179055610874826129fc565b5f81518351146119a95760405162461bcd60e51b8152600401610a1c90614077565b5f5b8351811015611d41575f8482815181106119c7576119c7613f88565b602002602001015190505f8483815181106119e4576119e4613f88565b60200260200101519050600c5f8381526020019081526020015f205f0160169054906101000a900460ff1615156001151514611a565760405162461bcd60e51b815260206004820152601160248201527004e6f74204372616674696e672044726f7607c1b6044820152606401610a1c565b5f828152600b6020526040902060070154600160a01b900460ff161515600114611a925760405162461bcd60e51b8152600401610a1c906140c6565b5f828152600b602052604090206002810154600390910154611ab5908390613fb0565b1115611ad35760405162461bcd60e51b8152600401610a1c90613fc3565b5f828152600b6020526040902060040154611aef576001611b18565b5f828152600b602052604090206004015481611b0b338561082f565b611b159190613fb0565b11155b611b345760405162461bcd60e51b8152600401610a1c906140fd565b5f828152600c6020526040808220549051627eeac760e11b8152336004820152602481018590526001600160a01b039091169190829062fdd58e90604401602060405180830381865afa158015611b8d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bb1919061416c565b11611bf65760405162461bcd60e51b81526020600482015260156024820152742237b2b9b713ba1037bbb7103a3432903a37b5b2b760591b6044820152606401610a1c565b5f838152600b6020526040902060010154611c1290839061400a565b611c1c9086613fb0565b945084341015611c3e5760405162461bcd60e51b8152600401610a1c9061412b565b5f838152600b60205260408082206007015490516001600160a01b039091169187156108fc02918891818181858888f19350505050158015611c82573d5f803e3d5ffd5b50604051637a94c56560e11b815233600482015260248101849052604481018390526001600160a01b0382169063f5298aca906064015f604051808303815f87803b158015611ccf575f80fd5b505af1158015611ce1573d5f803e3d5ffd5b50505050611d0b33848460405180604001604052806002815260200161060f60f31b81525061280c565b5f8051602061426d833981519152838333604051611d2b93929190613feb565b60405180910390a15050508060010190506119ab565b50803411156111f957336108fc611d588334614159565b6040518115909202915f818181858888f19350505050158015610b30573d5f803e3d5ffd5b8051825114611d9e5760405162461bcd60e51b8152600401610a1c90614077565b5f805b83518110156115d8575f848281518110611dbd57611dbd613f88565b602002602001015190505f848381518110611dda57611dda613f88565b60200260200101519050600c5f8381526020019081526020015f205f0160149054906101000a900460ff1615156001151514611e4c5760405162461bcd60e51b815260206004820152601160248201527004e6f742061205075626c69632044726f7607c1b6044820152606401610a1c565b5f828152600b6020526040902060070154600160a01b900460ff161515600114611e885760405162461bcd60e51b8152600401610a1c906140c6565b5f828152600b60205260409020600201548551869085908110611ead57611ead613f88565b6020026020010151600b5f8581526020019081526020015f2060030154611ed49190613fb0565b1115611ef25760405162461bcd60e51b8152600401610a1c90613fc3565b5f828152600b6020526040902060040154611f0e576001611f37565b5f828152600b602052604090206004015481611f2a898561082f565b611f349190613fb0565b11155b611f535760405162461bcd60e51b8152600401610a1c906140fd565b5f828152600b6020526040902060010154611f6f90829061400a565b611f799085613fb0565b935083341015611f9b5760405162461bcd60e51b8152600401610a1c9061412b565b5f828152600b60205260408082206007015490516001600160a01b039091169186156108fc02918791818181858888f19350505050158015611fdf573d5f803e3d5ffd5b5061200687838360405180604001604052806002815260200161060f60f31b81525061280c565b5f828152600b602052604081206003018054839290612026908490613fb0565b90915550506040515f8051602061426d8339815191529061204c90849084908b90613feb565b60405180910390a15050600101611da1565b815183511461207f5760405162461bcd60e51b8152600401610a1c90614077565b5f805b84518110156123aa575f85828151811061209e5761209e613f88565b602002602001015190505f8583815181106120bb576120bb613f88565b60200260200101519050600c5f8381526020019081526020015f205f0160159054906101000a900460ff161515600115151461212e5760405162461bcd60e51b815260206004820152601260248201527104e6f742057686974656c6973742044726f760741b6044820152606401610a1c565b5f828152600b6020526040902060070154600160a01b900460ff16151560011461216a5760405162461bcd60e51b8152600401610a1c906140c6565b5f828152600b60205260409020600281015460039091015461218d908390613fb0565b11156121ab5760405162461bcd60e51b8152600401610a1c90613fc3565b6040516bffffffffffffffffffffffff1960608a901b1660208201525f906034016040516020818303038152906040528051906020012090506121f186600a5483612a7a565b61223d5760405162461bcd60e51b815260206004820152601860248201527f496e76616c69642057686974656c6973742050726f6f662e00000000000000006044820152606401610a1c565b5f838152600b6020526040902060040154612259576001612282565b5f838152600b6020526040902060040154826122758b8661082f565b61227f9190613fb0565b11155b61229e5760405162461bcd60e51b8152600401610a1c906140fd565b5f838152600b60205260409020600101546122ba90839061400a565b6122c49086613fb0565b9450843410156122e65760405162461bcd60e51b8152600401610a1c9061412b565b5f838152600b60205260408082206007015490516001600160a01b039091169187156108fc02918891818181858888f1935050505015801561232a573d5f803e3d5ffd5b5061235189848460405180604001604052806002815260200161060f60f31b81525061280c565b5f838152600b602052604081206003018054849290612371908490613fb0565b90915550506040515f8051602061426d8339815191529061239790859085908d90613feb565b60405180910390a1505050600101612082565b508034111561161457336108fc6123c18334614159565b6040518115909202915f818181858888f19350505050158015610c3f573d5f803e3d5ffd5b6001600160a01b038281165f9081526001602090815260408083209385168352929052205460ff168061085057600354600160a81b900460ff16156108505761242d61091e565b6001600160a01b0316826001600160a01b031614905092915050565b336001600160a01b038616811480159061246a575061246886826123e6565b155b1561249b5760405163711bec9160e11b81526001600160a01b03808316600483015287166024820152604401610a1c565b610c3f8686868686612a8f565b6124b06126f3565b6001600160a01b0381166124d957604051631e4fbdf760e01b81525f6004820152602401610a1c565b610cb58161291f565b6124ea6126f3565b845186511480156124fc575083518651145b8015612509575082518651145b8015612516575080518651145b8015612523575081518651145b61253f5760405162461bcd60e51b8152600401610a1c90614040565b5f5b86518110156111d5575f87828151811061255d5761255d613f88565b6020026020010151905080600b5f8381526020019081526020015f205f018190555086828151811061259157612591613f88565b6020026020010151600b5f8381526020019081526020015f20600101819055508582815181106125c3576125c3613f88565b6020026020010151600b5f8381526020019081526020015f20600201819055508482815181106125f5576125f5613f88565b6020026020010151600b5f8381526020019081526020015f206004018190555083828151811061262757612627613f88565b6020026020010151600b5f8381526020019081526020015f206007015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555082828151811061267857612678613f88565b6020908102919091018101515f928352600b825260408084206007018054921515600160a01b0260ff60a01b1990931692909217909155600c9091529020805460ff60a81b1916600160a81b179055600101612541565b5f6001600160e01b0319821663152a902d60e11b1480610850575061085082612b12565b6004546001600160a01b0316331461120f5760405163118cdaa760e01b8152336004820152602401610a1c565b61120f6126f3565b6127328282612b51565b6040516001600160601b03821681526001600160a01b038316907f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef9060200160405180910390a25050565b60605f61278983612bf3565b60010190505f816001600160401b038111156127a7576127a761331f565b6040519080825280601f01601f1916602001820160405280156127d1576020820181803683370190505b5090508181016020015b5f19016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846127db57509392505050565b6001600160a01b03841661283557604051632bfa23e760e11b81525f6004820152602401610a1c565b60408051600180825260208201869052818301908152606082018590526080820190925290610c3f5f87848487612cca565b6001600160a01b03841661289057604051632bfa23e760e11b81525f6004820152602401610a1c565b6001600160a01b0385166128b857604051626a0d4560e21b81525f6004820152602401610a1c565b6116148585858585612cca565b6128d0838383612d1d565b6040516001600160601b03821681526001600160a01b0383169084907f7f5b076c952c0ec86e5425963c1326dd0f03a3595c19f81d765e8ff559a6e33c906020015b60405180910390a3505050565b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6001600160a01b0382166129985760405162ced3e160e81b81525f6004820152602401610a1c565b6001600160a01b038381165f81815260016020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319101612912565b6001600160a01b03811615610cb557803b8015610874576040805163fb2de5d760e01b8152306004820152610483602482015290516001600160a01b0384169163fb2de5d7916044808301925f92919082900301818387803b158015612a60575f80fd5b505af1925050508015612a71575060015b15610874575050565b5f82612a868584612ddd565b14949350505050565b6001600160a01b038416612ab857604051632bfa23e760e11b81525f6004820152602401610a1c565b6001600160a01b038516612ae057604051626a0d4560e21b81525f6004820152602401610a1c565b604080516001808252602082018690528183019081526060820185905260808201909252906111d58787848487612cca565b5f6001600160e01b03198216632b435fdb60e21b1480612b4257506001600160e01b0319821663503e914d60e11b145b80610850575061085082612e17565b6127106001600160601b038216811015612b9057604051636f483d0960e01b81526001600160601b038316600482015260248101829052604401610a1c565b6001600160a01b038316612bb957604051635b6cc80560e11b81525f6004820152602401610a1c565b50604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600555565b5f8072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310612c315772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310612c5d576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310612c7b57662386f26fc10000830492506010015b6305f5e1008310612c93576305f5e100830492506008015b6127108310612ca757612710830492506004015b60648310612cb9576064830492506002015b600a83106108505760010192915050565b612cd685858585612e66565b6001600160a01b038416156116145782513390600103612d0f5760208481015190840151612d08838989858589613075565b5050610c3f565b610c3f818787878787613196565b6127106001600160601b038216811015612d635760405163dfd1fc1b60e01b8152600481018590526001600160601b038316602482015260448101829052606401610a1c565b6001600160a01b038316612d9357604051634b4f842960e11b8152600481018590525f6024820152604401610a1c565b506040805180820182526001600160a01b0393841681526001600160601b0392831660208083019182525f968752600690529190942093519051909116600160a01b029116179055565b5f81815b8451811015610fe957612e0d82868381518110612e0057612e00613f88565b602002602001015161327d565b9150600101612de1565b5f6001600160e01b03198216636cdb3d1360e11b1480612e4757506001600160e01b031982166303a24d0760e21b145b8061085057506301ffc9a760e01b6001600160e01b0319831614610850565b8051825114612e955781518151604051635b05999160e01b815260048101929092526024820152604401610a1c565b335f5b8351811015612f97576020818102858101820151908501909101516001600160a01b03881615612f49575f828152602081815260408083206001600160a01b038c16845290915290205481811015612f23576040516303dee4c560e01b81526001600160a01b038a166004820152602481018290526044810183905260648101849052608401610a1c565b5f838152602081815260408083206001600160a01b038d16845290915290209082900390555b6001600160a01b03871615612f8d575f828152602081815260408083206001600160a01b038b16845290915281208054839290612f87908490613fb0565b90915550505b5050600101612e98565b5082516001036130175760208301515f906020840151909150856001600160a01b0316876001600160a01b0316846001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051613008929190918252602082015260400190565b60405180910390a45050611614565b836001600160a01b0316856001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051613066929190614183565b60405180910390a45050505050565b6001600160a01b0384163b15610c3f5760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906130b990899089908890889088906004016141b0565b6020604051808303815f875af19250505080156130f3575060408051601f3d908101601f191682019092526130f0918101906141f4565b60015b61315a573d808015613120576040519150601f19603f3d011682016040523d82523d5f602084013e613125565b606091505b5080515f0361315257604051632bfa23e760e11b81526001600160a01b0386166004820152602401610a1c565b805181602001fd5b6001600160e01b0319811663f23a6e6160e01b146111d557604051632bfa23e760e11b81526001600160a01b0386166004820152602401610a1c565b6001600160a01b0384163b15610c3f5760405163bc197c8160e01b81526001600160a01b0385169063bc197c81906131da908990899088908890889060040161420f565b6020604051808303815f875af1925050508015613214575060408051601f3d908101601f19168201909252613211918101906141f4565b60015b613241573d808015613120576040519150601f19603f3d011682016040523d82523d5f602084013e613125565b6001600160e01b0319811663bc197c8160e01b146111d557604051632bfa23e760e11b81526001600160a01b0386166004820152602401610a1c565b5f818310613297575f8281526020849052604090206132a5565b5f8381526020839052604090205b9392505050565b80356001600160a01b03811681146132c2575f80fd5b919050565b5f80604083850312156132d8575f80fd5b6132e1836132ac565b946020939093013593505050565b6001600160e01b031981168114610cb5575f80fd5b5f60208284031215613314575f80fd5b81356132a5816132ef565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561335b5761335b61331f565b604052919050565b5f806001600160401b0384111561337c5761337c61331f565b50601f8301601f191660200161339181613333565b9150508281528383830111156133a5575f80fd5b828260208301375f602084830101529392505050565b5f602082840312156133cb575f80fd5b81356001600160401b038111156133e0575f80fd5b8201601f810184136133f0575f80fd5b6133ff84823560208401613363565b949350505050565b80356001600160601b03811681146132c2575f80fd5b5f806040838503121561342e575f80fd5b613437836132ac565b915061344560208401613407565b90509250929050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6132a5602083018461344e565b5f6020828403121561349e575f80fd5b5035919050565b5f6001600160401b038211156134bd576134bd61331f565b5060051b60200190565b5f82601f8301126134d6575f80fd5b81356134e96134e4826134a5565b613333565b8082825260208201915060208360051b86010192508583111561350a575f80fd5b602085015b8381101561352757803583526020928301920161350f565b5095945050505050565b5f805f60608486031215613543575f80fd5b61354c846132ac565b925060208401356001600160401b03811115613566575f80fd5b613572868287016134c7565b92505060408401356001600160401b0381111561358d575f80fd5b613599868287016134c7565b9150509250925092565b5f80604083850312156135b4575f80fd5b50508035926020909101359150565b5f82601f8301126135d2575f80fd5b6132a583833560208501613363565b5f805f805f60a086880312156135f5575f80fd5b6135fe866132ac565b945061360c602087016132ac565b935060408601356001600160401b03811115613626575f80fd5b613632888289016134c7565b93505060608601356001600160401b0381111561364d575f80fd5b613659888289016134c7565b92505060808601356001600160401b03811115613674575f80fd5b613680888289016135c3565b9150509295509295909350565b803580151581146132c2575f80fd5b5f82601f8301126136ab575f80fd5b81356136b96134e4826134a5565b8082825260208201915060208360051b8601019250858311156136da575f80fd5b602085015b83811015613527576136f08161368d565b8352602092830192016136df565b5f82601f83011261370d575f80fd5b813561371b6134e4826134a5565b8082825260208201915060208360051b86010192508583111561373c575f80fd5b602085015b8381101561352757613752816132ac565b835260209283019201613741565b5f805f805f805f80610100898b031215613778575f80fd5b88356001600160401b0381111561378d575f80fd5b6137998b828c016134c7565b98505060208901356001600160401b038111156137b4575f80fd5b6137c08b828c016134c7565b97505060408901356001600160401b038111156137db575f80fd5b6137e78b828c016134c7565b96505060608901356001600160401b03811115613802575f80fd5b61380e8b828c016134c7565b95505060808901356001600160401b03811115613829575f80fd5b6138358b828c016134c7565b94505060a08901356001600160401b03811115613850575f80fd5b61385c8b828c016134c7565b93505060c08901356001600160401b03811115613877575f80fd5b6138838b828c0161369c565b92505060e08901356001600160401b0381111561389e575f80fd5b6138aa8b828c016136fe565b9150509295985092959890939650565b5f80604083850312156138cb575f80fd5b82356001600160401b038111156138e0575f80fd5b6138ec858286016136fe565b92505060208301356001600160401b03811115613907575f80fd5b613913858286016134c7565b9150509250929050565b5f8151808452602084019350602083015f5b8281101561394d57815186526020958601959091019060010161392f565b5093949350505050565b602081525f6132a5602083018461391d565b5f805f805f8060c0878903121561397e575f80fd5b86356001600160401b03811115613993575f80fd5b61399f89828a016134c7565b96505060208701356001600160401b038111156139ba575f80fd5b6139c689828a016134c7565b95505060408701356001600160401b038111156139e1575f80fd5b6139ed89828a016134c7565b94505060608701356001600160401b03811115613a08575f80fd5b613a1489828a016134c7565b93505060808701356001600160401b03811115613a2f575f80fd5b613a3b89828a016136fe565b92505060a08701356001600160401b03811115613a56575f80fd5b613a6289828a0161369c565b9150509295509295509295565b5f805f60608486031215613a81575f80fd5b83359250613a91602085016132ac565b9150613a9f60408501613407565b90509250925092565b5f60208284031215613ab8575f80fd5b6132a58261368d565b5f8060408385031215613ad2575f80fd5b613adb836132ac565b91506134456020840161368d565b5f805f805f805f60e0888a031215613aff575f80fd5b87356001600160401b03811115613b14575f80fd5b613b208a828b016134c7565b97505060208801356001600160401b03811115613b3b575f80fd5b613b478a828b016134c7565b96505060408801356001600160401b03811115613b62575f80fd5b613b6e8a828b016134c7565b95505060608801356001600160401b03811115613b89575f80fd5b613b958a828b016134c7565b94505060808801356001600160401b03811115613bb0575f80fd5b613bbc8a828b016136fe565b93505060a08801356001600160401b03811115613bd7575f80fd5b613be38a828b0161369c565b92505060c08801356001600160401b03811115613bfe575f80fd5b613c0a8a828b016136fe565b91505092959891949750929550565b5f60208284031215613c29575f80fd5b6132a5826132ac565b5f8060408385031215613c43575f80fd5b82356001600160401b03811115613c58575f80fd5b6138ec858286016134c7565b5f805f8060808587031215613c77575f80fd5b613c80856132ac565b935060208501356001600160401b03811115613c9a575f80fd5b613ca6878288016134c7565b93505060408501356001600160401b03811115613cc1575f80fd5b613ccd878288016134c7565b92505060608501356001600160401b03811115613ce8575f80fd5b8501601f81018713613cf8575f80fd5b8035613d066134e4826134a5565b8082825260208201915060208360051b850101925089831115613d27575f80fd5b6020840193505b82841015613d49578335825260209384019390910190613d2e565b969995985093965050505050565b5f8060408385031215613d68575f80fd5b613d71836132ac565b9150613445602084016132ac565b5f805f805f60a08688031215613d93575f80fd5b613d9c866132ac565b9450613daa602087016132ac565b9350604086013592506060860135915060808601356001600160401b03811115613674575f80fd5b600181811c90821680613de657607f821691505b602082108103613e0457634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156111f957805f5260205f20601f840160051c81016020851015613e2f5750805b601f840160051c820191505b81811015611614575f8155600101613e3b565b81516001600160401b03811115613e6757613e6761331f565b613e7b81613e758454613dd2565b84613e0a565b6020601f821160018114613ead575f8315613e965750848201515b5f19600385901b1c1916600184901b178455611614565b5f84815260208120601f198516915b82811015613edc5787850151825560209485019460019092019101613ebc565b5084821015613ef957868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f808454613f1581613dd2565b600182168015613f2c5760018114613f4157613f6e565b60ff1983168652811515820286019350613f6e565b875f5260205f205f5b83811015613f6657815488820152600190910190602001613f4a565b505081860193505b50505083518060208601835e5f9101908152949350505050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b8082018082111561085057610850613f9c565b6020808252600e908201526d537570706c79206578636565647360901b604082015260600190565b92835260208301919091526001600160a01b0316604082015260600190565b808202811582820484141761085057610850613f9c565b5f8261403b57634e487b7160e01b5f52601260045260245ffd5b500490565b6020808252601a908201527f4172726179206c656e6774687320646f206e6f74206d61746368000000000000604082015260600190565b6020808252602f908201527f506c6561736520656e74657220636f7272656374206c656e67746820666f722060408201526e69647320616e6420616d6f756e747360881b606082015260800190565b6020808252601a908201527f4d696e74696e67206973206e6f7420656e61626c656420796574000000000000604082015260600190565b6020808252601490820152731b5a5b9d1a5b99c81b1a5b5a5d08195e18d9595960621b604082015260600190565b602080825260149082015273125b9cdd59999a58da595b9d081c185e5b595b9d60621b604082015260600190565b8181038181111561085057610850613f9c565b5f6020828403121561417c575f80fd5b5051919050565b604081525f614195604083018561391d565b82810360208401526141a7818561391d565b95945050505050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190525f906141e99083018461344e565b979650505050505050565b5f60208284031215614204575f80fd5b81516132a5816132ef565b6001600160a01b0386811682528516602082015260a0604082018190525f9061423a9083018661391d565b828103606084015261424c818661391d565b90508281036080840152614260818561344e565b9897505050505050505056fe259eb7b480b3d449f506927269e4665c83c69e4cd797143eaa8f84632dc7a02ba26469706673582212202b0de0f737d4a3636f6fb2ae297126add522df40725116e61930f7d4fc030ccf64736f6c634300081a00330000000000000000000000002dcbc1e2dd803a6ea5a0995b2445e1d28e841b2200000000000000000000000000000000000000000000000000000000000001f400000000000000000000000059de7273191e6bf1907d614e94ecfbe8e5fb7318

Deployed Bytecode

0x608060405260043610610227575f3560e01c80635944c75311610129578063a7c570a5116100a8578063ded0ec121161006d578063ded0ec12146107a0578063e985e9c5146107b3578063f242432a146107d2578063f2fde38b146107f1578063fb7b453914610810575f80fd5b8063a7c570a51461070e578063a9fc664e1461072d578063bd85b0391461074c578063c493c32c1461077a578063d753eeea1461078d575f80fd5b80638da5cb5b116100ee5780638da5cb5b1461067157806395d89b411461068e5780639d7f4ebf146106a25780639e05d240146106d0578063a22cb465146106ef575f80fd5b80635944c753146105ec5780636221d13c1461060b578063715018a61461062b5780637cb647591461063f578063862dadf41461065e575f80fd5b8063122d6a87116101b55780632eb4a7ab1161017a5780632eb4a7ab146105595780633ccfd60b1461056e5780634010ff55146105825780634e1273f4146105a15780634e8cdb7e146105cd575f80fd5b8063122d6a87146103855780631586db9b1461041d5780631e3f27da146104dd5780632a55205a146104fc5780632eb2c2d61461053a575f80fd5b806304634d8d116101fb57806304634d8d146102ec57806306fdde031461030b578063098144d41461032c5780630d705df6146103405780630e89341c14610366575f80fd5b8062fdd58e1461022b578063014635461461025d57806301ffc9a71461029c57806302fe5305146102cb575b5f80fd5b348015610236575f80fd5b5061024a6102453660046132c7565b61082f565b6040519081526020015b60405180910390f35b348015610268575f80fd5b5061028473721c0078c2328597ca70f5451fff5a7b38d4e94781565b6040516001600160a01b039091168152602001610254565b3480156102a7575f80fd5b506102bb6102b6366004613304565b610856565b6040519015158152602001610254565b3480156102d6575f80fd5b506102ea6102e53660046133bb565b610860565b005b3480156102f7575f80fd5b506102ea61030636600461341d565b610878565b348015610316575f80fd5b5061031f610892565b604051610254919061347c565b348015610337575f80fd5b5061028461091e565b34801561034b575f80fd5b5060408051631854b24160e01b81525f602082015201610254565b348015610371575f80fd5b5061031f61038036600461348e565b610958565b348015610390575f80fd5b506103e361039f36600461348e565b600c6020525f90815260409020546001600160a01b0381169060ff600160a01b8204811691600160a81b8104821691600160b01b8204811691600160b81b90041685565b604080516001600160a01b03909616865293151560208601529115159284019290925290151560608301521515608082015260a001610254565b348015610428575f80fd5b5061048e61043736600461348e565b600b6020525f9081526040902080546001820154600283015460038401546004850154600586015460068701546007909701549596949593949293919290916001600160a01b03811690600160a01b900460ff1689565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c08401526001600160a01b031660e0830152151561010082015261012001610254565b3480156104e8575f80fd5b506102ea6104f7366004613531565b6109b4565b348015610507575f80fd5b5061051b6105163660046135a3565b610b36565b604080516001600160a01b039093168352602083019190915201610254565b348015610545575f80fd5b506102ea6105543660046135e1565b610be0565b348015610564575f80fd5b5061024a600a5481565b348015610579575f80fd5b506102ea610c47565b34801561058d575f80fd5b506102ea61059c366004613760565b610cb8565b3480156105ac575f80fd5b506105c06105bb3660046138ba565b610f27565b6040516102549190613957565b3480156105d8575f80fd5b506102ea6105e7366004613969565b610ff1565b3480156105f7575f80fd5b506102ea610606366004613a6f565b6111de565b348015610616575f80fd5b506003546102bb90600160a81b900460ff1681565b348015610636575f80fd5b506102ea6111fe565b34801561064a575f80fd5b506102ea61065936600461348e565b611211565b6102ea61066c366004613531565b61121e565b34801561067c575f80fd5b506004546001600160a01b0316610284565b348015610699575f80fd5b5061031f61161b565b3480156106ad575f80fd5b5061024a6106bc36600461348e565b5f908152600b602052604090206003015490565b3480156106db575f80fd5b506102ea6106ea366004613aa8565b611628565b3480156106fa575f80fd5b506102ea610709366004613ac1565b611688565b348015610719575f80fd5b506102ea610728366004613ae9565b611693565b348015610738575f80fd5b506102ea610747366004613c19565b6118ce565b348015610757575f80fd5b5061024a61076636600461348e565b5f908152600b602052604090206002015490565b6102ea610788366004613c32565b611987565b6102ea61079b366004613531565b611d7d565b6102ea6107ae366004613c64565b61205e565b3480156107be575f80fd5b506102bb6107cd366004613d57565b6123e6565b3480156107dd575f80fd5b506102ea6107ec366004613d7f565b612449565b3480156107fc575f80fd5b506102ea61080b366004613c19565b6124a8565b34801561081b575f80fd5b506102ea61082a366004613969565b6124e2565b5f818152602081815260408083206001600160a01b03861684529091529020545b92915050565b5f610850826126cf565b6108686126f3565b60096108748282613e4e565b5050565b6108806126f3565b610888612720565b6108748282612728565b6007805461089f90613dd2565b80601f01602080910402602001604051908101604052809291908181526020018280546108cb90613dd2565b80156109165780601f106108ed57610100808354040283529160200191610916565b820191905f5260205f20905b8154815290600101906020018083116108f957829003601f168201915b505050505081565b60035461010090046001600160a01b0316806109555760035460ff16610955575073721c0078c2328597ca70f5451fff5a7b38d4e9475b90565b60605f6009805461096890613dd2565b9050116109835760405180602001604052805f815250610850565b600961098e8361277d565b60405160200161099f929190613f08565b60405160208183030381529060405292915050565b6109bc6126f3565b8051825114610a255760405162461bcd60e51b815260206004820152602a60248201527f506c6561736520656e74657220636f7272656374206c656e67746820616e642060448201526918dbdc9c9958dd081a5960b21b60648201526084015b60405180910390fd5b5f5b8251811015610b30575f838281518110610a4357610a43613f88565b602002602001015190505f838381518110610a6057610a60613f88565b6020908102919091018101515f848152600b9092526040909120600281015460039091015491925090610a94908390613fb0565b1115610ab25760405162461bcd60e51b8152600401610a1c90613fc3565b610ad886838360405180604001604052806002815260200161060f60f31b81525061280c565b5f828152600b602052604081206003018054839290610af8908490613fb0565b90915550506040515f8051602061426d83398151915290610b1e90849084908a90613feb565b60405180910390a15050600101610a27565b50505050565b5f8281526006602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610baa5750604080518082019091526005546001600160a01b0381168252600160a01b90046001600160601b031660208201525b60208101515f9061271090610bc8906001600160601b03168761400a565b610bd29190614021565b915196919550909350505050565b336001600160a01b0386168114801590610c015750610bff86826123e6565b155b15610c325760405163711bec9160e11b81526001600160a01b03808316600483015287166024820152604401610a1c565b610c3f8686868686612867565b505050505050565b610c4f6126f3565b6040515f90339047908381818185875af1925050503d805f8114610c8e576040519150601f19603f3d011682016040523d82523d5f602084013e610c93565b606091505b5050905080610cb557604051631d42c86760e21b815260040160405180910390fd5b50565b610cc06126f3565b86518851148015610cd2575085518851145b8015610cdf575084518851145b8015610cec575083518851145b8015610cf9575082518851145b8015610d06575081518851145b8015610d13575080518851145b610d2f5760405162461bcd60e51b8152600401610a1c90614040565b5f5b8851811015610f1c575f898281518110610d4d57610d4d613f88565b6020026020010151905080600b5f8381526020019081526020015f205f0181905550888281518110610d8157610d81613f88565b6020026020010151600b5f8381526020019081526020015f2060010181905550878281518110610db357610db3613f88565b6020026020010151600b5f8381526020019081526020015f2060020181905550868281518110610de557610de5613f88565b6020026020010151600b5f8381526020019081526020015f2060040181905550858281518110610e1757610e17613f88565b6020026020010151600b5f8381526020019081526020015f2060050181905550848281518110610e4957610e49613f88565b6020026020010151600b5f8381526020019081526020015f2060060181905550838281518110610e7b57610e7b613f88565b6020026020010151600b5f8381526020019081526020015f2060070160146101000a81548160ff021916908315150217905550828281518110610ec057610ec0613f88565b6020908102919091018101515f928352600b8252604080842060070180546001600160a01b039093166001600160a01b031990931692909217909155600c9091529020805460ff60b81b1916600160b81b179055600101610d31565b505050505050505050565b60608151835114610f585781518351604051635b05999160e01b815260048101929092526024820152604401610a1c565b5f83516001600160401b03811115610f7257610f7261331f565b604051908082528060200260200182016040528015610f9b578160200160208202803683370190505b5090505f5b8451811015610fe957602080820286010151610fc49060208084028701015161082f565b828281518110610fd657610fd6613f88565b6020908102919091010152600101610fa0565b509392505050565b610ff96126f3565b8451865114801561100b575083518651145b8015611018575082518651145b8015611025575080518651145b8015611032575081518651145b61104e5760405162461bcd60e51b8152600401610a1c90614040565b5f5b86518110156111d5575f87828151811061106c5761106c613f88565b6020026020010151905080600b5f8381526020019081526020015f205f01819055508682815181106110a0576110a0613f88565b6020026020010151600b5f8381526020019081526020015f20600101819055508582815181106110d2576110d2613f88565b6020026020010151600b5f8381526020019081526020015f206002018190555084828151811061110457611104613f88565b6020026020010151600b5f8381526020019081526020015f206004018190555083828151811061113657611136613f88565b6020026020010151600b5f8381526020019081526020015f206007015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555082828151811061118757611187613f88565b6020908102919091018101515f928352600b825260408084206007018054921515600160a01b90810260ff60a01b1994851617909155600c9093529092208054909216179055600101611050565b50505050505050565b6111e66126f3565b6111ee612720565b6111f98383836128c5565b505050565b6112066126f3565b61120f5f61291f565b565b6112196126f3565b600a55565b805182511461123f5760405162461bcd60e51b8152600401610a1c90614077565b5f805b83518110156115d8575f84828151811061125e5761125e613f88565b602002602001015190505f84838151811061127b5761127b613f88565b60200260200101519050600c5f8381526020019081526020015f205f0160179054906101000a900460ff16151560011515146112ee5760405162461bcd60e51b815260206004820152601260248201527104e6f742061204c696d697465642044726f760741b6044820152606401610a1c565b5f828152600b6020526040902060070154600160a01b900460ff16151560011461132a5760405162461bcd60e51b8152600401610a1c906140c6565b5f828152600b6020526040902060020154855186908590811061134f5761134f613f88565b6020026020010151600b5f8581526020019081526020015f20600301546113769190613fb0565b11156113945760405162461bcd60e51b8152600401610a1c90613fc3565b5f828152600b60205260409020600401546113b05760016113d9565b5f828152600b6020526040902060040154816113cc898561082f565b6113d69190613fb0565b11155b6113f55760405162461bcd60e51b8152600401610a1c906140fd565b5f828152600b60205260409020600501541580159061142357505f828152600b602052604090206006015415155b156114cd575f828152600b602052604090206005015442101561147a5760405162461bcd60e51b815260206004820152600f60248201526e139bdd0814dd185c9d1959081e595d608a1b6044820152606401610a1c565b5f828152600b60205260409020600601544211156114cd5760405162461bcd60e51b815260206004820152601060248201526f1b5a5b9d1a5b99c81d1a5b5948195b9960821b6044820152606401610a1c565b5f828152600b60205260409020600101546114e990829061400a565b6114f39085613fb0565b9350833410156115155760405162461bcd60e51b8152600401610a1c9061412b565b5f828152600b60205260408082206007015490516001600160a01b039091169186156108fc02918791818181858888f19350505050158015611559573d5f803e3d5ffd5b5061158087838360405180604001604052806002815260200161060f60f31b81525061280c565b5f828152600b6020526040812060030180548392906115a0908490613fb0565b90915550506040515f8051602061426d833981519152906115c690849084908b90613feb565b60405180910390a15050600101611242565b5080341115610b3057336108fc6115ef8334614159565b6040518115909202915f818181858888f19350505050158015611614573d5f803e3d5ffd5b5050505050565b6008805461089f90613dd2565b611630612720565b60038054821515600160a81b0260ff60a81b199091161790556040517f6787c7f9a80aa0f5ceddab2c54f1f5169c0b88e75dd5e19d5e858a64144c7dbc9061167d90831515815260200190565b60405180910390a150565b610874338383612970565b61169b6126f3565b855187511480156116ad575084518751145b80156116ba575083518751145b80156116c7575081518751145b80156116d4575082518751145b6116f05760405162461bcd60e51b8152600401610a1c90614040565b5f5b87518110156118c4575f88828151811061170e5761170e613f88565b6020026020010151905080600b5f8381526020019081526020015f205f018190555087828151811061174257611742613f88565b6020026020010151600b5f8381526020019081526020015f206001018190555086828151811061177457611774613f88565b6020026020010151600b5f8381526020019081526020015f20600201819055508582815181106117a6576117a6613f88565b6020026020010151600b5f8381526020019081526020015f20600401819055508382815181106117d8576117d8613f88565b6020026020010151600b5f8381526020019081526020015f2060070160146101000a81548160ff02191690831515021790555084828151811061181d5761181d613f88565b6020908102919091018101515f838152600b8352604080822060070180546001600160a01b039094166001600160a01b031990941693909317909255600c9092529020805460ff60b01b1916600160b01b179055825183908390811061188557611885613f88565b6020908102919091018101515f928352600c909152604090912080546001600160a01b0319166001600160a01b039092169190911790556001016116f2565b5050505050505050565b6118d6612720565b6001600160a01b038116803b151590158015906118f1575080155b1561190f576040516332483afb60e01b815260040160405180910390fd5b7fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac61193861091e565b604080516001600160a01b03928316815291851660208301520160405180910390a1600380546001600160a01b038416610100026001600160a81b0319909116176001179055610874826129fc565b5f81518351146119a95760405162461bcd60e51b8152600401610a1c90614077565b5f5b8351811015611d41575f8482815181106119c7576119c7613f88565b602002602001015190505f8483815181106119e4576119e4613f88565b60200260200101519050600c5f8381526020019081526020015f205f0160169054906101000a900460ff1615156001151514611a565760405162461bcd60e51b815260206004820152601160248201527004e6f74204372616674696e672044726f7607c1b6044820152606401610a1c565b5f828152600b6020526040902060070154600160a01b900460ff161515600114611a925760405162461bcd60e51b8152600401610a1c906140c6565b5f828152600b602052604090206002810154600390910154611ab5908390613fb0565b1115611ad35760405162461bcd60e51b8152600401610a1c90613fc3565b5f828152600b6020526040902060040154611aef576001611b18565b5f828152600b602052604090206004015481611b0b338561082f565b611b159190613fb0565b11155b611b345760405162461bcd60e51b8152600401610a1c906140fd565b5f828152600c6020526040808220549051627eeac760e11b8152336004820152602481018590526001600160a01b039091169190829062fdd58e90604401602060405180830381865afa158015611b8d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bb1919061416c565b11611bf65760405162461bcd60e51b81526020600482015260156024820152742237b2b9b713ba1037bbb7103a3432903a37b5b2b760591b6044820152606401610a1c565b5f838152600b6020526040902060010154611c1290839061400a565b611c1c9086613fb0565b945084341015611c3e5760405162461bcd60e51b8152600401610a1c9061412b565b5f838152600b60205260408082206007015490516001600160a01b039091169187156108fc02918891818181858888f19350505050158015611c82573d5f803e3d5ffd5b50604051637a94c56560e11b815233600482015260248101849052604481018390526001600160a01b0382169063f5298aca906064015f604051808303815f87803b158015611ccf575f80fd5b505af1158015611ce1573d5f803e3d5ffd5b50505050611d0b33848460405180604001604052806002815260200161060f60f31b81525061280c565b5f8051602061426d833981519152838333604051611d2b93929190613feb565b60405180910390a15050508060010190506119ab565b50803411156111f957336108fc611d588334614159565b6040518115909202915f818181858888f19350505050158015610b30573d5f803e3d5ffd5b8051825114611d9e5760405162461bcd60e51b8152600401610a1c90614077565b5f805b83518110156115d8575f848281518110611dbd57611dbd613f88565b602002602001015190505f848381518110611dda57611dda613f88565b60200260200101519050600c5f8381526020019081526020015f205f0160149054906101000a900460ff1615156001151514611e4c5760405162461bcd60e51b815260206004820152601160248201527004e6f742061205075626c69632044726f7607c1b6044820152606401610a1c565b5f828152600b6020526040902060070154600160a01b900460ff161515600114611e885760405162461bcd60e51b8152600401610a1c906140c6565b5f828152600b60205260409020600201548551869085908110611ead57611ead613f88565b6020026020010151600b5f8581526020019081526020015f2060030154611ed49190613fb0565b1115611ef25760405162461bcd60e51b8152600401610a1c90613fc3565b5f828152600b6020526040902060040154611f0e576001611f37565b5f828152600b602052604090206004015481611f2a898561082f565b611f349190613fb0565b11155b611f535760405162461bcd60e51b8152600401610a1c906140fd565b5f828152600b6020526040902060010154611f6f90829061400a565b611f799085613fb0565b935083341015611f9b5760405162461bcd60e51b8152600401610a1c9061412b565b5f828152600b60205260408082206007015490516001600160a01b039091169186156108fc02918791818181858888f19350505050158015611fdf573d5f803e3d5ffd5b5061200687838360405180604001604052806002815260200161060f60f31b81525061280c565b5f828152600b602052604081206003018054839290612026908490613fb0565b90915550506040515f8051602061426d8339815191529061204c90849084908b90613feb565b60405180910390a15050600101611da1565b815183511461207f5760405162461bcd60e51b8152600401610a1c90614077565b5f805b84518110156123aa575f85828151811061209e5761209e613f88565b602002602001015190505f8583815181106120bb576120bb613f88565b60200260200101519050600c5f8381526020019081526020015f205f0160159054906101000a900460ff161515600115151461212e5760405162461bcd60e51b815260206004820152601260248201527104e6f742057686974656c6973742044726f760741b6044820152606401610a1c565b5f828152600b6020526040902060070154600160a01b900460ff16151560011461216a5760405162461bcd60e51b8152600401610a1c906140c6565b5f828152600b60205260409020600281015460039091015461218d908390613fb0565b11156121ab5760405162461bcd60e51b8152600401610a1c90613fc3565b6040516bffffffffffffffffffffffff1960608a901b1660208201525f906034016040516020818303038152906040528051906020012090506121f186600a5483612a7a565b61223d5760405162461bcd60e51b815260206004820152601860248201527f496e76616c69642057686974656c6973742050726f6f662e00000000000000006044820152606401610a1c565b5f838152600b6020526040902060040154612259576001612282565b5f838152600b6020526040902060040154826122758b8661082f565b61227f9190613fb0565b11155b61229e5760405162461bcd60e51b8152600401610a1c906140fd565b5f838152600b60205260409020600101546122ba90839061400a565b6122c49086613fb0565b9450843410156122e65760405162461bcd60e51b8152600401610a1c9061412b565b5f838152600b60205260408082206007015490516001600160a01b039091169187156108fc02918891818181858888f1935050505015801561232a573d5f803e3d5ffd5b5061235189848460405180604001604052806002815260200161060f60f31b81525061280c565b5f838152600b602052604081206003018054849290612371908490613fb0565b90915550506040515f8051602061426d8339815191529061239790859085908d90613feb565b60405180910390a1505050600101612082565b508034111561161457336108fc6123c18334614159565b6040518115909202915f818181858888f19350505050158015610c3f573d5f803e3d5ffd5b6001600160a01b038281165f9081526001602090815260408083209385168352929052205460ff168061085057600354600160a81b900460ff16156108505761242d61091e565b6001600160a01b0316826001600160a01b031614905092915050565b336001600160a01b038616811480159061246a575061246886826123e6565b155b1561249b5760405163711bec9160e11b81526001600160a01b03808316600483015287166024820152604401610a1c565b610c3f8686868686612a8f565b6124b06126f3565b6001600160a01b0381166124d957604051631e4fbdf760e01b81525f6004820152602401610a1c565b610cb58161291f565b6124ea6126f3565b845186511480156124fc575083518651145b8015612509575082518651145b8015612516575080518651145b8015612523575081518651145b61253f5760405162461bcd60e51b8152600401610a1c90614040565b5f5b86518110156111d5575f87828151811061255d5761255d613f88565b6020026020010151905080600b5f8381526020019081526020015f205f018190555086828151811061259157612591613f88565b6020026020010151600b5f8381526020019081526020015f20600101819055508582815181106125c3576125c3613f88565b6020026020010151600b5f8381526020019081526020015f20600201819055508482815181106125f5576125f5613f88565b6020026020010151600b5f8381526020019081526020015f206004018190555083828151811061262757612627613f88565b6020026020010151600b5f8381526020019081526020015f206007015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555082828151811061267857612678613f88565b6020908102919091018101515f928352600b825260408084206007018054921515600160a01b0260ff60a01b1990931692909217909155600c9091529020805460ff60a81b1916600160a81b179055600101612541565b5f6001600160e01b0319821663152a902d60e11b1480610850575061085082612b12565b6004546001600160a01b0316331461120f5760405163118cdaa760e01b8152336004820152602401610a1c565b61120f6126f3565b6127328282612b51565b6040516001600160601b03821681526001600160a01b038316907f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef9060200160405180910390a25050565b60605f61278983612bf3565b60010190505f816001600160401b038111156127a7576127a761331f565b6040519080825280601f01601f1916602001820160405280156127d1576020820181803683370190505b5090508181016020015b5f19016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846127db57509392505050565b6001600160a01b03841661283557604051632bfa23e760e11b81525f6004820152602401610a1c565b60408051600180825260208201869052818301908152606082018590526080820190925290610c3f5f87848487612cca565b6001600160a01b03841661289057604051632bfa23e760e11b81525f6004820152602401610a1c565b6001600160a01b0385166128b857604051626a0d4560e21b81525f6004820152602401610a1c565b6116148585858585612cca565b6128d0838383612d1d565b6040516001600160601b03821681526001600160a01b0383169084907f7f5b076c952c0ec86e5425963c1326dd0f03a3595c19f81d765e8ff559a6e33c906020015b60405180910390a3505050565b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6001600160a01b0382166129985760405162ced3e160e81b81525f6004820152602401610a1c565b6001600160a01b038381165f81815260016020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319101612912565b6001600160a01b03811615610cb557803b8015610874576040805163fb2de5d760e01b8152306004820152610483602482015290516001600160a01b0384169163fb2de5d7916044808301925f92919082900301818387803b158015612a60575f80fd5b505af1925050508015612a71575060015b15610874575050565b5f82612a868584612ddd565b14949350505050565b6001600160a01b038416612ab857604051632bfa23e760e11b81525f6004820152602401610a1c565b6001600160a01b038516612ae057604051626a0d4560e21b81525f6004820152602401610a1c565b604080516001808252602082018690528183019081526060820185905260808201909252906111d58787848487612cca565b5f6001600160e01b03198216632b435fdb60e21b1480612b4257506001600160e01b0319821663503e914d60e11b145b80610850575061085082612e17565b6127106001600160601b038216811015612b9057604051636f483d0960e01b81526001600160601b038316600482015260248101829052604401610a1c565b6001600160a01b038316612bb957604051635b6cc80560e11b81525f6004820152602401610a1c565b50604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600555565b5f8072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310612c315772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310612c5d576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310612c7b57662386f26fc10000830492506010015b6305f5e1008310612c93576305f5e100830492506008015b6127108310612ca757612710830492506004015b60648310612cb9576064830492506002015b600a83106108505760010192915050565b612cd685858585612e66565b6001600160a01b038416156116145782513390600103612d0f5760208481015190840151612d08838989858589613075565b5050610c3f565b610c3f818787878787613196565b6127106001600160601b038216811015612d635760405163dfd1fc1b60e01b8152600481018590526001600160601b038316602482015260448101829052606401610a1c565b6001600160a01b038316612d9357604051634b4f842960e11b8152600481018590525f6024820152604401610a1c565b506040805180820182526001600160a01b0393841681526001600160601b0392831660208083019182525f968752600690529190942093519051909116600160a01b029116179055565b5f81815b8451811015610fe957612e0d82868381518110612e0057612e00613f88565b602002602001015161327d565b9150600101612de1565b5f6001600160e01b03198216636cdb3d1360e11b1480612e4757506001600160e01b031982166303a24d0760e21b145b8061085057506301ffc9a760e01b6001600160e01b0319831614610850565b8051825114612e955781518151604051635b05999160e01b815260048101929092526024820152604401610a1c565b335f5b8351811015612f97576020818102858101820151908501909101516001600160a01b03881615612f49575f828152602081815260408083206001600160a01b038c16845290915290205481811015612f23576040516303dee4c560e01b81526001600160a01b038a166004820152602481018290526044810183905260648101849052608401610a1c565b5f838152602081815260408083206001600160a01b038d16845290915290209082900390555b6001600160a01b03871615612f8d575f828152602081815260408083206001600160a01b038b16845290915281208054839290612f87908490613fb0565b90915550505b5050600101612e98565b5082516001036130175760208301515f906020840151909150856001600160a01b0316876001600160a01b0316846001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051613008929190918252602082015260400190565b60405180910390a45050611614565b836001600160a01b0316856001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051613066929190614183565b60405180910390a45050505050565b6001600160a01b0384163b15610c3f5760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906130b990899089908890889088906004016141b0565b6020604051808303815f875af19250505080156130f3575060408051601f3d908101601f191682019092526130f0918101906141f4565b60015b61315a573d808015613120576040519150601f19603f3d011682016040523d82523d5f602084013e613125565b606091505b5080515f0361315257604051632bfa23e760e11b81526001600160a01b0386166004820152602401610a1c565b805181602001fd5b6001600160e01b0319811663f23a6e6160e01b146111d557604051632bfa23e760e11b81526001600160a01b0386166004820152602401610a1c565b6001600160a01b0384163b15610c3f5760405163bc197c8160e01b81526001600160a01b0385169063bc197c81906131da908990899088908890889060040161420f565b6020604051808303815f875af1925050508015613214575060408051601f3d908101601f19168201909252613211918101906141f4565b60015b613241573d808015613120576040519150601f19603f3d011682016040523d82523d5f602084013e613125565b6001600160e01b0319811663bc197c8160e01b146111d557604051632bfa23e760e11b81526001600160a01b0386166004820152602401610a1c565b5f818310613297575f8281526020849052604090206132a5565b5f8381526020839052604090205b9392505050565b80356001600160a01b03811681146132c2575f80fd5b919050565b5f80604083850312156132d8575f80fd5b6132e1836132ac565b946020939093013593505050565b6001600160e01b031981168114610cb5575f80fd5b5f60208284031215613314575f80fd5b81356132a5816132ef565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561335b5761335b61331f565b604052919050565b5f806001600160401b0384111561337c5761337c61331f565b50601f8301601f191660200161339181613333565b9150508281528383830111156133a5575f80fd5b828260208301375f602084830101529392505050565b5f602082840312156133cb575f80fd5b81356001600160401b038111156133e0575f80fd5b8201601f810184136133f0575f80fd5b6133ff84823560208401613363565b949350505050565b80356001600160601b03811681146132c2575f80fd5b5f806040838503121561342e575f80fd5b613437836132ac565b915061344560208401613407565b90509250929050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6132a5602083018461344e565b5f6020828403121561349e575f80fd5b5035919050565b5f6001600160401b038211156134bd576134bd61331f565b5060051b60200190565b5f82601f8301126134d6575f80fd5b81356134e96134e4826134a5565b613333565b8082825260208201915060208360051b86010192508583111561350a575f80fd5b602085015b8381101561352757803583526020928301920161350f565b5095945050505050565b5f805f60608486031215613543575f80fd5b61354c846132ac565b925060208401356001600160401b03811115613566575f80fd5b613572868287016134c7565b92505060408401356001600160401b0381111561358d575f80fd5b613599868287016134c7565b9150509250925092565b5f80604083850312156135b4575f80fd5b50508035926020909101359150565b5f82601f8301126135d2575f80fd5b6132a583833560208501613363565b5f805f805f60a086880312156135f5575f80fd5b6135fe866132ac565b945061360c602087016132ac565b935060408601356001600160401b03811115613626575f80fd5b613632888289016134c7565b93505060608601356001600160401b0381111561364d575f80fd5b613659888289016134c7565b92505060808601356001600160401b03811115613674575f80fd5b613680888289016135c3565b9150509295509295909350565b803580151581146132c2575f80fd5b5f82601f8301126136ab575f80fd5b81356136b96134e4826134a5565b8082825260208201915060208360051b8601019250858311156136da575f80fd5b602085015b83811015613527576136f08161368d565b8352602092830192016136df565b5f82601f83011261370d575f80fd5b813561371b6134e4826134a5565b8082825260208201915060208360051b86010192508583111561373c575f80fd5b602085015b8381101561352757613752816132ac565b835260209283019201613741565b5f805f805f805f80610100898b031215613778575f80fd5b88356001600160401b0381111561378d575f80fd5b6137998b828c016134c7565b98505060208901356001600160401b038111156137b4575f80fd5b6137c08b828c016134c7565b97505060408901356001600160401b038111156137db575f80fd5b6137e78b828c016134c7565b96505060608901356001600160401b03811115613802575f80fd5b61380e8b828c016134c7565b95505060808901356001600160401b03811115613829575f80fd5b6138358b828c016134c7565b94505060a08901356001600160401b03811115613850575f80fd5b61385c8b828c016134c7565b93505060c08901356001600160401b03811115613877575f80fd5b6138838b828c0161369c565b92505060e08901356001600160401b0381111561389e575f80fd5b6138aa8b828c016136fe565b9150509295985092959890939650565b5f80604083850312156138cb575f80fd5b82356001600160401b038111156138e0575f80fd5b6138ec858286016136fe565b92505060208301356001600160401b03811115613907575f80fd5b613913858286016134c7565b9150509250929050565b5f8151808452602084019350602083015f5b8281101561394d57815186526020958601959091019060010161392f565b5093949350505050565b602081525f6132a5602083018461391d565b5f805f805f8060c0878903121561397e575f80fd5b86356001600160401b03811115613993575f80fd5b61399f89828a016134c7565b96505060208701356001600160401b038111156139ba575f80fd5b6139c689828a016134c7565b95505060408701356001600160401b038111156139e1575f80fd5b6139ed89828a016134c7565b94505060608701356001600160401b03811115613a08575f80fd5b613a1489828a016134c7565b93505060808701356001600160401b03811115613a2f575f80fd5b613a3b89828a016136fe565b92505060a08701356001600160401b03811115613a56575f80fd5b613a6289828a0161369c565b9150509295509295509295565b5f805f60608486031215613a81575f80fd5b83359250613a91602085016132ac565b9150613a9f60408501613407565b90509250925092565b5f60208284031215613ab8575f80fd5b6132a58261368d565b5f8060408385031215613ad2575f80fd5b613adb836132ac565b91506134456020840161368d565b5f805f805f805f60e0888a031215613aff575f80fd5b87356001600160401b03811115613b14575f80fd5b613b208a828b016134c7565b97505060208801356001600160401b03811115613b3b575f80fd5b613b478a828b016134c7565b96505060408801356001600160401b03811115613b62575f80fd5b613b6e8a828b016134c7565b95505060608801356001600160401b03811115613b89575f80fd5b613b958a828b016134c7565b94505060808801356001600160401b03811115613bb0575f80fd5b613bbc8a828b016136fe565b93505060a08801356001600160401b03811115613bd7575f80fd5b613be38a828b0161369c565b92505060c08801356001600160401b03811115613bfe575f80fd5b613c0a8a828b016136fe565b91505092959891949750929550565b5f60208284031215613c29575f80fd5b6132a5826132ac565b5f8060408385031215613c43575f80fd5b82356001600160401b03811115613c58575f80fd5b6138ec858286016134c7565b5f805f8060808587031215613c77575f80fd5b613c80856132ac565b935060208501356001600160401b03811115613c9a575f80fd5b613ca6878288016134c7565b93505060408501356001600160401b03811115613cc1575f80fd5b613ccd878288016134c7565b92505060608501356001600160401b03811115613ce8575f80fd5b8501601f81018713613cf8575f80fd5b8035613d066134e4826134a5565b8082825260208201915060208360051b850101925089831115613d27575f80fd5b6020840193505b82841015613d49578335825260209384019390910190613d2e565b969995985093965050505050565b5f8060408385031215613d68575f80fd5b613d71836132ac565b9150613445602084016132ac565b5f805f805f60a08688031215613d93575f80fd5b613d9c866132ac565b9450613daa602087016132ac565b9350604086013592506060860135915060808601356001600160401b03811115613674575f80fd5b600181811c90821680613de657607f821691505b602082108103613e0457634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156111f957805f5260205f20601f840160051c81016020851015613e2f5750805b601f840160051c820191505b81811015611614575f8155600101613e3b565b81516001600160401b03811115613e6757613e6761331f565b613e7b81613e758454613dd2565b84613e0a565b6020601f821160018114613ead575f8315613e965750848201515b5f19600385901b1c1916600184901b178455611614565b5f84815260208120601f198516915b82811015613edc5787850151825560209485019460019092019101613ebc565b5084821015613ef957868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f808454613f1581613dd2565b600182168015613f2c5760018114613f4157613f6e565b60ff1983168652811515820286019350613f6e565b875f5260205f205f5b83811015613f6657815488820152600190910190602001613f4a565b505081860193505b50505083518060208601835e5f9101908152949350505050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b8082018082111561085057610850613f9c565b6020808252600e908201526d537570706c79206578636565647360901b604082015260600190565b92835260208301919091526001600160a01b0316604082015260600190565b808202811582820484141761085057610850613f9c565b5f8261403b57634e487b7160e01b5f52601260045260245ffd5b500490565b6020808252601a908201527f4172726179206c656e6774687320646f206e6f74206d61746368000000000000604082015260600190565b6020808252602f908201527f506c6561736520656e74657220636f7272656374206c656e67746820666f722060408201526e69647320616e6420616d6f756e747360881b606082015260800190565b6020808252601a908201527f4d696e74696e67206973206e6f7420656e61626c656420796574000000000000604082015260600190565b6020808252601490820152731b5a5b9d1a5b99c81b1a5b5a5d08195e18d9595960621b604082015260600190565b602080825260149082015273125b9cdd59999a58da595b9d081c185e5b595b9d60621b604082015260600190565b8181038181111561085057610850613f9c565b5f6020828403121561417c575f80fd5b5051919050565b604081525f614195604083018561391d565b82810360208401526141a7818561391d565b95945050505050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190525f906141e99083018461344e565b979650505050505050565b5f60208284031215614204575f80fd5b81516132a5816132ef565b6001600160a01b0386811682528516602082015260a0604082018190525f9061423a9083018661391d565b828103606084015261424c818661391d565b90508281036080840152614260818561344e565b9897505050505050505056fe259eb7b480b3d449f506927269e4665c83c69e4cd797143eaa8f84632dc7a02ba26469706673582212202b0de0f737d4a3636f6fb2ae297126add522df40725116e61930f7d4fc030ccf64736f6c634300081a0033

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

0000000000000000000000002dcbc1e2dd803a6ea5a0995b2445e1d28e841b2200000000000000000000000000000000000000000000000000000000000001f400000000000000000000000059de7273191e6bf1907d614e94ecfbe8e5fb7318

-----Decoded View---------------
Arg [0] : royaltyReceiver_ (address): 0x2DCbc1E2dd803a6Ea5A0995B2445e1d28E841B22
Arg [1] : royaltyFeeNumerator_ (uint96): 500
Arg [2] : initialOwner (address): 0x59dE7273191E6bf1907d614e94eCFbe8e5FB7318

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000002dcbc1e2dd803a6ea5a0995b2445e1d28e841b22
Arg [1] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [2] : 00000000000000000000000059de7273191e6bf1907d614e94ecfbe8e5fb7318


Deployed Bytecode Sourcemap

128627:14601:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66559:134;;;;;;;;;;-1:-1:-1;66559:134:0;;;;;:::i;:::-;;:::i;:::-;;;643:25:1;;;631:2;616:18;66559:134:0;;;;;;;;17064:104;;;;;;;;;;;;17125:42;17064:104;;;;;-1:-1:-1;;;;;843:32:1;;;825:51;;813:2;798:18;17064:104:0;679:203:1;142100:205:0;;;;;;;;;;-1:-1:-1;142100:205:0;;;;;:::i;:::-;;:::i;:::-;;;1438:14:1;;1431:22;1413:41;;1401:2;1386:18;142100:205:0;1273:187:1;129681:90:0;;;;;;;;;;-1:-1:-1;129681:90:0;;;;;:::i;:::-;;:::i;:::-;;142317:186;;;;;;;;;;-1:-1:-1;142317:186:0;;;;;:::i;:::-;;:::i;128766:34::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;18862:298::-;;;;;;;;;;;;;:::i;88107:261::-;;;;;;;;;;-1:-1:-1;88107:261:0;;;-1:-1:-1;;;3920:52:1;;88171:24:0;4003:2:1;3988:18;;3981:50;3893:18;88107:261:0;3754:283:1;142726:284:0;;;;;;;;;;-1:-1:-1;142726:284:0;;;;;:::i;:::-;;:::i;129388:37::-;;;;;;;;;;-1:-1:-1;129388:37:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;129388:37:0;;;;-1:-1:-1;;;129388:37:0;;;;;-1:-1:-1;;;129388:37:0;;;;;-1:-1:-1;;;129388:37:0;;;;;-1:-1:-1;;;129388:37:0;;;;;;;;;-1:-1:-1;;;;;4526:32:1;;;4508:51;;4602:14;;4595:22;4590:2;4575:18;;4568:50;4661:14;;4654:22;4634:18;;;4627:50;;;;4720:14;;4713:22;4708:2;4693:18;;4686:50;4780:14;4773:22;4767:3;4752:19;;4745:51;4495:3;4480:19;129388:37:0;4273:529:1;129342:39:0;;;;;;;;;;-1:-1:-1;129342:39:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;129342:39:0;;;-1:-1:-1;;;129342:39:0;;;;;;;;;;5172:25:1;;;5228:2;5213:18;;5206:34;;;;5256:18;;;5249:34;;;;5314:2;5299:18;;5292:34;;;;5357:3;5342:19;;5335:35;;;;5401:3;5386:19;;5379:35;5445:3;5430:19;;5423:35;-1:-1:-1;;;;;5495:32:1;5489:3;5474:19;;5467:61;5572:14;5565:22;5559:3;5544:19;;5537:51;5159:3;5144:19;129342:39:0;4807:787:1;134468:756:0;;;;;;;;;;-1:-1:-1;134468:756:0;;;;;:::i;:::-;;:::i;96339:429::-;;;;;;;;;;-1:-1:-1;96339:429:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;7727:32:1;;;7709:51;;7791:2;7776:18;;7769:34;;;;7682:18;96339:429:0;7535:274:1;68382:441:0;;;;;;;;;;-1:-1:-1;68382:441:0;;;;;:::i;:::-;;:::i;128871:25::-;;;;;;;;;;;;;;;;143018:207;;;;;;;;;;;;;:::i;130944:1328::-;;;;;;;;;;-1:-1:-1;130944:1328:0;;;;;:::i;:::-;;:::i;66859:567::-;;;;;;;;;;-1:-1:-1;66859:567:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;129893:1043::-;;;;;;;;;;-1:-1:-1;129893:1043:0;;;;;:::i;:::-;;:::i;142511:207::-;;;;;;;;;;-1:-1:-1;142511:207:0;;;;;:::i;:::-;;:::i;5489:45::-;;;;;;;;;;-1:-1:-1;5489:45:0;;;;-1:-1:-1;;;5489:45:0;;;;;;3599:103;;;;;;;;;;;;;:::i;129779:106::-;;;;;;;;;;-1:-1:-1;129779:106:0;;;;;:::i;:::-;;:::i;136669:1797::-;;;;;;:::i;:::-;;:::i;2924:87::-;;;;;;;;;;-1:-1:-1;2997:6:0;;-1:-1:-1;;;;;2997:6:0;2924:87;;128807:36;;;;;;;;;;;;;:::i;141987:105::-;;;;;;;;;;-1:-1:-1;141987:105:0;;;;;:::i;:::-;142042:7;142069:8;;;:3;:8;;;;;:15;;;;141987:105;5914:257;;;;;;;;;;-1:-1:-1;5914:257:0;;;;;:::i;:::-;;:::i;67499:146::-;;;;;;;;;;-1:-1:-1;67499:146:0;;;;;:::i;:::-;;:::i;132280:1124::-;;;;;;;;;;-1:-1:-1;132280:1124:0;;;;;:::i;:::-;;:::i;18152:595::-;;;;;;;;;;-1:-1:-1;18152:595:0;;;;;:::i;:::-;;:::i;141874:105::-;;;;;;;;;;-1:-1:-1;141874:105:0;;;;;:::i;:::-;141928:7;141955;;;:3;:7;;;;;:16;;;;141874:105;140183:1683;;;;;;:::i;:::-;;:::i;135232:1429::-;;;;;;:::i;:::-;;:::i;138474:1701::-;;;;;;:::i;:::-;;:::i;86974:370::-;;;;;;;;;;-1:-1:-1;86974:370:0;;;;;:::i;:::-;;:::i;67948:357::-;;;;;;;;;;-1:-1:-1;67948:357:0;;;;;:::i;:::-;;:::i;3857:220::-;;;;;;;;;;-1:-1:-1;3857:220:0;;;;;:::i;:::-;;:::i;133412:1048::-;;;;;;;;;;-1:-1:-1;133412:1048:0;;;;;:::i;:::-;;:::i;66559:134::-;66636:7;66663:13;;;;;;;;;;;-1:-1:-1;;;;;66663:22:0;;;;;;;;;;66559:134;;;;;:::o;142100:205::-;142232:4;142261:36;142285:11;142261:23;:36::i;129681:90::-;2810:13;:11;:13::i;:::-;129747:7:::1;:16;129757:6:::0;129747:7;:16:::1;:::i;:::-;;129681:90:::0;:::o;142317:186::-;2810:13;:11;:13::i;:::-;142411:31:::1;:29;:31::i;:::-;142453:42;142472:8;142482:12;142453:18;:42::i;128766:34::-:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;18862:298::-;18966:17;;;;;-1:-1:-1;;;;;18966:17:0;;18996:157;;19045:22;;;;19040:102;;-1:-1:-1;17125:42:0;19040:102;18862:298;:::o;142726:284::-;142782:13;142852:1;142834:7;142828:21;;;;;:::i;:::-;;;:25;:174;;;;;;;;;;;;;;;;;142919:7;142928:32;142956:3;142928:27;:32::i;:::-;142902:59;;;;;;;;;:::i;:::-;;;;;;;;;;;;;142808:194;142726:284;-1:-1:-1;;142726:284:0:o;134468:756::-;2810:13;:11;:13::i;:::-;134650:7:::1;:14;134636:3;:10;:28;134614:120;;;::::0;-1:-1:-1;;;134614:120:0;;25416:2:1;134614:120:0::1;::::0;::::1;25398:21:1::0;25455:2;25435:18;;;25428:30;25494:34;25474:18;;;25467:62;-1:-1:-1;;;25545:18:1;;;25538:40;25595:19;;134614:120:0::1;;;;;;;;;134750:9;134745:472;134769:3;:10;134765:1;:14;134745:472;;;134801:10;134814:3;134818:1;134814:6;;;;;;;;:::i;:::-;;;;;;;134801:19;;134835:14;134852:7;134860:1;134852:10;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;134930:7:::1;::::0;;;:3:::1;:7:::0;;;;;;;:16:::1;::::0;::::1;::::0;134903:14:::1;::::0;;::::1;::::0;134852:10;;-1:-1:-1;134930:16:0;134903:23:::1;::::0;134852:10;;134903:23:::1;:::i;:::-;:43;;134877:119;;;;-1:-1:-1::0;;;134877:119:0::1;;;;;;;:::i;:::-;135043:32;135049:7;135058:2;135062:6;135043:32;;;;;;;;;;;;;-1:-1:-1::0;;;135043:32:0::1;;::::0;:5:::1;:32::i;:::-;135132:7;::::0;;;:3:::1;:7;::::0;;;;:14:::1;;:24:::0;;135150:6;;135132:7;:24:::1;::::0;135150:6;;135132:24:::1;:::i;:::-;::::0;;;-1:-1:-1;;135178:27:0::1;::::0;-1:-1:-1;;;;;;;;;;;135178:27:0;::::1;::::0;135185:2;;135189:6;;135197:7;;135178:27:::1;:::i;:::-;;;;;;;;-1:-1:-1::0;;134781:3:0::1;;134745:472;;;;134468:756:::0;;;:::o;96339:429::-;96425:7;96483:26;;;:17;:26;;;;;;;;96454:55;;;;;;;;;-1:-1:-1;;;;;96454:55:0;;;;;-1:-1:-1;;;96454:55:0;;;-1:-1:-1;;;;;96454:55:0;;;;;;;;96425:7;;96522:92;;-1:-1:-1;96573:29:0;;;;;;;;;96583:19;96573:29;-1:-1:-1;;;;;96573:29:0;;;;-1:-1:-1;;;96573:29:0;;-1:-1:-1;;;;;96573:29:0;;;;;96522:92;96663:23;;;;96626:21;;97134:5;;96651:35;;-1:-1:-1;;;;;96651:35:0;:9;:35;:::i;:::-;96650:57;;;;:::i;:::-;96728:16;;;;;-1:-1:-1;96339:429:0;;-1:-1:-1;;;;96339:429:0:o;68382:441::-;775:10;-1:-1:-1;;;;;68627:14:0;;;;;;;:49;;;68646:30;68663:4;68669:6;68646:16;:30::i;:::-;68645:31;68627:49;68623:131;;;68700:42;;-1:-1:-1;;;68700:42:0;;-1:-1:-1;;;;;27431:32:1;;;68700:42:0;;;27413:51:1;27500:32;;27480:18;;;27473:60;27386:18;;68700:42:0;27239:300:1;68623:131:0;68764:51;68787:4;68793:2;68797:3;68802:6;68810:4;68764:22;:51::i;:::-;68572:251;68382:441;;;;;:::o;143018:207::-;2810:13;:11;:13::i;:::-;143087:82:::1;::::0;143069:12:::1;::::0;143095:10:::1;::::0;143133:21:::1;::::0;143069:12;143087:82;143069:12;143087:82;143133:21;143095:10;143087:82:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;143068:101;;;143185:7;143180:37;;143201:16;;-1:-1:-1::0;;;143201:16:0::1;;;;;;;;;;;143180:37;143057:168;143018:207::o:0;130944:1328::-;2810:13;:11;:13::i;:::-;131353:11:::1;:18;131338:4;:11;:33;:85;;;;;131407:9;:16;131392:4;:11;:31;131338:85;:143;;;;;131459:15;:22;131444:4;:11;:37;131338:143;:197;;;;;131517:11;:18;131502:4;:11;:33;131338:197;:249;;;;;131571:9;:16;131556:4;:11;:31;131338:249;:304;;;;;131623:12;:19;131608:4;:11;:34;131338:304;:355;;;;;131677:9;:16;131662:4;:11;:31;131338:355;131316:431;;;;-1:-1:-1::0;;;131316:431:0::1;;;;;;;:::i;:::-;131765:9;131760:505;131784:4;:11;131780:1;:15;131760:505;;;131817:10;131830:4;131835:1;131830:7;;;;;;;;:::i;:::-;;;;;;;131817:20;;131865:2;131852:3;:7;131856:2;131852:7;;;;;;;;;;;:10;;:15;;;;131902:11;131914:1;131902:14;;;;;;;;:::i;:::-;;;;;;;131882:3;:7;131886:2;131882:7;;;;;;;;;;;:17;;:34;;;;131950:9;131960:1;131950:12;;;;;;;;:::i;:::-;;;;;;;131931:3;:7;131935:2;131931:7;;;;;;;;;;;:16;;:31;;;;132001:15;132017:1;132001:18;;;;;;;;:::i;:::-;;;;;;;131977:3;:7;131981:2;131977:7;;;;;;;;;;;:21;;:42;;;;132054:11;132066:1;132054:14;;;;;;;;:::i;:::-;;;;;;;132034:3;:7;132038:2;132034:7;;;;;;;;;;;:17;;:34;;;;132101:9;132111:1;132101:12;;;;;;;;:::i;:::-;;;;;;;132083:3;:7;132087:2;132083:7;;;;;;;;;;;:15;;:30;;;;132149:12;132162:1;132149:15;;;;;;;;:::i;:::-;;;;;;;132128:3;:7;132132:2;132128:7;;;;;;;;;;;:18;;;:36;;;;;;;;;;;;;;;;;;132202:9;132212:1;132202:12;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;132179:7:::1;::::0;;;:3:::1;:7:::0;;;;;;:20:::1;;:35:::0;;-1:-1:-1;;;;;132179:35:0;;::::1;-1:-1:-1::0;;;;;;132179:35:0;;::::1;::::0;;;::::1;::::0;;;132229:3:::1;:7:::0;;;;;:24;;-1:-1:-1;;;;132229:24:0::1;-1:-1:-1::0;;;132229:24:0::1;::::0;;132179:35;131797:3:::1;131760:505;;;;130944:1328:::0;;;;;;;;:::o;66859:567::-;66986:16;67038:3;:10;67019:8;:15;:29;67015:123;;67098:10;;67110:15;;67072:54;;-1:-1:-1;;;67072:54:0;;;;;28283:25:1;;;;28324:18;;;28317:34;28256:18;;67072:54:0;28109:248:1;67015:123:0;67150:30;67197:8;:15;-1:-1:-1;;;;;67183:30:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;67183:30:0;;67150:63;;67231:9;67226:160;67250:8;:15;67246:1;:19;67226:160;;;57857:4;57848:14;;;57828:35;;;57822:42;67306:68;;57857:4;57848:14;;;57828:35;;;57822:42;66559:134;:::i;67306:68::-;67287:13;67301:1;67287:16;;;;;;;;:::i;:::-;;;;;;;;;;:87;67267:3;;67226:160;;;-1:-1:-1;67405:13:0;66859:567;-1:-1:-1;;;66859:567:0:o;129893:1043::-;2810:13;:11;:13::i;:::-;130217:11:::1;:18;130202:4;:11;:33;:85;;;;;130271:9;:16;130256:4;:11;:31;130202:85;:143;;;;;130323:15;:22;130308:4;:11;:37;130202:143;:198;;;;;130381:12;:19;130366:4;:11;:34;130202:198;:250;;;;;130436:9;:16;130421:4;:11;:31;130202:250;130180:326;;;;-1:-1:-1::0;;;130180:326:0::1;;;;;;;:::i;:::-;130524:9;130519:410;130543:4;:11;130539:1;:15;130519:410;;;130576:10;130589:4;130594:1;130589:7;;;;;;;;:::i;:::-;;;;;;;130576:20;;130624:2;130611:3;:7;130615:2;130611:7;;;;;;;;;;;:10;;:15;;;;130661:11;130673:1;130661:14;;;;;;;;:::i;:::-;;;;;;;130641:3;:7;130645:2;130641:7;;;;;;;;;;;:17;;:34;;;;130709:9;130719:1;130709:12;;;;;;;;:::i;:::-;;;;;;;130690:3;:7;130694:2;130690:7;;;;;;;;;;;:16;;:31;;;;130760:15;130776:1;130760:18;;;;;;;;:::i;:::-;;;;;;;130736:3;:7;130740:2;130736:7;;;;;;;;;;;:21;;:42;;;;130816:9;130826:1;130816:12;;;;;;;;:::i;:::-;;;;;;;130793:3;:7;130797:2;130793:7;;;;;;;;;;;:20;;;:35;;;;;-1:-1:-1::0;;;;;130793:35:0::1;;;;;-1:-1:-1::0;;;;;130793:35:0::1;;;;;;130864:12;130877:1;130864:15;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;130843:7:::1;::::0;;;:3:::1;:7:::0;;;;;;:18:::1;;:36:::0;;;::::1;;-1:-1:-1::0;;;130843:36:0;;::::1;-1:-1:-1::0;;;;130843:36:0;;::::1;;::::0;;;130894:3:::1;:7:::0;;;;;;:23;;;;::::1;;::::0;;-1:-1:-1;130556:3:0::1;130519:410;;;;129893:1043:::0;;;;;;:::o;142511:207::-;2810:13;:11;:13::i;:::-;142619:31:::1;:29;:31::i;:::-;142661:49;142678:7;142687:8;142697:12;142661:16;:49::i;:::-;142511:207:::0;;;:::o;3599:103::-;2810:13;:11;:13::i;:::-;3664:30:::1;3691:1;3664:18;:30::i;:::-;3599:103::o:0;129779:106::-;2810:13;:11;:13::i;:::-;129853:10:::1;:24:::0;129779:106::o;136669:1797::-;136853:7;:14;136839:3;:10;:28;136817:125;;;;-1:-1:-1;;;136817:125:0;;;;;;;:::i;:::-;136953:17;;136981:1363;137005:3;:10;137001:1;:14;136981:1363;;;137037:10;137050:3;137054:1;137050:6;;;;;;;;:::i;:::-;;;;;;;137037:19;;137071:14;137088:7;137096:1;137088:10;;;;;;;;:::i;:::-;;;;;;;137071:27;;137139:3;:7;137143:2;137139:7;;;;;;;;;;;:17;;;;;;;;;;;;:25;;137160:4;137139:25;;;137113:105;;;;-1:-1:-1;;;137113:105:0;;28980:2:1;137113:105:0;;;28962:21:1;29019:2;28999:18;;;28992:30;-1:-1:-1;;;29038:18:1;;;29031:48;29096:18;;137113:105:0;28778:342:1;137113:105:0;137241:7;;;;:3;:7;;;;;:18;;;-1:-1:-1;;;137241:18:0;;;;:26;;137263:4;137241:26;137233:65;;;;-1:-1:-1;;;137233:65:0;;;;;;;:::i;:::-;137370:7;;;;:3;:7;;;;;:16;;;137356:10;;:7;;137364:1;;137356:10;;;;;;:::i;:::-;;;;;;;137339:3;:7;137343:2;137339:7;;;;;;;;;;;:14;;;:27;;;;:::i;:::-;:47;;137313:123;;;;-1:-1:-1;;;137313:123:0;;;;;;;:::i;:::-;137497:1;137473:7;;;:3;:7;;;;;:21;;;:117;;137586:4;137473:117;;;137549:7;;;;:3;:7;;;;;:21;;;137539:6;137514:22;137524:7;137553:2;137514:9;:22::i;:::-;:31;;;;:::i;:::-;:56;;137473:117;137451:191;;;;-1:-1:-1;;;137451:191:0;;;;;;;:::i;:::-;137681:1;137661:7;;;:3;:7;;;;;:17;;;:21;;;;:44;;-1:-1:-1;137704:1:0;137686:7;;;:3;:7;;;;;:15;;;:19;;137661:44;137657:353;;;137775:7;;;;:3;:7;;;;;:17;;;137756:15;:36;;137726:125;;;;-1:-1:-1;;;137726:125:0;;30031:2:1;137726:125:0;;;30013:21:1;30070:2;30050:18;;;30043:30;-1:-1:-1;;;30089:18:1;;;30082:45;30144:18;;137726:125:0;29829:339:1;137726:125:0;137919:7;;;;:3;:7;;;;;:15;;;137900;:34;;137870:124;;;;-1:-1:-1;;;137870:124:0;;30375:2:1;137870:124:0;;;30357:21:1;30414:2;30394:18;;;30387:30;-1:-1:-1;;;30433:18:1;;;30426:46;30489:18;;137870:124:0;30173:340:1;137870:124:0;138037:7;;;;:3;:7;;;;;:17;;;:26;;138057:6;;138037:26;:::i;:::-;138024:39;;;;:::i;:::-;;;138099:9;138086;:22;;138078:55;;;;-1:-1:-1;;;138078:55:0;;;;;;;:::i;:::-;138156:7;;;;:3;:7;;;;;;:20;;;138148:49;;-1:-1:-1;;;;;138156:20:0;;;;138148:49;;;;;138187:9;;138148:49;138156:7;138148:49;138187:9;138156:20;138148:49;;;;;;;;;;;;;;;;;;;;;138214:32;138220:7;138229:2;138233:6;138214:32;;;;;;;;;;;;;-1:-1:-1;;;138214:32:0;;;:5;:32::i;:::-;138261:7;;;;:3;:7;;;;;:14;;:24;;138279:6;;138261:7;:24;;138279:6;;138261:24;:::i;:::-;;;;-1:-1:-1;;138305:27:0;;-1:-1:-1;;;;;;;;;;;138305:27:0;;;138312:2;;138316:6;;138324:7;;138305:27;:::i;:::-;;;;;;;;-1:-1:-1;;137017:3:0;;136981:1363;;;;138370:9;138358;:21;138354:105;;;138404:10;138396:51;138425:21;138437:9;138425;:21;:::i;:::-;138396:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;136806:1660;136669:1797;;;:::o;128807:36::-;;;;;;;:::i;5914:257::-;6006:31;:29;:31::i;:::-;6048:33;:47;;;;;-1:-1:-1;;;6048:47:0;-1:-1:-1;;;;6048:47:0;;;;;;6111:52;;;;;;6084:11;1438:14:1;1431:22;1413:41;;1401:2;1386:18;;1273:187;6111:52:0;;;;;;;;5914:257;:::o;67499:146::-;67585:52;775:10;67618:8;67628;67585:18;:52::i;132280:1124::-;2810:13;:11;:13::i;:::-;132638:11:::1;:18;132623:4;:11;:33;:85;;;;;132692:9;:16;132677:4;:11;:31;132623:85;:143;;;;;132744:15;:22;132729:4;:11;:37;132623:143;:198;;;;;132802:12;:19;132787:4;:11;:34;132623:198;:249;;;;;132856:9;:16;132841:4;:11;:31;132623:249;132601:325;;;;-1:-1:-1::0;;;132601:325:0::1;;;;;;;:::i;:::-;132944:9;132939:458;132963:4;:11;132959:1;:15;132939:458;;;132996:10;133009:4;133014:1;133009:7;;;;;;;;:::i;:::-;;;;;;;132996:20;;133044:2;133031:3;:7;133035:2;133031:7;;;;;;;;;;;:10;;:15;;;;133081:11;133093:1;133081:14;;;;;;;;:::i;:::-;;;;;;;133061:3;:7;133065:2;133061:7;;;;;;;;;;;:17;;:34;;;;133129:9;133139:1;133129:12;;;;;;;;:::i;:::-;;;;;;;133110:3;:7;133114:2;133110:7;;;;;;;;;;;:16;;:31;;;;133180:15;133196:1;133180:18;;;;;;;;:::i;:::-;;;;;;;133156:3;:7;133160:2;133156:7;;;;;;;;;;;:21;;:42;;;;133234:12;133247:1;133234:15;;;;;;;;:::i;:::-;;;;;;;133213:3;:7;133217:2;133213:7;;;;;;;;;;;:18;;;:36;;;;;;;;;;;;;;;;;;133287:9;133297:1;133287:12;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;133264:7:::1;::::0;;;:3:::1;:7:::0;;;;;;:20:::1;;:35:::0;;-1:-1:-1;;;;;133264:35:0;;::::1;-1:-1:-1::0;;;;;;133264:35:0;;::::1;::::0;;;::::1;::::0;;;133314:3:::1;:7:::0;;;;;:20;;-1:-1:-1;;;;133314:20:0::1;-1:-1:-1::0;;;133314:20:0::1;::::0;;133375:10;;:7;;133383:1;;133375:10;::::1;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;133349:7:::1;::::0;;;:3:::1;:7:::0;;;;;;;:36;;-1:-1:-1;;;;;;133349:36:0::1;-1:-1:-1::0;;;;;133349:36:0;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;132976:3:0::1;132939:458;;;;132280:1124:::0;;;;;;;:::o;18152:595::-;18228:31;:29;:31::i;:::-;-1:-1:-1;;;;;18304:30:0;;;;:34;;;18354:32;;;;:61;;;18391:24;18390:25;18354:61;18351:152;;;18439:52;;-1:-1:-1;;;18439:52:0;;;;;;;;;;;18351:152;18520:77;18553:22;:20;:22::i;:::-;18520:77;;;-1:-1:-1;;;;;27431:32:1;;;27413:51;;27500:32;;;27495:2;27480:18;;27473:60;27386:18;18520:77:0;;;;;;;18610:22;:29;;-1:-1:-1;;;;;18650:38:0;;18610:29;18650:38;-1:-1:-1;;;;;;18650:38:0;;;;18635:4;18650:38;;;18701;18670:18;18701;:38::i;140183:1683::-;140278:17;140342:7;:14;140328:3;:10;:28;140306:125;;;;-1:-1:-1;;;140306:125:0;;;;;;;:::i;:::-;140447:9;140442:1302;140466:3;:10;140462:1;:14;140442:1302;;;140498:10;140511:3;140515:1;140511:6;;;;;;;;:::i;:::-;;;;;;;140498:19;;140532:14;140549:7;140557:1;140549:10;;;;;;;;:::i;:::-;;;;;;;140532:27;;140604:3;:7;140608:2;140604:7;;;;;;;;;;;:13;;;;;;;;;;;;:21;;140621:4;140604:21;;;140574:104;;;;-1:-1:-1;;;140574:104:0;;31202:2:1;140574:104:0;;;31184:21:1;31241:2;31221:18;;;31214:30;-1:-1:-1;;;31260:18:1;;;31253:47;31317:18;;140574:104:0;31000:341:1;140574:104:0;140701:7;;;;:3;:7;;;;;:18;;;-1:-1:-1;;;140701:18:0;;;;:26;;140723:4;140701:26;140693:65;;;;-1:-1:-1;;;140693:65:0;;;;;;;:::i;:::-;140826:7;;;;:3;:7;;;;;:16;;;;140799:14;;;;;:23;;140816:6;;140799:23;:::i;:::-;:43;;140773:119;;;;-1:-1:-1;;;140773:119:0;;;;;;;:::i;:::-;140953:1;140929:7;;;:3;:7;;;;;:21;;;:120;;141045:4;140929:120;;;141008:7;;;;:3;:7;;;;;:21;;;140998:6;140970:25;140980:10;141012:2;140970:9;:25::i;:::-;:34;;;;:::i;:::-;:59;;140929:120;140907:194;;;;-1:-1:-1;;;140907:194:0;;;;;;;:::i;:::-;141116:17;141144:7;;;:3;:7;;;;;;:23;141209:35;;-1:-1:-1;;;141209:35:0;;141229:10;141209:35;;;7709:51:1;7776:18;;;7769:34;;;-1:-1:-1;;;;;141144:23:0;;;;141116:17;141144:23;;141209:19;;7682:18:1;;141209:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:39;141183:122;;;;-1:-1:-1;;;141183:122:0;;31737:2:1;141183:122:0;;;31719:21:1;31776:2;31756:18;;;31749:30;-1:-1:-1;;;31795:18:1;;;31788:51;31856:18;;141183:122:0;31535:345:1;141183:122:0;141384:7;;;;:3;:7;;;;;:17;;;:26;;141404:6;;141384:26;:::i;:::-;141371:39;;;;:::i;:::-;;;141446:9;141433;:22;;141425:55;;;;-1:-1:-1;;;141425:55:0;;;;;;;:::i;:::-;141503:7;;;;:3;:7;;;;;;:20;;;141495:49;;-1:-1:-1;;;;;141503:20:0;;;;141495:49;;;;;141534:9;;141495:49;141503:7;141495:49;141534:9;141503:20;141495:49;;;;;;;;;;;;;;;;;;;;-1:-1:-1;141559:38:0;;-1:-1:-1;;;141559:38:0;;141574:10;141559:38;;;32087:51:1;32154:18;;;32147:34;;;32197:18;;;32190:34;;;-1:-1:-1;;;;;141559:14:0;;;;;32060:18:1;;141559:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;141645:35;141651:10;141663:2;141667:6;141645:35;;;;;;;;;;;;;-1:-1:-1;;;141645:35:0;;;:5;:35::i;:::-;-1:-1:-1;;;;;;;;;;;141709:2:0;141713:6;141721:10;141702:30;;;;;;;;:::i;:::-;;;;;;;;140483:1261;;;140478:3;;;;;140442:1302;;;;141770:9;141758;:21;141754:105;;;141804:10;141796:51;141825:21;141837:9;141825;:21;:::i;:::-;141796:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;135232:1429;135415:7;:14;135401:3;:10;:28;135379:125;;;;-1:-1:-1;;;135379:125:0;;;;;;;:::i;:::-;135515:17;;135543:996;135567:3;:10;135563:1;:14;135543:996;;;135599:10;135612:3;135616:1;135612:6;;;;;;;;:::i;:::-;;;;;;;135599:19;;135633:14;135650:7;135658:1;135650:10;;;;;;;;:::i;:::-;;;;;;;135633:27;;135701:3;:7;135705:2;135701:7;;;;;;;;;;;:16;;;;;;;;;;;;:24;;135721:4;135701:24;;;135675:103;;;;-1:-1:-1;;;135675:103:0;;32437:2:1;135675:103:0;;;32419:21:1;32476:2;32456:18;;;32449:30;-1:-1:-1;;;32495:18:1;;;32488:47;32552:18;;135675:103:0;32235:341:1;135675:103:0;135801:7;;;;:3;:7;;;;;:18;;;-1:-1:-1;;;135801:18:0;;;;:26;;135823:4;135801:26;135793:65;;;;-1:-1:-1;;;135793:65:0;;;;;;;:::i;:::-;135930:7;;;;:3;:7;;;;;:16;;;135916:10;;:7;;135924:1;;135916:10;;;;;;:::i;:::-;;;;;;;135899:3;:7;135903:2;135899:7;;;;;;;;;;;:14;;;:27;;;;:::i;:::-;:47;;135873:123;;;;-1:-1:-1;;;135873:123:0;;;;;;;:::i;:::-;136057:1;136033:7;;;:3;:7;;;;;:21;;;:117;;136146:4;136033:117;;;136109:7;;;;:3;:7;;;;;:21;;;136099:6;136074:22;136084:7;136113:2;136074:9;:22::i;:::-;:31;;;;:::i;:::-;:56;;136033:117;136011:191;;;;-1:-1:-1;;;136011:191:0;;;;;;;:::i;:::-;136230:7;;;;:3;:7;;;;;:17;;;:26;;136250:6;;136230:26;:::i;:::-;136217:39;;;;:::i;:::-;;;136292:9;136279;:22;;136271:55;;;;-1:-1:-1;;;136271:55:0;;;;;;;:::i;:::-;136349:7;;;;:3;:7;;;;;;:20;;;136341:49;;-1:-1:-1;;;;;136349:20:0;;;;136341:49;;;;;136380:9;;136341:49;136349:7;136341:49;136380:9;136349:20;136341:49;;;;;;;;;;;;;;;;;;;;;136407:32;136413:7;136422:2;136426:6;136407:32;;;;;;;;;;;;;-1:-1:-1;;;136407:32:0;;;:5;:32::i;:::-;136454:7;;;;:3;:7;;;;;:14;;:24;;136472:6;;136454:7;:24;;136472:6;;136454:24;:::i;:::-;;;;-1:-1:-1;;136500:27:0;;-1:-1:-1;;;;;;;;;;;136500:27:0;;;136507:2;;136511:6;;136519:7;;136500:27;:::i;:::-;;;;;;;;-1:-1:-1;;135579:3:0;;135543:996;;138474:1701;138699:7;:14;138685:3;:10;:28;138663:125;;;;-1:-1:-1;;;138663:125:0;;;;;;;:::i;:::-;138799:17;;138827:1226;138851:3;:10;138847:1;:14;138827:1226;;;138883:10;138896:3;138900:1;138896:6;;;;;;;;:::i;:::-;;;;;;;138883:19;;138917:14;138934:7;138942:1;138934:10;;;;;;;;:::i;:::-;;;;;;;138917:27;;138985:3;:7;138989:2;138985:7;;;;;;;;;;;:19;;;;;;;;;;;;:27;;139008:4;138985:27;;;138959:107;;;;-1:-1:-1;;;138959:107:0;;32783:2:1;138959:107:0;;;32765:21:1;32822:2;32802:18;;;32795:30;-1:-1:-1;;;32841:18:1;;;32834:48;32899:18;;138959:107:0;32581:342:1;138959:107:0;139089:7;;;;:3;:7;;;;;:18;;;-1:-1:-1;;;139089:18:0;;;;:26;;139111:4;139089:26;139081:65;;;;-1:-1:-1;;;139081:65:0;;;;;;;:::i;:::-;139214:7;;;;:3;:7;;;;;:16;;;;139187:14;;;;;:23;;139204:6;;139187:23;:::i;:::-;:43;;139161:119;;;;-1:-1:-1;;;139161:119:0;;;;;;;:::i;:::-;139320:25;;-1:-1:-1;;33077:2:1;33073:15;;;33069:53;139320:25:0;;;33057:66:1;139295:12:0;;33139::1;;139320:25:0;;;;;;;;;;;;139310:36;;;;;;139295:51;;139387:49;139406:11;139419:10;;139431:4;139387:18;:49::i;:::-;139361:135;;;;-1:-1:-1;;;139361:135:0;;33364:2:1;139361:135:0;;;33346:21:1;33403:2;33383:18;;;33376:30;33442:26;33422:18;;;33415:54;33486:18;;139361:135:0;33162:348:1;139361:135:0;139559:1;139535:7;;;:3;:7;;;;;:21;;;:117;;139648:4;139535:117;;;139611:7;;;;:3;:7;;;;;:21;;;139601:6;139576:22;139586:7;139615:2;139576:9;:22::i;:::-;:31;;;;:::i;:::-;:56;;139535:117;139513:191;;;;-1:-1:-1;;;139513:191:0;;;;;;;:::i;:::-;139746:7;;;;:3;:7;;;;;:17;;;:26;;139766:6;;139746:26;:::i;:::-;139733:39;;;;:::i;:::-;;;139808:9;139795;:22;;139787:55;;;;-1:-1:-1;;;139787:55:0;;;;;;;:::i;:::-;139865:7;;;;:3;:7;;;;;;:20;;;139857:49;;-1:-1:-1;;;;;139865:20:0;;;;139857:49;;;;;139896:9;;139857:49;139865:7;139857:49;139896:9;139865:20;139857:49;;;;;;;;;;;;;;;;;;;;;139923:32;139929:7;139938:2;139942:6;139923:32;;;;;;;;;;;;;-1:-1:-1;;;139923:32:0;;;:5;:32::i;:::-;139970:7;;;;:3;:7;;;;;:14;;:24;;139988:6;;139970:7;:24;;139988:6;;139970:24;:::i;:::-;;;;-1:-1:-1;;140014:27:0;;-1:-1:-1;;;;;;;;;;;140014:27:0;;;140021:2;;140025:6;;140033:7;;140014:27;:::i;:::-;;;;;;;;-1:-1:-1;;;138863:3:0;;138827:1226;;;;140079:9;140067;:21;140063:105;;;140113:10;140105:51;140134:21;140146:9;140134;:21;:::i;:::-;140105:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86974:370;-1:-1:-1;;;;;67831:27:0;;;87071:15;67831:27;;;:18;:27;;;;;;;;:37;;;;;;;;;;;;;87164:173;;87200:33;;-1:-1:-1;;;87200:33:0;;;;87196:130;;;87287:22;:20;:22::i;:::-;-1:-1:-1;;;;;87267:43:0;:8;-1:-1:-1;;;;;87267:43:0;;87254:56;;86974:370;;;;:::o;67948:357::-;775:10;-1:-1:-1;;;;;68116:14:0;;;;;;;:49;;;68135:30;68152:4;68158:6;68135:16;:30::i;:::-;68134:31;68116:49;68112:131;;;68189:42;;-1:-1:-1;;;68189:42:0;;-1:-1:-1;;;;;27431:32:1;;;68189:42:0;;;27413:51:1;27500:32;;27480:18;;;27473:60;27386:18;;68189:42:0;27239:300:1;68112:131:0;68253:44;68271:4;68277:2;68281;68285:5;68292:4;68253:17;:44::i;3857:220::-;2810:13;:11;:13::i;:::-;-1:-1:-1;;;;;3942:22:0;::::1;3938:93;;3988:31;::::0;-1:-1:-1;;;3988:31:0;;4016:1:::1;3988:31;::::0;::::1;825:51:1::0;798:18;;3988:31:0::1;679:203:1::0;3938:93:0::1;4041:28;4060:8;4041:18;:28::i;133412:1048::-:0;2810:13;:11;:13::i;:::-;133739:11:::1;:18;133724:4;:11;:33;:85;;;;;133793:9;:16;133778:4;:11;:31;133724:85;:143;;;;;133845:15;:22;133830:4;:11;:37;133724:143;:198;;;;;133903:12;:19;133888:4;:11;:34;133724:198;:249;;;;;133957:9;:16;133942:4;:11;:31;133724:249;133702:325;;;;-1:-1:-1::0;;;133702:325:0::1;;;;;;;:::i;:::-;134045:9;134040:413;134064:4;:11;134060:1;:15;134040:413;;;134097:10;134110:4;134115:1;134110:7;;;;;;;;:::i;:::-;;;;;;;134097:20;;134145:2;134132:3;:7;134136:2;134132:7;;;;;;;;;;;:10;;:15;;;;134182:11;134194:1;134182:14;;;;;;;;:::i;:::-;;;;;;;134162:3;:7;134166:2;134162:7;;;;;;;;;;;:17;;:34;;;;134230:9;134240:1;134230:12;;;;;;;;:::i;:::-;;;;;;;134211:3;:7;134215:2;134211:7;;;;;;;;;;;:16;;:31;;;;134281:15;134297:1;134281:18;;;;;;;;:::i;:::-;;;;;;;134257:3;:7;134261:2;134257:7;;;;;;;;;;;:21;;:42;;;;134337:9;134347:1;134337:12;;;;;;;;:::i;:::-;;;;;;;134314:3;:7;134318:2;134314:7;;;;;;;;;;;:20;;;:35;;;;;-1:-1:-1::0;;;;;134314:35:0::1;;;;;-1:-1:-1::0;;;;;134314:35:0::1;;;;;;134385:12;134398:1;134385:15;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;134364:7:::1;::::0;;;:3:::1;:7:::0;;;;;;:18:::1;;:36:::0;;;::::1;;-1:-1:-1::0;;;134364:36:0::1;-1:-1:-1::0;;;;134364:36:0;;::::1;::::0;;;::::1;::::0;;;134415:3:::1;:7:::0;;;;;:26;;-1:-1:-1;;;;134415:26:0::1;-1:-1:-1::0;;;134415:26:0::1;::::0;;-1:-1:-1;134077:3:0::1;134040:413;;96069:215:::0;96171:4;-1:-1:-1;;;;;;96195:41:0;;-1:-1:-1;;;96195:41:0;;:81;;;96240:36;96264:11;96240:23;:36::i;3089:166::-;2997:6;;-1:-1:-1;;;;;2997:6:0;775:10;3149:23;3145:103;;3196:40;;-1:-1:-1;;;3196:40:0;;775:10;3196:40;;;825:51:1;798:18;;3196:40:0;679:203:1;4615:104:0;4698:13;:11;:13::i;99718:217::-;99822:48;99847:8;99857:12;99822:24;:48::i;:::-;99886:41;;-1:-1:-1;;;;;33677:39:1;;33659:58;;-1:-1:-1;;;;;99886:41:0;;;;;33647:2:1;33632:18;99886:41:0;;;;;;;99718:217;;:::o;125812:727::-;125868:13;125919:14;125936:28;125958:5;125936:21;:28::i;:::-;125967:1;125936:32;125919:49;;125983:20;126017:6;-1:-1:-1;;;;;126006:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;126006:18:0;-1:-1:-1;125983:41:0;-1:-1:-1;126148:28:0;;;126164:2;126148:28;126205:288;-1:-1:-1;;126237:5:0;-1:-1:-1;;;126374:2:0;126363:14;;126358:30;126237:5;126345:44;126435:2;126426:11;;;-1:-1:-1;126456:21:0;126205:288;126456:21;-1:-1:-1;126514:6:0;125812:727;-1:-1:-1;;;125812:727:0:o;75291:352::-;-1:-1:-1;;;;;75388:16:0;;75384:90;;75428:34;;-1:-1:-1;;;75428:34:0;;75459:1;75428:34;;;825:51:1;798:18;;75428:34:0;679:203:1;75384:90:0;81075:4;81069:11;;81147:1;81132:17;;;81280:4;81268:17;;81261:35;;;81400:17;;;81431;;;80885:23;81469:17;;81462:35;;;81608:17;;;81595:31;;;81069:11;75574:61;-1:-1:-1;75613:2:0;81069:11;81400:17;75630:4;75574:26;:61::i;73510:459::-;-1:-1:-1;;;;;73710:16:0;;73706:90;;73750:34;;-1:-1:-1;;;73750:34:0;;73781:1;73750:34;;;825:51:1;798:18;;73750:34:0;679:203:1;73706:90:0;-1:-1:-1;;;;;73810:18:0;;73806:90;;73852:32;;-1:-1:-1;;;73852:32:0;;73881:1;73852:32;;;825:51:1;798:18;;73852:32:0;679:203:1;73806:90:0;73906:55;73933:4;73939:2;73943:3;73948:6;73956:4;73906:26;:55::i;99943:246::-;100062:55;100085:7;100094:8;100104:12;100062:22;:55::i;:::-;100133:48;;-1:-1:-1;;;;;33677:39:1;;33659:58;;-1:-1:-1;;;;;100133:48:0;;;100149:7;;100133:48;;33647:2:1;33632:18;100133:48:0;;;;;;;;99943:246;;;:::o;4237:191::-;4330:6;;;-1:-1:-1;;;;;4347:17:0;;;-1:-1:-1;;;;;;4347:17:0;;;;;;;4380:40;;4330:6;;;4347:17;4330:6;;4380:40;;4311:16;;4380:40;4300:128;4237:191;:::o;77885:321::-;-1:-1:-1;;;;;77993:22:0;;77989:96;;78039:34;;-1:-1:-1;;;78039:34:0;;78070:1;78039:34;;;825:51:1;798:18;;78039:34:0;679:203:1;77989:96:0;-1:-1:-1;;;;;78095:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;78095:46:0;;;;;;;;;;78157:41;;1413::1;;;78157::0;;1386:18:1;78157:41:0;1273:187:1;22392:459:0;-1:-1:-1;;;;;22463:23:0;;;22459:385;;22592:22;;22646:21;;22643:190;;22692:95;;;-1:-1:-1;;;22692:95:0;;22767:4;22692:95;;;33900:51:1;83382:4:0;33967:18:1;;;33960:47;22692:95:0;;-1:-1:-1;;;;;22692:66:0;;;;;33873:18:1;;;;;-1:-1:-1;;22692:95:0;;;;;;;-1:-1:-1;22692:66:0;:95;;;;;;;;;;;;;;;;;;;;;;;;;22688:130;;;22488:356;22392:459;:::o;102092:156::-;102183:4;102236;102207:25;102220:5;102227:4;102207:12;:25::i;:::-;:33;;102092:156;-1:-1:-1;;;;102092:156:0:o;72624:472::-;-1:-1:-1;;;;;72747:16:0;;72743:90;;72787:34;;-1:-1:-1;;;72787:34:0;;72818:1;72787:34;;;825:51:1;798:18;;72787:34:0;679:203:1;72743:90:0;-1:-1:-1;;;;;72847:18:0;;72843:90;;72889:32;;-1:-1:-1;;;72889:32:0;;72918:1;72889:32;;;825:51:1;798:18;;72889:32:0;679:203:1;72843:90:0;81075:4;81069:11;;81147:1;81132:17;;;81280:4;81268:17;;81261:35;;;81400:17;;;81431;;;80885:23;81469:17;;81462:35;;;81608:17;;;81595:31;;;81069:11;73033:55;73060:4;73066:2;81069:11;81400:17;73083:4;73033:26;:55::i;87638:289::-;87723:4;-1:-1:-1;;;;;;87757:46:0;;-1:-1:-1;;;87757:46:0;;:112;;-1:-1:-1;;;;;;;87817:52:0;;-1:-1:-1;;;87817:52:0;87757:112;:162;;;;87883:36;87907:11;87883:23;:36::i;97418:518::-;97134:5;-1:-1:-1;;;;;97567:26:0;;;-1:-1:-1;97563:176:0;;;97672:55;;-1:-1:-1;;;97672:55:0;;-1:-1:-1;;;;;34209:39:1;;97672:55:0;;;34191:58:1;34265:18;;;34258:34;;;34164:18;;97672:55:0;34018:280:1;97563:176:0;-1:-1:-1;;;;;97753:22:0;;97749:110;;97799:48;;-1:-1:-1;;;97799:48:0;;97844:1;97799:48;;;825:51:1;798:18;;97799:48:0;679:203:1;97749:110:0;-1:-1:-1;97893:35:0;;;;;;;;;-1:-1:-1;;;;;97893:35:0;;;;;;-1:-1:-1;;;;;97893:35:0;;;;;;;;;;-1:-1:-1;;;97871:57:0;;;;:19;:57;97418:518::o;121239:948::-;121292:7;;-1:-1:-1;;;121370:17:0;;121366:106;;-1:-1:-1;;;121408:17:0;;;-1:-1:-1;121454:2:0;121444:12;121366:106;121499:8;121490:5;:17;121486:106;;121537:8;121528:17;;;-1:-1:-1;121574:2:0;121564:12;121486:106;121619:8;121610:5;:17;121606:106;;121657:8;121648:17;;;-1:-1:-1;121694:2:0;121684:12;121606:106;121739:7;121730:5;:16;121726:103;;121776:7;121767:16;;;-1:-1:-1;121812:1:0;121802:11;121726:103;121856:7;121847:5;:16;121843:103;;121893:7;121884:16;;;-1:-1:-1;121929:1:0;121919:11;121843:103;121973:7;121964:5;:16;121960:103;;122010:7;122001:16;;;-1:-1:-1;122046:1:0;122036:11;121960:103;122090:7;122081:5;:16;122077:68;;122128:1;122118:11;122173:6;121239:948;-1:-1:-1;;121239:948:0:o;71445:708::-;71653:30;71661:4;71667:2;71671:3;71676:6;71653:7;:30::i;:::-;-1:-1:-1;;;;;71698:16:0;;;71694:452;;71781:10;;775;;71795:1;71781:15;71777:358;;57857:4;57828:35;;;57822:42;57828:35;;;57822:42;71937:67;71968:8;71978:4;71984:2;57822:42;;71999:4;71937:30;:67::i;:::-;71798:222;;71777:358;;;72045:74;72081:8;72091:4;72097:2;72101:3;72106:6;72114:4;72045:35;:74::i;98387:554::-;97134:5;-1:-1:-1;;;;;98551:26:0;;;-1:-1:-1;98547:183:0;;;98656:62;;-1:-1:-1;;;98656:62:0;;;;;34504:25:1;;;-1:-1:-1;;;;;34565:39:1;;34545:18;;;34538:67;34621:18;;;34614:34;;;34477:18;;98656:62:0;34303:351:1;98547:183:0;-1:-1:-1;;;;;98744:22:0;;98740:117;;98790:55;;-1:-1:-1;;;98790:55:0;;;;;34833:25:1;;;98842:1:0;34874:18:1;;;34867:60;34806:18;;98790:55:0;34659:274:1;98740:117:0;-1:-1:-1;98898:35:0;;;;;;;;-1:-1:-1;;;;;98898:35:0;;;;;-1:-1:-1;;;;;98898:35:0;;;;;;;;;;-1:-1:-1;98869:26:0;;;:17;:26;;;;;;:64;;;;;;;-1:-1:-1;;;98869:64:0;;;;;;98387:554::o;102811:296::-;102894:7;102937:4;102894:7;102952:118;102976:5;:12;102972:1;:16;102952:118;;;103025:33;103035:12;103049:5;103055:1;103049:8;;;;;;;;:::i;:::-;;;;;;;103025:9;:33::i;:::-;103010:48;-1:-1:-1;102990:3:0;;102952:118;;65668:310;65770:4;-1:-1:-1;;;;;;65807:41:0;;-1:-1:-1;;;65807:41:0;;:110;;-1:-1:-1;;;;;;;65865:52:0;;-1:-1:-1;;;65865:52:0;65807:110;:163;;;-1:-1:-1;;;;;;;;;;33310:40:0;;;65934:36;33210:148;69540:1315;69676:6;:13;69662:3;:10;:27;69658:119;;69739:10;;69751:13;;69713:52;;-1:-1:-1;;;69713:52:0;;;;;28283:25:1;;;;28324:18;;;28317:34;28256:18;;69713:52:0;28109:248:1;69658:119:0;775:10;69789:16;69833:709;69857:3;:10;69853:1;:14;69833:709;;;57857:4;57848:14;;;57828:35;;;;;57822:42;57828:35;;;;;;57822:42;-1:-1:-1;;;;;70007:18:0;;;70003:429;;70046:19;70068:13;;;;;;;;;;;-1:-1:-1;;;;;70068:19:0;;;;;;;;;;70110;;;70106:131;;;70161:56;;-1:-1:-1;;;70161:56:0;;-1:-1:-1;;;;;35187:32:1;;70161:56:0;;;35169:51:1;35236:18;;;35229:34;;;35279:18;;;35272:34;;;35322:18;;;35315:34;;;35141:19;;70161:56:0;34938:417:1;70106:131:0;70356:9;:13;;;;;;;;;;;-1:-1:-1;;;;;70356:19:0;;;;;;;;;70378;;;;70356:41;;70003:429;-1:-1:-1;;;;;70452:16:0;;;70448:83;;70489:9;:13;;;;;;;;;;;-1:-1:-1;;;;;70489:17:0;;;;;;;;;:26;;70510:5;;70489:9;:26;;70510:5;;70489:26;:::i;:::-;;;;-1:-1:-1;;70448:83:0;-1:-1:-1;;69869:3:0;;69833:709;;;;70558:3;:10;70572:1;70558:15;70554:294;;57857:4;57828:35;;57822:42;70590:10;;57857:4;57828:35;;57822:42;70590:38;;-1:-1:-1;70738:2:0;-1:-1:-1;;;;;70707:45:0;70732:4;-1:-1:-1;;;;;70707:45:0;70722:8;-1:-1:-1;;;;;70707:45:0;;70742:2;70746:5;70707:45;;;;;;28283:25:1;;;28339:2;28324:18;;28317:34;28271:2;28256:18;;28109:248;70707:45:0;;;;;;;;70575:189;;70554:294;;;70820:2;-1:-1:-1;;;;;70790:46:0;70814:4;-1:-1:-1;;;;;70790:46:0;70804:8;-1:-1:-1;;;;;70790:46:0;;70824:3;70829:6;70790:46;;;;;;;:::i;:::-;;;;;;;;69647:1208;69540:1315;;;;:::o;78390:1000::-;-1:-1:-1;;;;;78604:14:0;;;:18;78600:783;;78643:71;;-1:-1:-1;;;78643:71:0;;-1:-1:-1;;;;;78643:38:0;;;;;:71;;78682:8;;78692:4;;78698:2;;78702:5;;78709:4;;78643:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;78643:71:0;;;;;;;;-1:-1:-1;;78643:71:0;;;;;;;;;;;;:::i;:::-;;;78639:733;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79004:6;:13;79021:1;79004:18;79000:357;;79110:26;;-1:-1:-1;;;79110:26:0;;-1:-1:-1;;;;;843:32:1;;79110:26:0;;;825:51:1;798:18;;79110:26:0;679:203:1;79000:357:0;79307:6;79301:13;79292:6;79288:2;79284:15;79277:38;78639:733;-1:-1:-1;;;;;;78764:55:0;;-1:-1:-1;;;78764:55:0;78760:177;;78891:26;;-1:-1:-1;;;78891:26:0;;-1:-1:-1;;;;;843:32:1;;78891:26:0;;;825:51:1;798:18;;78891:26:0;679:203:1;79584:1069:0;-1:-1:-1;;;;;79823:14:0;;;:18;79819:827;;79862:78;;-1:-1:-1;;;79862:78:0;;-1:-1:-1;;;;;79862:43:0;;;;;:78;;79906:8;;79916:4;;79922:3;;79927:6;;79935:4;;79862:78;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;79862:78:0;;;;;;;;-1:-1:-1;;79862:78:0;;;;;;;;;;;;:::i;:::-;;;79858:777;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;80022:60:0;;-1:-1:-1;;;80022:60:0;80018:182;;80154:26;;-1:-1:-1;;;80154:26:0;;-1:-1:-1;;;;;843:32:1;;80154:26:0;;;825:51:1;798:18;;80154:26:0;679:203:1;110241:149:0;110304:7;110335:1;110331;:5;:51;;110583:13;110677:15;;;110713:4;110706:15;;;110760:4;110744:21;;110331:51;;;110583:13;110677:15;;;110713:4;110706:15;;;110760:4;110744:21;;110339:20;110324:58;110241:149;-1:-1:-1;;;110241:149:0:o;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:300::-;260:6;268;321:2;309:9;300:7;296:23;292:32;289:52;;;337:1;334;327:12;289:52;360:29;379:9;360:29;:::i;:::-;350:39;458:2;443:18;;;;430:32;;-1:-1:-1;;;192:300:1:o;887:131::-;-1:-1:-1;;;;;;961:32:1;;951:43;;941:71;;1008:1;1005;998:12;1023:245;1081:6;1134:2;1122:9;1113:7;1109:23;1105:32;1102:52;;;1150:1;1147;1140:12;1102:52;1189:9;1176:23;1208:30;1232:5;1208:30;:::i;1465:127::-;1526:10;1521:3;1517:20;1514:1;1507:31;1557:4;1554:1;1547:15;1581:4;1578:1;1571:15;1597:275;1668:2;1662:9;1733:2;1714:13;;-1:-1:-1;;1710:27:1;1698:40;;-1:-1:-1;;;;;1753:34:1;;1789:22;;;1750:62;1747:88;;;1815:18;;:::i;:::-;1851:2;1844:22;1597:275;;-1:-1:-1;1597:275:1:o;1877:450::-;1942:5;1974:1;-1:-1:-1;;;;;1990:6:1;1987:30;1984:56;;;2020:18;;:::i;:::-;-1:-1:-1;2086:2:1;2065:15;;-1:-1:-1;;2061:29:1;2092:4;2057:40;2115:21;2057:40;2115:21;:::i;:::-;2106:30;;;2159:6;2152:5;2145:21;2199:3;2190:6;2185:3;2181:16;2178:25;2175:45;;;2216:1;2213;2206:12;2175:45;2265:6;2260:3;2253:4;2246:5;2242:16;2229:43;2319:1;2312:4;2303:6;2296:5;2292:18;2288:29;2281:40;1877:450;;;;;:::o;2332:451::-;2401:6;2454:2;2442:9;2433:7;2429:23;2425:32;2422:52;;;2470:1;2467;2460:12;2422:52;2510:9;2497:23;-1:-1:-1;;;;;2535:6:1;2532:30;2529:50;;;2575:1;2572;2565:12;2529:50;2598:22;;2651:4;2643:13;;2639:27;-1:-1:-1;2629:55:1;;2680:1;2677;2670:12;2629:55;2703:74;2769:7;2764:2;2751:16;2746:2;2742;2738:11;2703:74;:::i;:::-;2693:84;2332:451;-1:-1:-1;;;;2332:451:1:o;2788:179::-;2855:20;;-1:-1:-1;;;;;2904:38:1;;2894:49;;2884:77;;2957:1;2954;2947:12;2972:258;3039:6;3047;3100:2;3088:9;3079:7;3075:23;3071:32;3068:52;;;3116:1;3113;3106:12;3068:52;3139:29;3158:9;3139:29;:::i;:::-;3129:39;;3187:37;3220:2;3209:9;3205:18;3187:37;:::i;:::-;3177:47;;2972:258;;;;;:::o;3235:289::-;3277:3;3315:5;3309:12;3342:6;3337:3;3330:19;3398:6;3391:4;3384:5;3380:16;3373:4;3368:3;3364:14;3358:47;3450:1;3443:4;3434:6;3429:3;3425:16;3421:27;3414:38;3513:4;3506:2;3502:7;3497:2;3489:6;3485:15;3481:29;3476:3;3472:39;3468:50;3461:57;;;3235:289;;;;:::o;3529:220::-;3678:2;3667:9;3660:21;3641:4;3698:45;3739:2;3728:9;3724:18;3716:6;3698:45;:::i;4042:226::-;4101:6;4154:2;4142:9;4133:7;4129:23;4125:32;4122:52;;;4170:1;4167;4160:12;4122:52;-1:-1:-1;4215:23:1;;4042:226;-1:-1:-1;4042:226:1:o;5599:183::-;5659:4;-1:-1:-1;;;;;5684:6:1;5681:30;5678:56;;;5714:18;;:::i;:::-;-1:-1:-1;5759:1:1;5755:14;5771:4;5751:25;;5599:183::o;5787:723::-;5841:5;5894:3;5887:4;5879:6;5875:17;5871:27;5861:55;;5912:1;5909;5902:12;5861:55;5952:6;5939:20;5979:64;5995:47;6035:6;5995:47;:::i;:::-;5979:64;:::i;:::-;6067:3;6091:6;6086:3;6079:19;6123:4;6118:3;6114:14;6107:21;;6184:4;6174:6;6171:1;6167:14;6159:6;6155:27;6151:38;6137:52;;6212:3;6204:6;6201:15;6198:35;;;6229:1;6226;6219:12;6198:35;6265:4;6257:6;6253:17;6279:200;6295:6;6290:3;6287:15;6279:200;;;6387:17;;6417:18;;6464:4;6455:14;;;;6312;6279:200;;;-1:-1:-1;6497:7:1;5787:723;-1:-1:-1;;;;;5787:723:1:o;6515:664::-;6642:6;6650;6658;6711:2;6699:9;6690:7;6686:23;6682:32;6679:52;;;6727:1;6724;6717:12;6679:52;6750:29;6769:9;6750:29;:::i;:::-;6740:39;;6830:2;6819:9;6815:18;6802:32;-1:-1:-1;;;;;6849:6:1;6846:30;6843:50;;;6889:1;6886;6879:12;6843:50;6912:61;6965:7;6956:6;6945:9;6941:22;6912:61;:::i;:::-;6902:71;;;7026:2;7015:9;7011:18;6998:32;-1:-1:-1;;;;;7045:8:1;7042:32;7039:52;;;7087:1;7084;7077:12;7039:52;7110:63;7165:7;7154:8;7143:9;7139:24;7110:63;:::i;:::-;7100:73;;;6515:664;;;;;:::o;7184:346::-;7252:6;7260;7313:2;7301:9;7292:7;7288:23;7284:32;7281:52;;;7329:1;7326;7319:12;7281:52;-1:-1:-1;;7374:23:1;;;7494:2;7479:18;;;7466:32;;-1:-1:-1;7184:346:1:o;7814:221::-;7856:5;7909:3;7902:4;7894:6;7890:17;7886:27;7876:55;;7927:1;7924;7917:12;7876:55;7949:80;8025:3;8016:6;8003:20;7996:4;7988:6;7984:17;7949:80;:::i;8040:954::-;8194:6;8202;8210;8218;8226;8279:3;8267:9;8258:7;8254:23;8250:33;8247:53;;;8296:1;8293;8286:12;8247:53;8319:29;8338:9;8319:29;:::i;:::-;8309:39;;8367:38;8401:2;8390:9;8386:18;8367:38;:::i;:::-;8357:48;;8456:2;8445:9;8441:18;8428:32;-1:-1:-1;;;;;8475:6:1;8472:30;8469:50;;;8515:1;8512;8505:12;8469:50;8538:61;8591:7;8582:6;8571:9;8567:22;8538:61;:::i;:::-;8528:71;;;8652:2;8641:9;8637:18;8624:32;-1:-1:-1;;;;;8671:8:1;8668:32;8665:52;;;8713:1;8710;8703:12;8665:52;8736:63;8791:7;8780:8;8769:9;8765:24;8736:63;:::i;:::-;8726:73;;;8852:3;8841:9;8837:19;8824:33;-1:-1:-1;;;;;8872:8:1;8869:32;8866:52;;;8914:1;8911;8904:12;8866:52;8937:51;8980:7;8969:8;8958:9;8954:24;8937:51;:::i;:::-;8927:61;;;8040:954;;;;;;;;:::o;9181:160::-;9246:20;;9302:13;;9295:21;9285:32;;9275:60;;9331:1;9328;9321:12;9346:669;9397:5;9450:3;9443:4;9435:6;9431:17;9427:27;9417:55;;9468:1;9465;9458:12;9417:55;9508:6;9495:20;9535:64;9551:47;9591:6;9551:47;:::i;9535:64::-;9623:3;9647:6;9642:3;9635:19;9679:4;9674:3;9670:14;9663:21;;9740:4;9730:6;9727:1;9723:14;9715:6;9711:27;9707:38;9693:52;;9768:3;9760:6;9757:15;9754:35;;;9785:1;9782;9775:12;9754:35;9821:4;9813:6;9809:17;9835:149;9851:6;9846:3;9843:15;9835:149;;;9919:20;9935:3;9919:20;:::i;:::-;9907:33;;9969:4;9960:14;;;;9868;9835:149;;10020:675;10074:5;10127:3;10120:4;10112:6;10108:17;10104:27;10094:55;;10145:1;10142;10135:12;10094:55;10185:6;10172:20;10212:64;10228:47;10268:6;10228:47;:::i;10212:64::-;10300:3;10324:6;10319:3;10312:19;10356:4;10351:3;10347:14;10340:21;;10417:4;10407:6;10404:1;10400:14;10392:6;10388:27;10384:38;10370:52;;10445:3;10437:6;10434:15;10431:35;;;10462:1;10459;10452:12;10431:35;10498:4;10490:6;10486:17;10512:152;10528:6;10523:3;10520:15;10512:152;;;10596:23;10615:3;10596:23;:::i;:::-;10584:36;;10649:4;10640:14;;;;10545;10512:152;;10700:2041;11019:6;11027;11035;11043;11051;11059;11067;11075;11128:3;11116:9;11107:7;11103:23;11099:33;11096:53;;;11145:1;11142;11135:12;11096:53;11185:9;11172:23;-1:-1:-1;;;;;11210:6:1;11207:30;11204:50;;;11250:1;11247;11240:12;11204:50;11273:61;11326:7;11317:6;11306:9;11302:22;11273:61;:::i;:::-;11263:71;;;11387:2;11376:9;11372:18;11359:32;-1:-1:-1;;;;;11406:8:1;11403:32;11400:52;;;11448:1;11445;11438:12;11400:52;11471:63;11526:7;11515:8;11504:9;11500:24;11471:63;:::i;:::-;11461:73;;;11587:2;11576:9;11572:18;11559:32;-1:-1:-1;;;;;11606:8:1;11603:32;11600:52;;;11648:1;11645;11638:12;11600:52;11671:63;11726:7;11715:8;11704:9;11700:24;11671:63;:::i;:::-;11661:73;;;11787:2;11776:9;11772:18;11759:32;-1:-1:-1;;;;;11806:8:1;11803:32;11800:52;;;11848:1;11845;11838:12;11800:52;11871:63;11926:7;11915:8;11904:9;11900:24;11871:63;:::i;:::-;11861:73;;;11987:3;11976:9;11972:19;11959:33;-1:-1:-1;;;;;12007:8:1;12004:32;12001:52;;;12049:1;12046;12039:12;12001:52;12072:63;12127:7;12116:8;12105:9;12101:24;12072:63;:::i;:::-;12062:73;;;12188:3;12177:9;12173:19;12160:33;-1:-1:-1;;;;;12208:8:1;12205:32;12202:52;;;12250:1;12247;12240:12;12202:52;12273:63;12328:7;12317:8;12306:9;12302:24;12273:63;:::i;:::-;12263:73;;;12389:3;12378:9;12374:19;12361:33;-1:-1:-1;;;;;12409:8:1;12406:32;12403:52;;;12451:1;12448;12441:12;12403:52;12474:60;12526:7;12515:8;12504:9;12500:24;12474:60;:::i;:::-;12464:70;;;12587:3;12576:9;12572:19;12559:33;-1:-1:-1;;;;;12607:8:1;12604:32;12601:52;;;12649:1;12646;12639:12;12601:52;12672:63;12727:7;12716:8;12705:9;12701:24;12672:63;:::i;:::-;12662:73;;;10700:2041;;;;;;;;;;;:::o;12746:590::-;12864:6;12872;12925:2;12913:9;12904:7;12900:23;12896:32;12893:52;;;12941:1;12938;12931:12;12893:52;12981:9;12968:23;-1:-1:-1;;;;;13006:6:1;13003:30;13000:50;;;13046:1;13043;13036:12;13000:50;13069:61;13122:7;13113:6;13102:9;13098:22;13069:61;:::i;:::-;13059:71;;;13183:2;13172:9;13168:18;13155:32;-1:-1:-1;;;;;13202:8:1;13199:32;13196:52;;;13244:1;13241;13234:12;13196:52;13267:63;13322:7;13311:8;13300:9;13296:24;13267:63;:::i;:::-;13257:73;;;12746:590;;;;;:::o;13341:420::-;13394:3;13432:5;13426:12;13459:6;13454:3;13447:19;13491:4;13486:3;13482:14;13475:21;;13530:4;13523:5;13519:16;13553:1;13563:173;13577:6;13574:1;13571:13;13563:173;;;13638:13;;13626:26;;13681:4;13672:14;;;;13709:17;;;;13599:1;13592:9;13563:173;;;-1:-1:-1;13752:3:1;;13341:420;-1:-1:-1;;;;13341:420:1:o;13766:261::-;13945:2;13934:9;13927:21;13908:4;13965:56;14017:2;14006:9;14002:18;13994:6;13965:56;:::i;14032:1555::-;14283:6;14291;14299;14307;14315;14323;14376:3;14364:9;14355:7;14351:23;14347:33;14344:53;;;14393:1;14390;14383:12;14344:53;14433:9;14420:23;-1:-1:-1;;;;;14458:6:1;14455:30;14452:50;;;14498:1;14495;14488:12;14452:50;14521:61;14574:7;14565:6;14554:9;14550:22;14521:61;:::i;:::-;14511:71;;;14635:2;14624:9;14620:18;14607:32;-1:-1:-1;;;;;14654:8:1;14651:32;14648:52;;;14696:1;14693;14686:12;14648:52;14719:63;14774:7;14763:8;14752:9;14748:24;14719:63;:::i;:::-;14709:73;;;14835:2;14824:9;14820:18;14807:32;-1:-1:-1;;;;;14854:8:1;14851:32;14848:52;;;14896:1;14893;14886:12;14848:52;14919:63;14974:7;14963:8;14952:9;14948:24;14919:63;:::i;:::-;14909:73;;;15035:2;15024:9;15020:18;15007:32;-1:-1:-1;;;;;15054:8:1;15051:32;15048:52;;;15096:1;15093;15086:12;15048:52;15119:63;15174:7;15163:8;15152:9;15148:24;15119:63;:::i;:::-;15109:73;;;15235:3;15224:9;15220:19;15207:33;-1:-1:-1;;;;;15255:8:1;15252:32;15249:52;;;15297:1;15294;15287:12;15249:52;15320:63;15375:7;15364:8;15353:9;15349:24;15320:63;:::i;:::-;15310:73;;;15436:3;15425:9;15421:19;15408:33;-1:-1:-1;;;;;15456:8:1;15453:32;15450:52;;;15498:1;15495;15488:12;15450:52;15521:60;15573:7;15562:8;15551:9;15547:24;15521:60;:::i;:::-;15511:70;;;14032:1555;;;;;;;;:::o;15592:372::-;15668:6;15676;15684;15737:2;15725:9;15716:7;15712:23;15708:32;15705:52;;;15753:1;15750;15743:12;15705:52;15798:23;;;-1:-1:-1;15864:38:1;15898:2;15883:18;;15864:38;:::i;:::-;15854:48;;15921:37;15954:2;15943:9;15939:18;15921:37;:::i;:::-;15911:47;;15592:372;;;;;:::o;16200:180::-;16256:6;16309:2;16297:9;16288:7;16284:23;16280:32;16277:52;;;16325:1;16322;16315:12;16277:52;16348:26;16364:9;16348:26;:::i;16385:254::-;16450:6;16458;16511:2;16499:9;16490:7;16486:23;16482:32;16479:52;;;16527:1;16524;16517:12;16479:52;16550:29;16569:9;16550:29;:::i;:::-;16540:39;;16598:35;16629:2;16618:9;16614:18;16598:35;:::i;16644:1798::-;16929:6;16937;16945;16953;16961;16969;16977;17030:3;17018:9;17009:7;17005:23;17001:33;16998:53;;;17047:1;17044;17037:12;16998:53;17087:9;17074:23;-1:-1:-1;;;;;17112:6:1;17109:30;17106:50;;;17152:1;17149;17142:12;17106:50;17175:61;17228:7;17219:6;17208:9;17204:22;17175:61;:::i;:::-;17165:71;;;17289:2;17278:9;17274:18;17261:32;-1:-1:-1;;;;;17308:8:1;17305:32;17302:52;;;17350:1;17347;17340:12;17302:52;17373:63;17428:7;17417:8;17406:9;17402:24;17373:63;:::i;:::-;17363:73;;;17489:2;17478:9;17474:18;17461:32;-1:-1:-1;;;;;17508:8:1;17505:32;17502:52;;;17550:1;17547;17540:12;17502:52;17573:63;17628:7;17617:8;17606:9;17602:24;17573:63;:::i;:::-;17563:73;;;17689:2;17678:9;17674:18;17661:32;-1:-1:-1;;;;;17708:8:1;17705:32;17702:52;;;17750:1;17747;17740:12;17702:52;17773:63;17828:7;17817:8;17806:9;17802:24;17773:63;:::i;:::-;17763:73;;;17889:3;17878:9;17874:19;17861:33;-1:-1:-1;;;;;17909:8:1;17906:32;17903:52;;;17951:1;17948;17941:12;17903:52;17974:63;18029:7;18018:8;18007:9;18003:24;17974:63;:::i;:::-;17964:73;;;18090:3;18079:9;18075:19;18062:33;-1:-1:-1;;;;;18110:8:1;18107:32;18104:52;;;18152:1;18149;18142:12;18104:52;18175:60;18227:7;18216:8;18205:9;18201:24;18175:60;:::i;:::-;18165:70;;;18288:3;18277:9;18273:19;18260:33;-1:-1:-1;;;;;18308:8:1;18305:32;18302:52;;;18350:1;18347;18340:12;18302:52;18373:63;18428:7;18417:8;18406:9;18402:24;18373:63;:::i;:::-;18363:73;;;16644:1798;;;;;;;;;;:::o;18447:186::-;18506:6;18559:2;18547:9;18538:7;18534:23;18530:32;18527:52;;;18575:1;18572;18565:12;18527:52;18598:29;18617:9;18598:29;:::i;18638:590::-;18756:6;18764;18817:2;18805:9;18796:7;18792:23;18788:32;18785:52;;;18833:1;18830;18823:12;18785:52;18873:9;18860:23;-1:-1:-1;;;;;18898:6:1;18895:30;18892:50;;;18938:1;18935;18928:12;18892:50;18961:61;19014:7;19005:6;18994:9;18990:22;18961:61;:::i;19233:1499::-;19394:6;19402;19410;19418;19471:3;19459:9;19450:7;19446:23;19442:33;19439:53;;;19488:1;19485;19478:12;19439:53;19511:29;19530:9;19511:29;:::i;:::-;19501:39;;19591:2;19580:9;19576:18;19563:32;-1:-1:-1;;;;;19610:6:1;19607:30;19604:50;;;19650:1;19647;19640:12;19604:50;19673:61;19726:7;19717:6;19706:9;19702:22;19673:61;:::i;:::-;19663:71;;;19787:2;19776:9;19772:18;19759:32;-1:-1:-1;;;;;19806:8:1;19803:32;19800:52;;;19848:1;19845;19838:12;19800:52;19871:63;19926:7;19915:8;19904:9;19900:24;19871:63;:::i;:::-;19861:73;;;19987:2;19976:9;19972:18;19959:32;-1:-1:-1;;;;;20006:8:1;20003:32;20000:52;;;20048:1;20045;20038:12;20000:52;20071:24;;20126:4;20118:13;;20114:27;-1:-1:-1;20104:55:1;;20155:1;20152;20145:12;20104:55;20195:2;20182:16;20218:64;20234:47;20274:6;20234:47;:::i;20218:64::-;20304:3;20328:6;20323:3;20316:19;20360:2;20355:3;20351:12;20344:19;;20415:2;20405:6;20402:1;20398:14;20394:2;20390:23;20386:32;20372:46;;20441:7;20433:6;20430:19;20427:39;;;20462:1;20459;20452:12;20427:39;20494:2;20490;20486:11;20475:22;;20506:196;20522:6;20517:3;20514:15;20506:196;;;20612:17;;20642:18;;20689:2;20539:12;;;;20680;;;;20506:196;;;19233:1499;;;;-1:-1:-1;19233:1499:1;;-1:-1:-1;;;;;19233:1499:1:o;20737:260::-;20805:6;20813;20866:2;20854:9;20845:7;20841:23;20837:32;20834:52;;;20882:1;20879;20872:12;20834:52;20905:29;20924:9;20905:29;:::i;:::-;20895:39;;20953:38;20987:2;20976:9;20972:18;20953:38;:::i;21002:704::-;21106:6;21114;21122;21130;21138;21191:3;21179:9;21170:7;21166:23;21162:33;21159:53;;;21208:1;21205;21198:12;21159:53;21231:29;21250:9;21231:29;:::i;:::-;21221:39;;21279:38;21313:2;21302:9;21298:18;21279:38;:::i;:::-;21269:48;-1:-1:-1;21386:2:1;21371:18;;21358:32;;-1:-1:-1;21487:2:1;21472:18;;21459:32;;-1:-1:-1;21568:3:1;21553:19;;21540:33;-1:-1:-1;;;;;21585:30:1;;21582:50;;;21628:1;21625;21618:12;21711:380;21790:1;21786:12;;;;21833;;;21854:61;;21908:4;21900:6;21896:17;21886:27;;21854:61;21961:2;21953:6;21950:14;21930:18;21927:38;21924:161;;22007:10;22002:3;21998:20;21995:1;21988:31;22042:4;22039:1;22032:15;22070:4;22067:1;22060:15;21924:161;;21711:380;;;:::o;22222:518::-;22324:2;22319:3;22316:11;22313:421;;;22360:5;22357:1;22350:16;22404:4;22401:1;22391:18;22474:2;22462:10;22458:19;22455:1;22451:27;22445:4;22441:38;22510:4;22498:10;22495:20;22492:47;;;-1:-1:-1;22533:4:1;22492:47;22588:2;22583:3;22579:12;22576:1;22572:20;22566:4;22562:31;22552:41;;22643:81;22661:2;22654:5;22651:13;22643:81;;;22720:1;22706:16;;22687:1;22676:13;22643:81;;22916:1299;23042:3;23036:10;-1:-1:-1;;;;;23061:6:1;23058:30;23055:56;;;23091:18;;:::i;:::-;23120:97;23210:6;23170:38;23202:4;23196:11;23170:38;:::i;:::-;23164:4;23120:97;:::i;:::-;23266:4;23297:2;23286:14;;23314:1;23309:649;;;;24002:1;24019:6;24016:89;;;-1:-1:-1;24071:19:1;;;24065:26;24016:89;-1:-1:-1;;22873:1:1;22869:11;;;22865:24;22861:29;22851:40;22897:1;22893:11;;;22848:57;24118:81;;23279:930;;23309:649;22169:1;22162:14;;;22206:4;22193:18;;-1:-1:-1;;23345:20:1;;;23463:222;23477:7;23474:1;23471:14;23463:222;;;23559:19;;;23553:26;23538:42;;23666:4;23651:20;;;;23619:1;23607:14;;;;23493:12;23463:222;;;23467:3;23713:6;23704:7;23701:19;23698:201;;;23774:19;;;23768:26;-1:-1:-1;;23857:1:1;23853:14;;;23869:3;23849:24;23845:37;23841:42;23826:58;23811:74;;23698:201;-1:-1:-1;;;;23945:1:1;23929:14;;;23925:22;23912:36;;-1:-1:-1;22916:1299:1:o;24220:989::-;24396:3;24425:1;24458:6;24452:13;24488:36;24514:9;24488:36;:::i;:::-;24555:1;24540:17;;24566:133;;;;24713:1;24708:332;;;;24533:507;;24566:133;-1:-1:-1;;24599:24:1;;24587:37;;24672:14;;24665:22;24653:35;;24644:45;;;-1:-1:-1;24566:133:1;;24708:332;24739:6;24736:1;24729:17;24787:4;24784:1;24774:18;24814:1;24828:166;24842:6;24839:1;24836:13;24828:166;;;24922:14;;24909:11;;;24902:35;24978:1;24965:15;;;;24864:4;24857:12;24828:166;;;24832:3;;25023:6;25018:3;25014:16;25007:23;;24533:507;;;;25071:6;25065:13;25117:8;25110:4;25102:6;25098:17;25093:3;25087:39;25183:1;25145:18;;25172:13;;;25145:18;24220:989;-1:-1:-1;;;;24220:989:1:o;25625:127::-;25686:10;25681:3;25677:20;25674:1;25667:31;25717:4;25714:1;25707:15;25741:4;25738:1;25731:15;25757:127;25818:10;25813:3;25809:20;25806:1;25799:31;25849:4;25846:1;25839:15;25873:4;25870:1;25863:15;25889:125;25954:9;;;25975:10;;;25972:36;;;25988:18;;:::i;26019:338::-;26221:2;26203:21;;;26260:2;26240:18;;;26233:30;-1:-1:-1;;;26294:2:1;26279:18;;26272:44;26348:2;26333:18;;26019:338::o;26362:345::-;26564:25;;;26620:2;26605:18;;26598:34;;;;-1:-1:-1;;;;;26668:32:1;26663:2;26648:18;;26641:60;26552:2;26537:18;;26362:345::o;26712:168::-;26785:9;;;26816;;26833:15;;;26827:22;;26813:37;26803:71;;26854:18;;:::i;27017:217::-;27057:1;27083;27073:132;;27127:10;27122:3;27118:20;27115:1;27108:31;27162:4;27159:1;27152:15;27190:4;27187:1;27180:15;27073:132;-1:-1:-1;27219:9:1;;27017:217::o;27754:350::-;27956:2;27938:21;;;27995:2;27975:18;;;27968:30;28034:28;28029:2;28014:18;;28007:56;28095:2;28080:18;;27754:350::o;28362:411::-;28564:2;28546:21;;;28603:2;28583:18;;;28576:30;28642:34;28637:2;28622:18;;28615:62;-1:-1:-1;;;28708:2:1;28693:18;;28686:45;28763:3;28748:19;;28362:411::o;29125:350::-;29327:2;29309:21;;;29366:2;29346:18;;;29339:30;29405:28;29400:2;29385:18;;29378:56;29466:2;29451:18;;29125:350::o;29480:344::-;29682:2;29664:21;;;29721:2;29701:18;;;29694:30;-1:-1:-1;;;29755:2:1;29740:18;;29733:50;29815:2;29800:18;;29480:344::o;30518:::-;30720:2;30702:21;;;30759:2;30739:18;;;30732:30;-1:-1:-1;;;30793:2:1;30778:18;;30771:50;30853:2;30838:18;;30518:344::o;30867:128::-;30934:9;;;30955:11;;;30952:37;;;30969:18;;:::i;31346:184::-;31416:6;31469:2;31457:9;31448:7;31444:23;31440:32;31437:52;;;31485:1;31482;31475:12;31437:52;-1:-1:-1;31508:16:1;;31346:184;-1:-1:-1;31346:184:1:o;35360:465::-;35617:2;35606:9;35599:21;35580:4;35643:56;35695:2;35684:9;35680:18;35672:6;35643:56;:::i;:::-;35747:9;35739:6;35735:22;35730:2;35719:9;35715:18;35708:50;35775:44;35812:6;35804;35775:44;:::i;:::-;35767:52;35360:465;-1:-1:-1;;;;;35360:465:1:o;35830:557::-;-1:-1:-1;;;;;36089:32:1;;;36071:51;;36158:32;;36153:2;36138:18;;36131:60;36222:2;36207:18;;36200:34;;;36265:2;36250:18;;36243:34;;;36109:3;36308;36293:19;;36286:32;;;-1:-1:-1;;36335:46:1;;36361:19;;36353:6;36335:46;:::i;:::-;36327:54;35830:557;-1:-1:-1;;;;;;;35830:557:1:o;36392:249::-;36461:6;36514:2;36502:9;36493:7;36489:23;36485:32;36482:52;;;36530:1;36527;36520:12;36482:52;36562:9;36556:16;36581:30;36605:5;36581:30;:::i;36646:823::-;-1:-1:-1;;;;;37005:32:1;;;36987:51;;37074:32;;37069:2;37054:18;;37047:60;37025:3;37138:2;37123:18;;37116:31;;;-1:-1:-1;;37170:57:1;;37207:19;;37199:6;37170:57;:::i;:::-;37275:9;37267:6;37263:22;37258:2;37247:9;37243:18;37236:50;37309:44;37346:6;37338;37309:44;:::i;:::-;37295:58;;37402:9;37394:6;37390:22;37384:3;37373:9;37369:19;37362:51;37430:33;37456:6;37448;37430:33;:::i;:::-;37422:41;36646:823;-1:-1:-1;;;;;;;;36646:823:1:o

Swarm Source

ipfs://2b0de0f737d4a3636f6fb2ae297126add522df40725116e61930f7d4fc030ccf
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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