S Price: $0.814172 (+1.53%)

Token

Eggs (EGGS)

Overview

Max Total Supply

9,731,583.610438790862180084 EGGS

Holders

7

Total Transfers

-

Market

Price

$0.00 @ 0.000000 S

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
EGGS

Compiler Version
v0.8.28+commit.7893614a

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at SonicScan.org on 2025-02-13
*/

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-20 standard as defined in the ERC.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol


// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.20;


/**
 * @dev Interface for the optional metadata functions from the ERC-20 standard.
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

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


// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

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

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

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

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


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

/**
 * @dev Standard ERC-20 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
 */
interface IERC20Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC20InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC20InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     * @param allowance Amount of tokens a `spender` is allowed to operate with.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC20InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC20InvalidSpender(address spender);
}

/**
 * @dev Standard ERC-721 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
 */
interface IERC721Errors {
    /**
     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.
     * Used in balance queries.
     * @param owner Address of the current owner of a token.
     */
    error ERC721InvalidOwner(address owner);

    /**
     * @dev Indicates a `tokenId` whose `owner` is the zero address.
     * @param tokenId Identifier number of a token.
     */
    error ERC721NonexistentToken(uint256 tokenId);

    /**
     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param tokenId Identifier number of a token.
     * @param owner Address of the current owner of a token.
     */
    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC721InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC721InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param tokenId Identifier number of a token.
     */
    error ERC721InsufficientApproval(address operator, uint256 tokenId);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC721InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC721InvalidOperator(address operator);
}

/**
 * @dev Standard ERC-1155 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
 */
interface IERC1155Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     * @param tokenId Identifier number of a token.
     */
    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC1155InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC1155InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param owner Address of the current owner of a token.
     */
    error ERC1155MissingApprovalForAll(address operator, address owner);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC1155InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC1155InvalidOperator(address operator);

    /**
     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
     * Used in batch transfers.
     * @param idsLength Length of the array of token identifiers
     * @param valuesLength Length of the array of token amounts
     */
    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}

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


// OpenZeppelin Contracts (last updated v5.2.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.20;





/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * The default value of {decimals} is 18. To change this, you should override
 * this function so it returns a different value.
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC-20
 * applications.
 */
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
    mapping(address account => uint256) private _balances;

    mapping(address account => mapping(address spender => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the default value returned by this function, unless
     * it's overridden.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `value`.
     */
    function transfer(address to, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, value);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, value);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Skips emitting an {Approval} event indicating an allowance update. This is not
     * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `value`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `value`.
     */
    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, value);
        _transfer(from, to, value);
        return true;
    }

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _transfer(address from, address to, uint256 value) internal {
        if (from == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        if (to == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(from, to, value);
    }

    /**
     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
     * this function.
     *
     * Emits a {Transfer} event.
     */
    function _update(address from, address to, uint256 value) internal virtual {
        if (from == address(0)) {
            // Overflow check required: The rest of the code assumes that totalSupply never overflows
            _totalSupply += value;
        } else {
            uint256 fromBalance = _balances[from];
            if (fromBalance < value) {
                revert ERC20InsufficientBalance(from, fromBalance, value);
            }
            unchecked {
                // Overflow not possible: value <= fromBalance <= totalSupply.
                _balances[from] = fromBalance - value;
            }
        }

        if (to == address(0)) {
            unchecked {
                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
                _totalSupply -= value;
            }
        } else {
            unchecked {
                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
                _balances[to] += value;
            }
        }

        emit Transfer(from, to, value);
    }

    /**
     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
     * Relies on the `_update` mechanism
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _mint(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(address(0), account, value);
    }

    /**
     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
     * Relies on the `_update` mechanism.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead
     */
    function _burn(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        _update(account, address(0), value);
    }

    /**
     * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     *
     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
     */
    function _approve(address owner, address spender, uint256 value) internal {
        _approve(owner, spender, value, true);
    }

    /**
     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
     *
     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
     * `Approval` event during `transferFrom` operations.
     *
     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
     * true using the following override:
     *
     * ```solidity
     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
     *     super._approve(owner, spender, value, true);
     * }
     * ```
     *
     * Requirements are the same as {_approve}.
     */
    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
        if (owner == address(0)) {
            revert ERC20InvalidApprover(address(0));
        }
        if (spender == address(0)) {
            revert ERC20InvalidSpender(address(0));
        }
        _allowances[owner][spender] = value;
        if (emitEvent) {
            emit Approval(owner, spender, value);
        }
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `value`.
     *
     * Does not update the allowance value in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Does not emit an {Approval} event.
     */
    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance < type(uint256).max) {
            if (currentAllowance < value) {
                revert ERC20InsufficientAllowance(spender, currentAllowance, value);
            }
            unchecked {
                _approve(owner, spender, currentAllowance - value, false);
            }
        }
    }
}

// File: @openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Burnable.sol)

pragma solidity ^0.8.20;



/**
 * @dev Extension of {ERC20} that allows token holders to destroy both their own
 * tokens and those that they have an allowance for, in a way that can be
 * recognized off-chain (via event analysis).
 */
abstract contract ERC20Burnable is Context, ERC20 {
    /**
     * @dev Destroys a `value` amount of tokens from the caller.
     *
     * See {ERC20-_burn}.
     */
    function burn(uint256 value) public virtual {
        _burn(_msgSender(), value);
    }

    /**
     * @dev Destroys a `value` amount of tokens from `account`, deducting from
     * the caller's allowance.
     *
     * See {ERC20-_burn} and {ERC20-allowance}.
     *
     * Requirements:
     *
     * - the caller must have allowance for ``accounts``'s tokens of at least
     * `value`.
     */
    function burnFrom(address account, uint256 value) public virtual {
        _spendAllowance(account, _msgSender(), value);
        _burn(account, value);
    }
}

// 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: @openzeppelin/contracts/access/Ownable2Step.sol


// OpenZeppelin Contracts (last updated v5.1.0) (access/Ownable2Step.sol)

pragma solidity ^0.8.20;


/**
 * @dev Contract module which provides access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * This extension of the {Ownable} contract includes a two-step mechanism to transfer
 * ownership, where the new owner must call {acceptOwnership} in order to replace the
 * old one. This can help prevent common mistakes, such as transfers of ownership to
 * incorrect accounts, or to contracts that are unable to interact with the
 * permission system.
 *
 * The initial owner is specified at deployment time in the constructor for `Ownable`. This
 * can later be changed with {transferOwnership} and {acceptOwnership}.
 *
 * This module is used through inheritance. It will make available all functions
 * from parent (Ownable).
 */
abstract contract Ownable2Step is Ownable {
    address private _pendingOwner;

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

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

    /**
     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
     * Can only be called by the current owner.
     *
     * Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer.
     */
    function transferOwnership(address newOwner) public virtual override onlyOwner {
        _pendingOwner = newOwner;
        emit OwnershipTransferStarted(owner(), newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual override {
        delete _pendingOwner;
        super._transferOwnership(newOwner);
    }

    /**
     * @dev The new owner accepts the ownership transfer.
     */
    function acceptOwnership() public virtual {
        address sender = _msgSender();
        if (pendingOwner() != sender) {
            revert OwnableUnauthorizedAccount(sender);
        }
        _transferOwnership(sender);
    }
}

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


// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)

pragma solidity ^0.8.20;

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

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

    uint256 private _status;

    /**
     * @dev Unauthorized reentrant call.
     */
    error ReentrancyGuardReentrantCall();

    constructor() {
        _status = NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be NOT_ENTERED
        if (_status == ENTERED) {
            revert ReentrancyGuardReentrantCall();
        }

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

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

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == ENTERED;
    }
}

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


// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)

pragma solidity ^0.8.20;

/**
 * @dev Helper library for emitting standardized panic codes.
 *
 * ```solidity
 * contract Example {
 *      using Panic for uint256;
 *
 *      // Use any of the declared internal constants
 *      function foo() { Panic.GENERIC.panic(); }
 *
 *      // Alternatively
 *      function foo() { Panic.panic(Panic.GENERIC); }
 * }
 * ```
 *
 * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].
 *
 * _Available since v5.1._
 */
// slither-disable-next-line unused-state
library Panic {
    /// @dev generic / unspecified error
    uint256 internal constant GENERIC = 0x00;
    /// @dev used by the assert() builtin
    uint256 internal constant ASSERT = 0x01;
    /// @dev arithmetic underflow or overflow
    uint256 internal constant UNDER_OVERFLOW = 0x11;
    /// @dev division or modulo by zero
    uint256 internal constant DIVISION_BY_ZERO = 0x12;
    /// @dev enum conversion error
    uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;
    /// @dev invalid encoding in storage
    uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;
    /// @dev empty array pop
    uint256 internal constant EMPTY_ARRAY_POP = 0x31;
    /// @dev array out of bounds access
    uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;
    /// @dev resource error (too large allocation or too large array)
    uint256 internal constant RESOURCE_ERROR = 0x41;
    /// @dev calling invalid internal function
    uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;

    /// @dev Reverts with a panic code. Recommended to use with
    /// the internal constants with predefined codes.
    function panic(uint256 code) internal pure {
        assembly ("memory-safe") {
            mstore(0x00, 0x4e487b71)
            mstore(0x20, code)
            revert(0x1c, 0x24)
        }
    }
}

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


// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.

pragma solidity ^0.8.20;

/**
 * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such an operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeCast {
    /**
     * @dev Value doesn't fit in an uint of `bits` size.
     */
    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);

    /**
     * @dev An int value doesn't fit in an uint of `bits` size.
     */
    error SafeCastOverflowedIntToUint(int256 value);

    /**
     * @dev Value doesn't fit in an int of `bits` size.
     */
    error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);

    /**
     * @dev An uint value doesn't fit in an int of `bits` size.
     */
    error SafeCastOverflowedUintToInt(uint256 value);

    /**
     * @dev Returns the downcasted uint248 from uint256, reverting on
     * overflow (when the input is greater than largest uint248).
     *
     * Counterpart to Solidity's `uint248` operator.
     *
     * Requirements:
     *
     * - input must fit into 248 bits
     */
    function toUint248(uint256 value) internal pure returns (uint248) {
        if (value > type(uint248).max) {
            revert SafeCastOverflowedUintDowncast(248, value);
        }
        return uint248(value);
    }

    /**
     * @dev Returns the downcasted uint240 from uint256, reverting on
     * overflow (when the input is greater than largest uint240).
     *
     * Counterpart to Solidity's `uint240` operator.
     *
     * Requirements:
     *
     * - input must fit into 240 bits
     */
    function toUint240(uint256 value) internal pure returns (uint240) {
        if (value > type(uint240).max) {
            revert SafeCastOverflowedUintDowncast(240, value);
        }
        return uint240(value);
    }

    /**
     * @dev Returns the downcasted uint232 from uint256, reverting on
     * overflow (when the input is greater than largest uint232).
     *
     * Counterpart to Solidity's `uint232` operator.
     *
     * Requirements:
     *
     * - input must fit into 232 bits
     */
    function toUint232(uint256 value) internal pure returns (uint232) {
        if (value > type(uint232).max) {
            revert SafeCastOverflowedUintDowncast(232, value);
        }
        return uint232(value);
    }

    /**
     * @dev Returns the downcasted uint224 from uint256, reverting on
     * overflow (when the input is greater than largest uint224).
     *
     * Counterpart to Solidity's `uint224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     */
    function toUint224(uint256 value) internal pure returns (uint224) {
        if (value > type(uint224).max) {
            revert SafeCastOverflowedUintDowncast(224, value);
        }
        return uint224(value);
    }

    /**
     * @dev Returns the downcasted uint216 from uint256, reverting on
     * overflow (when the input is greater than largest uint216).
     *
     * Counterpart to Solidity's `uint216` operator.
     *
     * Requirements:
     *
     * - input must fit into 216 bits
     */
    function toUint216(uint256 value) internal pure returns (uint216) {
        if (value > type(uint216).max) {
            revert SafeCastOverflowedUintDowncast(216, value);
        }
        return uint216(value);
    }

    /**
     * @dev Returns the downcasted uint208 from uint256, reverting on
     * overflow (when the input is greater than largest uint208).
     *
     * Counterpart to Solidity's `uint208` operator.
     *
     * Requirements:
     *
     * - input must fit into 208 bits
     */
    function toUint208(uint256 value) internal pure returns (uint208) {
        if (value > type(uint208).max) {
            revert SafeCastOverflowedUintDowncast(208, value);
        }
        return uint208(value);
    }

    /**
     * @dev Returns the downcasted uint200 from uint256, reverting on
     * overflow (when the input is greater than largest uint200).
     *
     * Counterpart to Solidity's `uint200` operator.
     *
     * Requirements:
     *
     * - input must fit into 200 bits
     */
    function toUint200(uint256 value) internal pure returns (uint200) {
        if (value > type(uint200).max) {
            revert SafeCastOverflowedUintDowncast(200, value);
        }
        return uint200(value);
    }

    /**
     * @dev Returns the downcasted uint192 from uint256, reverting on
     * overflow (when the input is greater than largest uint192).
     *
     * Counterpart to Solidity's `uint192` operator.
     *
     * Requirements:
     *
     * - input must fit into 192 bits
     */
    function toUint192(uint256 value) internal pure returns (uint192) {
        if (value > type(uint192).max) {
            revert SafeCastOverflowedUintDowncast(192, value);
        }
        return uint192(value);
    }

    /**
     * @dev Returns the downcasted uint184 from uint256, reverting on
     * overflow (when the input is greater than largest uint184).
     *
     * Counterpart to Solidity's `uint184` operator.
     *
     * Requirements:
     *
     * - input must fit into 184 bits
     */
    function toUint184(uint256 value) internal pure returns (uint184) {
        if (value > type(uint184).max) {
            revert SafeCastOverflowedUintDowncast(184, value);
        }
        return uint184(value);
    }

    /**
     * @dev Returns the downcasted uint176 from uint256, reverting on
     * overflow (when the input is greater than largest uint176).
     *
     * Counterpart to Solidity's `uint176` operator.
     *
     * Requirements:
     *
     * - input must fit into 176 bits
     */
    function toUint176(uint256 value) internal pure returns (uint176) {
        if (value > type(uint176).max) {
            revert SafeCastOverflowedUintDowncast(176, value);
        }
        return uint176(value);
    }

    /**
     * @dev Returns the downcasted uint168 from uint256, reverting on
     * overflow (when the input is greater than largest uint168).
     *
     * Counterpart to Solidity's `uint168` operator.
     *
     * Requirements:
     *
     * - input must fit into 168 bits
     */
    function toUint168(uint256 value) internal pure returns (uint168) {
        if (value > type(uint168).max) {
            revert SafeCastOverflowedUintDowncast(168, value);
        }
        return uint168(value);
    }

    /**
     * @dev Returns the downcasted uint160 from uint256, reverting on
     * overflow (when the input is greater than largest uint160).
     *
     * Counterpart to Solidity's `uint160` operator.
     *
     * Requirements:
     *
     * - input must fit into 160 bits
     */
    function toUint160(uint256 value) internal pure returns (uint160) {
        if (value > type(uint160).max) {
            revert SafeCastOverflowedUintDowncast(160, value);
        }
        return uint160(value);
    }

    /**
     * @dev Returns the downcasted uint152 from uint256, reverting on
     * overflow (when the input is greater than largest uint152).
     *
     * Counterpart to Solidity's `uint152` operator.
     *
     * Requirements:
     *
     * - input must fit into 152 bits
     */
    function toUint152(uint256 value) internal pure returns (uint152) {
        if (value > type(uint152).max) {
            revert SafeCastOverflowedUintDowncast(152, value);
        }
        return uint152(value);
    }

    /**
     * @dev Returns the downcasted uint144 from uint256, reverting on
     * overflow (when the input is greater than largest uint144).
     *
     * Counterpart to Solidity's `uint144` operator.
     *
     * Requirements:
     *
     * - input must fit into 144 bits
     */
    function toUint144(uint256 value) internal pure returns (uint144) {
        if (value > type(uint144).max) {
            revert SafeCastOverflowedUintDowncast(144, value);
        }
        return uint144(value);
    }

    /**
     * @dev Returns the downcasted uint136 from uint256, reverting on
     * overflow (when the input is greater than largest uint136).
     *
     * Counterpart to Solidity's `uint136` operator.
     *
     * Requirements:
     *
     * - input must fit into 136 bits
     */
    function toUint136(uint256 value) internal pure returns (uint136) {
        if (value > type(uint136).max) {
            revert SafeCastOverflowedUintDowncast(136, value);
        }
        return uint136(value);
    }

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        if (value > type(uint128).max) {
            revert SafeCastOverflowedUintDowncast(128, value);
        }
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint120 from uint256, reverting on
     * overflow (when the input is greater than largest uint120).
     *
     * Counterpart to Solidity's `uint120` operator.
     *
     * Requirements:
     *
     * - input must fit into 120 bits
     */
    function toUint120(uint256 value) internal pure returns (uint120) {
        if (value > type(uint120).max) {
            revert SafeCastOverflowedUintDowncast(120, value);
        }
        return uint120(value);
    }

    /**
     * @dev Returns the downcasted uint112 from uint256, reverting on
     * overflow (when the input is greater than largest uint112).
     *
     * Counterpart to Solidity's `uint112` operator.
     *
     * Requirements:
     *
     * - input must fit into 112 bits
     */
    function toUint112(uint256 value) internal pure returns (uint112) {
        if (value > type(uint112).max) {
            revert SafeCastOverflowedUintDowncast(112, value);
        }
        return uint112(value);
    }

    /**
     * @dev Returns the downcasted uint104 from uint256, reverting on
     * overflow (when the input is greater than largest uint104).
     *
     * Counterpart to Solidity's `uint104` operator.
     *
     * Requirements:
     *
     * - input must fit into 104 bits
     */
    function toUint104(uint256 value) internal pure returns (uint104) {
        if (value > type(uint104).max) {
            revert SafeCastOverflowedUintDowncast(104, value);
        }
        return uint104(value);
    }

    /**
     * @dev Returns the downcasted uint96 from uint256, reverting on
     * overflow (when the input is greater than largest uint96).
     *
     * Counterpart to Solidity's `uint96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     */
    function toUint96(uint256 value) internal pure returns (uint96) {
        if (value > type(uint96).max) {
            revert SafeCastOverflowedUintDowncast(96, value);
        }
        return uint96(value);
    }

    /**
     * @dev Returns the downcasted uint88 from uint256, reverting on
     * overflow (when the input is greater than largest uint88).
     *
     * Counterpart to Solidity's `uint88` operator.
     *
     * Requirements:
     *
     * - input must fit into 88 bits
     */
    function toUint88(uint256 value) internal pure returns (uint88) {
        if (value > type(uint88).max) {
            revert SafeCastOverflowedUintDowncast(88, value);
        }
        return uint88(value);
    }

    /**
     * @dev Returns the downcasted uint80 from uint256, reverting on
     * overflow (when the input is greater than largest uint80).
     *
     * Counterpart to Solidity's `uint80` operator.
     *
     * Requirements:
     *
     * - input must fit into 80 bits
     */
    function toUint80(uint256 value) internal pure returns (uint80) {
        if (value > type(uint80).max) {
            revert SafeCastOverflowedUintDowncast(80, value);
        }
        return uint80(value);
    }

    /**
     * @dev Returns the downcasted uint72 from uint256, reverting on
     * overflow (when the input is greater than largest uint72).
     *
     * Counterpart to Solidity's `uint72` operator.
     *
     * Requirements:
     *
     * - input must fit into 72 bits
     */
    function toUint72(uint256 value) internal pure returns (uint72) {
        if (value > type(uint72).max) {
            revert SafeCastOverflowedUintDowncast(72, value);
        }
        return uint72(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        if (value > type(uint64).max) {
            revert SafeCastOverflowedUintDowncast(64, value);
        }
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint56 from uint256, reverting on
     * overflow (when the input is greater than largest uint56).
     *
     * Counterpart to Solidity's `uint56` operator.
     *
     * Requirements:
     *
     * - input must fit into 56 bits
     */
    function toUint56(uint256 value) internal pure returns (uint56) {
        if (value > type(uint56).max) {
            revert SafeCastOverflowedUintDowncast(56, value);
        }
        return uint56(value);
    }

    /**
     * @dev Returns the downcasted uint48 from uint256, reverting on
     * overflow (when the input is greater than largest uint48).
     *
     * Counterpart to Solidity's `uint48` operator.
     *
     * Requirements:
     *
     * - input must fit into 48 bits
     */
    function toUint48(uint256 value) internal pure returns (uint48) {
        if (value > type(uint48).max) {
            revert SafeCastOverflowedUintDowncast(48, value);
        }
        return uint48(value);
    }

    /**
     * @dev Returns the downcasted uint40 from uint256, reverting on
     * overflow (when the input is greater than largest uint40).
     *
     * Counterpart to Solidity's `uint40` operator.
     *
     * Requirements:
     *
     * - input must fit into 40 bits
     */
    function toUint40(uint256 value) internal pure returns (uint40) {
        if (value > type(uint40).max) {
            revert SafeCastOverflowedUintDowncast(40, value);
        }
        return uint40(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        if (value > type(uint32).max) {
            revert SafeCastOverflowedUintDowncast(32, value);
        }
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint24 from uint256, reverting on
     * overflow (when the input is greater than largest uint24).
     *
     * Counterpart to Solidity's `uint24` operator.
     *
     * Requirements:
     *
     * - input must fit into 24 bits
     */
    function toUint24(uint256 value) internal pure returns (uint24) {
        if (value > type(uint24).max) {
            revert SafeCastOverflowedUintDowncast(24, value);
        }
        return uint24(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        if (value > type(uint16).max) {
            revert SafeCastOverflowedUintDowncast(16, value);
        }
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        if (value > type(uint8).max) {
            revert SafeCastOverflowedUintDowncast(8, value);
        }
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        if (value < 0) {
            revert SafeCastOverflowedIntToUint(value);
        }
        return uint256(value);
    }

    /**
     * @dev Returns the downcasted int248 from int256, reverting on
     * overflow (when the input is less than smallest int248 or
     * greater than largest int248).
     *
     * Counterpart to Solidity's `int248` operator.
     *
     * Requirements:
     *
     * - input must fit into 248 bits
     */
    function toInt248(int256 value) internal pure returns (int248 downcasted) {
        downcasted = int248(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(248, value);
        }
    }

    /**
     * @dev Returns the downcasted int240 from int256, reverting on
     * overflow (when the input is less than smallest int240 or
     * greater than largest int240).
     *
     * Counterpart to Solidity's `int240` operator.
     *
     * Requirements:
     *
     * - input must fit into 240 bits
     */
    function toInt240(int256 value) internal pure returns (int240 downcasted) {
        downcasted = int240(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(240, value);
        }
    }

    /**
     * @dev Returns the downcasted int232 from int256, reverting on
     * overflow (when the input is less than smallest int232 or
     * greater than largest int232).
     *
     * Counterpart to Solidity's `int232` operator.
     *
     * Requirements:
     *
     * - input must fit into 232 bits
     */
    function toInt232(int256 value) internal pure returns (int232 downcasted) {
        downcasted = int232(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(232, value);
        }
    }

    /**
     * @dev Returns the downcasted int224 from int256, reverting on
     * overflow (when the input is less than smallest int224 or
     * greater than largest int224).
     *
     * Counterpart to Solidity's `int224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     */
    function toInt224(int256 value) internal pure returns (int224 downcasted) {
        downcasted = int224(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(224, value);
        }
    }

    /**
     * @dev Returns the downcasted int216 from int256, reverting on
     * overflow (when the input is less than smallest int216 or
     * greater than largest int216).
     *
     * Counterpart to Solidity's `int216` operator.
     *
     * Requirements:
     *
     * - input must fit into 216 bits
     */
    function toInt216(int256 value) internal pure returns (int216 downcasted) {
        downcasted = int216(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(216, value);
        }
    }

    /**
     * @dev Returns the downcasted int208 from int256, reverting on
     * overflow (when the input is less than smallest int208 or
     * greater than largest int208).
     *
     * Counterpart to Solidity's `int208` operator.
     *
     * Requirements:
     *
     * - input must fit into 208 bits
     */
    function toInt208(int256 value) internal pure returns (int208 downcasted) {
        downcasted = int208(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(208, value);
        }
    }

    /**
     * @dev Returns the downcasted int200 from int256, reverting on
     * overflow (when the input is less than smallest int200 or
     * greater than largest int200).
     *
     * Counterpart to Solidity's `int200` operator.
     *
     * Requirements:
     *
     * - input must fit into 200 bits
     */
    function toInt200(int256 value) internal pure returns (int200 downcasted) {
        downcasted = int200(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(200, value);
        }
    }

    /**
     * @dev Returns the downcasted int192 from int256, reverting on
     * overflow (when the input is less than smallest int192 or
     * greater than largest int192).
     *
     * Counterpart to Solidity's `int192` operator.
     *
     * Requirements:
     *
     * - input must fit into 192 bits
     */
    function toInt192(int256 value) internal pure returns (int192 downcasted) {
        downcasted = int192(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(192, value);
        }
    }

    /**
     * @dev Returns the downcasted int184 from int256, reverting on
     * overflow (when the input is less than smallest int184 or
     * greater than largest int184).
     *
     * Counterpart to Solidity's `int184` operator.
     *
     * Requirements:
     *
     * - input must fit into 184 bits
     */
    function toInt184(int256 value) internal pure returns (int184 downcasted) {
        downcasted = int184(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(184, value);
        }
    }

    /**
     * @dev Returns the downcasted int176 from int256, reverting on
     * overflow (when the input is less than smallest int176 or
     * greater than largest int176).
     *
     * Counterpart to Solidity's `int176` operator.
     *
     * Requirements:
     *
     * - input must fit into 176 bits
     */
    function toInt176(int256 value) internal pure returns (int176 downcasted) {
        downcasted = int176(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(176, value);
        }
    }

    /**
     * @dev Returns the downcasted int168 from int256, reverting on
     * overflow (when the input is less than smallest int168 or
     * greater than largest int168).
     *
     * Counterpart to Solidity's `int168` operator.
     *
     * Requirements:
     *
     * - input must fit into 168 bits
     */
    function toInt168(int256 value) internal pure returns (int168 downcasted) {
        downcasted = int168(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(168, value);
        }
    }

    /**
     * @dev Returns the downcasted int160 from int256, reverting on
     * overflow (when the input is less than smallest int160 or
     * greater than largest int160).
     *
     * Counterpart to Solidity's `int160` operator.
     *
     * Requirements:
     *
     * - input must fit into 160 bits
     */
    function toInt160(int256 value) internal pure returns (int160 downcasted) {
        downcasted = int160(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(160, value);
        }
    }

    /**
     * @dev Returns the downcasted int152 from int256, reverting on
     * overflow (when the input is less than smallest int152 or
     * greater than largest int152).
     *
     * Counterpart to Solidity's `int152` operator.
     *
     * Requirements:
     *
     * - input must fit into 152 bits
     */
    function toInt152(int256 value) internal pure returns (int152 downcasted) {
        downcasted = int152(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(152, value);
        }
    }

    /**
     * @dev Returns the downcasted int144 from int256, reverting on
     * overflow (when the input is less than smallest int144 or
     * greater than largest int144).
     *
     * Counterpart to Solidity's `int144` operator.
     *
     * Requirements:
     *
     * - input must fit into 144 bits
     */
    function toInt144(int256 value) internal pure returns (int144 downcasted) {
        downcasted = int144(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(144, value);
        }
    }

    /**
     * @dev Returns the downcasted int136 from int256, reverting on
     * overflow (when the input is less than smallest int136 or
     * greater than largest int136).
     *
     * Counterpart to Solidity's `int136` operator.
     *
     * Requirements:
     *
     * - input must fit into 136 bits
     */
    function toInt136(int256 value) internal pure returns (int136 downcasted) {
        downcasted = int136(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(136, value);
        }
    }

    /**
     * @dev Returns the downcasted int128 from int256, reverting on
     * overflow (when the input is less than smallest int128 or
     * greater than largest int128).
     *
     * Counterpart to Solidity's `int128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     */
    function toInt128(int256 value) internal pure returns (int128 downcasted) {
        downcasted = int128(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(128, value);
        }
    }

    /**
     * @dev Returns the downcasted int120 from int256, reverting on
     * overflow (when the input is less than smallest int120 or
     * greater than largest int120).
     *
     * Counterpart to Solidity's `int120` operator.
     *
     * Requirements:
     *
     * - input must fit into 120 bits
     */
    function toInt120(int256 value) internal pure returns (int120 downcasted) {
        downcasted = int120(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(120, value);
        }
    }

    /**
     * @dev Returns the downcasted int112 from int256, reverting on
     * overflow (when the input is less than smallest int112 or
     * greater than largest int112).
     *
     * Counterpart to Solidity's `int112` operator.
     *
     * Requirements:
     *
     * - input must fit into 112 bits
     */
    function toInt112(int256 value) internal pure returns (int112 downcasted) {
        downcasted = int112(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(112, value);
        }
    }

    /**
     * @dev Returns the downcasted int104 from int256, reverting on
     * overflow (when the input is less than smallest int104 or
     * greater than largest int104).
     *
     * Counterpart to Solidity's `int104` operator.
     *
     * Requirements:
     *
     * - input must fit into 104 bits
     */
    function toInt104(int256 value) internal pure returns (int104 downcasted) {
        downcasted = int104(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(104, value);
        }
    }

    /**
     * @dev Returns the downcasted int96 from int256, reverting on
     * overflow (when the input is less than smallest int96 or
     * greater than largest int96).
     *
     * Counterpart to Solidity's `int96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     */
    function toInt96(int256 value) internal pure returns (int96 downcasted) {
        downcasted = int96(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(96, value);
        }
    }

    /**
     * @dev Returns the downcasted int88 from int256, reverting on
     * overflow (when the input is less than smallest int88 or
     * greater than largest int88).
     *
     * Counterpart to Solidity's `int88` operator.
     *
     * Requirements:
     *
     * - input must fit into 88 bits
     */
    function toInt88(int256 value) internal pure returns (int88 downcasted) {
        downcasted = int88(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(88, value);
        }
    }

    /**
     * @dev Returns the downcasted int80 from int256, reverting on
     * overflow (when the input is less than smallest int80 or
     * greater than largest int80).
     *
     * Counterpart to Solidity's `int80` operator.
     *
     * Requirements:
     *
     * - input must fit into 80 bits
     */
    function toInt80(int256 value) internal pure returns (int80 downcasted) {
        downcasted = int80(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(80, value);
        }
    }

    /**
     * @dev Returns the downcasted int72 from int256, reverting on
     * overflow (when the input is less than smallest int72 or
     * greater than largest int72).
     *
     * Counterpart to Solidity's `int72` operator.
     *
     * Requirements:
     *
     * - input must fit into 72 bits
     */
    function toInt72(int256 value) internal pure returns (int72 downcasted) {
        downcasted = int72(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(72, value);
        }
    }

    /**
     * @dev Returns the downcasted int64 from int256, reverting on
     * overflow (when the input is less than smallest int64 or
     * greater than largest int64).
     *
     * Counterpart to Solidity's `int64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     */
    function toInt64(int256 value) internal pure returns (int64 downcasted) {
        downcasted = int64(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(64, value);
        }
    }

    /**
     * @dev Returns the downcasted int56 from int256, reverting on
     * overflow (when the input is less than smallest int56 or
     * greater than largest int56).
     *
     * Counterpart to Solidity's `int56` operator.
     *
     * Requirements:
     *
     * - input must fit into 56 bits
     */
    function toInt56(int256 value) internal pure returns (int56 downcasted) {
        downcasted = int56(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(56, value);
        }
    }

    /**
     * @dev Returns the downcasted int48 from int256, reverting on
     * overflow (when the input is less than smallest int48 or
     * greater than largest int48).
     *
     * Counterpart to Solidity's `int48` operator.
     *
     * Requirements:
     *
     * - input must fit into 48 bits
     */
    function toInt48(int256 value) internal pure returns (int48 downcasted) {
        downcasted = int48(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(48, value);
        }
    }

    /**
     * @dev Returns the downcasted int40 from int256, reverting on
     * overflow (when the input is less than smallest int40 or
     * greater than largest int40).
     *
     * Counterpart to Solidity's `int40` operator.
     *
     * Requirements:
     *
     * - input must fit into 40 bits
     */
    function toInt40(int256 value) internal pure returns (int40 downcasted) {
        downcasted = int40(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(40, value);
        }
    }

    /**
     * @dev Returns the downcasted int32 from int256, reverting on
     * overflow (when the input is less than smallest int32 or
     * greater than largest int32).
     *
     * Counterpart to Solidity's `int32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     */
    function toInt32(int256 value) internal pure returns (int32 downcasted) {
        downcasted = int32(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(32, value);
        }
    }

    /**
     * @dev Returns the downcasted int24 from int256, reverting on
     * overflow (when the input is less than smallest int24 or
     * greater than largest int24).
     *
     * Counterpart to Solidity's `int24` operator.
     *
     * Requirements:
     *
     * - input must fit into 24 bits
     */
    function toInt24(int256 value) internal pure returns (int24 downcasted) {
        downcasted = int24(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(24, value);
        }
    }

    /**
     * @dev Returns the downcasted int16 from int256, reverting on
     * overflow (when the input is less than smallest int16 or
     * greater than largest int16).
     *
     * Counterpart to Solidity's `int16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     */
    function toInt16(int256 value) internal pure returns (int16 downcasted) {
        downcasted = int16(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(16, value);
        }
    }

    /**
     * @dev Returns the downcasted int8 from int256, reverting on
     * overflow (when the input is less than smallest int8 or
     * greater than largest int8).
     *
     * Counterpart to Solidity's `int8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits
     */
    function toInt8(int256 value) internal pure returns (int8 downcasted) {
        downcasted = int8(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(8, value);
        }
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
        if (value > uint256(type(int256).max)) {
            revert SafeCastOverflowedUintToInt(value);
        }
        return int256(value);
    }

    /**
     * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.
     */
    function toUint(bool b) internal pure returns (uint256 u) {
        assembly ("memory-safe") {
            u := iszero(iszero(b))
        }
    }
}

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


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

pragma solidity ^0.8.20;



/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Floor, // Toward negative infinity
        Ceil, // Toward positive infinity
        Trunc, // Toward zero
        Expand // Away from zero
    }

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

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

    /**
     * @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow).
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
        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 success flag (no division by zero).
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

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

    /**
     * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.
     *
     * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.
     * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute
     * one branch when needed, making this function more expensive.
     */
    function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {
        unchecked {
            // branchless ternary works because:
            // b ^ (a ^ b) == a
            // b ^ 0 == b
            return b ^ ((a ^ b) * SafeCast.toUint(condition));
        }
    }

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

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

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

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds towards infinity instead
     * of rounding towards zero.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        if (b == 0) {
            // Guarantee the same behavior as in a regular Solidity division.
            Panic.panic(Panic.DIVISION_BY_ZERO);
        }

        // The following calculation ensures accurate ceiling division without overflow.
        // Since a is non-zero, (a - 1) / b will not overflow.
        // The largest possible result occurs when (a - 1) / b is type(uint256).max,
        // but the largest value we can obtain is type(uint256).max - 1, which happens
        // when a = type(uint256).max and b = 1.
        unchecked {
            return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);
        }
    }

    /**
     * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
     * denominator == 0.
     *
     * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by
     * Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use
            // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2²⁵⁶ + 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²⁵⁶. Also prevents denominator == 0.
            if (denominator <= prod1) {
                Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_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.

            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²⁵⁶ / 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²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such
            // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv ≡ 1 mod 2⁴.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
            // works in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2⁸
            inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶
            inverse *= 2 - denominator * inverse; // inverse mod 2³²
            inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴
            inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸
            inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶

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

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

    /**
     * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.
     *
     * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.
     * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.
     *
     * If the input value is not inversible, 0 is returned.
     *
     * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the
     * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.
     */
    function invMod(uint256 a, uint256 n) internal pure returns (uint256) {
        unchecked {
            if (n == 0) return 0;

            // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)
            // Used to compute integers x and y such that: ax + ny = gcd(a, n).
            // When the gcd is 1, then the inverse of a modulo n exists and it's x.
            // ax + ny = 1
            // ax = 1 + (-y)n
            // ax ≡ 1 (mod n) # x is the inverse of a modulo n

            // If the remainder is 0 the gcd is n right away.
            uint256 remainder = a % n;
            uint256 gcd = n;

            // Therefore the initial coefficients are:
            // ax + ny = gcd(a, n) = n
            // 0a + 1n = n
            int256 x = 0;
            int256 y = 1;

            while (remainder != 0) {
                uint256 quotient = gcd / remainder;

                (gcd, remainder) = (
                    // The old remainder is the next gcd to try.
                    remainder,
                    // Compute the next remainder.
                    // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd
                    // where gcd is at most n (capped to type(uint256).max)
                    gcd - remainder * quotient
                );

                (x, y) = (
                    // Increment the coefficient of a.
                    y,
                    // Decrement the coefficient of n.
                    // Can overflow, but the result is casted to uint256 so that the
                    // next value of y is "wrapped around" to a value between 0 and n - 1.
                    x - y * int256(quotient)
                );
            }

            if (gcd != 1) return 0; // No inverse exists.
            return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.
        }
    }

    /**
     * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.
     *
     * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is
     * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that
     * `a**(p-2)` is the modular multiplicative inverse of a in Fp.
     *
     * NOTE: this function does NOT check that `p` is a prime greater than `2`.
     */
    function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {
        unchecked {
            return Math.modExp(a, p - 2, p);
        }
    }

    /**
     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)
     *
     * Requirements:
     * - modulus can't be zero
     * - underlying staticcall to precompile must succeed
     *
     * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make
     * sure the chain you're using it on supports the precompiled contract for modular exponentiation
     * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,
     * the underlying function will succeed given the lack of a revert, but the result may be incorrectly
     * interpreted as 0.
     */
    function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {
        (bool success, uint256 result) = tryModExp(b, e, m);
        if (!success) {
            Panic.panic(Panic.DIVISION_BY_ZERO);
        }
        return result;
    }

    /**
     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).
     * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying
     * to operate modulo 0 or if the underlying precompile reverted.
     *
     * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain
     * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in
     * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack
     * of a revert, but the result may be incorrectly interpreted as 0.
     */
    function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {
        if (m == 0) return (false, 0);
        assembly ("memory-safe") {
            let ptr := mload(0x40)
            // | Offset    | Content    | Content (Hex)                                                      |
            // |-----------|------------|--------------------------------------------------------------------|
            // | 0x00:0x1f | size of b  | 0x0000000000000000000000000000000000000000000000000000000000000020 |
            // | 0x20:0x3f | size of e  | 0x0000000000000000000000000000000000000000000000000000000000000020 |
            // | 0x40:0x5f | size of m  | 0x0000000000000000000000000000000000000000000000000000000000000020 |
            // | 0x60:0x7f | value of b | 0x<.............................................................b> |
            // | 0x80:0x9f | value of e | 0x<.............................................................e> |
            // | 0xa0:0xbf | value of m | 0x<.............................................................m> |
            mstore(ptr, 0x20)
            mstore(add(ptr, 0x20), 0x20)
            mstore(add(ptr, 0x40), 0x20)
            mstore(add(ptr, 0x60), b)
            mstore(add(ptr, 0x80), e)
            mstore(add(ptr, 0xa0), m)

            // Given the result < m, it's guaranteed to fit in 32 bytes,
            // so we can use the memory scratch space located at offset 0.
            success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)
            result := mload(0x00)
        }
    }

    /**
     * @dev Variant of {modExp} that supports inputs of arbitrary length.
     */
    function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {
        (bool success, bytes memory result) = tryModExp(b, e, m);
        if (!success) {
            Panic.panic(Panic.DIVISION_BY_ZERO);
        }
        return result;
    }

    /**
     * @dev Variant of {tryModExp} that supports inputs of arbitrary length.
     */
    function tryModExp(
        bytes memory b,
        bytes memory e,
        bytes memory m
    ) internal view returns (bool success, bytes memory result) {
        if (_zeroBytes(m)) return (false, new bytes(0));

        uint256 mLen = m.length;

        // Encode call args in result and move the free memory pointer
        result = abi.encodePacked(b.length, e.length, mLen, b, e, m);

        assembly ("memory-safe") {
            let dataPtr := add(result, 0x20)
            // Write result on top of args to avoid allocating extra memory.
            success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)
            // Overwrite the length.
            // result.length > returndatasize() is guaranteed because returndatasize() == m.length
            mstore(result, mLen)
            // Set the memory pointer after the returned data.
            mstore(0x40, add(dataPtr, mLen))
        }
    }

    /**
     * @dev Returns whether the provided byte array is zero.
     */
    function _zeroBytes(bytes memory byteArray) private pure returns (bool) {
        for (uint256 i = 0; i < byteArray.length; ++i) {
            if (byteArray[i] != 0) {
                return false;
            }
        }
        return true;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
     * towards zero.
     *
     * This method is based on Newton's method for computing square roots; the algorithm is restricted to only
     * using integer operations.
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        unchecked {
            // Take care of easy edge cases when a == 0 or a == 1
            if (a <= 1) {
                return a;
            }

            // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a
            // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between
            // the current value as `ε_n = | x_n - sqrt(a) |`.
            //
            // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root
            // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is
            // bigger than any uint256.
            //
            // By noticing that
            // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`
            // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar
            // to the msb function.
            uint256 aa = a;
            uint256 xn = 1;

            if (aa >= (1 << 128)) {
                aa >>= 128;
                xn <<= 64;
            }
            if (aa >= (1 << 64)) {
                aa >>= 64;
                xn <<= 32;
            }
            if (aa >= (1 << 32)) {
                aa >>= 32;
                xn <<= 16;
            }
            if (aa >= (1 << 16)) {
                aa >>= 16;
                xn <<= 8;
            }
            if (aa >= (1 << 8)) {
                aa >>= 8;
                xn <<= 4;
            }
            if (aa >= (1 << 4)) {
                aa >>= 4;
                xn <<= 2;
            }
            if (aa >= (1 << 2)) {
                xn <<= 1;
            }

            // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).
            //
            // We can refine our estimation by noticing that the middle of that interval minimizes the error.
            // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).
            // This is going to be our x_0 (and ε_0)
            xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)

            // From here, Newton's method give us:
            // x_{n+1} = (x_n + a / x_n) / 2
            //
            // One should note that:
            // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a
            //              = ((x_n² + a) / (2 * x_n))² - a
            //              = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a
            //              = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)
            //              = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)
            //              = (x_n² - a)² / (2 * x_n)²
            //              = ((x_n² - a) / (2 * x_n))²
            //              ≥ 0
            // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n
            //
            // This gives us the proof of quadratic convergence of the sequence:
            // ε_{n+1} = | x_{n+1} - sqrt(a) |
            //         = | (x_n + a / x_n) / 2 - sqrt(a) |
            //         = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |
            //         = | (x_n - sqrt(a))² / (2 * x_n) |
            //         = | ε_n² / (2 * x_n) |
            //         = ε_n² / | (2 * x_n) |
            //
            // For the first iteration, we have a special case where x_0 is known:
            // ε_1 = ε_0² / | (2 * x_0) |
            //     ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))
            //     ≤ 2**(2*e-4) / (3 * 2**(e-1))
            //     ≤ 2**(e-3) / 3
            //     ≤ 2**(e-3-log2(3))
            //     ≤ 2**(e-4.5)
            //
            // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:
            // ε_{n+1} = ε_n² / | (2 * x_n) |
            //         ≤ (2**(e-k))² / (2 * 2**(e-1))
            //         ≤ 2**(2*e-2*k) / 2**e
            //         ≤ 2**(e-2*k)
            xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5)  -- special case, see above
            xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9)    -- general case with k = 4.5
            xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18)   -- general case with k = 9
            xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36)   -- general case with k = 18
            xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72)   -- general case with k = 36
            xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144)  -- general case with k = 72

            // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision
            // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either
            // sqrt(a) or sqrt(a) + 1.
            return xn - SafeCast.toUint(xn > a / xn);
        }
    }

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

    /**
     * @dev Return the log in base 2 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        uint256 exp;
        unchecked {
            exp = 128 * SafeCast.toUint(value > (1 << 128) - 1);
            value >>= exp;
            result += exp;

            exp = 64 * SafeCast.toUint(value > (1 << 64) - 1);
            value >>= exp;
            result += exp;

            exp = 32 * SafeCast.toUint(value > (1 << 32) - 1);
            value >>= exp;
            result += exp;

            exp = 16 * SafeCast.toUint(value > (1 << 16) - 1);
            value >>= exp;
            result += exp;

            exp = 8 * SafeCast.toUint(value > (1 << 8) - 1);
            value >>= exp;
            result += exp;

            exp = 4 * SafeCast.toUint(value > (1 << 4) - 1);
            value >>= exp;
            result += exp;

            exp = 2 * SafeCast.toUint(value > (1 << 2) - 1);
            value >>= exp;
            result += exp;

            result += SafeCast.toUint(value > 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);
        }
    }

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

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

    /**
     * @dev Return the log in base 256 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        uint256 isGt;
        unchecked {
            isGt = SafeCast.toUint(value > (1 << 128) - 1);
            value >>= isGt * 128;
            result += isGt * 16;

            isGt = SafeCast.toUint(value > (1 << 64) - 1);
            value >>= isGt * 64;
            result += isGt * 8;

            isGt = SafeCast.toUint(value > (1 << 32) - 1);
            value >>= isGt * 32;
            result += isGt * 4;

            isGt = SafeCast.toUint(value > (1 << 16) - 1);
            value >>= isGt * 16;
            result += isGt * 2;

            result += SafeCast.toUint(value > (1 << 8) - 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);
        }
    }

    /**
     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
     */
    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
        return uint8(rounding) % 2 == 1;
    }
}

// File: contracts/EGGS.sol

//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;





contract EGGS is ERC20Burnable, Ownable2Step, ReentrancyGuard {
    address payable public FEE_ADDRESS;

    uint256 private constant MIN = 1000;

    uint16 public sell_fee = 975;
    uint16 public buy_fee = 975;
    uint16 public buy_fee_leverage = 10;
    uint16 private constant FEE_BASE_1000 = 1000;

    uint16 private constant FEES_BUY = 125;
    uint16 private constant FEES_SELL = 125;

    bool public start = false;

    uint128 private constant SONICinWEI = 1 * 10 ** 18;

    uint256 private totalBorrowed = 0;
    uint256 private totalCollateral = 0;

    uint128 public constant maxSupply = 10e28;
    uint256 public totalMinted;
    uint256 public lastPrice = 0;

    struct Loan {
        uint256 collateral; // shares of token staked
        uint256 borrowed; // user reward per token paid
        uint256 endDate;
        uint256 numberOfDays;
    }

    mapping(address => Loan) public Loans;

    mapping(uint256 => uint256) public BorrowedByDate;
    mapping(uint256 => uint256) public CollateralByDate;
    uint256 public lastLiquidationDate;
    event Price(uint256 time, uint256 price, uint256 volumeInSonic);
    event MaxUpdated(uint256 max);
    event SellFeeUpdated(uint256 sellFee);
    event FeeAddressUpdated(address _address);
    event BuyFeeUpdated(uint256 buyFee);
    event LeverageFeeUpdated(uint256 leverageFee);
    event Started(bool started);
    event Liquidate(uint256 time, uint256 amount);
    event LoanDataUpdate(
        uint256 collateralByDate,
        uint256 borrowedByDate,
        uint256 totalBorrowed,
        uint256 totalCollateral
    );
    event SendSonic(address to, uint256 amount);

    constructor() ERC20("Eggs", "EGGS") Ownable(msg.sender) {
        lastLiquidationDate = getMidnightTimestamp(block.timestamp);
    }
    function setStart() public payable onlyOwner {
        require(FEE_ADDRESS != address(0x0), "Must set fee address");
        uint256 teamMint = msg.value * MIN;
        require(teamMint >= 1 ether);
        mint(msg.sender, teamMint);

        _transfer(
            msg.sender,
            0x000000000000000000000000000000000000dEaD,
            1 ether
        );
        start = true;
        emit Started(true);
    }

    function mint(address to, uint256 value) private {
        require(to != address(0x0), "Can't mint to to 0x0 address");
        totalMinted = totalMinted + value;
        require(totalMinted <= maxSupply, "NO MORE EGGS");

        _mint(to, value);
    }

    function setFeeAddress(address _address) external onlyOwner {
        require(
            _address != address(0x0),
            "Can't set fee address to 0x0 address"
        );
        FEE_ADDRESS = payable(_address);
        emit FeeAddressUpdated(_address);
    }

    function setBuyFee(uint16 amount) external onlyOwner {
        require(amount <= 992, "buy fee must be greater than FEES_BUY");
        require(amount >= 975, "buy fee must be less than 2.5%");
        buy_fee = amount;
        emit BuyFeeUpdated(amount);
    }
    function setBuyFeeLeverage(uint16 amount) external onlyOwner {
        require(amount <= 25, "leverage buy fee must be less 2.5%");
        require(amount >= 0, "leverage buy fee must be greater than 0%");
        buy_fee_leverage = amount;
        emit LeverageFeeUpdated(amount);
    }
    function setSellFee(uint16 amount) external onlyOwner {
        require(amount <= 992, "sell fee must be greater than FEES_SELL");
        require(amount >= 975, "sell fee must be less than 2.5%");
        sell_fee = amount;
        emit SellFeeUpdated(amount);
    }
    function buy(address receiver) external payable nonReentrant {
        liquidate();
        require(start, "Trading must be initialized");

        require(receiver != address(0x0), "Reciever cannot be 0x0 address");

        // Mint Eggs to sender
        // AUDIT: to user round down
        uint256 eggs = SONICtoEGGS(msg.value);

        mint(receiver, (eggs * getBuyFee()) / FEE_BASE_1000);

        // Team fee
        uint256 feeAddressAmount = msg.value / FEES_BUY;
        require(feeAddressAmount > MIN, "must trade over min");
        sendSonic(FEE_ADDRESS, feeAddressAmount);

        safetyCheck(msg.value);
    }
    function sell(uint256 eggs) external nonReentrant {
        liquidate();

        // Total Eth to be sent
        // AUDIT: to user round down
        uint256 sonic = EGGStoSONIC(eggs);

        // Burn of JAY
        uint256 feeAddressAmount = sonic / FEES_SELL;
        _burn(msg.sender, eggs);

        // Payment to sender
        sendSonic(msg.sender, (sonic * sell_fee) / FEE_BASE_1000);

        // Team fee

        require(feeAddressAmount > MIN, "must trade over min");
        sendSonic(FEE_ADDRESS, feeAddressAmount);

        safetyCheck(sonic);
    }

    // Calculation may be off if liqudation is due to occur
    function getBuyAmount(uint256 amount) public view returns (uint256) {
        uint256 eggs = SONICtoEGGSNoTrade(amount);
        return ((eggs * getBuyFee()) / FEE_BASE_1000);
    }
    function leverageFee(
        uint256 sonic,
        uint256 numberOfDays
    ) public view returns (uint256) {
        uint256 mintFee = (sonic * buy_fee_leverage) / FEE_BASE_1000;

        uint256 interest = getInterestFee(sonic, numberOfDays);

        return (mintFee + interest);
    }

    function leverage(
        uint256 sonic,
        uint256 numberOfDays
    ) public payable nonReentrant {
        require(start, "Trading must be initialized");
        require(
            numberOfDays < 366,
            "Max borrow/extension must be 365 days or less"
        );

        Loan memory userLoan = Loans[msg.sender];
        if (userLoan.borrowed != 0) {
            if (isLoanExpired(msg.sender)) {
                delete Loans[msg.sender];
            }
            require(
                Loans[msg.sender].borrowed == 0,
                "Use account with no loans"
            );
        }
        liquidate();
        uint256 endDate = getMidnightTimestamp(
            (numberOfDays * 1 days) + block.timestamp
        );

        uint256 sonicFee = leverageFee(sonic, numberOfDays);

        uint256 userSonic = sonic - sonicFee;

        uint256 feeAddressAmount = (sonicFee * 3) / 10;
        uint256 userBorrow = (userSonic * 99) / 100;
        uint256 overCollateralizationAmount = (userSonic) / 100;
        uint256 subValue = feeAddressAmount + overCollateralizationAmount;
        uint256 totalFee = (sonicFee + overCollateralizationAmount);
        uint256 feeOverage;
        if (msg.value > totalFee) {
            feeOverage = msg.value - totalFee;
            sendSonic(msg.sender, feeOverage);
        }
        require(
            msg.value - feeOverage == totalFee,
            "Insufficient sonic fee sent"
        );

        // AUDIT: to user round down
        uint256 userEggs = SONICtoEGGSLev(userSonic, subValue);
        mint(address(this), userEggs);

        require(feeAddressAmount > MIN, "Fees must be higher than min.");
        sendSonic(FEE_ADDRESS, feeAddressAmount);

        addLoansByDate(userBorrow, userEggs, endDate);
        Loans[msg.sender] = Loan({
            collateral: userEggs,
            borrowed: userBorrow,
            endDate: endDate,
            numberOfDays: numberOfDays
        });

        safetyCheck(sonic);
    }

    function getInterestFee(
        uint256 amount,
        uint256 numberOfDays
    ) public pure returns (uint256) {
        uint256 interest = Math.mulDiv(0.039e18, numberOfDays, 365) + 0.001e18;
        return Math.mulDiv(amount, interest, 1e18);
    }

    function borrow(uint256 sonic, uint256 numberOfDays) public nonReentrant {
        require(
            numberOfDays < 366,
            "Max borrow/extension must be 365 days or less"
        );
        require(sonic != 0, "Must borrow more than 0");
        if (isLoanExpired(msg.sender)) {
            delete Loans[msg.sender];
        }
        require(
            Loans[msg.sender].borrowed == 0,
            "Use borrowMore to borrow more"
        );
        liquidate();
        uint256 endDate = getMidnightTimestamp(
            (numberOfDays * 1 days) + block.timestamp
        );

        uint256 sonicFee = getInterestFee(sonic, numberOfDays);

        uint256 feeAddressFee = (sonicFee * 3) / 10;

        //AUDIT: eggs required from user round up?
        uint256 userEggs = SONICtoEGGSNoTradeCeil(sonic);

        uint256 newUserBorrow = (sonic * 99) / 100;

        Loans[msg.sender] = Loan({
            collateral: userEggs,
            borrowed: newUserBorrow,
            endDate: endDate,
            numberOfDays: numberOfDays
        });

        _transfer(msg.sender, address(this), userEggs);
        require(feeAddressFee > MIN, "Fees must be higher than min.");

        sendSonic(msg.sender, newUserBorrow - sonicFee);
        sendSonic(FEE_ADDRESS, feeAddressFee);

        addLoansByDate(newUserBorrow, userEggs, endDate);

        safetyCheck(sonicFee);
    }
    function borrowMore(uint256 sonic) public nonReentrant {
        require(!isLoanExpired(msg.sender), "Loan expired use borrow");
        require(sonic != 0, "Must borrow more than 0");
        liquidate();
        uint256 userBorrowed = Loans[msg.sender].borrowed;
        uint256 userCollateral = Loans[msg.sender].collateral;
        uint256 userEndDate = Loans[msg.sender].endDate;

        uint256 todayMidnight = getMidnightTimestamp(block.timestamp);
        uint256 newBorrowLength = (userEndDate - todayMidnight) / 1 days;

        uint256 sonicFee = getInterestFee(sonic, newBorrowLength);

        //AUDIT: eggs required from user round up?
        uint256 userEggs = SONICtoEGGSNoTradeCeil(sonic);
        uint256 userBorrowedInEggs = SONICtoEGGSNoTrade(userBorrowed);
        uint256 userExcessInEggs = ((userCollateral) * 99) /
            100 -
            userBorrowedInEggs;

        uint256 requireCollateralFromUser = userEggs;
        if (userExcessInEggs >= userEggs) {
            requireCollateralFromUser = 0;
        } else {
            requireCollateralFromUser =
                requireCollateralFromUser -
                userExcessInEggs;
        }

        uint256 feeAddressFee = (sonicFee * 3) / 10;

        uint256 newUserBorrow = (sonic * 99) / 100;

        uint256 newUserBorrowTotal = userBorrowed + newUserBorrow;
        uint256 newUserCollateralTotal = userCollateral +
            requireCollateralFromUser;

        Loans[msg.sender] = Loan({
            collateral: newUserCollateralTotal,
            borrowed: newUserBorrowTotal,
            endDate: userEndDate,
            numberOfDays: newBorrowLength
        });

        if (requireCollateralFromUser != 0) {
            _transfer(msg.sender, address(this), requireCollateralFromUser);
        }

        require(feeAddressFee > MIN, "Fees must be higher than min.");
        sendSonic(FEE_ADDRESS, feeAddressFee);
        sendSonic(msg.sender, newUserBorrow - sonicFee);

        addLoansByDate(newUserBorrow, requireCollateralFromUser, userEndDate);

        safetyCheck(sonicFee);
    }

    function removeCollateral(uint256 amount) public nonReentrant {
        require(
            !isLoanExpired(msg.sender),
            "Your loan has been liquidated, no collateral to remove"
        );
        liquidate();
        uint256 collateral = Loans[msg.sender].collateral;
        // AUDIT: to user round down
        require(
            Loans[msg.sender].borrowed <=
                (EGGStoSONIC(collateral - amount) * 99) / 100,
            "Require 99% collateralization rate"
        );
        Loans[msg.sender].collateral = Loans[msg.sender].collateral - amount;
        _transfer(address(this), msg.sender, amount);
        subLoansByDate(0, amount, Loans[msg.sender].endDate);

        safetyCheck(0);
    }
    function repay() public payable nonReentrant {
        uint256 borrowed = Loans[msg.sender].borrowed;
        require(borrowed > msg.value, "Must repay less than borrowed amount");
        require(msg.value != 0, "Must repay something");

        require(
            !isLoanExpired(msg.sender),
            "Your loan has been liquidated, cannot repay"
        );
        uint256 newBorrow = borrowed - msg.value;
        Loans[msg.sender].borrowed = newBorrow;
        subLoansByDate(msg.value, 0, Loans[msg.sender].endDate);

        safetyCheck(0);
    }
    function closePosition() public payable nonReentrant {
        uint256 borrowed = Loans[msg.sender].borrowed;
        uint256 collateral = Loans[msg.sender].collateral;
        require(
            !isLoanExpired(msg.sender),
            "Your loan has been liquidated, no collateral to remove"
        );
        require(borrowed == msg.value, "Must return entire borrowed amount");
        _transfer(address(this), msg.sender, collateral);
        subLoansByDate(borrowed, collateral, Loans[msg.sender].endDate);

        delete Loans[msg.sender];
        safetyCheck(0);
    }
    function flashClosePosition() public nonReentrant {
        require(
            !isLoanExpired(msg.sender),
            "Your loan has been liquidated, no collateral to remove"
        );
        liquidate();
        uint256 borrowed = Loans[msg.sender].borrowed;

        uint256 collateral = Loans[msg.sender].collateral;

        // AUDIT: from user round up
        uint256 collateralInSonic = EGGStoSONIC(collateral);
        _burn(address(this), collateral);

        uint256 collateralInSonicAfterFee = (collateralInSonic * 99) / 100;

        uint256 fee = collateralInSonic / 100;
        require(
            collateralInSonicAfterFee >= borrowed,
            "You do not have enough collateral to close position"
        );

        uint256 toUser = collateralInSonicAfterFee - borrowed;
        uint256 feeAddressFee = (fee * 3) / 10;

        sendSonic(msg.sender, toUser);

        require(feeAddressFee > MIN, "Fees must be higher than min.");
        sendSonic(FEE_ADDRESS, feeAddressFee);
        subLoansByDate(borrowed, collateral, Loans[msg.sender].endDate);

        delete Loans[msg.sender];
        safetyCheck(borrowed);
    }

    function extendLoan(
        uint256 numberOfDays
    ) public payable nonReentrant returns (uint256) {
        uint256 oldEndDate = Loans[msg.sender].endDate;
        uint256 borrowed = Loans[msg.sender].borrowed;
        uint256 collateral = Loans[msg.sender].collateral;
        uint256 _numberOfDays = Loans[msg.sender].numberOfDays;

        uint256 newEndDate = oldEndDate + (numberOfDays * 1 days);

        uint256 loanFee = getInterestFee(borrowed, numberOfDays);
        require(
            !isLoanExpired(msg.sender),
            "Your loan has been liquidated, no collateral to remove"
        );
        require(loanFee == msg.value, "Loan extension fee incorrect");
        uint256 feeAddressFee = (loanFee * 3) / 10;
        require(feeAddressFee > MIN, "Fees must be higher than min.");
        sendSonic(FEE_ADDRESS, feeAddressFee);
        subLoansByDate(borrowed, collateral, oldEndDate);
        addLoansByDate(borrowed, collateral, newEndDate);
        Loans[msg.sender].endDate = newEndDate;
        Loans[msg.sender].numberOfDays = numberOfDays + _numberOfDays;
        require(
            (newEndDate - block.timestamp) / 1 days < 366,
            "Loan must be under 365 days"
        );

        safetyCheck(msg.value);
        return loanFee;
    }

    function liquidate() public {
        uint256 borrowed;
        uint256 collateral;

        while (lastLiquidationDate < block.timestamp) {
            collateral = collateral + CollateralByDate[lastLiquidationDate];
            borrowed = borrowed + BorrowedByDate[lastLiquidationDate];
            lastLiquidationDate = lastLiquidationDate + 1 days;
        }
        if (collateral != 0) {
            totalCollateral = totalCollateral - collateral;
            _burn(address(this), collateral);
        }
        if (borrowed != 0) {
            totalBorrowed = totalBorrowed - borrowed;
            emit Liquidate(lastLiquidationDate - 1 days, borrowed);
        }
    }

    function addLoansByDate(
        uint256 borrowed,
        uint256 collateral,
        uint256 date
    ) private {
        CollateralByDate[date] = CollateralByDate[date] + collateral;
        BorrowedByDate[date] = BorrowedByDate[date] + borrowed;
        totalBorrowed = totalBorrowed + borrowed;
        totalCollateral = totalCollateral + collateral;
        emit LoanDataUpdate(
            CollateralByDate[date],
            BorrowedByDate[date],
            totalBorrowed,
            totalCollateral
        );
    }
    function subLoansByDate(
        uint256 borrowed,
        uint256 collateral,
        uint256 date
    ) private {
        CollateralByDate[date] = CollateralByDate[date] - collateral;
        BorrowedByDate[date] = BorrowedByDate[date] - borrowed;
        totalBorrowed = totalBorrowed - borrowed;
        totalCollateral = totalCollateral - collateral;
        emit LoanDataUpdate(
            CollateralByDate[date],
            BorrowedByDate[date],
            totalBorrowed,
            totalCollateral
        );
    }

    // utility fxns
    function getMidnightTimestamp(uint256 date) public pure returns (uint256) {
        uint256 midnightTimestamp = date - (date % 86400); // Subtracting the remainder when divided by the number of seconds in a day (86400)
        return midnightTimestamp + 1 days;
    }

    function getLoansExpiringByDate(
        uint256 date
    ) public view returns (uint256, uint256) {
        return (
            BorrowedByDate[getMidnightTimestamp(date)],
            CollateralByDate[getMidnightTimestamp(date)]
        );
    }

    function getLoanByAddress(
        address _address
    ) public view returns (uint256, uint256, uint256) {
        if (Loans[_address].endDate >= block.timestamp) {
            return (
                Loans[_address].collateral,
                Loans[_address].borrowed,
                Loans[_address].endDate
            );
        } else {
            return (0, 0, 0);
        }
    }

    function isLoanExpired(address _address) public view returns (bool) {
        return Loans[_address].endDate < block.timestamp;
    }

    function getBuyFee() public view returns (uint256) {
        return buy_fee;
    }

    // Buy Eggs

    function getTotalBorrowed() public view returns (uint256) {
        return totalBorrowed;
    }

    function getTotalCollateral() public view returns (uint256) {
        return totalCollateral;
    }

    function getBacking() public view returns (uint256) {
        return address(this).balance + getTotalBorrowed();
    }

    function safetyCheck(uint256 sonic) private {
        uint256 newPrice = (getBacking() * 1 ether) / totalSupply();
        uint256 _totalColateral = balanceOf(address(this));
        require(
            _totalColateral >= totalCollateral,
            "The eggs balance of the contract must be greater than or equal to the collateral"
        );
        require(lastPrice <= newPrice, "The price of eggs cannot decrease");
        lastPrice = newPrice;
        emit Price(block.timestamp, newPrice, sonic);
    }

    function EGGStoSONIC(uint256 value) public view returns (uint256) {
        return Math.mulDiv(value, getBacking(), totalSupply());
    }

    function SONICtoEGGS(uint256 value) public view returns (uint256) {
        return Math.mulDiv(value, totalSupply(), getBacking() - value);
    }

    function SONICtoEGGSLev(
        uint256 value,
        uint256 fee
    ) public view returns (uint256) {
        uint256 backing = getBacking() - fee;
        return (value * totalSupply() + (backing - 1)) / backing;
    }

    function SONICtoEGGSNoTradeCeil(
        uint256 value
    ) public view returns (uint256) {
        uint256 backing = getBacking();
        return (value * totalSupply() + (backing - 1)) / backing;
    }
    function SONICtoEGGSNoTrade(uint256 value) public view returns (uint256) {
        uint256 backing = getBacking();
        return Math.mulDiv(value, totalSupply(), backing);
    }

    function sendSonic(address _address, uint256 _value) internal {
        (bool success, ) = _address.call{value: _value}("");
        require(success, "SONIC Transfer failed.");
        emit SendSonic(_address, _value);
    }

    //utils
    function getBuyEggs(uint256 amount) external view returns (uint256) {
        return
            (amount * (totalSupply()) * (buy_fee)) /
            (getBacking()) /
            (FEE_BASE_1000);
    }

    receive() external payable {}

    fallback() external payable {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","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":"ReentrancyGuardReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"buyFee","type":"uint256"}],"name":"BuyFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_address","type":"address"}],"name":"FeeAddressUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"leverageFee","type":"uint256"}],"name":"LeverageFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Liquidate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"collateralByDate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"borrowedByDate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalBorrowed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalCollateral","type":"uint256"}],"name":"LoanDataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"max","type":"uint256"}],"name":"MaxUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"volumeInSonic","type":"uint256"}],"name":"Price","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"sellFee","type":"uint256"}],"name":"SellFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SendSonic","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"started","type":"bool"}],"name":"Started","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"BorrowedByDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"CollateralByDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"EGGStoSONIC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_ADDRESS","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"Loans","outputs":[{"internalType":"uint256","name":"collateral","type":"uint256"},{"internalType":"uint256","name":"borrowed","type":"uint256"},{"internalType":"uint256","name":"endDate","type":"uint256"},{"internalType":"uint256","name":"numberOfDays","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SONICtoEGGS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SONICtoEGGSLev","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SONICtoEGGSNoTrade","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SONICtoEGGSNoTradeCeil","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"sonic","type":"uint256"},{"internalType":"uint256","name":"numberOfDays","type":"uint256"}],"name":"borrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"sonic","type":"uint256"}],"name":"borrowMore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"buy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"buy_fee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buy_fee_leverage","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"closePosition","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfDays","type":"uint256"}],"name":"extendLoan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"flashClosePosition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getBacking","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getBuyAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getBuyEggs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBuyFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"numberOfDays","type":"uint256"}],"name":"getInterestFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getLoanByAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"date","type":"uint256"}],"name":"getLoansExpiringByDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"date","type":"uint256"}],"name":"getMidnightTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getTotalBorrowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isLoanExpired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastLiquidationDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"sonic","type":"uint256"},{"internalType":"uint256","name":"numberOfDays","type":"uint256"}],"name":"leverage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"sonic","type":"uint256"},{"internalType":"uint256","name":"numberOfDays","type":"uint256"}],"name":"leverageFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"removeCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"repay","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"eggs","type":"uint256"}],"name":"sell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sell_fee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"amount","type":"uint16"}],"name":"setBuyFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"amount","type":"uint16"}],"name":"setBuyFeeLeverage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setFeeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"amount","type":"uint16"}],"name":"setSellFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setStart","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"start","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040526103cf600860146101000a81548161ffff021916908361ffff1602179055506103cf600860166101000a81548161ffff021916908361ffff160217905550600a600860186101000a81548161ffff021916908361ffff1602179055505f6008601a6101000a81548160ff0219169083151502179055505f6009555f600a555f600c55348015610091575f5ffd5b50336040518060400160405280600481526020017f45676773000000000000000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f4547475300000000000000000000000000000000000000000000000000000000815250816003908161010e919061052e565b50806004908161011e919061052e565b5050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610191575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401610188919061063c565b60405180910390fd5b6101a0816101c360201b60201c565b5060016007819055506101b8426101f960201b60201c565b601081905550610745565b60065f6101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556101f68161022e60201b60201c565b50565b5f5f620151808361020a9190610682565b8361021591906106df565b905062015180816102269190610712565b915050919050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061036c57607f821691505b60208210810361037f5761037e610328565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026103e17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826103a6565b6103eb86836103a6565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61042f61042a61042584610403565b61040c565b610403565b9050919050565b5f819050919050565b61044883610415565b61045c61045482610436565b8484546103b2565b825550505050565b5f5f905090565b610473610464565b61047e81848461043f565b505050565b5b818110156104a1576104965f8261046b565b600181019050610484565b5050565b601f8211156104e6576104b781610385565b6104c084610397565b810160208510156104cf578190505b6104e36104db85610397565b830182610483565b50505b505050565b5f82821c905092915050565b5f6105065f19846008026104eb565b1980831691505092915050565b5f61051e83836104f7565b9150826002028217905092915050565b610537826102f1565b67ffffffffffffffff8111156105505761054f6102fb565b5b61055a8254610355565b6105658282856104a5565b5f60209050601f831160018114610596575f8415610584578287015190505b61058e8582610513565b8655506105f5565b601f1984166105a486610385565b5f5b828110156105cb578489015182556001820191506020850194506020810190506105a6565b868310156105e857848901516105e4601f8916826104f7565b8355505b6001600288020188555050505b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610626826105fd565b9050919050565b6106368161061c565b82525050565b5f60208201905061064f5f83018461062d565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61068c82610403565b915061069783610403565b9250826106a7576106a6610655565b5b828206905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6106e982610403565b91506106f483610403565b925082820390508181111561070c5761070b6106b2565b5b92915050565b5f61071c82610403565b915061072783610403565b925082820190508082111561073f5761073e6106b2565b5b92915050565b615cff806107525f395ff3fe6080604052600436106103a5575f3560e01c806379ba5097116101e6578063b6013e9a1161010c578063dd62ed3e1161009f578063e4849b321161006e578063e4849b3214610db8578063eb1edd6114610de0578063f088d54714610e0a578063f2fde38b14610e26576103a6565b8063dd62ed3e14610cee578063e064648a14610d2a578063e30c397814610d52578063e3eb5ed314610d7c576103a6565b8063c94220ab116100db578063c94220ab14610c34578063c962a4b514610c5e578063d5abeb0114610c9a578063d6eb591014610cc4576103a6565b8063b6013e9a14610b88578063bd0fe67914610bc4578063be9a655514610c00578063c393d0e314610c2a576103a6565b806395ced06f11610184578063a2309ff811610153578063a2309ff814610ab9578063a9059cbb14610ae3578063a925e4a414610b1f578063abd545bf14610b5e576103a6565b806395ced06f14610a1357806395d89b4114610a515780639d0bf2e914610a7b5780639d41ac3a14610aa3576103a6565b80638705fcd4116101c05780638705fcd41461095b578063886433ac146109835780638da5cb5b146109bf5780638f818b90146109e9576103a6565b806379ba5097146108ed57806379cc6790146109035780637ace2ac91461092b576103a6565b80633237c158116102cb57806342966c681161026957806370a082311161023857806370a082311461083757806370c476711461087357806370f84ba91461089b578063715018a6146108d7576103a6565b806342966c681461077b57806342c95e19146107a35780634fbf3ab0146107df5780635e96263c1461081b576103a6565b806335975a37116102a557806335975a371461070157806336189d431461070b5780633be4e59814610735578063402d888314610771576103a6565b80633237c1581461067357806333e516d51461069b5780633421f750146106d7576103a6565b80630ecbcdab116103435780631fb87f39116103125780631fb87f39146105bb57806323b872dd146105f757806328a0702514610633578063313ce56714610649576103a6565b80630ecbcdab14610517578063162b51fc1461053f57806317a5a97e1461056957806318160ddd14610591576103a6565b8063053f14da1161037f578063053f14da1461044b57806306fdde0314610475578063095ea7b31461049f5780630df1ff24146104db576103a6565b8063024cad3b146103a85780630307c4a1146103e5578063035b7c4b1461040f576103a6565b5b005b3480156103b3575f5ffd5b506103ce60048036038101906103c9919061463c565b610e4e565b6040516103dc929190614676565b60405180910390f35b3480156103f0575f5ffd5b506103f9610e8d565b604051610406919061469d565b60405180910390f35b34801561041a575f5ffd5b50610435600480360381019061043091906146b6565b610e96565b604051610442919061469d565b60405180910390f35b348015610456575f5ffd5b5061045f610edc565b60405161046c919061469d565b60405180910390f35b348015610480575f5ffd5b50610489610ee2565b6040516104969190614764565b60405180910390f35b3480156104aa575f5ffd5b506104c560048036038101906104c091906147de565b610f72565b6040516104d29190614836565b60405180910390f35b3480156104e6575f5ffd5b5061050160048036038101906104fc919061463c565b610f94565b60405161050e919061469d565b60405180910390f35b348015610522575f5ffd5b5061053d600480360381019061053891906146b6565b610fb5565b005b34801561054a575f5ffd5b506105536112e8565b604051610560919061486b565b60405180910390f35b348015610574575f5ffd5b5061058f600480360381019061058a91906148ae565b6112fc565b005b34801561059c575f5ffd5b506105a56113ea565b6040516105b2919061469d565b60405180910390f35b3480156105c6575f5ffd5b506105e160048036038101906105dc919061463c565b6113f3565b6040516105ee919061469d565b60405180910390f35b348015610602575f5ffd5b5061061d600480360381019061061891906148d9565b61142c565b60405161062a9190614836565b60405180910390f35b34801561063e575f5ffd5b5061064761145a565b005b348015610654575f5ffd5b5061065d611554565b60405161066a9190614944565b60405180910390f35b34801561067e575f5ffd5b506106996004803603810190610694919061463c565b61155c565b005b3480156106a6575f5ffd5b506106c160048036038101906106bc919061463c565b61179f565b6040516106ce919061469d565b60405180910390f35b3480156106e2575f5ffd5b506106eb6117cb565b6040516106f8919061469d565b60405180910390f35b6107096117d1565b005b348015610716575f5ffd5b5061071f611902565b60405161072c919061486b565b60405180910390f35b348015610740575f5ffd5b5061075b600480360381019061075691906146b6565b611916565b604051610768919061469d565b60405180910390f35b61077961196e565b005b348015610786575f5ffd5b506107a1600480360381019061079c919061463c565b611b3b565b005b3480156107ae575f5ffd5b506107c960048036038101906107c4919061463c565b611b4f565b6040516107d6919061469d565b60405180910390f35b3480156107ea575f5ffd5b506108056004803603810190610800919061463c565b611b98565b604051610812919061469d565b60405180910390f35b610835600480360381019061083091906146b6565b611bad565b005b348015610842575f5ffd5b5061085d6004803603810190610858919061495d565b612008565b60405161086a919061469d565b60405180910390f35b34801561087e575f5ffd5b50610899600480360381019061089491906148ae565b61204d565b005b3480156108a6575f5ffd5b506108c160048036038101906108bc919061495d565b61213e565b6040516108ce9190614836565b60405180910390f35b3480156108e2575f5ffd5b506108eb612189565b005b3480156108f8575f5ffd5b5061090161219c565b005b34801561090e575f5ffd5b50610929600480360381019061092491906147de565b61222a565b005b6109456004803603810190610940919061463c565b61224a565b604051610952919061469d565b60405180910390f35b348015610966575f5ffd5b50610981600480360381019061097c919061495d565b6125ca565b005b34801561098e575f5ffd5b506109a960048036038101906109a4919061463c565b6126ba565b6040516109b6919061469d565b60405180910390f35b3480156109ca575f5ffd5b506109d3612717565b6040516109e09190614997565b60405180910390f35b3480156109f4575f5ffd5b506109fd61273f565b604051610a0a919061469d565b60405180910390f35b348015610a1e575f5ffd5b50610a396004803603810190610a34919061495d565b61275a565b604051610a48939291906149b0565b60405180910390f35b348015610a5c575f5ffd5b50610a65612882565b604051610a729190614764565b60405180910390f35b348015610a86575f5ffd5b50610aa16004803603810190610a9c919061463c565b612912565b005b348015610aae575f5ffd5b50610ab7612cb0565b005b348015610ac4575f5ffd5b50610acd612f79565b604051610ada919061469d565b60405180910390f35b348015610aee575f5ffd5b50610b096004803603810190610b0491906147de565b612f7f565b604051610b169190614836565b60405180910390f35b348015610b2a575f5ffd5b50610b456004803603810190610b40919061495d565b612fa1565b604051610b5594939291906149e5565b60405180910390f35b348015610b69575f5ffd5b50610b72612fcd565b604051610b7f919061486b565b60405180910390f35b348015610b93575f5ffd5b50610bae6004803603810190610ba9919061463c565b612fe1565b604051610bbb919061469d565b60405180910390f35b348015610bcf575f5ffd5b50610bea6004803603810190610be591906146b6565b613007565b604051610bf7919061469d565b60405180910390f35b348015610c0b575f5ffd5b50610c1461305c565b604051610c219190614836565b60405180910390f35b610c3261306f565b005b348015610c3f575f5ffd5b50610c4861324f565b604051610c55919061469d565b60405180910390f35b348015610c69575f5ffd5b50610c846004803603810190610c7f919061463c565b613268565b604051610c91919061469d565b60405180910390f35b348015610ca5575f5ffd5b50610cae61327d565b604051610cbb9190614a52565b60405180910390f35b348015610ccf575f5ffd5b50610cd861328e565b604051610ce5919061469d565b60405180910390f35b348015610cf9575f5ffd5b50610d146004803603810190610d0f9190614a6b565b613297565b604051610d21919061469d565b60405180910390f35b348015610d35575f5ffd5b50610d506004803603810190610d4b91906148ae565b613319565b005b348015610d5d575f5ffd5b50610d6661340a565b604051610d739190614997565b60405180910390f35b348015610d87575f5ffd5b50610da26004803603810190610d9d919061463c565b613432565b604051610daf919061469d565b60405180910390f35b348015610dc3575f5ffd5b50610dde6004803603810190610dd9919061463c565b613467565b005b348015610deb575f5ffd5b50610df4613560565b604051610e019190614ac9565b60405180910390f35b610e246004803603810190610e1f919061495d565b613585565b005b348015610e31575f5ffd5b50610e4c6004803603810190610e47919061495d565b613724565b005b5f5f600e5f610e5c85613432565b81526020019081526020015f2054600f5f610e7686613432565b81526020019081526020015f205491509150915091565b5f600954905090565b5f5f66038d7ea4c68000610eb4668a8e4b1a3d80008561016d6137d0565b610ebe9190614b0f565b9050610ed38482670de0b6b3a76400006137d0565b91505092915050565b600c5481565b606060038054610ef190614b6f565b80601f0160208091040260200160405190810160405280929190818152602001828054610f1d90614b6f565b8015610f685780601f10610f3f57610100808354040283529160200191610f68565b820191905f5260205f20905b815481529060010190602001808311610f4b57829003601f168201915b5050505050905090565b5f5f610f7c6138b5565b9050610f898185856138bc565b600191505092915050565b5f610fae82610fa161324f565b610fa96113ea565b6137d0565b9050919050565b610fbd6138ce565b61016e8110611001576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff890614c0f565b60405180910390fd5b5f8203611043576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103a90614c77565b60405180910390fd5b61104c3361213e565b156110ad57600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f5f82015f9055600182015f9055600282015f9055600382015f905550505b5f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600101541461112f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112690614cdf565b60405180910390fd5b61113761145a565b5f61115a42620151808461114b9190614cfd565b6111559190614b0f565b613432565b90505f6111678484610e96565b90505f600a6003836111799190614cfd565b6111839190614d6b565b90505f61118f86611b4f565b90505f60646063886111a19190614cfd565b6111ab9190614d6b565b9050604051806080016040528083815260200182815260200186815260200187815250600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f820151815f015560208201518160010155604082015181600201556060820151816003015590505061123f333084613914565b6103e88311611283576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127a90614de5565b60405180910390fd5b6112983385836112939190614e03565b613a04565b6112c360085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684613a04565b6112ce818387613aea565b6112d784613bde565b50505050506112e4613ceb565b5050565b600860169054906101000a900461ffff1681565b611304613cf5565b60198161ffff16111561134c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134390614ea6565b60405180910390fd5b5f8161ffff161015611393576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138a90614f34565b60405180910390fd5b80600860186101000a81548161ffff021916908361ffff1602179055507fd4e469371f09a592c9c4fde36ed11fd123a8cc55d93bd2920ea6ad544dff4395816040516113df9190614f8b565b60405180910390a150565b5f600254905090565b5f5f6113fe83612fe1565b90506103e861ffff1661140f61273f565b8261141a9190614cfd565b6114249190614d6b565b915050919050565b5f5f6114366138b5565b9050611443858285613d7c565b61144e858585613914565b60019150509392505050565b5f5f5b4260105410156114c557600f5f60105481526020019081526020015f2054816114869190614b0f565b9050600e5f60105481526020019081526020015f2054826114a79190614b0f565b9150620151806010546114ba9190614b0f565b60108190555061145d565b5f81146114eb5780600a546114da9190614e03565b600a819055506114ea3082613e0f565b5b5f821461155057816009546115009190614e03565b6009819055507f253e5385159062a101837d58c10ad4694c58979ebc3ba6b5cb2cbba2fe461692620151806010546115389190614e03565b83604051611547929190614676565b60405180910390a15b5050565b5f6012905090565b6115646138ce565b61156d3361213e565b156115ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115a490615014565b60405180910390fd5b6115b561145a565b5f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0154905060646063611610848461160b9190614e03565b610f94565b61161a9190614cfd565b6116249190614d6b565b600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015411156116a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169d906150a2565b60405180910390fd5b81600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f01546116f19190614e03565b600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f018190555061173f303384613914565b61178a5f83600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060020154613e8e565b6117935f613bde565b5061179c613ceb565b50565b5f6117c4826117ac6113ea565b846117b561324f565b6117bf9190614e03565b6137d0565b9050919050565b60105481565b6117d9613cf5565b5f73ffffffffffffffffffffffffffffffffffffffff1660085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603611868576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185f9061510a565b60405180910390fd5b5f6103e8346118779190614cfd565b9050670de0b6b3a764000081101561188d575f5ffd5b6118973382613f82565b6118ac3361dead670de0b6b3a7640000613914565b60016008601a6101000a81548160ff0219169083151502179055507f4f366f0dc5cd876e456f089309e0c62fc2bc0e116c6f6ae308c392b4ad45b5b960016040516118f79190614836565b60405180910390a150565b600860189054906101000a900461ffff1681565b5f5f6103e861ffff16600860189054906101000a900461ffff1661ffff168561193f9190614cfd565b6119499190614d6b565b90505f6119568585610e96565b905080826119649190614b0f565b9250505092915050565b6119766138ce565b5f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015490503481116119fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f390615198565b60405180910390fd5b5f3403611a3e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3590615200565b60405180910390fd5b611a473361213e565b15611a87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a7e9061528e565b60405180910390fd5b5f3482611a949190614e03565b905080600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010181905550611b26345f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060020154613e8e565b611b2f5f613bde565b5050611b39613ceb565b565b611b4c611b466138b5565b82613e0f565b50565b5f5f611b5961324f565b905080600182611b699190614e03565b611b716113ea565b85611b7c9190614cfd565b611b869190614b0f565b611b909190614d6b565b915050919050565b600e602052805f5260405f205f915090505481565b611bb56138ce565b6008601a9054906101000a900460ff16611c04576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bfb906152f6565b60405180910390fd5b61016e8110611c48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3f90614c0f565b60405180910390fd5b5f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206040518060800160405290815f8201548152602001600182015481526020016002820154815260200160038201548152505090505f816020015114611db257611cce3361213e565b15611d2f57600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f5f82015f9055600182015f9055600282015f9055600382015f905550505b5f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015414611db1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611da89061535e565b60405180910390fd5b5b611dba61145a565b5f611ddd426201518085611dce9190614cfd565b611dd89190614b0f565b613432565b90505f611dea8585611916565b90505f8186611df99190614e03565b90505f600a600384611e0b9190614cfd565b611e159190614d6b565b90505f6064606384611e279190614cfd565b611e319190614d6b565b90505f606484611e419190614d6b565b90505f8184611e509190614b0f565b90505f8287611e5f9190614b0f565b90505f81341115611e83578134611e769190614e03565b9050611e823382613a04565b5b818134611e909190614e03565b14611ed0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ec7906153c6565b60405180910390fd5b5f611edb8885613007565b9050611ee73082613f82565b6103e88711611f2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f2290614de5565b60405180910390fd5b611f5660085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1688613a04565b611f6186828c613aea565b60405180608001604052808281526020018781526020018b81526020018d815250600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f820151815f0155602082015181600101556040820151816002015560608201518160030155905050611ff18d613bde565b5050505050505050505050612004613ceb565b5050565b5f5f5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b612055613cf5565b6103e08161ffff16111561209e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161209590615454565b60405180910390fd5b6103cf8161ffff1610156120e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120de906154bc565b60405180910390fd5b80600860166101000a81548161ffff021916908361ffff1602179055507f7c1445c98b278c9970d007fca6048704bcb25af7cc4a04eb56565d9a9f149ca3816040516121339190614f8b565b60405180910390a150565b5f42600d5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060020154109050919050565b612191613cf5565b61219a5f614076565b565b5f6121a56138b5565b90508073ffffffffffffffffffffffffffffffffffffffff166121c661340a565b73ffffffffffffffffffffffffffffffffffffffff161461221e57806040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016122159190614997565b60405180910390fd5b61222781614076565b50565b61223c826122366138b5565b83613d7c565b6122468282613e0f565b5050565b5f6122536138ce565b5f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206002015490505f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015490505f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015490505f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206003015490505f62015180876123729190614cfd565b8561237d9190614b0f565b90505f61238a8589610e96565b90506123953361213e565b156123d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123cc90615014565b60405180910390fd5b348114612417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240e90615524565b60405180910390fd5b5f600a6003836124279190614cfd565b6124319190614d6b565b90506103e88111612477576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161246e90614de5565b60405180910390fd5b6124a260085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682613a04565b6124ad868689613e8e565b6124b8868685613aea565b82600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206002018190555083896125099190614b0f565b600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206003018190555061016e6201518042856125609190614e03565b61256a9190614d6b565b106125aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125a19061558c565b60405180910390fd5b6125b334613bde565b819750505050505050506125c5613ceb565b919050565b6125d2613cf5565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612640576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126379061561a565b60405180910390fd5b8060085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f446e39bcf1b47cfadfaa23442cb4b34682cfe6bd9220da084894e3b1f834e4f3816040516126af9190614997565b60405180910390a150565b5f6103e861ffff166126ca61324f565b600860169054906101000a900461ffff1661ffff166126e76113ea565b856126f29190614cfd565b6126fc9190614cfd565b6127069190614d6b565b6127109190614d6b565b9050919050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f600860169054906101000a900461ffff1661ffff16905090565b5f5f5f42600d5f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600201541061287157600d5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0154600d5f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010154600d5f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206002015492509250925061287b565b5f5f5f9250925092505b9193909250565b60606004805461289190614b6f565b80601f01602080910402602001604051908101604052809291908181526020018280546128bd90614b6f565b80156129085780601f106128df57610100808354040283529160200191612908565b820191905f5260205f20905b8154815290600101906020018083116128eb57829003601f168201915b5050505050905090565b61291a6138ce565b6129233361213e565b15612963576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161295a90615682565b60405180910390fd5b5f81036129a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161299c90614c77565b60405180910390fd5b6129ad61145a565b5f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015490505f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015490505f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206002015490505f612a8242613432565b90505f620151808284612a959190614e03565b612a9f9190614d6b565b90505f612aac8783610e96565b90505f612ab888611b4f565b90505f612ac488612fe1565b90505f81606460638a612ad79190614cfd565b612ae19190614d6b565b612aeb9190614e03565b90505f839050838210612b00575f9050612b0f565b8181612b0c9190614e03565b90505b5f600a600387612b1f9190614cfd565b612b299190614d6b565b90505f606460638e612b3b9190614cfd565b612b459190614d6b565b90505f818d612b549190614b0f565b90505f848d612b639190614b0f565b905060405180608001604052808281526020018381526020018d81526020018b815250600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f820151815f01556020820151816001015560408201518160020155606082015181600301559050505f8514612bff57612bfe333087613914565b5b6103e88411612c43576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c3a90614de5565b60405180910390fd5b612c6e60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685613a04565b612c83338a85612c7e9190614e03565b613a04565b612c8e83868e613aea565b612c9789613bde565b5050505050505050505050505050612cad613ceb565b50565b612cb86138ce565b612cc13361213e565b15612d01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cf890615014565b60405180910390fd5b612d0961145a565b5f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015490505f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015490505f612d9a82610f94565b9050612da63083613e0f565b5f6064606383612db69190614cfd565b612dc09190614d6b565b90505f606483612dd09190614d6b565b905084821015612e15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e0c90615710565b60405180910390fd5b5f8583612e229190614e03565b90505f600a600384612e349190614cfd565b612e3e9190614d6b565b9050612e4a3383613a04565b6103e88111612e8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e8590614de5565b60405180910390fd5b612eb960085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682613a04565b612f048787600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060020154613e8e565b600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f5f82015f9055600182015f9055600282015f9055600382015f90555050612f6887613bde565b50505050505050612f77613ceb565b565b600b5481565b5f5f612f896138b5565b9050612f96818585613914565b600191505092915050565b600d602052805f5260405f205f91509050805f0154908060010154908060020154908060030154905084565b600860149054906101000a900461ffff1681565b5f5f612feb61324f565b9050612fff83612ff96113ea565b836137d0565b915050919050565b5f5f8261301261324f565b61301c9190614e03565b90508060018261302c9190614e03565b6130346113ea565b8661303f9190614cfd565b6130499190614b0f565b6130539190614d6b565b91505092915050565b6008601a9054906101000a900460ff1681565b6130776138ce565b5f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015490505f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015490506131073361213e565b15613147576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161313e90615014565b60405180910390fd5b348214613189576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131809061579e565b60405180910390fd5b613194303383613914565b6131df8282600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060020154613e8e565b600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f5f82015f9055600182015f9055600282015f9055600382015f905550506132435f613bde565b505061324d613ceb565b565b5f613258610e8d565b476132639190614b0f565b905090565b600f602052805f5260405f205f915090505481565b6c01431e0fae6d7217caa000000081565b5f600a54905090565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b613321613cf5565b6103e08161ffff16111561336a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133619061582c565b60405180910390fd5b6103cf8161ffff1610156133b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133aa90615894565b60405180910390fd5b80600860146101000a81548161ffff021916908361ffff1602179055507f495ee53ee22006979ebc689a00ed737d7c13b6419142f82dcaea4ed95ac1e780816040516133ff9190614f8b565b60405180910390a150565b5f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f5f620151808361344391906158b2565b8361344e9190614e03565b9050620151808161345f9190614b0f565b915050919050565b61346f6138ce565b61347761145a565b5f61348182610f94565b90505f607d61ffff16826134959190614d6b565b90506134a13384613e0f565b6134db336103e861ffff16600860149054906101000a900461ffff1661ffff16856134cc9190614cfd565b6134d69190614d6b565b613a04565b6103e8811161351f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135169061592c565b60405180910390fd5b61354a60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682613a04565b61355382613bde565b505061355d613ceb565b50565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61358d6138ce565b61359561145a565b6008601a9054906101000a900460ff166135e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135db906152f6565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161364990615994565b60405180910390fd5b5f61365c3461179f565b905061368b826103e861ffff1661367161273f565b8461367c9190614cfd565b6136869190614d6b565b613f82565b5f607d61ffff163461369d9190614d6b565b90506103e881116136e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136da9061592c565b60405180910390fd5b61370e60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682613a04565b61371734613bde565b5050613721613ceb565b50565b61372c613cf5565b8060065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff1661378b612717565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b5f5f83850290505f5f19858709828110838203039150505f8103613808578382816137fe576137fd614d3e565b5b04925050506138ae565b808411613827576138266138215f8614601260116140a6565b6140bf565b5b5f8486880990508281118203915080830392505f855f038616905080860495508084049350600181825f0304019050808302841793505f600287600302189050808702600203810290508087026002038102905080870260020381029050808702600203810290508087026002038102905080870260020381029050808502955050505050505b9392505050565b5f33905090565b6138c983838360016140d0565b505050565b60026007540361390a576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600781905550565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603613984575f6040517f96c6fd1e00000000000000000000000000000000000000000000000000000000815260040161397b9190614997565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036139f4575f6040517fec442f050000000000000000000000000000000000000000000000000000000081526004016139eb9190614997565b60405180910390fd5b6139ff83838361429f565b505050565b5f8273ffffffffffffffffffffffffffffffffffffffff1682604051613a29906159df565b5f6040518083038185875af1925050503d805f8114613a63576040519150601f19603f3d011682016040523d82523d5f602084013e613a68565b606091505b5050905080613aac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613aa390615a3d565b60405180910390fd5b7f03bbe564cb1b78e43195eeadbde99e5b89b19345862807fcfb59f884e4165e258383604051613add929190615a5b565b60405180910390a1505050565b81600f5f8381526020019081526020015f2054613b079190614b0f565b600f5f8381526020019081526020015f208190555082600e5f8381526020019081526020015f2054613b399190614b0f565b600e5f8381526020019081526020015f208190555082600954613b5c9190614b0f565b60098190555081600a54613b709190614b0f565b600a819055507faec00f5213a37254bc68a26b0685d1a5b2bf513e1e587c94c7df7f4a62b56c9c600f5f8381526020019081526020015f2054600e5f8481526020019081526020015f2054600954600a54604051613bd194939291906149e5565b60405180910390a1505050565b5f613be76113ea565b670de0b6b3a7640000613bf861324f565b613c029190614cfd565b613c0c9190614d6b565b90505f613c1830612008565b9050600a54811015613c5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613c5690615b18565b60405180910390fd5b81600c541115613ca4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613c9b90615ba6565b60405180910390fd5b81600c819055507f4afcb4a87cdbd9974efdb92ee48bc8d7cd0ae4bf217004db3d080cbaee652ca7428385604051613cde939291906149b0565b60405180910390a1505050565b6001600781905550565b613cfd6138b5565b73ffffffffffffffffffffffffffffffffffffffff16613d1b612717565b73ffffffffffffffffffffffffffffffffffffffff1614613d7a57613d3e6138b5565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401613d719190614997565b60405180910390fd5b565b5f613d878484613297565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811015613e095781811015613dfa578281836040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401613df193929190615bc4565b60405180910390fd5b613e0884848484035f6140d0565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613e7f575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401613e769190614997565b60405180910390fd5b613e8a825f8361429f565b5050565b81600f5f8381526020019081526020015f2054613eab9190614e03565b600f5f8381526020019081526020015f208190555082600e5f8381526020019081526020015f2054613edd9190614e03565b600e5f8381526020019081526020015f208190555082600954613f009190614e03565b60098190555081600a54613f149190614e03565b600a819055507faec00f5213a37254bc68a26b0685d1a5b2bf513e1e587c94c7df7f4a62b56c9c600f5f8381526020019081526020015f2054600e5f8481526020019081526020015f2054600954600a54604051613f7594939291906149e5565b60405180910390a1505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613ff0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613fe790615c43565b60405180910390fd5b80600b54613ffe9190614b0f565b600b819055506c01431e0fae6d7217caa00000006fffffffffffffffffffffffffffffffff16600b541115614068576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161405f90615cab565b60405180910390fd5b61407282826144b8565b5050565b60065f6101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556140a381614537565b50565b5f6140b0846145fa565b82841802821890509392505050565b634e487b715f52806020526024601cfd5b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603614140575f6040517fe602df050000000000000000000000000000000000000000000000000000000081526004016141379190614997565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036141b0575f6040517f94280d620000000000000000000000000000000000000000000000000000000081526004016141a79190614997565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508015614299578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051614290919061469d565b60405180910390a35b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036142ef578060025f8282546142e39190614b0f565b925050819055506143bd565b5f5f5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015614378578381836040517fe450d38c00000000000000000000000000000000000000000000000000000000815260040161436f93929190615bc4565b60405180910390fd5b8181035f5f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603614404578060025f828254039250508190555061444e565b805f5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516144ab919061469d565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603614528575f6040517fec442f0500000000000000000000000000000000000000000000000000000000815260040161451f9190614997565b60405180910390fd5b6145335f838361429f565b5050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f8115159050919050565b5f5ffd5b5f819050919050565b61461b81614609565b8114614625575f5ffd5b50565b5f8135905061463681614612565b92915050565b5f6020828403121561465157614650614605565b5b5f61465e84828501614628565b91505092915050565b61467081614609565b82525050565b5f6040820190506146895f830185614667565b6146966020830184614667565b9392505050565b5f6020820190506146b05f830184614667565b92915050565b5f5f604083850312156146cc576146cb614605565b5b5f6146d985828601614628565b92505060206146ea85828601614628565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f614736826146f4565b61474081856146fe565b935061475081856020860161470e565b6147598161471c565b840191505092915050565b5f6020820190508181035f83015261477c818461472c565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6147ad82614784565b9050919050565b6147bd816147a3565b81146147c7575f5ffd5b50565b5f813590506147d8816147b4565b92915050565b5f5f604083850312156147f4576147f3614605565b5b5f614801858286016147ca565b925050602061481285828601614628565b9150509250929050565b5f8115159050919050565b6148308161481c565b82525050565b5f6020820190506148495f830184614827565b92915050565b5f61ffff82169050919050565b6148658161484f565b82525050565b5f60208201905061487e5f83018461485c565b92915050565b61488d8161484f565b8114614897575f5ffd5b50565b5f813590506148a881614884565b92915050565b5f602082840312156148c3576148c2614605565b5b5f6148d08482850161489a565b91505092915050565b5f5f5f606084860312156148f0576148ef614605565b5b5f6148fd868287016147ca565b935050602061490e868287016147ca565b925050604061491f86828701614628565b9150509250925092565b5f60ff82169050919050565b61493e81614929565b82525050565b5f6020820190506149575f830184614935565b92915050565b5f6020828403121561497257614971614605565b5b5f61497f848285016147ca565b91505092915050565b614991816147a3565b82525050565b5f6020820190506149aa5f830184614988565b92915050565b5f6060820190506149c35f830186614667565b6149d06020830185614667565b6149dd6040830184614667565b949350505050565b5f6080820190506149f85f830187614667565b614a056020830186614667565b614a126040830185614667565b614a1f6060830184614667565b95945050505050565b5f6fffffffffffffffffffffffffffffffff82169050919050565b614a4c81614a28565b82525050565b5f602082019050614a655f830184614a43565b92915050565b5f5f60408385031215614a8157614a80614605565b5b5f614a8e858286016147ca565b9250506020614a9f858286016147ca565b9150509250929050565b5f614ab382614784565b9050919050565b614ac381614aa9565b82525050565b5f602082019050614adc5f830184614aba565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f614b1982614609565b9150614b2483614609565b9250828201905080821115614b3c57614b3b614ae2565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680614b8657607f821691505b602082108103614b9957614b98614b42565b5b50919050565b7f4d617820626f72726f772f657874656e73696f6e206d757374206265203336355f8201527f2064617973206f72206c65737300000000000000000000000000000000000000602082015250565b5f614bf9602d836146fe565b9150614c0482614b9f565b604082019050919050565b5f6020820190508181035f830152614c2681614bed565b9050919050565b7f4d75737420626f72726f77206d6f7265207468616e20300000000000000000005f82015250565b5f614c616017836146fe565b9150614c6c82614c2d565b602082019050919050565b5f6020820190508181035f830152614c8e81614c55565b9050919050565b7f55736520626f72726f774d6f726520746f20626f72726f77206d6f72650000005f82015250565b5f614cc9601d836146fe565b9150614cd482614c95565b602082019050919050565b5f6020820190508181035f830152614cf681614cbd565b9050919050565b5f614d0782614609565b9150614d1283614609565b9250828202614d2081614609565b91508282048414831517614d3757614d36614ae2565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f614d7582614609565b9150614d8083614609565b925082614d9057614d8f614d3e565b5b828204905092915050565b7f46656573206d75737420626520686967686572207468616e206d696e2e0000005f82015250565b5f614dcf601d836146fe565b9150614dda82614d9b565b602082019050919050565b5f6020820190508181035f830152614dfc81614dc3565b9050919050565b5f614e0d82614609565b9150614e1883614609565b9250828203905081811115614e3057614e2f614ae2565b5b92915050565b7f6c657665726167652062757920666565206d757374206265206c65737320322e5f8201527f3525000000000000000000000000000000000000000000000000000000000000602082015250565b5f614e906022836146fe565b9150614e9b82614e36565b604082019050919050565b5f6020820190508181035f830152614ebd81614e84565b9050919050565b7f6c657665726167652062757920666565206d75737420626520677265617465725f8201527f207468616e203025000000000000000000000000000000000000000000000000602082015250565b5f614f1e6028836146fe565b9150614f2982614ec4565b604082019050919050565b5f6020820190508181035f830152614f4b81614f12565b9050919050565b5f819050919050565b5f614f75614f70614f6b8461484f565b614f52565b614609565b9050919050565b614f8581614f5b565b82525050565b5f602082019050614f9e5f830184614f7c565b92915050565b7f596f7572206c6f616e20686173206265656e206c6971756964617465642c206e5f8201527f6f20636f6c6c61746572616c20746f2072656d6f766500000000000000000000602082015250565b5f614ffe6036836146fe565b915061500982614fa4565b604082019050919050565b5f6020820190508181035f83015261502b81614ff2565b9050919050565b7f526571756972652039392520636f6c6c61746572616c697a6174696f6e2072615f8201527f7465000000000000000000000000000000000000000000000000000000000000602082015250565b5f61508c6022836146fe565b915061509782615032565b604082019050919050565b5f6020820190508181035f8301526150b981615080565b9050919050565b7f4d757374207365742066656520616464726573730000000000000000000000005f82015250565b5f6150f46014836146fe565b91506150ff826150c0565b602082019050919050565b5f6020820190508181035f830152615121816150e8565b9050919050565b7f4d757374207265706179206c657373207468616e20626f72726f77656420616d5f8201527f6f756e7400000000000000000000000000000000000000000000000000000000602082015250565b5f6151826024836146fe565b915061518d82615128565b604082019050919050565b5f6020820190508181035f8301526151af81615176565b9050919050565b7f4d75737420726570617920736f6d657468696e670000000000000000000000005f82015250565b5f6151ea6014836146fe565b91506151f5826151b6565b602082019050919050565b5f6020820190508181035f830152615217816151de565b9050919050565b7f596f7572206c6f616e20686173206265656e206c6971756964617465642c20635f8201527f616e6e6f74207265706179000000000000000000000000000000000000000000602082015250565b5f615278602b836146fe565b91506152838261521e565b604082019050919050565b5f6020820190508181035f8301526152a58161526c565b9050919050565b7f54726164696e67206d75737420626520696e697469616c697a656400000000005f82015250565b5f6152e0601b836146fe565b91506152eb826152ac565b602082019050919050565b5f6020820190508181035f83015261530d816152d4565b9050919050565b7f557365206163636f756e742077697468206e6f206c6f616e73000000000000005f82015250565b5f6153486019836146fe565b915061535382615314565b602082019050919050565b5f6020820190508181035f8301526153758161533c565b9050919050565b7f496e73756666696369656e7420736f6e6963206665652073656e7400000000005f82015250565b5f6153b0601b836146fe565b91506153bb8261537c565b602082019050919050565b5f6020820190508181035f8301526153dd816153a4565b9050919050565b7f62757920666565206d7573742062652067726561746572207468616e204645455f8201527f535f425559000000000000000000000000000000000000000000000000000000602082015250565b5f61543e6025836146fe565b9150615449826153e4565b604082019050919050565b5f6020820190508181035f83015261546b81615432565b9050919050565b7f62757920666565206d757374206265206c657373207468616e20322e352500005f82015250565b5f6154a6601e836146fe565b91506154b182615472565b602082019050919050565b5f6020820190508181035f8301526154d38161549a565b9050919050565b7f4c6f616e20657874656e73696f6e2066656520696e636f7272656374000000005f82015250565b5f61550e601c836146fe565b9150615519826154da565b602082019050919050565b5f6020820190508181035f83015261553b81615502565b9050919050565b7f4c6f616e206d75737420626520756e64657220333635206461797300000000005f82015250565b5f615576601b836146fe565b915061558182615542565b602082019050919050565b5f6020820190508181035f8301526155a38161556a565b9050919050565b7f43616e27742073657420666565206164647265737320746f20307830206164645f8201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b5f6156046024836146fe565b915061560f826155aa565b604082019050919050565b5f6020820190508181035f830152615631816155f8565b9050919050565b7f4c6f616e20657870697265642075736520626f72726f770000000000000000005f82015250565b5f61566c6017836146fe565b915061567782615638565b602082019050919050565b5f6020820190508181035f83015261569981615660565b9050919050565b7f596f7520646f206e6f74206861766520656e6f75676820636f6c6c61746572615f8201527f6c20746f20636c6f736520706f736974696f6e00000000000000000000000000602082015250565b5f6156fa6033836146fe565b9150615705826156a0565b604082019050919050565b5f6020820190508181035f830152615727816156ee565b9050919050565b7f4d7573742072657475726e20656e7469726520626f72726f77656420616d6f755f8201527f6e74000000000000000000000000000000000000000000000000000000000000602082015250565b5f6157886022836146fe565b91506157938261572e565b604082019050919050565b5f6020820190508181035f8301526157b58161577c565b9050919050565b7f73656c6c20666565206d7573742062652067726561746572207468616e2046455f8201527f45535f53454c4c00000000000000000000000000000000000000000000000000602082015250565b5f6158166027836146fe565b9150615821826157bc565b604082019050919050565b5f6020820190508181035f8301526158438161580a565b9050919050565b7f73656c6c20666565206d757374206265206c657373207468616e20322e3525005f82015250565b5f61587e601f836146fe565b91506158898261584a565b602082019050919050565b5f6020820190508181035f8301526158ab81615872565b9050919050565b5f6158bc82614609565b91506158c783614609565b9250826158d7576158d6614d3e565b5b828206905092915050565b7f6d757374207472616465206f766572206d696e000000000000000000000000005f82015250565b5f6159166013836146fe565b9150615921826158e2565b602082019050919050565b5f6020820190508181035f8301526159438161590a565b9050919050565b7f52656369657665722063616e6e6f7420626520307830206164647265737300005f82015250565b5f61597e601e836146fe565b91506159898261594a565b602082019050919050565b5f6020820190508181035f8301526159ab81615972565b9050919050565b5f81905092915050565b50565b5f6159ca5f836159b2565b91506159d5826159bc565b5f82019050919050565b5f6159e9826159bf565b9150819050919050565b7f534f4e4943205472616e73666572206661696c65642e000000000000000000005f82015250565b5f615a276016836146fe565b9150615a32826159f3565b602082019050919050565b5f6020820190508181035f830152615a5481615a1b565b9050919050565b5f604082019050615a6e5f830185614988565b615a7b6020830184614667565b9392505050565b7f54686520656767732062616c616e6365206f662074686520636f6e74726163745f8201527f206d7573742062652067726561746572207468616e206f7220657175616c207460208201527f6f2074686520636f6c6c61746572616c00000000000000000000000000000000604082015250565b5f615b026050836146fe565b9150615b0d82615a82565b606082019050919050565b5f6020820190508181035f830152615b2f81615af6565b9050919050565b7f546865207072696365206f6620656767732063616e6e6f7420646563726561735f8201527f6500000000000000000000000000000000000000000000000000000000000000602082015250565b5f615b906021836146fe565b9150615b9b82615b36565b604082019050919050565b5f6020820190508181035f830152615bbd81615b84565b9050919050565b5f606082019050615bd75f830186614988565b615be46020830185614667565b615bf16040830184614667565b949350505050565b7f43616e2774206d696e7420746f20746f203078302061646472657373000000005f82015250565b5f615c2d601c836146fe565b9150615c3882615bf9565b602082019050919050565b5f6020820190508181035f830152615c5a81615c21565b9050919050565b7f4e4f204d4f5245204547475300000000000000000000000000000000000000005f82015250565b5f615c95600c836146fe565b9150615ca082615c61565b602082019050919050565b5f6020820190508181035f830152615cc281615c89565b905091905056fea2646970667358221220232ac30dbbab817d1348eaeac4cf0ec0aa588e938f2b8b5d570097dbb67d8c9c64736f6c634300081c0033

Deployed Bytecode

0x6080604052600436106103a5575f3560e01c806379ba5097116101e6578063b6013e9a1161010c578063dd62ed3e1161009f578063e4849b321161006e578063e4849b3214610db8578063eb1edd6114610de0578063f088d54714610e0a578063f2fde38b14610e26576103a6565b8063dd62ed3e14610cee578063e064648a14610d2a578063e30c397814610d52578063e3eb5ed314610d7c576103a6565b8063c94220ab116100db578063c94220ab14610c34578063c962a4b514610c5e578063d5abeb0114610c9a578063d6eb591014610cc4576103a6565b8063b6013e9a14610b88578063bd0fe67914610bc4578063be9a655514610c00578063c393d0e314610c2a576103a6565b806395ced06f11610184578063a2309ff811610153578063a2309ff814610ab9578063a9059cbb14610ae3578063a925e4a414610b1f578063abd545bf14610b5e576103a6565b806395ced06f14610a1357806395d89b4114610a515780639d0bf2e914610a7b5780639d41ac3a14610aa3576103a6565b80638705fcd4116101c05780638705fcd41461095b578063886433ac146109835780638da5cb5b146109bf5780638f818b90146109e9576103a6565b806379ba5097146108ed57806379cc6790146109035780637ace2ac91461092b576103a6565b80633237c158116102cb57806342966c681161026957806370a082311161023857806370a082311461083757806370c476711461087357806370f84ba91461089b578063715018a6146108d7576103a6565b806342966c681461077b57806342c95e19146107a35780634fbf3ab0146107df5780635e96263c1461081b576103a6565b806335975a37116102a557806335975a371461070157806336189d431461070b5780633be4e59814610735578063402d888314610771576103a6565b80633237c1581461067357806333e516d51461069b5780633421f750146106d7576103a6565b80630ecbcdab116103435780631fb87f39116103125780631fb87f39146105bb57806323b872dd146105f757806328a0702514610633578063313ce56714610649576103a6565b80630ecbcdab14610517578063162b51fc1461053f57806317a5a97e1461056957806318160ddd14610591576103a6565b8063053f14da1161037f578063053f14da1461044b57806306fdde0314610475578063095ea7b31461049f5780630df1ff24146104db576103a6565b8063024cad3b146103a85780630307c4a1146103e5578063035b7c4b1461040f576103a6565b5b005b3480156103b3575f5ffd5b506103ce60048036038101906103c9919061463c565b610e4e565b6040516103dc929190614676565b60405180910390f35b3480156103f0575f5ffd5b506103f9610e8d565b604051610406919061469d565b60405180910390f35b34801561041a575f5ffd5b50610435600480360381019061043091906146b6565b610e96565b604051610442919061469d565b60405180910390f35b348015610456575f5ffd5b5061045f610edc565b60405161046c919061469d565b60405180910390f35b348015610480575f5ffd5b50610489610ee2565b6040516104969190614764565b60405180910390f35b3480156104aa575f5ffd5b506104c560048036038101906104c091906147de565b610f72565b6040516104d29190614836565b60405180910390f35b3480156104e6575f5ffd5b5061050160048036038101906104fc919061463c565b610f94565b60405161050e919061469d565b60405180910390f35b348015610522575f5ffd5b5061053d600480360381019061053891906146b6565b610fb5565b005b34801561054a575f5ffd5b506105536112e8565b604051610560919061486b565b60405180910390f35b348015610574575f5ffd5b5061058f600480360381019061058a91906148ae565b6112fc565b005b34801561059c575f5ffd5b506105a56113ea565b6040516105b2919061469d565b60405180910390f35b3480156105c6575f5ffd5b506105e160048036038101906105dc919061463c565b6113f3565b6040516105ee919061469d565b60405180910390f35b348015610602575f5ffd5b5061061d600480360381019061061891906148d9565b61142c565b60405161062a9190614836565b60405180910390f35b34801561063e575f5ffd5b5061064761145a565b005b348015610654575f5ffd5b5061065d611554565b60405161066a9190614944565b60405180910390f35b34801561067e575f5ffd5b506106996004803603810190610694919061463c565b61155c565b005b3480156106a6575f5ffd5b506106c160048036038101906106bc919061463c565b61179f565b6040516106ce919061469d565b60405180910390f35b3480156106e2575f5ffd5b506106eb6117cb565b6040516106f8919061469d565b60405180910390f35b6107096117d1565b005b348015610716575f5ffd5b5061071f611902565b60405161072c919061486b565b60405180910390f35b348015610740575f5ffd5b5061075b600480360381019061075691906146b6565b611916565b604051610768919061469d565b60405180910390f35b61077961196e565b005b348015610786575f5ffd5b506107a1600480360381019061079c919061463c565b611b3b565b005b3480156107ae575f5ffd5b506107c960048036038101906107c4919061463c565b611b4f565b6040516107d6919061469d565b60405180910390f35b3480156107ea575f5ffd5b506108056004803603810190610800919061463c565b611b98565b604051610812919061469d565b60405180910390f35b610835600480360381019061083091906146b6565b611bad565b005b348015610842575f5ffd5b5061085d6004803603810190610858919061495d565b612008565b60405161086a919061469d565b60405180910390f35b34801561087e575f5ffd5b50610899600480360381019061089491906148ae565b61204d565b005b3480156108a6575f5ffd5b506108c160048036038101906108bc919061495d565b61213e565b6040516108ce9190614836565b60405180910390f35b3480156108e2575f5ffd5b506108eb612189565b005b3480156108f8575f5ffd5b5061090161219c565b005b34801561090e575f5ffd5b50610929600480360381019061092491906147de565b61222a565b005b6109456004803603810190610940919061463c565b61224a565b604051610952919061469d565b60405180910390f35b348015610966575f5ffd5b50610981600480360381019061097c919061495d565b6125ca565b005b34801561098e575f5ffd5b506109a960048036038101906109a4919061463c565b6126ba565b6040516109b6919061469d565b60405180910390f35b3480156109ca575f5ffd5b506109d3612717565b6040516109e09190614997565b60405180910390f35b3480156109f4575f5ffd5b506109fd61273f565b604051610a0a919061469d565b60405180910390f35b348015610a1e575f5ffd5b50610a396004803603810190610a34919061495d565b61275a565b604051610a48939291906149b0565b60405180910390f35b348015610a5c575f5ffd5b50610a65612882565b604051610a729190614764565b60405180910390f35b348015610a86575f5ffd5b50610aa16004803603810190610a9c919061463c565b612912565b005b348015610aae575f5ffd5b50610ab7612cb0565b005b348015610ac4575f5ffd5b50610acd612f79565b604051610ada919061469d565b60405180910390f35b348015610aee575f5ffd5b50610b096004803603810190610b0491906147de565b612f7f565b604051610b169190614836565b60405180910390f35b348015610b2a575f5ffd5b50610b456004803603810190610b40919061495d565b612fa1565b604051610b5594939291906149e5565b60405180910390f35b348015610b69575f5ffd5b50610b72612fcd565b604051610b7f919061486b565b60405180910390f35b348015610b93575f5ffd5b50610bae6004803603810190610ba9919061463c565b612fe1565b604051610bbb919061469d565b60405180910390f35b348015610bcf575f5ffd5b50610bea6004803603810190610be591906146b6565b613007565b604051610bf7919061469d565b60405180910390f35b348015610c0b575f5ffd5b50610c1461305c565b604051610c219190614836565b60405180910390f35b610c3261306f565b005b348015610c3f575f5ffd5b50610c4861324f565b604051610c55919061469d565b60405180910390f35b348015610c69575f5ffd5b50610c846004803603810190610c7f919061463c565b613268565b604051610c91919061469d565b60405180910390f35b348015610ca5575f5ffd5b50610cae61327d565b604051610cbb9190614a52565b60405180910390f35b348015610ccf575f5ffd5b50610cd861328e565b604051610ce5919061469d565b60405180910390f35b348015610cf9575f5ffd5b50610d146004803603810190610d0f9190614a6b565b613297565b604051610d21919061469d565b60405180910390f35b348015610d35575f5ffd5b50610d506004803603810190610d4b91906148ae565b613319565b005b348015610d5d575f5ffd5b50610d6661340a565b604051610d739190614997565b60405180910390f35b348015610d87575f5ffd5b50610da26004803603810190610d9d919061463c565b613432565b604051610daf919061469d565b60405180910390f35b348015610dc3575f5ffd5b50610dde6004803603810190610dd9919061463c565b613467565b005b348015610deb575f5ffd5b50610df4613560565b604051610e019190614ac9565b60405180910390f35b610e246004803603810190610e1f919061495d565b613585565b005b348015610e31575f5ffd5b50610e4c6004803603810190610e47919061495d565b613724565b005b5f5f600e5f610e5c85613432565b81526020019081526020015f2054600f5f610e7686613432565b81526020019081526020015f205491509150915091565b5f600954905090565b5f5f66038d7ea4c68000610eb4668a8e4b1a3d80008561016d6137d0565b610ebe9190614b0f565b9050610ed38482670de0b6b3a76400006137d0565b91505092915050565b600c5481565b606060038054610ef190614b6f565b80601f0160208091040260200160405190810160405280929190818152602001828054610f1d90614b6f565b8015610f685780601f10610f3f57610100808354040283529160200191610f68565b820191905f5260205f20905b815481529060010190602001808311610f4b57829003601f168201915b5050505050905090565b5f5f610f7c6138b5565b9050610f898185856138bc565b600191505092915050565b5f610fae82610fa161324f565b610fa96113ea565b6137d0565b9050919050565b610fbd6138ce565b61016e8110611001576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff890614c0f565b60405180910390fd5b5f8203611043576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103a90614c77565b60405180910390fd5b61104c3361213e565b156110ad57600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f5f82015f9055600182015f9055600282015f9055600382015f905550505b5f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600101541461112f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112690614cdf565b60405180910390fd5b61113761145a565b5f61115a42620151808461114b9190614cfd565b6111559190614b0f565b613432565b90505f6111678484610e96565b90505f600a6003836111799190614cfd565b6111839190614d6b565b90505f61118f86611b4f565b90505f60646063886111a19190614cfd565b6111ab9190614d6b565b9050604051806080016040528083815260200182815260200186815260200187815250600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f820151815f015560208201518160010155604082015181600201556060820151816003015590505061123f333084613914565b6103e88311611283576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127a90614de5565b60405180910390fd5b6112983385836112939190614e03565b613a04565b6112c360085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684613a04565b6112ce818387613aea565b6112d784613bde565b50505050506112e4613ceb565b5050565b600860169054906101000a900461ffff1681565b611304613cf5565b60198161ffff16111561134c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134390614ea6565b60405180910390fd5b5f8161ffff161015611393576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138a90614f34565b60405180910390fd5b80600860186101000a81548161ffff021916908361ffff1602179055507fd4e469371f09a592c9c4fde36ed11fd123a8cc55d93bd2920ea6ad544dff4395816040516113df9190614f8b565b60405180910390a150565b5f600254905090565b5f5f6113fe83612fe1565b90506103e861ffff1661140f61273f565b8261141a9190614cfd565b6114249190614d6b565b915050919050565b5f5f6114366138b5565b9050611443858285613d7c565b61144e858585613914565b60019150509392505050565b5f5f5b4260105410156114c557600f5f60105481526020019081526020015f2054816114869190614b0f565b9050600e5f60105481526020019081526020015f2054826114a79190614b0f565b9150620151806010546114ba9190614b0f565b60108190555061145d565b5f81146114eb5780600a546114da9190614e03565b600a819055506114ea3082613e0f565b5b5f821461155057816009546115009190614e03565b6009819055507f253e5385159062a101837d58c10ad4694c58979ebc3ba6b5cb2cbba2fe461692620151806010546115389190614e03565b83604051611547929190614676565b60405180910390a15b5050565b5f6012905090565b6115646138ce565b61156d3361213e565b156115ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115a490615014565b60405180910390fd5b6115b561145a565b5f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0154905060646063611610848461160b9190614e03565b610f94565b61161a9190614cfd565b6116249190614d6b565b600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015411156116a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169d906150a2565b60405180910390fd5b81600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f01546116f19190614e03565b600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f018190555061173f303384613914565b61178a5f83600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060020154613e8e565b6117935f613bde565b5061179c613ceb565b50565b5f6117c4826117ac6113ea565b846117b561324f565b6117bf9190614e03565b6137d0565b9050919050565b60105481565b6117d9613cf5565b5f73ffffffffffffffffffffffffffffffffffffffff1660085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603611868576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185f9061510a565b60405180910390fd5b5f6103e8346118779190614cfd565b9050670de0b6b3a764000081101561188d575f5ffd5b6118973382613f82565b6118ac3361dead670de0b6b3a7640000613914565b60016008601a6101000a81548160ff0219169083151502179055507f4f366f0dc5cd876e456f089309e0c62fc2bc0e116c6f6ae308c392b4ad45b5b960016040516118f79190614836565b60405180910390a150565b600860189054906101000a900461ffff1681565b5f5f6103e861ffff16600860189054906101000a900461ffff1661ffff168561193f9190614cfd565b6119499190614d6b565b90505f6119568585610e96565b905080826119649190614b0f565b9250505092915050565b6119766138ce565b5f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015490503481116119fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f390615198565b60405180910390fd5b5f3403611a3e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3590615200565b60405180910390fd5b611a473361213e565b15611a87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a7e9061528e565b60405180910390fd5b5f3482611a949190614e03565b905080600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010181905550611b26345f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060020154613e8e565b611b2f5f613bde565b5050611b39613ceb565b565b611b4c611b466138b5565b82613e0f565b50565b5f5f611b5961324f565b905080600182611b699190614e03565b611b716113ea565b85611b7c9190614cfd565b611b869190614b0f565b611b909190614d6b565b915050919050565b600e602052805f5260405f205f915090505481565b611bb56138ce565b6008601a9054906101000a900460ff16611c04576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bfb906152f6565b60405180910390fd5b61016e8110611c48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3f90614c0f565b60405180910390fd5b5f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206040518060800160405290815f8201548152602001600182015481526020016002820154815260200160038201548152505090505f816020015114611db257611cce3361213e565b15611d2f57600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f5f82015f9055600182015f9055600282015f9055600382015f905550505b5f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015414611db1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611da89061535e565b60405180910390fd5b5b611dba61145a565b5f611ddd426201518085611dce9190614cfd565b611dd89190614b0f565b613432565b90505f611dea8585611916565b90505f8186611df99190614e03565b90505f600a600384611e0b9190614cfd565b611e159190614d6b565b90505f6064606384611e279190614cfd565b611e319190614d6b565b90505f606484611e419190614d6b565b90505f8184611e509190614b0f565b90505f8287611e5f9190614b0f565b90505f81341115611e83578134611e769190614e03565b9050611e823382613a04565b5b818134611e909190614e03565b14611ed0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ec7906153c6565b60405180910390fd5b5f611edb8885613007565b9050611ee73082613f82565b6103e88711611f2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f2290614de5565b60405180910390fd5b611f5660085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1688613a04565b611f6186828c613aea565b60405180608001604052808281526020018781526020018b81526020018d815250600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f820151815f0155602082015181600101556040820151816002015560608201518160030155905050611ff18d613bde565b5050505050505050505050612004613ceb565b5050565b5f5f5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b612055613cf5565b6103e08161ffff16111561209e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161209590615454565b60405180910390fd5b6103cf8161ffff1610156120e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120de906154bc565b60405180910390fd5b80600860166101000a81548161ffff021916908361ffff1602179055507f7c1445c98b278c9970d007fca6048704bcb25af7cc4a04eb56565d9a9f149ca3816040516121339190614f8b565b60405180910390a150565b5f42600d5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060020154109050919050565b612191613cf5565b61219a5f614076565b565b5f6121a56138b5565b90508073ffffffffffffffffffffffffffffffffffffffff166121c661340a565b73ffffffffffffffffffffffffffffffffffffffff161461221e57806040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016122159190614997565b60405180910390fd5b61222781614076565b50565b61223c826122366138b5565b83613d7c565b6122468282613e0f565b5050565b5f6122536138ce565b5f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206002015490505f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015490505f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015490505f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206003015490505f62015180876123729190614cfd565b8561237d9190614b0f565b90505f61238a8589610e96565b90506123953361213e565b156123d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123cc90615014565b60405180910390fd5b348114612417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240e90615524565b60405180910390fd5b5f600a6003836124279190614cfd565b6124319190614d6b565b90506103e88111612477576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161246e90614de5565b60405180910390fd5b6124a260085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682613a04565b6124ad868689613e8e565b6124b8868685613aea565b82600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206002018190555083896125099190614b0f565b600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206003018190555061016e6201518042856125609190614e03565b61256a9190614d6b565b106125aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125a19061558c565b60405180910390fd5b6125b334613bde565b819750505050505050506125c5613ceb565b919050565b6125d2613cf5565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612640576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126379061561a565b60405180910390fd5b8060085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f446e39bcf1b47cfadfaa23442cb4b34682cfe6bd9220da084894e3b1f834e4f3816040516126af9190614997565b60405180910390a150565b5f6103e861ffff166126ca61324f565b600860169054906101000a900461ffff1661ffff166126e76113ea565b856126f29190614cfd565b6126fc9190614cfd565b6127069190614d6b565b6127109190614d6b565b9050919050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f600860169054906101000a900461ffff1661ffff16905090565b5f5f5f42600d5f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600201541061287157600d5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0154600d5f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010154600d5f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206002015492509250925061287b565b5f5f5f9250925092505b9193909250565b60606004805461289190614b6f565b80601f01602080910402602001604051908101604052809291908181526020018280546128bd90614b6f565b80156129085780601f106128df57610100808354040283529160200191612908565b820191905f5260205f20905b8154815290600101906020018083116128eb57829003601f168201915b5050505050905090565b61291a6138ce565b6129233361213e565b15612963576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161295a90615682565b60405180910390fd5b5f81036129a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161299c90614c77565b60405180910390fd5b6129ad61145a565b5f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015490505f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015490505f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206002015490505f612a8242613432565b90505f620151808284612a959190614e03565b612a9f9190614d6b565b90505f612aac8783610e96565b90505f612ab888611b4f565b90505f612ac488612fe1565b90505f81606460638a612ad79190614cfd565b612ae19190614d6b565b612aeb9190614e03565b90505f839050838210612b00575f9050612b0f565b8181612b0c9190614e03565b90505b5f600a600387612b1f9190614cfd565b612b299190614d6b565b90505f606460638e612b3b9190614cfd565b612b459190614d6b565b90505f818d612b549190614b0f565b90505f848d612b639190614b0f565b905060405180608001604052808281526020018381526020018d81526020018b815250600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f820151815f01556020820151816001015560408201518160020155606082015181600301559050505f8514612bff57612bfe333087613914565b5b6103e88411612c43576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c3a90614de5565b60405180910390fd5b612c6e60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685613a04565b612c83338a85612c7e9190614e03565b613a04565b612c8e83868e613aea565b612c9789613bde565b5050505050505050505050505050612cad613ceb565b50565b612cb86138ce565b612cc13361213e565b15612d01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cf890615014565b60405180910390fd5b612d0961145a565b5f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015490505f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015490505f612d9a82610f94565b9050612da63083613e0f565b5f6064606383612db69190614cfd565b612dc09190614d6b565b90505f606483612dd09190614d6b565b905084821015612e15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e0c90615710565b60405180910390fd5b5f8583612e229190614e03565b90505f600a600384612e349190614cfd565b612e3e9190614d6b565b9050612e4a3383613a04565b6103e88111612e8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e8590614de5565b60405180910390fd5b612eb960085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682613a04565b612f048787600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060020154613e8e565b600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f5f82015f9055600182015f9055600282015f9055600382015f90555050612f6887613bde565b50505050505050612f77613ceb565b565b600b5481565b5f5f612f896138b5565b9050612f96818585613914565b600191505092915050565b600d602052805f5260405f205f91509050805f0154908060010154908060020154908060030154905084565b600860149054906101000a900461ffff1681565b5f5f612feb61324f565b9050612fff83612ff96113ea565b836137d0565b915050919050565b5f5f8261301261324f565b61301c9190614e03565b90508060018261302c9190614e03565b6130346113ea565b8661303f9190614cfd565b6130499190614b0f565b6130539190614d6b565b91505092915050565b6008601a9054906101000a900460ff1681565b6130776138ce565b5f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015490505f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f015490506131073361213e565b15613147576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161313e90615014565b60405180910390fd5b348214613189576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131809061579e565b60405180910390fd5b613194303383613914565b6131df8282600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060020154613e8e565b600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f5f82015f9055600182015f9055600282015f9055600382015f905550506132435f613bde565b505061324d613ceb565b565b5f613258610e8d565b476132639190614b0f565b905090565b600f602052805f5260405f205f915090505481565b6c01431e0fae6d7217caa000000081565b5f600a54905090565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b613321613cf5565b6103e08161ffff16111561336a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133619061582c565b60405180910390fd5b6103cf8161ffff1610156133b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133aa90615894565b60405180910390fd5b80600860146101000a81548161ffff021916908361ffff1602179055507f495ee53ee22006979ebc689a00ed737d7c13b6419142f82dcaea4ed95ac1e780816040516133ff9190614f8b565b60405180910390a150565b5f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f5f620151808361344391906158b2565b8361344e9190614e03565b9050620151808161345f9190614b0f565b915050919050565b61346f6138ce565b61347761145a565b5f61348182610f94565b90505f607d61ffff16826134959190614d6b565b90506134a13384613e0f565b6134db336103e861ffff16600860149054906101000a900461ffff1661ffff16856134cc9190614cfd565b6134d69190614d6b565b613a04565b6103e8811161351f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135169061592c565b60405180910390fd5b61354a60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682613a04565b61355382613bde565b505061355d613ceb565b50565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61358d6138ce565b61359561145a565b6008601a9054906101000a900460ff166135e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135db906152f6565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161364990615994565b60405180910390fd5b5f61365c3461179f565b905061368b826103e861ffff1661367161273f565b8461367c9190614cfd565b6136869190614d6b565b613f82565b5f607d61ffff163461369d9190614d6b565b90506103e881116136e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136da9061592c565b60405180910390fd5b61370e60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682613a04565b61371734613bde565b5050613721613ceb565b50565b61372c613cf5565b8060065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff1661378b612717565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b5f5f83850290505f5f19858709828110838203039150505f8103613808578382816137fe576137fd614d3e565b5b04925050506138ae565b808411613827576138266138215f8614601260116140a6565b6140bf565b5b5f8486880990508281118203915080830392505f855f038616905080860495508084049350600181825f0304019050808302841793505f600287600302189050808702600203810290508087026002038102905080870260020381029050808702600203810290508087026002038102905080870260020381029050808502955050505050505b9392505050565b5f33905090565b6138c983838360016140d0565b505050565b60026007540361390a576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600781905550565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603613984575f6040517f96c6fd1e00000000000000000000000000000000000000000000000000000000815260040161397b9190614997565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036139f4575f6040517fec442f050000000000000000000000000000000000000000000000000000000081526004016139eb9190614997565b60405180910390fd5b6139ff83838361429f565b505050565b5f8273ffffffffffffffffffffffffffffffffffffffff1682604051613a29906159df565b5f6040518083038185875af1925050503d805f8114613a63576040519150601f19603f3d011682016040523d82523d5f602084013e613a68565b606091505b5050905080613aac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613aa390615a3d565b60405180910390fd5b7f03bbe564cb1b78e43195eeadbde99e5b89b19345862807fcfb59f884e4165e258383604051613add929190615a5b565b60405180910390a1505050565b81600f5f8381526020019081526020015f2054613b079190614b0f565b600f5f8381526020019081526020015f208190555082600e5f8381526020019081526020015f2054613b399190614b0f565b600e5f8381526020019081526020015f208190555082600954613b5c9190614b0f565b60098190555081600a54613b709190614b0f565b600a819055507faec00f5213a37254bc68a26b0685d1a5b2bf513e1e587c94c7df7f4a62b56c9c600f5f8381526020019081526020015f2054600e5f8481526020019081526020015f2054600954600a54604051613bd194939291906149e5565b60405180910390a1505050565b5f613be76113ea565b670de0b6b3a7640000613bf861324f565b613c029190614cfd565b613c0c9190614d6b565b90505f613c1830612008565b9050600a54811015613c5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613c5690615b18565b60405180910390fd5b81600c541115613ca4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613c9b90615ba6565b60405180910390fd5b81600c819055507f4afcb4a87cdbd9974efdb92ee48bc8d7cd0ae4bf217004db3d080cbaee652ca7428385604051613cde939291906149b0565b60405180910390a1505050565b6001600781905550565b613cfd6138b5565b73ffffffffffffffffffffffffffffffffffffffff16613d1b612717565b73ffffffffffffffffffffffffffffffffffffffff1614613d7a57613d3e6138b5565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401613d719190614997565b60405180910390fd5b565b5f613d878484613297565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811015613e095781811015613dfa578281836040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401613df193929190615bc4565b60405180910390fd5b613e0884848484035f6140d0565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613e7f575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401613e769190614997565b60405180910390fd5b613e8a825f8361429f565b5050565b81600f5f8381526020019081526020015f2054613eab9190614e03565b600f5f8381526020019081526020015f208190555082600e5f8381526020019081526020015f2054613edd9190614e03565b600e5f8381526020019081526020015f208190555082600954613f009190614e03565b60098190555081600a54613f149190614e03565b600a819055507faec00f5213a37254bc68a26b0685d1a5b2bf513e1e587c94c7df7f4a62b56c9c600f5f8381526020019081526020015f2054600e5f8481526020019081526020015f2054600954600a54604051613f7594939291906149e5565b60405180910390a1505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613ff0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613fe790615c43565b60405180910390fd5b80600b54613ffe9190614b0f565b600b819055506c01431e0fae6d7217caa00000006fffffffffffffffffffffffffffffffff16600b541115614068576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161405f90615cab565b60405180910390fd5b61407282826144b8565b5050565b60065f6101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556140a381614537565b50565b5f6140b0846145fa565b82841802821890509392505050565b634e487b715f52806020526024601cfd5b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603614140575f6040517fe602df050000000000000000000000000000000000000000000000000000000081526004016141379190614997565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036141b0575f6040517f94280d620000000000000000000000000000000000000000000000000000000081526004016141a79190614997565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508015614299578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051614290919061469d565b60405180910390a35b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036142ef578060025f8282546142e39190614b0f565b925050819055506143bd565b5f5f5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015614378578381836040517fe450d38c00000000000000000000000000000000000000000000000000000000815260040161436f93929190615bc4565b60405180910390fd5b8181035f5f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603614404578060025f828254039250508190555061444e565b805f5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516144ab919061469d565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603614528575f6040517fec442f0500000000000000000000000000000000000000000000000000000000815260040161451f9190614997565b60405180910390fd5b6145335f838361429f565b5050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f8115159050919050565b5f5ffd5b5f819050919050565b61461b81614609565b8114614625575f5ffd5b50565b5f8135905061463681614612565b92915050565b5f6020828403121561465157614650614605565b5b5f61465e84828501614628565b91505092915050565b61467081614609565b82525050565b5f6040820190506146895f830185614667565b6146966020830184614667565b9392505050565b5f6020820190506146b05f830184614667565b92915050565b5f5f604083850312156146cc576146cb614605565b5b5f6146d985828601614628565b92505060206146ea85828601614628565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f614736826146f4565b61474081856146fe565b935061475081856020860161470e565b6147598161471c565b840191505092915050565b5f6020820190508181035f83015261477c818461472c565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6147ad82614784565b9050919050565b6147bd816147a3565b81146147c7575f5ffd5b50565b5f813590506147d8816147b4565b92915050565b5f5f604083850312156147f4576147f3614605565b5b5f614801858286016147ca565b925050602061481285828601614628565b9150509250929050565b5f8115159050919050565b6148308161481c565b82525050565b5f6020820190506148495f830184614827565b92915050565b5f61ffff82169050919050565b6148658161484f565b82525050565b5f60208201905061487e5f83018461485c565b92915050565b61488d8161484f565b8114614897575f5ffd5b50565b5f813590506148a881614884565b92915050565b5f602082840312156148c3576148c2614605565b5b5f6148d08482850161489a565b91505092915050565b5f5f5f606084860312156148f0576148ef614605565b5b5f6148fd868287016147ca565b935050602061490e868287016147ca565b925050604061491f86828701614628565b9150509250925092565b5f60ff82169050919050565b61493e81614929565b82525050565b5f6020820190506149575f830184614935565b92915050565b5f6020828403121561497257614971614605565b5b5f61497f848285016147ca565b91505092915050565b614991816147a3565b82525050565b5f6020820190506149aa5f830184614988565b92915050565b5f6060820190506149c35f830186614667565b6149d06020830185614667565b6149dd6040830184614667565b949350505050565b5f6080820190506149f85f830187614667565b614a056020830186614667565b614a126040830185614667565b614a1f6060830184614667565b95945050505050565b5f6fffffffffffffffffffffffffffffffff82169050919050565b614a4c81614a28565b82525050565b5f602082019050614a655f830184614a43565b92915050565b5f5f60408385031215614a8157614a80614605565b5b5f614a8e858286016147ca565b9250506020614a9f858286016147ca565b9150509250929050565b5f614ab382614784565b9050919050565b614ac381614aa9565b82525050565b5f602082019050614adc5f830184614aba565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f614b1982614609565b9150614b2483614609565b9250828201905080821115614b3c57614b3b614ae2565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680614b8657607f821691505b602082108103614b9957614b98614b42565b5b50919050565b7f4d617820626f72726f772f657874656e73696f6e206d757374206265203336355f8201527f2064617973206f72206c65737300000000000000000000000000000000000000602082015250565b5f614bf9602d836146fe565b9150614c0482614b9f565b604082019050919050565b5f6020820190508181035f830152614c2681614bed565b9050919050565b7f4d75737420626f72726f77206d6f7265207468616e20300000000000000000005f82015250565b5f614c616017836146fe565b9150614c6c82614c2d565b602082019050919050565b5f6020820190508181035f830152614c8e81614c55565b9050919050565b7f55736520626f72726f774d6f726520746f20626f72726f77206d6f72650000005f82015250565b5f614cc9601d836146fe565b9150614cd482614c95565b602082019050919050565b5f6020820190508181035f830152614cf681614cbd565b9050919050565b5f614d0782614609565b9150614d1283614609565b9250828202614d2081614609565b91508282048414831517614d3757614d36614ae2565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f614d7582614609565b9150614d8083614609565b925082614d9057614d8f614d3e565b5b828204905092915050565b7f46656573206d75737420626520686967686572207468616e206d696e2e0000005f82015250565b5f614dcf601d836146fe565b9150614dda82614d9b565b602082019050919050565b5f6020820190508181035f830152614dfc81614dc3565b9050919050565b5f614e0d82614609565b9150614e1883614609565b9250828203905081811115614e3057614e2f614ae2565b5b92915050565b7f6c657665726167652062757920666565206d757374206265206c65737320322e5f8201527f3525000000000000000000000000000000000000000000000000000000000000602082015250565b5f614e906022836146fe565b9150614e9b82614e36565b604082019050919050565b5f6020820190508181035f830152614ebd81614e84565b9050919050565b7f6c657665726167652062757920666565206d75737420626520677265617465725f8201527f207468616e203025000000000000000000000000000000000000000000000000602082015250565b5f614f1e6028836146fe565b9150614f2982614ec4565b604082019050919050565b5f6020820190508181035f830152614f4b81614f12565b9050919050565b5f819050919050565b5f614f75614f70614f6b8461484f565b614f52565b614609565b9050919050565b614f8581614f5b565b82525050565b5f602082019050614f9e5f830184614f7c565b92915050565b7f596f7572206c6f616e20686173206265656e206c6971756964617465642c206e5f8201527f6f20636f6c6c61746572616c20746f2072656d6f766500000000000000000000602082015250565b5f614ffe6036836146fe565b915061500982614fa4565b604082019050919050565b5f6020820190508181035f83015261502b81614ff2565b9050919050565b7f526571756972652039392520636f6c6c61746572616c697a6174696f6e2072615f8201527f7465000000000000000000000000000000000000000000000000000000000000602082015250565b5f61508c6022836146fe565b915061509782615032565b604082019050919050565b5f6020820190508181035f8301526150b981615080565b9050919050565b7f4d757374207365742066656520616464726573730000000000000000000000005f82015250565b5f6150f46014836146fe565b91506150ff826150c0565b602082019050919050565b5f6020820190508181035f830152615121816150e8565b9050919050565b7f4d757374207265706179206c657373207468616e20626f72726f77656420616d5f8201527f6f756e7400000000000000000000000000000000000000000000000000000000602082015250565b5f6151826024836146fe565b915061518d82615128565b604082019050919050565b5f6020820190508181035f8301526151af81615176565b9050919050565b7f4d75737420726570617920736f6d657468696e670000000000000000000000005f82015250565b5f6151ea6014836146fe565b91506151f5826151b6565b602082019050919050565b5f6020820190508181035f830152615217816151de565b9050919050565b7f596f7572206c6f616e20686173206265656e206c6971756964617465642c20635f8201527f616e6e6f74207265706179000000000000000000000000000000000000000000602082015250565b5f615278602b836146fe565b91506152838261521e565b604082019050919050565b5f6020820190508181035f8301526152a58161526c565b9050919050565b7f54726164696e67206d75737420626520696e697469616c697a656400000000005f82015250565b5f6152e0601b836146fe565b91506152eb826152ac565b602082019050919050565b5f6020820190508181035f83015261530d816152d4565b9050919050565b7f557365206163636f756e742077697468206e6f206c6f616e73000000000000005f82015250565b5f6153486019836146fe565b915061535382615314565b602082019050919050565b5f6020820190508181035f8301526153758161533c565b9050919050565b7f496e73756666696369656e7420736f6e6963206665652073656e7400000000005f82015250565b5f6153b0601b836146fe565b91506153bb8261537c565b602082019050919050565b5f6020820190508181035f8301526153dd816153a4565b9050919050565b7f62757920666565206d7573742062652067726561746572207468616e204645455f8201527f535f425559000000000000000000000000000000000000000000000000000000602082015250565b5f61543e6025836146fe565b9150615449826153e4565b604082019050919050565b5f6020820190508181035f83015261546b81615432565b9050919050565b7f62757920666565206d757374206265206c657373207468616e20322e352500005f82015250565b5f6154a6601e836146fe565b91506154b182615472565b602082019050919050565b5f6020820190508181035f8301526154d38161549a565b9050919050565b7f4c6f616e20657874656e73696f6e2066656520696e636f7272656374000000005f82015250565b5f61550e601c836146fe565b9150615519826154da565b602082019050919050565b5f6020820190508181035f83015261553b81615502565b9050919050565b7f4c6f616e206d75737420626520756e64657220333635206461797300000000005f82015250565b5f615576601b836146fe565b915061558182615542565b602082019050919050565b5f6020820190508181035f8301526155a38161556a565b9050919050565b7f43616e27742073657420666565206164647265737320746f20307830206164645f8201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b5f6156046024836146fe565b915061560f826155aa565b604082019050919050565b5f6020820190508181035f830152615631816155f8565b9050919050565b7f4c6f616e20657870697265642075736520626f72726f770000000000000000005f82015250565b5f61566c6017836146fe565b915061567782615638565b602082019050919050565b5f6020820190508181035f83015261569981615660565b9050919050565b7f596f7520646f206e6f74206861766520656e6f75676820636f6c6c61746572615f8201527f6c20746f20636c6f736520706f736974696f6e00000000000000000000000000602082015250565b5f6156fa6033836146fe565b9150615705826156a0565b604082019050919050565b5f6020820190508181035f830152615727816156ee565b9050919050565b7f4d7573742072657475726e20656e7469726520626f72726f77656420616d6f755f8201527f6e74000000000000000000000000000000000000000000000000000000000000602082015250565b5f6157886022836146fe565b91506157938261572e565b604082019050919050565b5f6020820190508181035f8301526157b58161577c565b9050919050565b7f73656c6c20666565206d7573742062652067726561746572207468616e2046455f8201527f45535f53454c4c00000000000000000000000000000000000000000000000000602082015250565b5f6158166027836146fe565b9150615821826157bc565b604082019050919050565b5f6020820190508181035f8301526158438161580a565b9050919050565b7f73656c6c20666565206d757374206265206c657373207468616e20322e3525005f82015250565b5f61587e601f836146fe565b91506158898261584a565b602082019050919050565b5f6020820190508181035f8301526158ab81615872565b9050919050565b5f6158bc82614609565b91506158c783614609565b9250826158d7576158d6614d3e565b5b828206905092915050565b7f6d757374207472616465206f766572206d696e000000000000000000000000005f82015250565b5f6159166013836146fe565b9150615921826158e2565b602082019050919050565b5f6020820190508181035f8301526159438161590a565b9050919050565b7f52656369657665722063616e6e6f7420626520307830206164647265737300005f82015250565b5f61597e601e836146fe565b91506159898261594a565b602082019050919050565b5f6020820190508181035f8301526159ab81615972565b9050919050565b5f81905092915050565b50565b5f6159ca5f836159b2565b91506159d5826159bc565b5f82019050919050565b5f6159e9826159bf565b9150819050919050565b7f534f4e4943205472616e73666572206661696c65642e000000000000000000005f82015250565b5f615a276016836146fe565b9150615a32826159f3565b602082019050919050565b5f6020820190508181035f830152615a5481615a1b565b9050919050565b5f604082019050615a6e5f830185614988565b615a7b6020830184614667565b9392505050565b7f54686520656767732062616c616e6365206f662074686520636f6e74726163745f8201527f206d7573742062652067726561746572207468616e206f7220657175616c207460208201527f6f2074686520636f6c6c61746572616c00000000000000000000000000000000604082015250565b5f615b026050836146fe565b9150615b0d82615a82565b606082019050919050565b5f6020820190508181035f830152615b2f81615af6565b9050919050565b7f546865207072696365206f6620656767732063616e6e6f7420646563726561735f8201527f6500000000000000000000000000000000000000000000000000000000000000602082015250565b5f615b906021836146fe565b9150615b9b82615b36565b604082019050919050565b5f6020820190508181035f830152615bbd81615b84565b9050919050565b5f606082019050615bd75f830186614988565b615be46020830185614667565b615bf16040830184614667565b949350505050565b7f43616e2774206d696e7420746f20746f203078302061646472657373000000005f82015250565b5f615c2d601c836146fe565b9150615c3882615bf9565b602082019050919050565b5f6020820190508181035f830152615c5a81615c21565b9050919050565b7f4e4f204d4f5245204547475300000000000000000000000000000000000000005f82015250565b5f615c95600c836146fe565b9150615ca082615c61565b602082019050919050565b5f6020820190508181035f830152615cc281615c89565b905091905056fea2646970667358221220232ac30dbbab817d1348eaeac4cf0ec0aa588e938f2b8b5d570097dbb67d8c9c64736f6c634300081c0033

Deployed Bytecode Sourcemap

100017:21213:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;117955:254;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;118881:97;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;107568:259;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100688:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;13005:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;15298:190;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119753:139;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;107835:1433;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;100208:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103125:292;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;14107:99;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105004:184;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16098:249;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;115859:693;;;;;;;;;;;;;:::i;:::-;;13958:84;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;111428:742;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;119900:147;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101082:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101861:434;;;:::i;:::-;;100242:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105194:299;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;112176:572;;;:::i;:::-;;22977:89;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;120292:209;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100968:49;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105501:2059;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;14269:118;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102853:266;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;118627:135;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25908:103;;;;;;;;;;;;;:::i;:::-;;29036:235;;;;;;;;;;;;;:::i;:::-;;23395:161;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;114544:1307;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102571:274;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;120946:206;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25233:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;118770:84;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;118217:402;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;13215:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;109274:2146;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;113352:1184;;;;;;;;;;;;;:::i;:::-;;100655:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;14592:182;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100922:37;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;100173:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;120507:182;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;120055:229;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100430:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;112754:592;;;:::i;:::-;;119095:120;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101024:51;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100607:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;118986:101;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;14837:142;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103423:272;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;27997:101;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;117677:270;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104351:584;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;100086:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103701:644;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;28424:181;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;117955:254;118038:7;118047;118089:14;:42;118104:26;118125:4;118104:20;:26::i;:::-;118089:42;;;;;;;;;;;;118146:16;:44;118163:26;118184:4;118163:20;:26::i;:::-;118146:44;;;;;;;;;;;;118067:134;;;;117955:254;;;:::o;118881:97::-;118930:7;118957:13;;118950:20;;118881:97;:::o;107568:259::-;107676:7;107696:16;107758:8;107715:40;107727:8;107737:12;107751:3;107715:11;:40::i;:::-;:51;;;;:::i;:::-;107696:70;;107784:35;107796:6;107804:8;107814:4;107784:11;:35::i;:::-;107777:42;;;107568:259;;;;:::o;100688:28::-;;;;:::o;13005:91::-;13050:13;13083:5;13076:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13005:91;:::o;15298:190::-;15371:4;15388:13;15404:12;:10;:12::i;:::-;15388:28;;15427:31;15436:5;15443:7;15452:5;15427:8;:31::i;:::-;15476:4;15469:11;;;15298:190;;;;:::o;119753:139::-;119810:7;119837:47;119849:5;119856:12;:10;:12::i;:::-;119870:13;:11;:13::i;:::-;119837:11;:47::i;:::-;119830:54;;119753:139;;;:::o;107835:1433::-;31867:21;:19;:21::i;:::-;107956:3:::1;107941:12;:18;107919:113;;;;;;;;;;;;:::i;:::-;;;;;;;;;108060:1;108051:5;:10:::0;108043:46:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;108104:25;108118:10;108104:13;:25::i;:::-;108100:82;;;108153:5;:17;108159:10;108153:17;;;;;;;;;;;;;;;;108146:24;;;;;;;;;;;;;;;;;;;;;;;;;;108100:82;108244:1;108214:5;:17;108220:10;108214:17;;;;;;;;;;;;;;;:26;;;:31;108192:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;108313:11;:9;:11::i;:::-;108335:15;108353:87;108414:15;108404:6;108389:12;:21;;;;:::i;:::-;108388:41;;;;:::i;:::-;108353:20;:87::i;:::-;108335:105;;108453:16;108472:35;108487:5;108494:12;108472:14;:35::i;:::-;108453:54;;108520:21;108561:2;108556:1;108545:8;:12;;;;:::i;:::-;108544:19;;;;:::i;:::-;108520:43;;108628:16;108647:29;108670:5;108647:22;:29::i;:::-;108628:48;;108689:21;108728:3;108722:2;108714:5;:10;;;;:::i;:::-;108713:18;;;;:::i;:::-;108689:42;;108764:162;;;;;;;;108796:8;108764:162;;;;108829:13;108764:162;;;;108866:7;108764:162;;;;108902:12;108764:162;;::::0;108744:5:::1;:17;108750:10;108744:17;;;;;;;;;;;;;;;:182;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;108939:46;108949:10;108969:4;108976:8;108939:9;:46::i;:::-;100160:4;109004:13;:19;108996:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;109070:47;109080:10;109108:8;109092:13;:24;;;;:::i;:::-;109070:9;:47::i;:::-;109128:37;109138:11;;;;;;;;;;;109151:13;109128:9;:37::i;:::-;109178:48;109193:13;109208:8;109218:7;109178:14;:48::i;:::-;109239:21;109251:8;109239:11;:21::i;:::-;107908:1360;;;;;31911:20:::0;:18;:20::i;:::-;107835:1433;;:::o;100208:27::-;;;;;;;;;;;;;:::o;103125:292::-;25119:13;:11;:13::i;:::-;103215:2:::1;103205:6;:12;;;;103197:59;;;;;;;;;;;;:::i;:::-;;;;;;;;;103285:1;103275:6;:11;;;;103267:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;103361:6;103342:16;;:25;;;;;;;;;;;;;;;;;;103383:26;103402:6;103383:26;;;;;;:::i;:::-;;;;;;;;103125:292:::0;:::o;14107:99::-;14159:7;14186:12;;14179:19;;14107:99;:::o;105004:184::-;105063:7;105083:12;105098:26;105117:6;105098:18;:26::i;:::-;105083:41;;100324:4;105143:36;;105151:11;:9;:11::i;:::-;105144:4;:18;;;;:::i;:::-;105143:36;;;;:::i;:::-;105135:45;;;105004:184;;;:::o;16098:249::-;16185:4;16202:15;16220:12;:10;:12::i;:::-;16202:30;;16243:37;16259:4;16265:7;16274:5;16243:15;:37::i;:::-;16291:26;16301:4;16307:2;16311:5;16291:9;:26::i;:::-;16335:4;16328:11;;;16098:249;;;;;:::o;115859:693::-;115898:16;115925:18;115956:273;115985:15;115963:19;;:37;115956:273;;;116043:16;:37;116060:19;;116043:37;;;;;;;;;;;;116030:10;:50;;;;:::i;:::-;116017:63;;116117:14;:35;116132:19;;116117:35;;;;;;;;;;;;116106:8;:46;;;;:::i;:::-;116095:57;;116211:6;116189:19;;:28;;;;:::i;:::-;116167:19;:50;;;;115956:273;;;116257:1;116243:10;:15;116239:141;;116311:10;116293:15;;:28;;;;:::i;:::-;116275:15;:46;;;;116336:32;116350:4;116357:10;116336:5;:32::i;:::-;116239:141;116406:1;116394:8;:13;116390:155;;116456:8;116440:13;;:24;;;;:::i;:::-;116424:13;:40;;;;116484:49;116516:6;116494:19;;:28;;;;:::i;:::-;116524:8;116484:49;;;;;;;:::i;:::-;;;;;;;;116390:155;115887:665;;115859:693::o;13958:84::-;14007:5;14032:2;14025:9;;13958:84;:::o;111428:742::-;31867:21;:19;:21::i;:::-;111524:25:::1;111538:10;111524:13;:25::i;:::-;111523:26;111501:130;;;;;;;;;;;;:::i;:::-;;;;;;;;;111642:11;:9;:11::i;:::-;111664:18;111685:5;:17;111691:10;111685:17;;;;;;;;;;;;;;;:28;;;111664:49;;111873:3;111867:2;111832:32;111857:6;111844:10;:19;;;;:::i;:::-;111832:11;:32::i;:::-;:37;;;;:::i;:::-;111831:45;;;;:::i;:::-;111784:5;:17;111790:10;111784:17;;;;;;;;;;;;;;;:26;;;:92;;111762:176;;;;;;;;;;;;:::i;:::-;;;;;;;;;112011:6;111980:5;:17;111986:10;111980:17;;;;;;;;;;;;;;;:28;;;:37;;;;:::i;:::-;111949:5;:17;111955:10;111949:17;;;;;;;;;;;;;;;:28;;:68;;;;112028:44;112046:4;112053:10;112065:6;112028:9;:44::i;:::-;112083:52;112098:1;112101:6;112109:5;:17;112115:10;112109:17;;;;;;;;;;;;;;;:25;;;112083:14;:52::i;:::-;112148:14;112160:1;112148:11;:14::i;:::-;111490:680;31911:20:::0;:18;:20::i;:::-;111428:742;:::o;119900:147::-;119957:7;119984:55;119996:5;120003:13;:11;:13::i;:::-;120033:5;120018:12;:10;:12::i;:::-;:20;;;;:::i;:::-;119984:11;:55::i;:::-;119977:62;;119900:147;;;:::o;101082:34::-;;;;:::o;101861:434::-;25119:13;:11;:13::i;:::-;101948:3:::1;101925:27;;:11;;;;;;;;;;;:27;;::::0;101917:60:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;101988:16;100160:4;102007:9;:15;;;;:::i;:::-;101988:34;;102053:7;102041:8;:19;;102033:28;;;;;;102072:26;102077:10;102089:8;102072:4;:26::i;:::-;102111:124;102135:10;102160:42;102217:7;102111:9;:124::i;:::-;102254:4;102246:5;;:12;;;;;;;;;;;;;;;;;;102274:13;102282:4;102274:13;;;;;;:::i;:::-;;;;;;;;101906:389;101861:434::o:0;100242:35::-;;;;;;;;;;;;;:::o;105194:299::-;105298:7;105318:15;100324:4;105336:42;;105345:16;;;;;;;;;;;105337:24;;:5;:24;;;;:::i;:::-;105336:42;;;;:::i;:::-;105318:60;;105391:16;105410:35;105425:5;105432:12;105410:14;:35::i;:::-;105391:54;;105476:8;105466:7;:18;;;;:::i;:::-;105458:27;;;;105194:299;;;;:::o;112176:572::-;31867:21;:19;:21::i;:::-;112232:16:::1;112251:5;:17;112257:10;112251:17;;;;;;;;;;;;;;;:26;;;112232:45;;112307:9;112296:8;:20;112288:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;112389:1;112376:9;:14:::0;112368:47:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;112451:25;112465:10;112451:13;:25::i;:::-;112450:26;112428:119;;;;;;;;;;;;:::i;:::-;;;;;;;;;112558:17;112589:9;112578:8;:20;;;;:::i;:::-;112558:40;;112638:9;112609:5;:17;112615:10;112609:17;;;;;;;;;;;;;;;:26;;:38;;;;112658:55;112673:9;112684:1;112687:5;:17;112693:10;112687:17;;;;;;;;;;;;;;;:25;;;112658:14;:55::i;:::-;112726:14;112738:1;112726:11;:14::i;:::-;112221:527;;31911:20:::0;:18;:20::i;:::-;112176:572::o;22977:89::-;23032:26;23038:12;:10;:12::i;:::-;23052:5;23032;:26::i;:::-;22977:89;:::o;120292:209::-;120376:7;120396:15;120414:12;:10;:12::i;:::-;120396:30;;120486:7;120480:1;120470:7;:11;;;;:::i;:::-;120453:13;:11;:13::i;:::-;120445:5;:21;;;;:::i;:::-;:37;;;;:::i;:::-;120444:49;;;;:::i;:::-;120437:56;;;120292:209;;;:::o;100968:49::-;;;;;;;;;;;;;;;;;:::o;105501:2059::-;31867:21;:19;:21::i;:::-;105628:5:::1;;;;;;;;;;;105620:45;;;;;;;;;;;;:::i;:::-;;;;;;;;;105713:3;105698:12;:18;105676:113;;;;;;;;;;;;:::i;:::-;;;;;;;;;105802:20;105825:5;:17;105831:10;105825:17;;;;;;;;;;;;;;;105802:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;105878:1;105857:8;:17;;;:22;105853:277;;105900:25;105914:10;105900:13;:25::i;:::-;105896:90;;;105953:5;:17;105959:10;105953:17;;;;;;;;;;;;;;;;105946:24;;;;;;;;;;;;;;;;;;;;;;;;;;105896:90;106056:1;106026:5;:17;106032:10;106026:17;;;;;;;;;;;;;;;:26;;;:31;106000:118;;;;;;;;;;;;:::i;:::-;;;;;;;;;105853:277;106140:11;:9;:11::i;:::-;106162:15;106180:87;106241:15;106231:6;106216:12;:21;;;;:::i;:::-;106215:41;;;;:::i;:::-;106180:20;:87::i;:::-;106162:105;;106280:16;106299:32;106311:5;106318:12;106299:11;:32::i;:::-;106280:51;;106344:17;106372:8;106364:5;:16;;;;:::i;:::-;106344:36;;106393:24;106437:2;106432:1;106421:8;:12;;;;:::i;:::-;106420:19;;;;:::i;:::-;106393:46;;106450:18;106490:3;106484:2;106472:9;:14;;;;:::i;:::-;106471:22;;;;:::i;:::-;106450:43;;106504:35;106556:3;106543:9;106542:17;;;;:::i;:::-;106504:55;;106570:16;106608:27;106589:16;:46;;;;:::i;:::-;106570:65;;106646:16;106677:27;106666:8;:38;;;;:::i;:::-;106646:59;;106716:18;106761:8;106749:9;:20;106745:134;;;106811:8;106799:9;:20;;;;:::i;:::-;106786:33;;106834;106844:10;106856;106834:9;:33::i;:::-;106745:134;106937:8;106923:10;106911:9;:22;;;;:::i;:::-;:34;106889:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;107051:16;107070:35;107085:9;107096:8;107070:14;:35::i;:::-;107051:54;;107116:29;107129:4;107136:8;107116:4;:29::i;:::-;100160:4;107166:16;:22;107158:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;107233:40;107243:11;;;;;;;;;;;107256:16;107233:9;:40::i;:::-;107286:45;107301:10;107313:8;107323:7;107286:14;:45::i;:::-;107362:159;;;;;;;;107394:8;107362:159;;;;107427:10;107362:159;;;;107461:7;107362:159;;;;107497:12;107362:159;;::::0;107342:5:::1;:17;107348:10;107342:17;;;;;;;;;;;;;;;:179;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;107534:18;107546:5;107534:11;:18::i;:::-;105609:1951;;;;;;;;;;;31911:20:::0;:18;:20::i;:::-;105501:2059;;:::o;14269:118::-;14334:7;14361:9;:18;14371:7;14361:18;;;;;;;;;;;;;;;;14354:25;;14269:118;;;:::o;102853:266::-;25119:13;:11;:13::i;:::-;102935:3:::1;102925:6;:13;;;;102917:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;103009:3;102999:6;:13;;;;102991:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;103068:6;103058:7;;:16;;;;;;;;;;;;;;;;;;103090:21;103104:6;103090:21;;;;;;:::i;:::-;;;;;;;;102853:266:::0;:::o;118627:135::-;118689:4;118739:15;118713:5;:15;118719:8;118713:15;;;;;;;;;;;;;;;:23;;;:41;118706:48;;118627:135;;;:::o;25908:103::-;25119:13;:11;:13::i;:::-;25973:30:::1;26000:1;25973:18;:30::i;:::-;25908:103::o:0;29036:235::-;29089:14;29106:12;:10;:12::i;:::-;29089:29;;29151:6;29133:24;;:14;:12;:14::i;:::-;:24;;;29129:98;;29208:6;29181:34;;;;;;;;;;;:::i;:::-;;;;;;;;29129:98;29237:26;29256:6;29237:18;:26::i;:::-;29078:193;29036:235::o;23395:161::-;23471:45;23487:7;23496:12;:10;:12::i;:::-;23510:5;23471:15;:45::i;:::-;23527:21;23533:7;23542:5;23527;:21::i;:::-;23395:161;;:::o;114544:1307::-;114639:7;31867:21;:19;:21::i;:::-;114659:18:::1;114680:5;:17;114686:10;114680:17;;;;;;;;;;;;;;;:25;;;114659:46;;114716:16;114735:5;:17;114741:10;114735:17;;;;;;;;;;;;;;;:26;;;114716:45;;114772:18;114793:5;:17;114799:10;114793:17;;;;;;;;;;;;;;;:28;;;114772:49;;114832:21;114856:5;:17;114862:10;114856:17;;;;;;;;;;;;;;;:30;;;114832:54;;114899:18;114949:6;114934:12;:21;;;;:::i;:::-;114920:10;:36;;;;:::i;:::-;114899:57;;114969:15;114987:38;115002:8;115012:12;114987:14;:38::i;:::-;114969:56;;115059:25;115073:10;115059:13;:25::i;:::-;115058:26;115036:130;;;;;;;;;;;;:::i;:::-;;;;;;;;;115196:9;115185:7;:20;115177:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;115249:21;115289:2;115284:1;115274:7;:11;;;;:::i;:::-;115273:18;;;;:::i;:::-;115249:42;;100160:4;115310:13;:19;115302:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;115374:37;115384:11;;;;;;;;;;;115397:13;115374:9;:37::i;:::-;115422:48;115437:8;115447:10;115459;115422:14;:48::i;:::-;115481;115496:8;115506:10;115518;115481:14;:48::i;:::-;115568:10;115540:5;:17;115546:10;115540:17;;;;;;;;;;;;;;;:25;;:38;;;;115637:13;115622:12;:28;;;;:::i;:::-;115589:5;:17;115595:10;115589:17;;;;;;;;;;;;;;;:30;;:61;;;;115725:3;115716:6;115697:15;115684:10;:28;;;;:::i;:::-;115683:39;;;;:::i;:::-;:45;115661:122;;;;;;;;;;;;:::i;:::-;;;;;;;;;115796:22;115808:9;115796:11;:22::i;:::-;115836:7;115829:14;;;;;;;;;31911:20:::0;:18;:20::i;:::-;114544:1307;;;:::o;102571:274::-;25119:13;:11;:13::i;:::-;102684:3:::1;102664:24;;:8;:24;;::::0;102642:110:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;102785:8;102763:11;;:31;;;;;;;;;;;;;;;;;;102810:27;102828:8;102810:27;;;;;;:::i;:::-;;;;;;;;102571:274:::0;:::o;120946:206::-;121005:7;100324:4;121045:99;;121100:12;:10;:12::i;:::-;121074:7;;;;;;;;;;;121046:36;;121056:13;:11;:13::i;:::-;121046:6;:24;;;;:::i;:::-;:36;;;;:::i;:::-;121045:68;;;;:::i;:::-;:99;;;;:::i;:::-;121025:119;;120946:206;;;:::o;25233:87::-;25279:7;25306:6;;;;;;;;;;;25299:13;;25233:87;:::o;118770:84::-;118812:7;118839;;;;;;;;;;;118832:14;;;;118770:84;:::o;118217:402::-;118298:7;118307;118316;118367:15;118340:5;:15;118346:8;118340:15;;;;;;;;;;;;;;;:23;;;:42;118336:276;;118425:5;:15;118431:8;118425:15;;;;;;;;;;;;;;;:26;;;118470:5;:15;118476:8;118470:15;;;;;;;;;;;;;;;:24;;;118513:5;:15;118519:8;118513:15;;;;;;;;;;;;;;;:23;;;118399:152;;;;;;;;118336:276;118592:1;118595;118598;118584:16;;;;;;118217:402;;;;;;:::o;13215:95::-;13262:13;13295:7;13288:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13215:95;:::o;109274:2146::-;31867:21;:19;:21::i;:::-;109349:25:::1;109363:10;109349:13;:25::i;:::-;109348:26;109340:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;109430:1;109421:5;:10:::0;109413:46:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;109470:11;:9;:11::i;:::-;109492:20;109515:5;:17;109521:10;109515:17;;;;;;;;;;;;;;;:26;;;109492:49;;109552:22;109577:5;:17;109583:10;109577:17;;;;;;;;;;;;;;;:28;;;109552:53;;109616:19;109638:5;:17;109644:10;109638:17;;;;;;;;;;;;;;;:25;;;109616:47;;109676:21;109700:37;109721:15;109700:20;:37::i;:::-;109676:61;;109748:23;109806:6;109789:13;109775:11;:27;;;;:::i;:::-;109774:38;;;;:::i;:::-;109748:64;;109825:16;109844:38;109859:5;109866:15;109844:14;:38::i;:::-;109825:57;;109947:16;109966:29;109989:5;109966:22;:29::i;:::-;109947:48;;110006:26;110035:32;110054:12;110035:18;:32::i;:::-;110006:61;;110078:24;110163:18;110144:3;110125:2;110107:14;110106:21;;;;:::i;:::-;110105:42;;;;:::i;:::-;:76;;;;:::i;:::-;110078:103;;110194:33;110230:8;110194:44;;110273:8;110253:16;:28;110249:229;;110326:1;110298:29;;110249:229;;;110450:16;110405:25;:61;;;;:::i;:::-;110360:106;;110249:229;110490:21;110531:2;110526:1;110515:8;:12;;;;:::i;:::-;110514:19;;;;:::i;:::-;110490:43;;110546:21;110585:3;110579:2;110571:5;:10;;;;:::i;:::-;110570:18;;;;:::i;:::-;110546:42;;110601:26;110645:13;110630:12;:28;;;;:::i;:::-;110601:57;;110669:30;110732:25;110702:14;:55;;;;:::i;:::-;110669:88;;110790:188;;;;;;;;110822:22;110790:188;;;;110869:18;110790:188;;;;110911:11;110790:188;;;;110951:15;110790:188;;::::0;110770:5:::1;:17;110776:10;110770:17;;;;;;;;;;;;;;;:208;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;111024:1;110995:25;:30;110991:126;;111042:63;111052:10;111072:4;111079:25;111042:9;:63::i;:::-;110991:126;100160:4;111137:13;:19;111129:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;111201:37;111211:11;;;;;;;;;;;111224:13;111201:9;:37::i;:::-;111249:47;111259:10;111287:8;111271:13;:24;;;;:::i;:::-;111249:9;:47::i;:::-;111309:69;111324:13;111339:25;111366:11;111309:14;:69::i;:::-;111391:21;111403:8;111391:11;:21::i;:::-;109329:2091;;;;;;;;;;;;;;31911:20:::0;:18;:20::i;:::-;109274:2146;:::o;113352:1184::-;31867:21;:19;:21::i;:::-;113436:25:::1;113450:10;113436:13;:25::i;:::-;113435:26;113413:130;;;;;;;;;;;;:::i;:::-;;;;;;;;;113554:11;:9;:11::i;:::-;113576:16;113595:5;:17;113601:10;113595:17;;;;;;;;;;;;;;;:26;;;113576:45;;113634:18;113655:5;:17;113661:10;113655:17;;;;;;;;;;;;;;;:28;;;113634:49;;113734:25;113762:23;113774:10;113762:11;:23::i;:::-;113734:51;;113796:32;113810:4;113817:10;113796:5;:32::i;:::-;113841:33;113904:3;113898:2;113878:17;:22;;;;:::i;:::-;113877:30;;;;:::i;:::-;113841:66;;113920:11;113954:3;113934:17;:23;;;;:::i;:::-;113920:37;;114019:8;113990:25;:37;;113968:138;;;;;;;;;;;;:::i;:::-;;;;;;;;;114119:14;114164:8;114136:25;:36;;;;:::i;:::-;114119:53;;114183:21;114219:2;114214:1;114208:3;:7;;;;:::i;:::-;114207:14;;;;:::i;:::-;114183:38;;114234:29;114244:10;114256:6;114234:9;:29::i;:::-;100160:4;114284:13;:19;114276:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;114348:37;114358:11;;;;;;;;;;;114371:13;114348:9;:37::i;:::-;114396:63;114411:8;114421:10;114433:5;:17;114439:10;114433:17;;;;;;;;;;;;;;;:25;;;114396:14;:63::i;:::-;114479:5;:17;114485:10;114479:17;;;;;;;;;;;;;;;;114472:24;;;;;;;;;;;;;;;;;;;;;;;;;;114507:21;114519:8;114507:11;:21::i;:::-;113402:1134;;;;;;;31911:20:::0;:18;:20::i;:::-;113352:1184::o;100655:26::-;;;;:::o;14592:182::-;14661:4;14678:13;14694:12;:10;:12::i;:::-;14678:28;;14717:27;14727:5;14734:2;14738:5;14717:9;:27::i;:::-;14762:4;14755:11;;;14592:182;;;;:::o;100922:37::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;100173:28::-;;;;;;;;;;;;;:::o;120507:182::-;120571:7;120591:15;120609:12;:10;:12::i;:::-;120591:30;;120639:42;120651:5;120658:13;:11;:13::i;:::-;120673:7;120639:11;:42::i;:::-;120632:49;;;120507:182;;;:::o;120055:229::-;120153:7;120173:15;120206:3;120191:12;:10;:12::i;:::-;:18;;;;:::i;:::-;120173:36;;120269:7;120263:1;120253:7;:11;;;;:::i;:::-;120236:13;:11;:13::i;:::-;120228:5;:21;;;;:::i;:::-;:37;;;;:::i;:::-;120227:49;;;;:::i;:::-;120220:56;;;120055:229;;;;:::o;100430:25::-;;;;;;;;;;;;;:::o;112754:592::-;31867:21;:19;:21::i;:::-;112818:16:::1;112837:5;:17;112843:10;112837:17;;;;;;;;;;;;;;;:26;;;112818:45;;112874:18;112895:5;:17;112901:10;112895:17;;;;;;;;;;;;;;;:28;;;112874:49;;112957:25;112971:10;112957:13;:25::i;:::-;112956:26;112934:130;;;;;;;;;;;;:::i;:::-;;;;;;;;;113095:9;113083:8;:21;113075:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;113154:48;113172:4;113179:10;113191;113154:9;:48::i;:::-;113213:63;113228:8;113238:10;113250:5;:17;113256:10;113250:17;;;;;;;;;;;;;;;:25;;;113213:14;:63::i;:::-;113296:5;:17;113302:10;113296:17;;;;;;;;;;;;;;;;113289:24;;;;;;;;;;;;;;;;;;;;;;;;;;113324:14;113336:1;113324:11;:14::i;:::-;112807:539;;31911:20:::0;:18;:20::i;:::-;112754:592::o;119095:120::-;119138:7;119189:18;:16;:18::i;:::-;119165:21;:42;;;;:::i;:::-;119158:49;;119095:120;:::o;101024:51::-;;;;;;;;;;;;;;;;;:::o;100607:41::-;100643:5;100607:41;:::o;118986:101::-;119037:7;119064:15;;119057:22;;118986:101;:::o;14837:142::-;14917:7;14944:11;:18;14956:5;14944:18;;;;;;;;;;;;;;;:27;14963:7;14944:27;;;;;;;;;;;;;;;;14937:34;;14837:142;;;;:::o;103423:272::-;25119:13;:11;:13::i;:::-;103506:3:::1;103496:6;:13;;;;103488:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;103582:3;103572:6;:13;;;;103564:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;103643:6;103632:8;;:17;;;;;;;;;;;;;;;;;;103665:22;103680:6;103665:22;;;;;;:::i;:::-;;;;;;;;103423:272:::0;:::o;27997:101::-;28050:7;28077:13;;;;;;;;;;;28070:20;;27997:101;:::o;117677:270::-;117742:7;117762:25;117805:5;117798:4;:12;;;;:::i;:::-;117790:4;:21;;;;:::i;:::-;117762:49;;117933:6;117913:17;:26;;;;:::i;:::-;117906:33;;;117677:270;;;:::o;104351:584::-;31867:21;:19;:21::i;:::-;104412:11:::1;:9;:11::i;:::-;104507:13;104523:17;104535:4;104523:11;:17::i;:::-;104507:33;;104577:24;100418:3;104604:17;;:5;:17;;;;:::i;:::-;104577:44;;104632:23;104638:10;104650:4;104632:5;:23::i;:::-;104698:57;104708:10;100324:4;104720:34;;104729:8;;;;;;;;;;;104721:16;;:5;:16;;;;:::i;:::-;104720:34;;;;:::i;:::-;104698:9;:57::i;:::-;100160:4;104799:16;:22;104791:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;104856:40;104866:11;;;;;;;;;;;104879:16;104856:9;:40::i;:::-;104909:18;104921:5;104909:11;:18::i;:::-;104401:534;;31911:20:::0;:18;:20::i;:::-;104351:584;:::o;100086:34::-;;;;;;;;;;;;;:::o;103701:644::-;31867:21;:19;:21::i;:::-;103773:11:::1;:9;:11::i;:::-;103803:5;;;;;;;;;;;103795:45;;;;;;;;;;;;:::i;:::-;;;;;;;;;103881:3;103861:24;;:8;:24;;::::0;103853:67:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;104003:12;104018:22;104030:9;104018:11;:22::i;:::-;104003:37;;104053:52;104058:8;100324:4;104068:36;;104076:11;:9;:11::i;:::-;104069:4;:18;;;;:::i;:::-;104068:36;;;;:::i;:::-;104053:4;:52::i;:::-;104139:24;100372:3;104166:20;;:9;:20;;;;:::i;:::-;104139:47;;100160:4;104205:16;:22;104197:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;104262:40;104272:11;;;;;;;;;;;104285:16;104262:9;:40::i;:::-;104315:22;104327:9;104315:11;:22::i;:::-;103762:583;;31911:20:::0;:18;:20::i;:::-;103701:644;:::o;28424:181::-;25119:13;:11;:13::i;:::-;28530:8:::1;28514:13;;:24;;;;;;;;;;;;;;;;;;28588:8;28554:43;;28579:7;:5;:7::i;:::-;28554:43;;;;;;;;;;;;28424:181:::0;:::o;76058:4305::-;76140:14;76500:13;76520:1;76516;:5;76500:21;;76581:13;76708:1;76704:6;76701:1;76698;76691:20;76765:5;76761:2;76758:13;76750:5;76746:2;76742:14;76738:34;76729:43;;76662:125;76880:1;76871:5;:10;76867:373;;77213:11;77205:5;:19;;;;;:::i;:::-;;;77198:26;;;;;;76867:373;77368:5;77353:11;:20;77349:145;;77394:84;77406:71;77429:1;77414:11;:16;33871:4;33774;77406:7;:71::i;:::-;77394:11;:84::i;:::-;77349:145;77756:17;77894:11;77891:1;77888;77881:25;77868:38;;78025:5;78014:9;78011:20;78004:5;78000:32;77991:41;;78070:9;78063:5;78059:21;78050:30;;78304:12;78338:11;78334:1;:15;78319:11;:31;78304:46;;78473:4;78460:11;78456:22;78441:37;;78568:4;78561:5;78557:16;78548:25;;78732:1;78725:4;78718;78715:1;78711:12;78707:23;78703:31;78695:39;;78835:4;78827:5;:12;78818:21;;;;79179:15;79217:1;79202:11;79198:1;:15;79197:21;79179:39;;79468:7;79454:11;:21;79450:1;:25;79439:36;;;;79539:7;79525:11;:21;79521:1;:25;79510:36;;;;79612:7;79598:11;:21;79594:1;:25;79583:36;;;;79684:7;79670:11;:21;79666:1;:25;79655:36;;;;79758:7;79744:11;:21;79740:1;:25;79729:36;;;;79833:7;79819:11;:21;79815:1;:25;79804:36;;;;80309:7;80301:5;:15;80292:24;;80331:13;;;;;76058:4305;;;;;;:::o;4304:98::-;4357:7;4384:10;4377:17;;4304:98;:::o;20157:130::-;20242:37;20251:5;20258:7;20267:5;20274:4;20242:8;:37::i;:::-;20157:130;;;:::o;31947:315::-;31245:1;32076:7;;:18;32072:88;;32118:30;;;;;;;;;;;;;;32072:88;31245:1;32237:7;:17;;;;31947:315::o;16732:308::-;16832:1;16816:18;;:4;:18;;;16812:88;;16885:1;16858:30;;;;;;;;;;;:::i;:::-;;;;;;;;16812:88;16928:1;16914:16;;:2;:16;;;16910:88;;16983:1;16954:32;;;;;;;;;;;:::i;:::-;;;;;;;;16910:88;17008:24;17016:4;17022:2;17026:5;17008:7;:24::i;:::-;16732:308;;;:::o;120697:228::-;120771:12;120789:8;:13;;120810:6;120789:32;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;120770:51;;;120840:7;120832:42;;;;;;;;;;;;:::i;:::-;;;;;;;;;120890:27;120900:8;120910:6;120890:27;;;;;;;:::i;:::-;;;;;;;;120759:166;120697:228;;:::o;116560:541::-;116739:10;116714:16;:22;116731:4;116714:22;;;;;;;;;;;;:35;;;;:::i;:::-;116689:16;:22;116706:4;116689:22;;;;;;;;;;;:60;;;;116806:8;116783:14;:20;116798:4;116783:20;;;;;;;;;;;;:31;;;;:::i;:::-;116760:14;:20;116775:4;116760:20;;;;;;;;;;;:54;;;;116857:8;116841:13;;:24;;;;:::i;:::-;116825:13;:40;;;;116912:10;116894:15;;:28;;;;:::i;:::-;116876:15;:46;;;;116938:155;116967:16;:22;116984:4;116967:22;;;;;;;;;;;;117004:14;:20;117019:4;117004:20;;;;;;;;;;;;117039:13;;117067:15;;116938:155;;;;;;;;;:::i;:::-;;;;;;;;116560:541;;;:::o;119223:522::-;119278:16;119324:13;:11;:13::i;:::-;119313:7;119298:12;:10;:12::i;:::-;:22;;;;:::i;:::-;119297:40;;;;:::i;:::-;119278:59;;119348:23;119374:24;119392:4;119374:9;:24::i;:::-;119348:50;;119450:15;;119431;:34;;119409:164;;;;;;;;;;;;:::i;:::-;;;;;;;;;119605:8;119592:9;;:21;;119584:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;119674:8;119662:9;:20;;;;119698:39;119704:15;119721:8;119731:5;119698:39;;;;;;;;:::i;:::-;;;;;;;;119267:478;;119223:522;:::o;32270:212::-;31202:1;32453:7;:21;;;;32270:212::o;25398:166::-;25469:12;:10;:12::i;:::-;25458:23;;:7;:5;:7::i;:::-;:23;;;25454:103;;25532:12;:10;:12::i;:::-;25505:40;;;;;;;;;;;:::i;:::-;;;;;;;;25454:103;25398:166::o;21889:486::-;21989:24;22016:25;22026:5;22033:7;22016:9;:25::i;:::-;21989:52;;22075:17;22056:16;:36;22052:316;;;22132:5;22113:16;:24;22109:132;;;22192:7;22201:16;22219:5;22165:60;;;;;;;;;;;;;:::i;:::-;;;;;;;;22109:132;22284:57;22293:5;22300:7;22328:5;22309:16;:24;22335:5;22284:8;:57::i;:::-;22052:316;21978:397;21889:486;;;:::o;19393:211::-;19483:1;19464:21;;:7;:21;;;19460:91;;19536:1;19509:30;;;;;;;;;;;:::i;:::-;;;;;;;;19460:91;19561:35;19569:7;19586:1;19590:5;19561:7;:35::i;:::-;19393:211;;:::o;117107:541::-;117286:10;117261:16;:22;117278:4;117261:22;;;;;;;;;;;;:35;;;;:::i;:::-;117236:16;:22;117253:4;117236:22;;;;;;;;;;;:60;;;;117353:8;117330:14;:20;117345:4;117330:20;;;;;;;;;;;;:31;;;;:::i;:::-;117307:14;:20;117322:4;117307:20;;;;;;;;;;;:54;;;;117404:8;117388:13;;:24;;;;:::i;:::-;117372:13;:40;;;;117459:10;117441:15;;:28;;;;:::i;:::-;117423:15;:46;;;;117485:155;117514:16;:22;117531:4;117514:22;;;;;;;;;;;;117551:14;:20;117566:4;117551:20;;;;;;;;;;;;117586:13;;117614:15;;117485:155;;;;;;;;;:::i;:::-;;;;;;;;117107:541;;;:::o;102303:260::-;102385:3;102371:18;;:2;:18;;;102363:59;;;;;;;;;;;;:::i;:::-;;;;;;;;;102461:5;102447:11;;:19;;;;:::i;:::-;102433:11;:33;;;;100643:5;102485:24;;:11;;:24;;102477:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;102539:16;102545:2;102549:5;102539;:16::i;:::-;102303:260;;:::o;28795:156::-;28885:13;;28878:20;;;;;;;;;;;28909:34;28934:8;28909:24;:34::i;:::-;28795:156;:::o;73826:301::-;73904:7;74081:26;74097:9;74081:15;:26::i;:::-;74076:1;74072;:5;74071:36;74066:1;:42;74059:49;;73826:301;;;;;:::o;34628:200::-;34735:10;34729:4;34722:24;34773:4;34767;34760:18;34805:4;34799;34792:18;21154:443;21284:1;21267:19;;:5;:19;;;21263:91;;21339:1;21310:32;;;;;;;;;;;:::i;:::-;;;;;;;;21263:91;21387:1;21368:21;;:7;:21;;;21364:92;;21441:1;21413:31;;;;;;;;;;;:::i;:::-;;;;;;;;21364:92;21496:5;21466:11;:18;21478:5;21466:18;;;;;;;;;;;;;;;:27;21485:7;21466:27;;;;;;;;;;;;;;;:35;;;;21516:9;21512:78;;;21563:7;21547:31;;21556:5;21547:31;;;21572:5;21547:31;;;;;;:::i;:::-;;;;;;;;21512:78;21154:443;;;;:::o;17364:1135::-;17470:1;17454:18;;:4;:18;;;17450:552;;17608:5;17592:12;;:21;;;;;;;:::i;:::-;;;;;;;;17450:552;;;17646:19;17668:9;:15;17678:4;17668:15;;;;;;;;;;;;;;;;17646:37;;17716:5;17702:11;:19;17698:117;;;17774:4;17780:11;17793:5;17749:50;;;;;;;;;;;;;:::i;:::-;;;;;;;;17698:117;17970:5;17956:11;:19;17938:9;:15;17948:4;17938:15;;;;;;;;;;;;;;;:37;;;;17631:371;17450:552;18032:1;18018:16;;:2;:16;;;18014:435;;18200:5;18184:12;;:21;;;;;;;;;;;18014:435;;;18417:5;18400:9;:13;18410:2;18400:13;;;;;;;;;;;;;;;;:22;;;;;;;;;;;18014:435;18481:2;18466:25;;18475:4;18466:25;;;18485:5;18466:25;;;;;;:::i;:::-;;;;;;;;17364:1135;;;:::o;18852:213::-;18942:1;18923:21;;:7;:21;;;18919:93;;18997:1;18968:32;;;;;;;;;;;:::i;:::-;;;;;;;;18919:93;19022:35;19038:1;19042:7;19051:5;19022:7;:35::i;:::-;18852:213;;:::o;26546:191::-;26620:16;26639:6;;;;;;;;;;;26620:25;;26665:8;26656:6;;:17;;;;;;;;;;;;;;;;;;26720:8;26689:40;;26710:8;26689:40;;;;;;;;;;;;26609:128;26546:191;:::o;70815:149::-;70862:9;70943:1;70936:9;70929:17;70924:22;;70815:149;;;:::o;88:117:1:-;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:139::-;591:5;629:6;616:20;607:29;;645:33;672:5;645:33;:::i;:::-;545:139;;;;:::o;690:329::-;749:6;798:2;786:9;777:7;773:23;769:32;766:119;;;804:79;;:::i;:::-;766:119;924:1;949:53;994:7;985:6;974:9;970:22;949:53;:::i;:::-;939:63;;895:117;690:329;;;;:::o;1025:118::-;1112:24;1130:5;1112:24;:::i;:::-;1107:3;1100:37;1025:118;;:::o;1149:332::-;1270:4;1308:2;1297:9;1293:18;1285:26;;1321:71;1389:1;1378:9;1374:17;1365:6;1321:71;:::i;:::-;1402:72;1470:2;1459:9;1455:18;1446:6;1402:72;:::i;:::-;1149:332;;;;;:::o;1487:222::-;1580:4;1618:2;1607:9;1603:18;1595:26;;1631:71;1699:1;1688:9;1684:17;1675:6;1631:71;:::i;:::-;1487:222;;;;:::o;1715:474::-;1783:6;1791;1840:2;1828:9;1819:7;1815:23;1811:32;1808:119;;;1846:79;;:::i;:::-;1808:119;1966:1;1991:53;2036:7;2027:6;2016:9;2012:22;1991:53;:::i;:::-;1981:63;;1937:117;2093:2;2119:53;2164:7;2155:6;2144:9;2140:22;2119:53;:::i;:::-;2109:63;;2064:118;1715:474;;;;;:::o;2195:99::-;2247:6;2281:5;2275:12;2265:22;;2195:99;;;:::o;2300:169::-;2384:11;2418:6;2413:3;2406:19;2458:4;2453:3;2449:14;2434:29;;2300:169;;;;:::o;2475:139::-;2564:6;2559:3;2554;2548:23;2605:1;2596:6;2591:3;2587:16;2580:27;2475:139;;;:::o;2620:102::-;2661:6;2712:2;2708:7;2703:2;2696:5;2692:14;2688:28;2678:38;;2620:102;;;:::o;2728:377::-;2816:3;2844:39;2877:5;2844:39;:::i;:::-;2899:71;2963:6;2958:3;2899:71;:::i;:::-;2892:78;;2979:65;3037:6;3032:3;3025:4;3018:5;3014:16;2979:65;:::i;:::-;3069:29;3091:6;3069:29;:::i;:::-;3064:3;3060:39;3053:46;;2820:285;2728:377;;;;:::o;3111:313::-;3224:4;3262:2;3251:9;3247:18;3239:26;;3311:9;3305:4;3301:20;3297:1;3286:9;3282:17;3275:47;3339:78;3412:4;3403:6;3339:78;:::i;:::-;3331:86;;3111:313;;;;:::o;3430:126::-;3467:7;3507:42;3500:5;3496:54;3485:65;;3430:126;;;:::o;3562:96::-;3599:7;3628:24;3646:5;3628:24;:::i;:::-;3617:35;;3562:96;;;:::o;3664:122::-;3737:24;3755:5;3737:24;:::i;:::-;3730:5;3727:35;3717:63;;3776:1;3773;3766:12;3717:63;3664:122;:::o;3792:139::-;3838:5;3876:6;3863:20;3854:29;;3892:33;3919:5;3892:33;:::i;:::-;3792:139;;;;:::o;3937:474::-;4005:6;4013;4062:2;4050:9;4041:7;4037:23;4033:32;4030:119;;;4068:79;;:::i;:::-;4030:119;4188:1;4213:53;4258:7;4249:6;4238:9;4234:22;4213:53;:::i;:::-;4203:63;;4159:117;4315:2;4341:53;4386:7;4377:6;4366:9;4362:22;4341:53;:::i;:::-;4331:63;;4286:118;3937:474;;;;;:::o;4417:90::-;4451:7;4494:5;4487:13;4480:21;4469:32;;4417:90;;;:::o;4513:109::-;4594:21;4609:5;4594:21;:::i;:::-;4589:3;4582:34;4513:109;;:::o;4628:210::-;4715:4;4753:2;4742:9;4738:18;4730:26;;4766:65;4828:1;4817:9;4813:17;4804:6;4766:65;:::i;:::-;4628:210;;;;:::o;4844:89::-;4880:7;4920:6;4913:5;4909:18;4898:29;;4844:89;;;:::o;4939:115::-;5024:23;5041:5;5024:23;:::i;:::-;5019:3;5012:36;4939:115;;:::o;5060:218::-;5151:4;5189:2;5178:9;5174:18;5166:26;;5202:69;5268:1;5257:9;5253:17;5244:6;5202:69;:::i;:::-;5060:218;;;;:::o;5284:120::-;5356:23;5373:5;5356:23;:::i;:::-;5349:5;5346:34;5336:62;;5394:1;5391;5384:12;5336:62;5284:120;:::o;5410:137::-;5455:5;5493:6;5480:20;5471:29;;5509:32;5535:5;5509:32;:::i;:::-;5410:137;;;;:::o;5553:327::-;5611:6;5660:2;5648:9;5639:7;5635:23;5631:32;5628:119;;;5666:79;;:::i;:::-;5628:119;5786:1;5811:52;5855:7;5846:6;5835:9;5831:22;5811:52;:::i;:::-;5801:62;;5757:116;5553:327;;;;:::o;5886:619::-;5963:6;5971;5979;6028:2;6016:9;6007:7;6003:23;5999:32;5996:119;;;6034:79;;:::i;:::-;5996:119;6154:1;6179:53;6224:7;6215:6;6204:9;6200:22;6179:53;:::i;:::-;6169:63;;6125:117;6281:2;6307:53;6352:7;6343:6;6332:9;6328:22;6307:53;:::i;:::-;6297:63;;6252:118;6409:2;6435:53;6480:7;6471:6;6460:9;6456:22;6435:53;:::i;:::-;6425:63;;6380:118;5886:619;;;;;:::o;6511:86::-;6546:7;6586:4;6579:5;6575:16;6564:27;;6511:86;;;:::o;6603:112::-;6686:22;6702:5;6686:22;:::i;:::-;6681:3;6674:35;6603:112;;:::o;6721:214::-;6810:4;6848:2;6837:9;6833:18;6825:26;;6861:67;6925:1;6914:9;6910:17;6901:6;6861:67;:::i;:::-;6721:214;;;;:::o;6941:329::-;7000:6;7049:2;7037:9;7028:7;7024:23;7020:32;7017:119;;;7055:79;;:::i;:::-;7017:119;7175:1;7200:53;7245:7;7236:6;7225:9;7221:22;7200:53;:::i;:::-;7190:63;;7146:117;6941:329;;;;:::o;7276:118::-;7363:24;7381:5;7363:24;:::i;:::-;7358:3;7351:37;7276:118;;:::o;7400:222::-;7493:4;7531:2;7520:9;7516:18;7508:26;;7544:71;7612:1;7601:9;7597:17;7588:6;7544:71;:::i;:::-;7400:222;;;;:::o;7628:442::-;7777:4;7815:2;7804:9;7800:18;7792:26;;7828:71;7896:1;7885:9;7881:17;7872:6;7828:71;:::i;:::-;7909:72;7977:2;7966:9;7962:18;7953:6;7909:72;:::i;:::-;7991;8059:2;8048:9;8044:18;8035:6;7991:72;:::i;:::-;7628:442;;;;;;:::o;8076:553::-;8253:4;8291:3;8280:9;8276:19;8268:27;;8305:71;8373:1;8362:9;8358:17;8349:6;8305:71;:::i;:::-;8386:72;8454:2;8443:9;8439:18;8430:6;8386:72;:::i;:::-;8468;8536:2;8525:9;8521:18;8512:6;8468:72;:::i;:::-;8550;8618:2;8607:9;8603:18;8594:6;8550:72;:::i;:::-;8076:553;;;;;;;:::o;8635:118::-;8672:7;8712:34;8705:5;8701:46;8690:57;;8635:118;;;:::o;8759:::-;8846:24;8864:5;8846:24;:::i;:::-;8841:3;8834:37;8759:118;;:::o;8883:222::-;8976:4;9014:2;9003:9;8999:18;8991:26;;9027:71;9095:1;9084:9;9080:17;9071:6;9027:71;:::i;:::-;8883:222;;;;:::o;9111:474::-;9179:6;9187;9236:2;9224:9;9215:7;9211:23;9207:32;9204:119;;;9242:79;;:::i;:::-;9204:119;9362:1;9387:53;9432:7;9423:6;9412:9;9408:22;9387:53;:::i;:::-;9377:63;;9333:117;9489:2;9515:53;9560:7;9551:6;9540:9;9536:22;9515:53;:::i;:::-;9505:63;;9460:118;9111:474;;;;;:::o;9591:104::-;9636:7;9665:24;9683:5;9665:24;:::i;:::-;9654:35;;9591:104;;;:::o;9701:142::-;9804:32;9830:5;9804:32;:::i;:::-;9799:3;9792:45;9701:142;;:::o;9849:254::-;9958:4;9996:2;9985:9;9981:18;9973:26;;10009:87;10093:1;10082:9;10078:17;10069:6;10009:87;:::i;:::-;9849:254;;;;:::o;10109:180::-;10157:77;10154:1;10147:88;10254:4;10251:1;10244:15;10278:4;10275:1;10268:15;10295:191;10335:3;10354:20;10372:1;10354:20;:::i;:::-;10349:25;;10388:20;10406:1;10388:20;:::i;:::-;10383:25;;10431:1;10428;10424:9;10417:16;;10452:3;10449:1;10446:10;10443:36;;;10459:18;;:::i;:::-;10443:36;10295:191;;;;:::o;10492:180::-;10540:77;10537:1;10530:88;10637:4;10634:1;10627:15;10661:4;10658:1;10651:15;10678:320;10722:6;10759:1;10753:4;10749:12;10739:22;;10806:1;10800:4;10796:12;10827:18;10817:81;;10883:4;10875:6;10871:17;10861:27;;10817:81;10945:2;10937:6;10934:14;10914:18;10911:38;10908:84;;10964:18;;:::i;:::-;10908:84;10729:269;10678:320;;;:::o;11004:232::-;11144:34;11140:1;11132:6;11128:14;11121:58;11213:15;11208:2;11200:6;11196:15;11189:40;11004:232;:::o;11242:366::-;11384:3;11405:67;11469:2;11464:3;11405:67;:::i;:::-;11398:74;;11481:93;11570:3;11481:93;:::i;:::-;11599:2;11594:3;11590:12;11583:19;;11242:366;;;:::o;11614:419::-;11780:4;11818:2;11807:9;11803:18;11795:26;;11867:9;11861:4;11857:20;11853:1;11842:9;11838:17;11831:47;11895:131;12021:4;11895:131;:::i;:::-;11887:139;;11614:419;;;:::o;12039:173::-;12179:25;12175:1;12167:6;12163:14;12156:49;12039:173;:::o;12218:366::-;12360:3;12381:67;12445:2;12440:3;12381:67;:::i;:::-;12374:74;;12457:93;12546:3;12457:93;:::i;:::-;12575:2;12570:3;12566:12;12559:19;;12218:366;;;:::o;12590:419::-;12756:4;12794:2;12783:9;12779:18;12771:26;;12843:9;12837:4;12833:20;12829:1;12818:9;12814:17;12807:47;12871:131;12997:4;12871:131;:::i;:::-;12863:139;;12590:419;;;:::o;13015:179::-;13155:31;13151:1;13143:6;13139:14;13132:55;13015:179;:::o;13200:366::-;13342:3;13363:67;13427:2;13422:3;13363:67;:::i;:::-;13356:74;;13439:93;13528:3;13439:93;:::i;:::-;13557:2;13552:3;13548:12;13541:19;;13200:366;;;:::o;13572:419::-;13738:4;13776:2;13765:9;13761:18;13753:26;;13825:9;13819:4;13815:20;13811:1;13800:9;13796:17;13789:47;13853:131;13979:4;13853:131;:::i;:::-;13845:139;;13572:419;;;:::o;13997:410::-;14037:7;14060:20;14078:1;14060:20;:::i;:::-;14055:25;;14094:20;14112:1;14094:20;:::i;:::-;14089:25;;14149:1;14146;14142:9;14171:30;14189:11;14171:30;:::i;:::-;14160:41;;14350:1;14341:7;14337:15;14334:1;14331:22;14311:1;14304:9;14284:83;14261:139;;14380:18;;:::i;:::-;14261:139;14045:362;13997:410;;;;:::o;14413:180::-;14461:77;14458:1;14451:88;14558:4;14555:1;14548:15;14582:4;14579:1;14572:15;14599:185;14639:1;14656:20;14674:1;14656:20;:::i;:::-;14651:25;;14690:20;14708:1;14690:20;:::i;:::-;14685:25;;14729:1;14719:35;;14734:18;;:::i;:::-;14719:35;14776:1;14773;14769:9;14764:14;;14599:185;;;;:::o;14790:179::-;14930:31;14926:1;14918:6;14914:14;14907:55;14790:179;:::o;14975:366::-;15117:3;15138:67;15202:2;15197:3;15138:67;:::i;:::-;15131:74;;15214:93;15303:3;15214:93;:::i;:::-;15332:2;15327:3;15323:12;15316:19;;14975:366;;;:::o;15347:419::-;15513:4;15551:2;15540:9;15536:18;15528:26;;15600:9;15594:4;15590:20;15586:1;15575:9;15571:17;15564:47;15628:131;15754:4;15628:131;:::i;:::-;15620:139;;15347:419;;;:::o;15772:194::-;15812:4;15832:20;15850:1;15832:20;:::i;:::-;15827:25;;15866:20;15884:1;15866:20;:::i;:::-;15861:25;;15910:1;15907;15903:9;15895:17;;15934:1;15928:4;15925:11;15922:37;;;15939:18;;:::i;:::-;15922:37;15772:194;;;;:::o;15972:221::-;16112:34;16108:1;16100:6;16096:14;16089:58;16181:4;16176:2;16168:6;16164:15;16157:29;15972:221;:::o;16199:366::-;16341:3;16362:67;16426:2;16421:3;16362:67;:::i;:::-;16355:74;;16438:93;16527:3;16438:93;:::i;:::-;16556:2;16551:3;16547:12;16540:19;;16199:366;;;:::o;16571:419::-;16737:4;16775:2;16764:9;16760:18;16752:26;;16824:9;16818:4;16814:20;16810:1;16799:9;16795:17;16788:47;16852:131;16978:4;16852:131;:::i;:::-;16844:139;;16571:419;;;:::o;16996:227::-;17136:34;17132:1;17124:6;17120:14;17113:58;17205:10;17200:2;17192:6;17188:15;17181:35;16996:227;:::o;17229:366::-;17371:3;17392:67;17456:2;17451:3;17392:67;:::i;:::-;17385:74;;17468:93;17557:3;17468:93;:::i;:::-;17586:2;17581:3;17577:12;17570:19;;17229:366;;;:::o;17601:419::-;17767:4;17805:2;17794:9;17790:18;17782:26;;17854:9;17848:4;17844:20;17840:1;17829:9;17825:17;17818:47;17882:131;18008:4;17882:131;:::i;:::-;17874:139;;17601:419;;;:::o;18026:60::-;18054:3;18075:5;18068:12;;18026:60;;;:::o;18092:140::-;18141:9;18174:52;18192:33;18201:23;18218:5;18201:23;:::i;:::-;18192:33;:::i;:::-;18174:52;:::i;:::-;18161:65;;18092:140;;;:::o;18238:129::-;18324:36;18354:5;18324:36;:::i;:::-;18319:3;18312:49;18238:129;;:::o;18373:220::-;18465:4;18503:2;18492:9;18488:18;18480:26;;18516:70;18583:1;18572:9;18568:17;18559:6;18516:70;:::i;:::-;18373:220;;;;:::o;18599:241::-;18739:34;18735:1;18727:6;18723:14;18716:58;18808:24;18803:2;18795:6;18791:15;18784:49;18599:241;:::o;18846:366::-;18988:3;19009:67;19073:2;19068:3;19009:67;:::i;:::-;19002:74;;19085:93;19174:3;19085:93;:::i;:::-;19203:2;19198:3;19194:12;19187:19;;18846:366;;;:::o;19218:419::-;19384:4;19422:2;19411:9;19407:18;19399:26;;19471:9;19465:4;19461:20;19457:1;19446:9;19442:17;19435:47;19499:131;19625:4;19499:131;:::i;:::-;19491:139;;19218:419;;;:::o;19643:221::-;19783:34;19779:1;19771:6;19767:14;19760:58;19852:4;19847:2;19839:6;19835:15;19828:29;19643:221;:::o;19870:366::-;20012:3;20033:67;20097:2;20092:3;20033:67;:::i;:::-;20026:74;;20109:93;20198:3;20109:93;:::i;:::-;20227:2;20222:3;20218:12;20211:19;;19870:366;;;:::o;20242:419::-;20408:4;20446:2;20435:9;20431:18;20423:26;;20495:9;20489:4;20485:20;20481:1;20470:9;20466:17;20459:47;20523:131;20649:4;20523:131;:::i;:::-;20515:139;;20242:419;;;:::o;20667:170::-;20807:22;20803:1;20795:6;20791:14;20784:46;20667:170;:::o;20843:366::-;20985:3;21006:67;21070:2;21065:3;21006:67;:::i;:::-;20999:74;;21082:93;21171:3;21082:93;:::i;:::-;21200:2;21195:3;21191:12;21184:19;;20843:366;;;:::o;21215:419::-;21381:4;21419:2;21408:9;21404:18;21396:26;;21468:9;21462:4;21458:20;21454:1;21443:9;21439:17;21432:47;21496:131;21622:4;21496:131;:::i;:::-;21488:139;;21215:419;;;:::o;21640:223::-;21780:34;21776:1;21768:6;21764:14;21757:58;21849:6;21844:2;21836:6;21832:15;21825:31;21640:223;:::o;21869:366::-;22011:3;22032:67;22096:2;22091:3;22032:67;:::i;:::-;22025:74;;22108:93;22197:3;22108:93;:::i;:::-;22226:2;22221:3;22217:12;22210:19;;21869:366;;;:::o;22241:419::-;22407:4;22445:2;22434:9;22430:18;22422:26;;22494:9;22488:4;22484:20;22480:1;22469:9;22465:17;22458:47;22522:131;22648:4;22522:131;:::i;:::-;22514:139;;22241:419;;;:::o;22666:170::-;22806:22;22802:1;22794:6;22790:14;22783:46;22666:170;:::o;22842:366::-;22984:3;23005:67;23069:2;23064:3;23005:67;:::i;:::-;22998:74;;23081:93;23170:3;23081:93;:::i;:::-;23199:2;23194:3;23190:12;23183:19;;22842:366;;;:::o;23214:419::-;23380:4;23418:2;23407:9;23403:18;23395:26;;23467:9;23461:4;23457:20;23453:1;23442:9;23438:17;23431:47;23495:131;23621:4;23495:131;:::i;:::-;23487:139;;23214:419;;;:::o;23639:230::-;23779:34;23775:1;23767:6;23763:14;23756:58;23848:13;23843:2;23835:6;23831:15;23824:38;23639:230;:::o;23875:366::-;24017:3;24038:67;24102:2;24097:3;24038:67;:::i;:::-;24031:74;;24114:93;24203:3;24114:93;:::i;:::-;24232:2;24227:3;24223:12;24216:19;;23875:366;;;:::o;24247:419::-;24413:4;24451:2;24440:9;24436:18;24428:26;;24500:9;24494:4;24490:20;24486:1;24475:9;24471:17;24464:47;24528:131;24654:4;24528:131;:::i;:::-;24520:139;;24247:419;;;:::o;24672:177::-;24812:29;24808:1;24800:6;24796:14;24789:53;24672:177;:::o;24855:366::-;24997:3;25018:67;25082:2;25077:3;25018:67;:::i;:::-;25011:74;;25094:93;25183:3;25094:93;:::i;:::-;25212:2;25207:3;25203:12;25196:19;;24855:366;;;:::o;25227:419::-;25393:4;25431:2;25420:9;25416:18;25408:26;;25480:9;25474:4;25470:20;25466:1;25455:9;25451:17;25444:47;25508:131;25634:4;25508:131;:::i;:::-;25500:139;;25227:419;;;:::o;25652:175::-;25792:27;25788:1;25780:6;25776:14;25769:51;25652:175;:::o;25833:366::-;25975:3;25996:67;26060:2;26055:3;25996:67;:::i;:::-;25989:74;;26072:93;26161:3;26072:93;:::i;:::-;26190:2;26185:3;26181:12;26174:19;;25833:366;;;:::o;26205:419::-;26371:4;26409:2;26398:9;26394:18;26386:26;;26458:9;26452:4;26448:20;26444:1;26433:9;26429:17;26422:47;26486:131;26612:4;26486:131;:::i;:::-;26478:139;;26205:419;;;:::o;26630:177::-;26770:29;26766:1;26758:6;26754:14;26747:53;26630:177;:::o;26813:366::-;26955:3;26976:67;27040:2;27035:3;26976:67;:::i;:::-;26969:74;;27052:93;27141:3;27052:93;:::i;:::-;27170:2;27165:3;27161:12;27154:19;;26813:366;;;:::o;27185:419::-;27351:4;27389:2;27378:9;27374:18;27366:26;;27438:9;27432:4;27428:20;27424:1;27413:9;27409:17;27402:47;27466:131;27592:4;27466:131;:::i;:::-;27458:139;;27185:419;;;:::o;27610:224::-;27750:34;27746:1;27738:6;27734:14;27727:58;27819:7;27814:2;27806:6;27802:15;27795:32;27610:224;:::o;27840:366::-;27982:3;28003:67;28067:2;28062:3;28003:67;:::i;:::-;27996:74;;28079:93;28168:3;28079:93;:::i;:::-;28197:2;28192:3;28188:12;28181:19;;27840:366;;;:::o;28212:419::-;28378:4;28416:2;28405:9;28401:18;28393:26;;28465:9;28459:4;28455:20;28451:1;28440:9;28436:17;28429:47;28493:131;28619:4;28493:131;:::i;:::-;28485:139;;28212:419;;;:::o;28637:180::-;28777:32;28773:1;28765:6;28761:14;28754:56;28637:180;:::o;28823:366::-;28965:3;28986:67;29050:2;29045:3;28986:67;:::i;:::-;28979:74;;29062:93;29151:3;29062:93;:::i;:::-;29180:2;29175:3;29171:12;29164:19;;28823:366;;;:::o;29195:419::-;29361:4;29399:2;29388:9;29384:18;29376:26;;29448:9;29442:4;29438:20;29434:1;29423:9;29419:17;29412:47;29476:131;29602:4;29476:131;:::i;:::-;29468:139;;29195:419;;;:::o;29620:178::-;29760:30;29756:1;29748:6;29744:14;29737:54;29620:178;:::o;29804:366::-;29946:3;29967:67;30031:2;30026:3;29967:67;:::i;:::-;29960:74;;30043:93;30132:3;30043:93;:::i;:::-;30161:2;30156:3;30152:12;30145:19;;29804:366;;;:::o;30176:419::-;30342:4;30380:2;30369:9;30365:18;30357:26;;30429:9;30423:4;30419:20;30415:1;30404:9;30400:17;30393:47;30457:131;30583:4;30457:131;:::i;:::-;30449:139;;30176:419;;;:::o;30601:177::-;30741:29;30737:1;30729:6;30725:14;30718:53;30601:177;:::o;30784:366::-;30926:3;30947:67;31011:2;31006:3;30947:67;:::i;:::-;30940:74;;31023:93;31112:3;31023:93;:::i;:::-;31141:2;31136:3;31132:12;31125:19;;30784:366;;;:::o;31156:419::-;31322:4;31360:2;31349:9;31345:18;31337:26;;31409:9;31403:4;31399:20;31395:1;31384:9;31380:17;31373:47;31437:131;31563:4;31437:131;:::i;:::-;31429:139;;31156:419;;;:::o;31581:223::-;31721:34;31717:1;31709:6;31705:14;31698:58;31790:6;31785:2;31777:6;31773:15;31766:31;31581:223;:::o;31810:366::-;31952:3;31973:67;32037:2;32032:3;31973:67;:::i;:::-;31966:74;;32049:93;32138:3;32049:93;:::i;:::-;32167:2;32162:3;32158:12;32151:19;;31810:366;;;:::o;32182:419::-;32348:4;32386:2;32375:9;32371:18;32363:26;;32435:9;32429:4;32425:20;32421:1;32410:9;32406:17;32399:47;32463:131;32589:4;32463:131;:::i;:::-;32455:139;;32182:419;;;:::o;32607:173::-;32747:25;32743:1;32735:6;32731:14;32724:49;32607:173;:::o;32786:366::-;32928:3;32949:67;33013:2;33008:3;32949:67;:::i;:::-;32942:74;;33025:93;33114:3;33025:93;:::i;:::-;33143:2;33138:3;33134:12;33127:19;;32786:366;;;:::o;33158:419::-;33324:4;33362:2;33351:9;33347:18;33339:26;;33411:9;33405:4;33401:20;33397:1;33386:9;33382:17;33375:47;33439:131;33565:4;33439:131;:::i;:::-;33431:139;;33158:419;;;:::o;33583:238::-;33723:34;33719:1;33711:6;33707:14;33700:58;33792:21;33787:2;33779:6;33775:15;33768:46;33583:238;:::o;33827:366::-;33969:3;33990:67;34054:2;34049:3;33990:67;:::i;:::-;33983:74;;34066:93;34155:3;34066:93;:::i;:::-;34184:2;34179:3;34175:12;34168:19;;33827:366;;;:::o;34199:419::-;34365:4;34403:2;34392:9;34388:18;34380:26;;34452:9;34446:4;34442:20;34438:1;34427:9;34423:17;34416:47;34480:131;34606:4;34480:131;:::i;:::-;34472:139;;34199:419;;;:::o;34624:221::-;34764:34;34760:1;34752:6;34748:14;34741:58;34833:4;34828:2;34820:6;34816:15;34809:29;34624:221;:::o;34851:366::-;34993:3;35014:67;35078:2;35073:3;35014:67;:::i;:::-;35007:74;;35090:93;35179:3;35090:93;:::i;:::-;35208:2;35203:3;35199:12;35192:19;;34851:366;;;:::o;35223:419::-;35389:4;35427:2;35416:9;35412:18;35404:26;;35476:9;35470:4;35466:20;35462:1;35451:9;35447:17;35440:47;35504:131;35630:4;35504:131;:::i;:::-;35496:139;;35223:419;;;:::o;35648:226::-;35788:34;35784:1;35776:6;35772:14;35765:58;35857:9;35852:2;35844:6;35840:15;35833:34;35648:226;:::o;35880:366::-;36022:3;36043:67;36107:2;36102:3;36043:67;:::i;:::-;36036:74;;36119:93;36208:3;36119:93;:::i;:::-;36237:2;36232:3;36228:12;36221:19;;35880:366;;;:::o;36252:419::-;36418:4;36456:2;36445:9;36441:18;36433:26;;36505:9;36499:4;36495:20;36491:1;36480:9;36476:17;36469:47;36533:131;36659:4;36533:131;:::i;:::-;36525:139;;36252:419;;;:::o;36677:181::-;36817:33;36813:1;36805:6;36801:14;36794:57;36677:181;:::o;36864:366::-;37006:3;37027:67;37091:2;37086:3;37027:67;:::i;:::-;37020:74;;37103:93;37192:3;37103:93;:::i;:::-;37221:2;37216:3;37212:12;37205:19;;36864:366;;;:::o;37236:419::-;37402:4;37440:2;37429:9;37425:18;37417:26;;37489:9;37483:4;37479:20;37475:1;37464:9;37460:17;37453:47;37517:131;37643:4;37517:131;:::i;:::-;37509:139;;37236:419;;;:::o;37661:176::-;37693:1;37710:20;37728:1;37710:20;:::i;:::-;37705:25;;37744:20;37762:1;37744:20;:::i;:::-;37739:25;;37783:1;37773:35;;37788:18;;:::i;:::-;37773:35;37829:1;37826;37822:9;37817:14;;37661:176;;;;:::o;37843:169::-;37983:21;37979:1;37971:6;37967:14;37960:45;37843:169;:::o;38018:366::-;38160:3;38181:67;38245:2;38240:3;38181:67;:::i;:::-;38174:74;;38257:93;38346:3;38257:93;:::i;:::-;38375:2;38370:3;38366:12;38359:19;;38018:366;;;:::o;38390:419::-;38556:4;38594:2;38583:9;38579:18;38571:26;;38643:9;38637:4;38633:20;38629:1;38618:9;38614:17;38607:47;38671:131;38797:4;38671:131;:::i;:::-;38663:139;;38390:419;;;:::o;38815:180::-;38955:32;38951:1;38943:6;38939:14;38932:56;38815:180;:::o;39001:366::-;39143:3;39164:67;39228:2;39223:3;39164:67;:::i;:::-;39157:74;;39240:93;39329:3;39240:93;:::i;:::-;39358:2;39353:3;39349:12;39342:19;;39001:366;;;:::o;39373:419::-;39539:4;39577:2;39566:9;39562:18;39554:26;;39626:9;39620:4;39616:20;39612:1;39601:9;39597:17;39590:47;39654:131;39780:4;39654:131;:::i;:::-;39646:139;;39373:419;;;:::o;39798:147::-;39899:11;39936:3;39921:18;;39798:147;;;;:::o;39951:114::-;;:::o;40071:398::-;40230:3;40251:83;40332:1;40327:3;40251:83;:::i;:::-;40244:90;;40343:93;40432:3;40343:93;:::i;:::-;40461:1;40456:3;40452:11;40445:18;;40071:398;;;:::o;40475:379::-;40659:3;40681:147;40824:3;40681:147;:::i;:::-;40674:154;;40845:3;40838:10;;40475:379;;;:::o;40860:172::-;41000:24;40996:1;40988:6;40984:14;40977:48;40860:172;:::o;41038:366::-;41180:3;41201:67;41265:2;41260:3;41201:67;:::i;:::-;41194:74;;41277:93;41366:3;41277:93;:::i;:::-;41395:2;41390:3;41386:12;41379:19;;41038:366;;;:::o;41410:419::-;41576:4;41614:2;41603:9;41599:18;41591:26;;41663:9;41657:4;41653:20;41649:1;41638:9;41634:17;41627:47;41691:131;41817:4;41691:131;:::i;:::-;41683:139;;41410:419;;;:::o;41835:332::-;41956:4;41994:2;41983:9;41979:18;41971:26;;42007:71;42075:1;42064:9;42060:17;42051:6;42007:71;:::i;:::-;42088:72;42156:2;42145:9;42141:18;42132:6;42088:72;:::i;:::-;41835:332;;;;;:::o;42173:304::-;42313:34;42309:1;42301:6;42297:14;42290:58;42382:34;42377:2;42369:6;42365:15;42358:59;42451:18;42446:2;42438:6;42434:15;42427:43;42173:304;:::o;42483:366::-;42625:3;42646:67;42710:2;42705:3;42646:67;:::i;:::-;42639:74;;42722:93;42811:3;42722:93;:::i;:::-;42840:2;42835:3;42831:12;42824:19;;42483:366;;;:::o;42855:419::-;43021:4;43059:2;43048:9;43044:18;43036:26;;43108:9;43102:4;43098:20;43094:1;43083:9;43079:17;43072:47;43136:131;43262:4;43136:131;:::i;:::-;43128:139;;42855:419;;;:::o;43280:220::-;43420:34;43416:1;43408:6;43404:14;43397:58;43489:3;43484:2;43476:6;43472:15;43465:28;43280:220;:::o;43506:366::-;43648:3;43669:67;43733:2;43728:3;43669:67;:::i;:::-;43662:74;;43745:93;43834:3;43745:93;:::i;:::-;43863:2;43858:3;43854:12;43847:19;;43506:366;;;:::o;43878:419::-;44044:4;44082:2;44071:9;44067:18;44059:26;;44131:9;44125:4;44121:20;44117:1;44106:9;44102:17;44095:47;44159:131;44285:4;44159:131;:::i;:::-;44151:139;;43878:419;;;:::o;44303:442::-;44452:4;44490:2;44479:9;44475:18;44467:26;;44503:71;44571:1;44560:9;44556:17;44547:6;44503:71;:::i;:::-;44584:72;44652:2;44641:9;44637:18;44628:6;44584:72;:::i;:::-;44666;44734:2;44723:9;44719:18;44710:6;44666:72;:::i;:::-;44303:442;;;;;;:::o;44751:178::-;44891:30;44887:1;44879:6;44875:14;44868:54;44751:178;:::o;44935:366::-;45077:3;45098:67;45162:2;45157:3;45098:67;:::i;:::-;45091:74;;45174:93;45263:3;45174:93;:::i;:::-;45292:2;45287:3;45283:12;45276:19;;44935:366;;;:::o;45307:419::-;45473:4;45511:2;45500:9;45496:18;45488:26;;45560:9;45554:4;45550:20;45546:1;45535:9;45531:17;45524:47;45588:131;45714:4;45588:131;:::i;:::-;45580:139;;45307:419;;;:::o;45732:162::-;45872:14;45868:1;45860:6;45856:14;45849:38;45732:162;:::o;45900:366::-;46042:3;46063:67;46127:2;46122:3;46063:67;:::i;:::-;46056:74;;46139:93;46228:3;46139:93;:::i;:::-;46257:2;46252:3;46248:12;46241:19;;45900:366;;;:::o;46272:419::-;46438:4;46476:2;46465:9;46461:18;46453:26;;46525:9;46519:4;46515:20;46511:1;46500:9;46496:17;46489:47;46553:131;46679:4;46553:131;:::i;:::-;46545:139;;46272:419;;;:::o

Swarm Source

ipfs://232ac30dbbab817d1348eaeac4cf0ec0aa588e938f2b8b5d570097dbb67d8c9c
[ 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.