ETH Price: $2,228.85 (-2.02%)
Gas: 0.31 Gwei
 

Overview

Max Total Supply

10,000,000 GRAY

Holders

4,748 (0.00%)

Transfers

-
151 ( -21.35%)

Market

Price

$0.18 @ 0.000083 ETH (+3.11%)

Onchain Market Cap

$1,842,960.00

Circulating Supply Market Cap

$1,841,829.00

Other Info

Token Contract (WITH 18 Decimals)

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

OVERVIEW

Gradient proposes a new off-market trading layer. Composed of the CORE (Coordinated Order Routing Engine) and 3 modular trading layers, Gradient is engineered to allow for price-impact free trading. The $GRAY token acts as the core economic component of the Gradient ecosystem.

Market

Volume (24H):$26,391.00
Market Capitalization:$1,841,829.00
Circulating Supply:10,000,000.00 GRAY
Market Data Source: Coinmarketcap

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
Gradient

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license
/**
 *Submitted for verification at Etherscan.io on 2025-06-04
*/

/* 

Gradient - Creating efficient markets beyond AMMs.

Website - https://gradient.trade
Telegram - https://t.me/useGradient
X - https://x.com/useGradient

*/

// 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/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/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/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.3.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}.
     *
     * Both 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) virtual 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/interfaces/IERC20.sol


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

pragma solidity ^0.8.20;


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


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

pragma solidity ^0.8.20;

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

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


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

pragma solidity ^0.8.20;


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


// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol)

pragma solidity ^0.8.20;



/**
 * @title IERC1363
 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
 *
 * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
 * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
 */
interface IERC1363 is IERC20, IERC165 {
    /*
     * Note: the ERC-165 identifier for this interface is 0xb0202a11.
     * 0xb0202a11 ===
     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^
     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^
     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
     */

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`
     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
     * @param to The address which you want to transfer to.
     * @param value The amount of tokens to be transferred.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function transferAndCall(address to, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`
     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
     * @param to The address which you want to transfer to.
     * @param value The amount of tokens to be transferred.
     * @param data Additional data with no specified format, sent in call to `to`.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
     * @param from The address which you want to send tokens from.
     * @param to The address which you want to transfer to.
     * @param value The amount of tokens to be transferred.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
     * @param from The address which you want to send tokens from.
     * @param to The address which you want to transfer to.
     * @param value The amount of tokens to be transferred.
     * @param data Additional data with no specified format, sent in call to `to`.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
     * @param spender The address which will spend the funds.
     * @param value The amount of tokens to be spent.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function approveAndCall(address spender, uint256 value) external returns (bool);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
     * @param spender The address which will spend the funds.
     * @param value The amount of tokens to be spent.
     * @param data Additional data with no specified format, sent in call to `spender`.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}

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


// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.20;



/**
 * @title SafeERC20
 * @dev Wrappers around ERC-20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    /**
     * @dev An operation with an ERC-20 token failed.
     */
    error SafeERC20FailedOperation(address token);

    /**
     * @dev Indicates a failed `decreaseAllowance` request.
     */
    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
    }

    /**
     * @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.
     */
    function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {
        return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value)));
    }

    /**
     * @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.
     */
    function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {
        return _callOptionalReturnBool(token, abi.encodeCall(token.transferFrom, (from, to, value)));
    }

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     *
     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
     * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
     */
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        forceApprove(token, spender, oldAllowance + value);
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
     * value, non-reverting calls are assumed to be successful.
     *
     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
     * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
        unchecked {
            uint256 currentAllowance = token.allowance(address(this), spender);
            if (currentAllowance < requestedDecrease) {
                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
            }
            forceApprove(token, spender, currentAllowance - requestedDecrease);
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
     * to be set to zero before setting it to a non-zero value, such as USDT.
     *
     * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
     * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
     * set here.
     */
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
            _callOptionalReturn(token, approvalCall);
        }
    }

    /**
     * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
     * targeting contracts.
     *
     * Reverts if the returned value is other than `true`.
     */
    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
        if (to.code.length == 0) {
            safeTransfer(token, to, value);
        } else if (!token.transferAndCall(to, value, data)) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
     * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
     * targeting contracts.
     *
     * Reverts if the returned value is other than `true`.
     */
    function transferFromAndCallRelaxed(
        IERC1363 token,
        address from,
        address to,
        uint256 value,
        bytes memory data
    ) internal {
        if (to.code.length == 0) {
            safeTransferFrom(token, from, to, value);
        } else if (!token.transferFromAndCall(from, to, value, data)) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
     * targeting contracts.
     *
     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
     * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
     * once without retrying, and relies on the returned value to be true.
     *
     * Reverts if the returned value is other than `true`.
     */
    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
        if (to.code.length == 0) {
            forceApprove(token, to, value);
        } else if (!token.approveAndCall(to, value, data)) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        uint256 returnSize;
        uint256 returnValue;
        assembly ("memory-safe") {
            let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
            // bubble errors
            if iszero(success) {
                let ptr := mload(0x40)
                returndatacopy(ptr, 0, returndatasize())
                revert(ptr, returndatasize())
            }
            returnSize := returndatasize()
            returnValue := mload(0)
        }

        if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
     */
    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        bool success;
        uint256 returnSize;
        uint256 returnValue;
        assembly ("memory-safe") {
            success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
            returnSize := returndatasize()
            returnValue := mload(0)
        }
        return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
    }
}

// File: @uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol

pragma solidity >=0.5.0;

interface IUniswapV2Factory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);

    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);

    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);

    function createPair(address tokenA, address tokenB) external returns (address pair);

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
}

// File: @uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol

pragma solidity >=0.6.2;

interface IUniswapV2Router01 {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB, uint liquidity);
    function addLiquidityETH(
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB);
    function removeLiquidityETH(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountToken, uint amountETH);
    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountA, uint amountB);
    function removeLiquidityETHWithPermit(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountToken, uint amountETH);
    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    function swapTokensForExactTokens(
        uint amountOut,
        uint amountInMax,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);
    function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
        external
        returns (uint[] memory amounts);
    function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        returns (uint[] memory amounts);
    function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);

    function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
    function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
    function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}

// File: @uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol

pragma solidity >=0.6.2;


interface IUniswapV2Router02 is IUniswapV2Router01 {
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountETH);
    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountETH);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external payable;
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
}

// File: contracts/Gradient.sol

//SPDX-License-Identifier: MIT
pragma solidity 0.8.20;







contract Gradient is ERC20, Ownable {
    using SafeERC20 for IERC20;
    IUniswapV2Router02 public dexRouter;
    address public dexPair;

    uint256 public liqTriggerAmount = 2e4 ether;
    uint256 public maxTxnLimit;
    uint256 public totalTaxRate;

    uint256 public liqFee;
    uint256 public ethFee;

    uint256 private liqPortion;
    uint256 private ethPortion;

    address public treasuryReceiver;
    bool public tradingEnabled;
    bool private swapping;

    mapping(address => bool) private _isTxLimitExempt;

    modifier swapLock() {
        require(!swapping, "Swap in progress");
        swapping = true;
        _;
        swapping = false;
    }

    event TxLimitUpdated(uint256 limit);
    event TaxRateUpdated(uint256 newRate);
    event TreasuryWithdrawn(address to, uint256 amount);
    event TokenRescue(address token, uint256 amount);
    event TradingActivated(bool enabled);
    event LiquidityTriggered(
        uint256 amountSwapped,
        uint256 tokensAdded,
        uint256 ethAdded
    );
    event ExemptionUpdated(address account, bool isExempt);

    constructor(
        address _router,
        uint256 _initialTaxRate,
        uint256 _ethFee,
        uint256 _liqFee,
        uint256 _maxTxn,
        address _treasury
    ) ERC20("Gradient", "GRAY") Ownable(msg.sender) {
        require(_initialTaxRate >= 100, "Tax rate is too low");
        _mint(_msgSender(), 10_000_000 ether);

        dexRouter = IUniswapV2Router02(_router);
        dexPair = IUniswapV2Factory(dexRouter.factory()).createPair(
            address(this),
            dexRouter.WETH()
        );

        totalTaxRate = _initialTaxRate;
        ethFee = _ethFee;
        liqFee = _liqFee;
        maxTxnLimit = _maxTxn;
        treasuryReceiver = _treasury;

        _isTxLimitExempt[address(this)] = true;
        _isTxLimitExempt[msg.sender] = true;
        _isTxLimitExempt[_router] = true;
        _isTxLimitExempt[dexPair] = true;
    }

    receive() external payable {}

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal override {
        require(amount > 0, "Transfer amount must be greater than 0");

        // Enforce trading and purchase limits
        if (!_isTxLimitExempt[from] || !_isTxLimitExempt[to]) {
            require(tradingEnabled, "Trading is not yet enabled");
        }

        uint256 taxAmount = 0;

        // Enforce max transaction size on buys
        if (
            from == dexPair && to != address(dexRouter) && !_isTxLimitExempt[to]
        ) {
            require(
                amount <= (totalSupply() * maxTxnLimit) / 1e4,
                "Txn exceeds limit"
            );
        }

        // Apply tax on buys and sells if not excluded and not internal
        if (
            (!_isTxLimitExempt[from] || !_isTxLimitExempt[to]) &&
            from != address(this) &&
            (from == dexPair || to == dexPair) &&
            totalTaxRate > 0
        ) {
            taxAmount = (amount * totalTaxRate) / 10_000;
            super._transfer(from, address(this), taxAmount);
        }

        // Trigger liquidity if conditions met
        if (!swapping && to == dexPair && !_isTxLimitExempt[from]) {
            uint256 contractBalance = balanceOf(address(this));
            if (contractBalance >= liqTriggerAmount) {
                uint256 maxSwap = liqTriggerAmount + (liqTriggerAmount / 5);
                if (contractBalance >= maxSwap) {
                    _handleLiquidity(maxSwap);
                } else {
                    _handleLiquidity(liqTriggerAmount);
                }
            }
        }

        super._transfer(from, to, amount - taxAmount);
    }

    function _handleLiquidity(uint256 amount) private swapLock {
        if (ethFee == 0 && liqFee == 0) return;

        uint256 initialETH = address(this).balance;
        uint256 combinedFee = totalTaxRate / 100;
        require(combinedFee > 0, "Invalid tax rate");

        uint256 toETH = (amount * ethFee) / combinedFee;
        uint256 toLiq = (amount * liqFee) / combinedFee;

        uint256 tokensToSwap = toETH + (toLiq / 2);
        uint256 tokensToLiq = toLiq - (toLiq / 2);

        _swapTokensForETH(tokensToSwap);
        uint256 ethGained = address(this).balance - initialETH;

        uint256 ethForLiq = (tokensToSwap > 0)
            ? (ethGained * (toLiq / 2)) / tokensToSwap
            : 0;
        uint256 ethForTreasury = ethGained - ethForLiq;

        if (tokensToLiq > 0 && ethForLiq > 0) {
            _addLiquidity(tokensToLiq, ethForLiq);
        }

        if (ethForTreasury > 0) {
            (bool success, ) = payable(treasuryReceiver).call{
                value: ethForTreasury
            }("");
            require(success, "Treasury transfer failed");
        }

        emit LiquidityTriggered(tokensToSwap, tokensToLiq, ethForLiq);
    }

    function _swapTokensForETH(uint256 tokens) private {
        if (tokens == 0) return;

        address[] memory route = new address[](2);
        route[0] = address(this);
        route[1] = dexRouter.WETH();

        _approve(address(this), address(dexRouter), tokens);
        dexRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokens,
            0,
            route,
            address(this),
            block.timestamp
        );
    }

    function _addLiquidity(uint256 tokens, uint256 eth) private {
        if (tokens == 0 || eth == 0) return;

        _approve(address(this), address(dexRouter), tokens);
        dexRouter.addLiquidityETH{value: eth}(
            address(this),
            tokens,
            0,
            0,
            owner(),
            block.timestamp
        );
    }

    function updateTaxRates(
        uint256 newETHFee,
        uint256 newLiqFee
    ) external onlyOwner {
        uint256 newTotal = newETHFee + newLiqFee;
        require(newTotal > 0, "Total tax rate cannot be zero");
        require(newTotal <= (totalTaxRate / 100), "Tax must be reduced");

        ethFee = newETHFee;
        liqFee = newLiqFee;
        totalTaxRate = newTotal * 100;
        emit TaxRateUpdated(totalTaxRate);
    }

    function activateTrading() external onlyOwner {
        require(!tradingEnabled, "Already active");
        tradingEnabled = true;
        emit TradingActivated(true);
    }

    function setTxnLimit(uint256 newLimit) external onlyOwner {
        maxTxnLimit = newLimit;
        emit TxLimitUpdated(newLimit);
    }

    function rescueETH(address payable recipient) external onlyOwner {
        uint256 amt = address(this).balance;
        require(amt > 0, "No ETH available");
        (bool success, ) = recipient.call{value: amt}("");
        require(success, "ETH transfer failed");
        emit TreasuryWithdrawn(recipient, amt);
    }

    function rescueTokens(address token) external onlyOwner {
        uint256 bal = IERC20(token).balanceOf(address(this));
        require(bal > 0, "No tokens available");
        IERC20(token).safeTransfer(owner(), bal);
        emit TokenRescue(token, bal);
    }

    function setExemption(address account, bool exempt) external onlyOwner {
        _isTxLimitExempt[account] = exempt;
        emit ExemptionUpdated(account, exempt);
    }

    function updateLiqTriggerAmount(uint256 newAmount) external onlyOwner {
        require(newAmount > 0, "Invalid amount");
        liqTriggerAmount = newAmount;
    }

    function updateTreasuryReceiver(address newReceiver) external onlyOwner {
        require(newReceiver != address(0), "Invalid address");
        treasuryReceiver = newReceiver;
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_router","type":"address"},{"internalType":"uint256","name":"_initialTaxRate","type":"uint256"},{"internalType":"uint256","name":"_ethFee","type":"uint256"},{"internalType":"uint256","name":"_liqFee","type":"uint256"},{"internalType":"uint256","name":"_maxTxn","type":"uint256"},{"internalType":"address","name":"_treasury","type":"address"}],"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":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","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":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"isExempt","type":"bool"}],"name":"ExemptionUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amountSwapped","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokensAdded","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAdded","type":"uint256"}],"name":"LiquidityTriggered","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":"newRate","type":"uint256"}],"name":"TaxRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokenRescue","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"TradingActivated","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TreasuryWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"limit","type":"uint256"}],"name":"TxLimitUpdated","type":"event"},{"inputs":[],"name":"activateTrading","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":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dexPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dexRouter","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liqFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liqTriggerAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTxnLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"recipient","type":"address"}],"name":"rescueETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"rescueTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"exempt","type":"bool"}],"name":"setExemption","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newLimit","type":"uint256"}],"name":"setTxnLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTaxRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradingEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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"},{"inputs":[],"name":"treasuryReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newAmount","type":"uint256"}],"name":"updateLiqTriggerAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newETHFee","type":"uint256"},{"internalType":"uint256","name":"newLiqFee","type":"uint256"}],"name":"updateTaxRates","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newReceiver","type":"address"}],"name":"updateTreasuryReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

608060405269043c33c19375648000006008553480156200001e575f80fd5b50604051620043fc380380620043fc8339818101604052810190620000449190620009e0565b336040518060400160405280600881526020017f4772616469656e740000000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f47524159000000000000000000000000000000000000000000000000000000008152508160039081620000c2919062000cd3565b508060049081620000d4919062000cd3565b5050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036200014a575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040162000141919062000dc8565b60405180910390fd5b6200015b81620005cb60201b60201c565b506064851015620001a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200019a9062000e41565b60405180910390fd5b620001cf620001b76200068e60201b60201c565b6a084595161401484a0000006200069560201b60201c565b8560065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200027a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620002a0919062000e61565b73ffffffffffffffffffffffffffffffffffffffff1663c9c653963060065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000327573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200034d919062000e61565b6040518363ffffffff1660e01b81526004016200036c92919062000e91565b6020604051808303815f875af115801562000389573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620003af919062000e61565b60075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600a8190555083600c8190555082600b819055508160098190555080600f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160105f3073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550600160105f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550600160105f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550600160105f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050505050505062000f8a565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160362000708575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401620006ff919062000dc8565b60405180910390fd5b6200071b5f83836200071f60201b60201c565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160362000773578060025f82825462000766919062000ee9565b9250508190555062000844565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015620007ff578381836040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401620007f69392919062000f34565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036200088d578060025f8282540392505081905550620008d7565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405162000936919062000f6f565b60405180910390a3505050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f620009728262000947565b9050919050565b620009848162000966565b81146200098f575f80fd5b50565b5f81519050620009a28162000979565b92915050565b5f819050919050565b620009bc81620009a8565b8114620009c7575f80fd5b50565b5f81519050620009da81620009b1565b92915050565b5f805f805f8060c08789031215620009fd57620009fc62000943565b5b5f62000a0c89828a0162000992565b965050602062000a1f89828a01620009ca565b955050604062000a3289828a01620009ca565b945050606062000a4589828a01620009ca565b935050608062000a5889828a01620009ca565b92505060a062000a6b89828a0162000992565b9150509295509295509295565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168062000af457607f821691505b60208210810362000b0a5762000b0962000aaf565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830262000b6e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000b31565b62000b7a868362000b31565b95508019841693508086168417925050509392505050565b5f819050919050565b5f62000bbb62000bb562000baf84620009a8565b62000b92565b620009a8565b9050919050565b5f819050919050565b62000bd68362000b9b565b62000bee62000be58262000bc2565b84845462000b3d565b825550505050565b5f90565b62000c0462000bf6565b62000c1181848462000bcb565b505050565b5b8181101562000c385762000c2c5f8262000bfa565b60018101905062000c17565b5050565b601f82111562000c875762000c518162000b10565b62000c5c8462000b22565b8101602085101562000c6c578190505b62000c8462000c7b8562000b22565b83018262000c16565b50505b505050565b5f82821c905092915050565b5f62000ca95f198460080262000c8c565b1980831691505092915050565b5f62000cc3838362000c98565b9150826002028217905092915050565b62000cde8262000a78565b67ffffffffffffffff81111562000cfa5762000cf962000a82565b5b62000d06825462000adc565b62000d1382828562000c3c565b5f60209050601f83116001811462000d49575f841562000d34578287015190505b62000d40858262000cb6565b86555062000daf565b601f19841662000d598662000b10565b5f5b8281101562000d825784890151825560018201915060208501945060208101905062000d5b565b8683101562000da2578489015162000d9e601f89168262000c98565b8355505b6001600288020188555050505b505050505050565b62000dc28162000966565b82525050565b5f60208201905062000ddd5f83018462000db7565b92915050565b5f82825260208201905092915050565b7f546178207261746520697320746f6f206c6f77000000000000000000000000005f82015250565b5f62000e2960138362000de3565b915062000e368262000df3565b602082019050919050565b5f6020820190508181035f83015262000e5a8162000e1b565b9050919050565b5f6020828403121562000e795762000e7862000943565b5b5f62000e888482850162000992565b91505092915050565b5f60408201905062000ea65f83018562000db7565b62000eb5602083018462000db7565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f62000ef582620009a8565b915062000f0283620009a8565b925082820190508082111562000f1d5762000f1c62000ebc565b5b92915050565b62000f2e81620009a8565b82525050565b5f60608201905062000f495f83018662000db7565b62000f58602083018562000f23565b62000f67604083018462000f23565b949350505050565b5f60208201905062000f845f83018462000f23565b92915050565b6134648062000f985f395ff3fe6080604052600436106101c4575f3560e01c80635735c7fb116100f6578063ab6a8b1c11610094578063e747f82b11610063578063e747f82b1461060f578063f242ab4114610639578063f2fde38b14610663578063f74568cc1461068b576101cb565b8063ab6a8b1c14610559578063ae1a374014610581578063bd51f245146105ab578063dd62ed3e146105d3576101cb565b8063715018a6116100d0578063715018a6146104b35780638da5cb5b146104c957806395d89b41146104f3578063a9059cbb1461051d576101cb565b80635735c7fb14610425578063681aa3621461044d57806370a0823114610477576101cb565b806318160ddd116101635780633ea6e0711161013d5780633ea6e0711461037f5780633fb0da64146103a75780634ada218b146103d15780634cf1115d146103fb576101cb565b806318160ddd146102ef57806323b872dd14610319578063313ce56714610355576101cb565b80630758d9241161019f5780630758d9241461024957806308b1fd8f14610273578063095ea7b31461029d5780630bd05b69146102d9576101cb565b8062ae3bf8146101cf57806304824e70146101f757806306fdde031461021f576101cb565b366101cb57005b5f80fd5b3480156101da575f80fd5b506101f560048036038101906101f09190612485565b6106b3565b005b348015610202575f80fd5b5061021d600480360381019061021891906124eb565b6107e7565b005b34801561022a575f80fd5b5061023361091b565b60405161024091906125a0565b60405180910390f35b348015610254575f80fd5b5061025d6109ab565b60405161026a919061261b565b60405180910390f35b34801561027e575f80fd5b506102876109d0565b6040516102949190612643565b60405180910390f35b3480156102a8575f80fd5b506102c360048036038101906102be919061268f565b6109f5565b6040516102d091906126e7565b60405180910390f35b3480156102e4575f80fd5b506102ed610a17565b005b3480156102fa575f80fd5b50610303610ac4565b604051610310919061270f565b60405180910390f35b348015610324575f80fd5b5061033f600480360381019061033a9190612728565b610acd565b60405161034c91906126e7565b60405180910390f35b348015610360575f80fd5b50610369610afb565b6040516103769190612793565b60405180910390f35b34801561038a575f80fd5b506103a560048036038101906103a091906127d6565b610b03565b005b3480156103b2575f80fd5b506103bb610b9c565b6040516103c8919061270f565b60405180910390f35b3480156103dc575f80fd5b506103e5610ba2565b6040516103f291906126e7565b60405180910390f35b348015610406575f80fd5b5061040f610bb5565b60405161041c919061270f565b60405180910390f35b348015610430575f80fd5b5061044b60048036038101906104469190612485565b610bbb565b005b348015610458575f80fd5b50610461610c74565b60405161046e919061270f565b60405180910390f35b348015610482575f80fd5b5061049d60048036038101906104989190612485565b610c7a565b6040516104aa919061270f565b60405180910390f35b3480156104be575f80fd5b506104c7610cbf565b005b3480156104d4575f80fd5b506104dd610cd2565b6040516104ea9190612643565b60405180910390f35b3480156104fe575f80fd5b50610507610cfa565b60405161051491906125a0565b60405180910390f35b348015610528575f80fd5b50610543600480360381019061053e919061268f565b610d8a565b60405161055091906126e7565b60405180910390f35b348015610564575f80fd5b5061057f600480360381019061057a9190612814565b610dac565b005b34801561058c575f80fd5b50610595610eb5565b6040516105a2919061270f565b60405180910390f35b3480156105b6575f80fd5b506105d160048036038101906105cc9190612852565b610ebb565b005b3480156105de575f80fd5b506105f960048036038101906105f4919061287d565b610f0f565b604051610606919061270f565b60405180910390f35b34801561061a575f80fd5b50610623610f91565b604051610630919061270f565b60405180910390f35b348015610644575f80fd5b5061064d610f97565b60405161065a9190612643565b60405180910390f35b34801561066e575f80fd5b5061068960048036038101906106849190612485565b610fbc565b005b348015610696575f80fd5b506106b160048036038101906106ac9190612852565b611040565b005b6106bb611089565b5f8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016106f59190612643565b602060405180830381865afa158015610710573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061073491906128cf565b90505f8111610778576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076f90612944565b60405180910390fd5b6107aa610783610cd2565b828473ffffffffffffffffffffffffffffffffffffffff166111109092919063ffffffff16565b7fc5d689286306e39777c305b4285e1bc86363039b612af79f65a09e2d185c3b6382826040516107db929190612962565b60405180910390a15050565b6107ef611089565b5f4790505f8111610835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161082c906129d3565b60405180910390fd5b5f8273ffffffffffffffffffffffffffffffffffffffff168260405161085a90612a1e565b5f6040518083038185875af1925050503d805f8114610894576040519150601f19603f3d011682016040523d82523d5f602084013e610899565b606091505b50509050806108dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d490612a7c565b60405180910390fd5b7f41fdd680478135993bc53fb2ffaf9560951b57ef62ff6badd02b61e018b4f17f838360405161090e929190612aba565b60405180910390a1505050565b60606003805461092a90612b0e565b80601f016020809104026020016040519081016040528092919081815260200182805461095690612b0e565b80156109a15780601f10610978576101008083540402835291602001916109a1565b820191905f5260205f20905b81548152906001019060200180831161098457829003601f168201915b5050505050905090565b60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f806109ff61118f565b9050610a0c818585611196565b600191505092915050565b610a1f611089565b600f60149054906101000a900460ff1615610a6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6690612b88565b60405180910390fd5b6001600f60146101000a81548160ff0219169083151502179055507f10cbdaa9da572a6586325ac920fff5d091e67fb26d94180f7b6376cbcda1a09e6001604051610aba91906126e7565b60405180910390a1565b5f600254905090565b5f80610ad761118f565b9050610ae48582856111a8565b610aef85858561123b565b60019150509392505050565b5f6012905090565b610b0b611089565b8060105f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055507f6c3adfee332544f29232690459f4fe23a1c9573efbaac65c9fc033355fb413f08282604051610b90929190612ba6565b60405180910390a15050565b600b5481565b600f60149054906101000a900460ff1681565b600c5481565b610bc3611089565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c31576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2890612c17565b60405180910390fd5b80600f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60095481565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610cc7611089565b610cd05f6117cb565b565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060048054610d0990612b0e565b80601f0160208091040260200160405190810160405280929190818152602001828054610d3590612b0e565b8015610d805780601f10610d5757610100808354040283529160200191610d80565b820191905f5260205f20905b815481529060010190602001808311610d6357829003601f168201915b5050505050905090565b5f80610d9461118f565b9050610da181858561123b565b600191505092915050565b610db4611089565b5f8183610dc19190612c62565b90505f8111610e05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dfc90612cdf565b60405180910390fd5b6064600a54610e149190612d2a565b811115610e56576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4d90612da4565b60405180910390fd5b82600c8190555081600b81905550606481610e719190612dc2565b600a819055507f82754e7bf8e3395ddb4a767c52b21ed0c3b9da843001b2e07ab46f2580323457600a54604051610ea8919061270f565b60405180910390a1505050565b600a5481565b610ec3611089565b5f8111610f05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610efc90612e4d565b60405180910390fd5b8060088190555050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b60085481565b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610fc4611089565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611034575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161102b9190612643565b60405180910390fd5b61103d816117cb565b50565b611048611089565b806009819055507fa53407ff336a78b145e1a297adce2a5d7a54e6c31d13b4e69e04aad80b07b44b8160405161107e919061270f565b60405180910390a150565b61109161118f565b73ffffffffffffffffffffffffffffffffffffffff166110af610cd2565b73ffffffffffffffffffffffffffffffffffffffff161461110e576110d261118f565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016111059190612643565b60405180910390fd5b565b61118a838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401611143929190612962565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061188e565b505050565b5f33905090565b6111a38383836001611929565b505050565b5f6111b38484610f0f565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8110156112355781811015611226578281836040517ffb8f41b200000000000000000000000000000000000000000000000000000000815260040161121d93929190612e6b565b60405180910390fd5b61123484848484035f611929565b5b50505050565b5f811161127d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127490612f10565b60405180910390fd5b60105f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16158061131a575060105f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16155b1561136f57600f60149054906101000a900460ff1661136e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136590612f78565b60405180910390fd5b5b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148015611419575060065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b801561146c575060105f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16155b156114d65761271060095461147f610ac4565b6114899190612dc2565b6114939190612d2a565b8211156114d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114cc90612fe0565b60405180910390fd5b5b60105f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff161580611573575060105f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16155b80156115ab57503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614155b801561165a575060075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611659575060075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b5b801561166757505f600a54115b1561169557612710600a548361167d9190612dc2565b6116879190612d2a565b9050611694843083611af8565b5b600f60159054906101000a900460ff161580156116fe575060075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b8015611751575060105f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16155b156117af575f61176030610c7a565b905060085481106117ad575f600560085461177b9190612d2a565b6008546117889190612c62565b905080821061179f5761179a81611be8565b6117ab565b6117aa600854611be8565b5b505b505b6117c5848483856117c09190612ffe565b611af8565b50505050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f8060205f8451602086015f885af1806118ad576040513d5f823e3d81fd5b3d92505f519150505f82146118c65760018114156118e1565b5f8473ffffffffffffffffffffffffffffffffffffffff163b145b1561192357836040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161191a9190612643565b60405180910390fd5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611999575f6040517fe602df050000000000000000000000000000000000000000000000000000000081526004016119909190612643565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611a09575f6040517f94280d62000000000000000000000000000000000000000000000000000000008152600401611a009190612643565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508015611af2578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051611ae9919061270f565b60405180910390a35b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611b68575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401611b5f9190612643565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611bd8575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401611bcf9190612643565b60405180910390fd5b611be3838383611edd565b505050565b600f60159054906101000a900460ff1615611c38576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2f9061307b565b60405180910390fd5b6001600f60156101000a81548160ff0219169083151502179055505f600c54148015611c6557505f600b54145b611ec0575f4790505f6064600a54611c7d9190612d2a565b90505f8111611cc1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cb8906130e3565b60405180910390fd5b5f81600c5485611cd19190612dc2565b611cdb9190612d2a565b90505f82600b5486611ced9190612dc2565b611cf79190612d2a565b90505f600282611d079190612d2a565b83611d129190612c62565b90505f600283611d229190612d2a565b83611d2d9190612ffe565b9050611d38826120f6565b5f8647611d459190612ffe565b90505f808411611d55575f611d79565b83600286611d639190612d2a565b83611d6e9190612dc2565b611d789190612d2a565b5b90505f8183611d889190612ffe565b90505f84118015611d9857505f82115b15611da857611da78483612335565b5b5f811115611e7b575f600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1682604051611df690612a1e565b5f6040518083038185875af1925050503d805f8114611e30576040519150601f19603f3d011682016040523d82523d5f602084013e611e35565b606091505b5050905080611e79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e709061314b565b60405180910390fd5b505b7fc5ab292b8c9ba63f89c2db518001d87ec0d51236f410bfb5c7e733f8022fce8b858584604051611eae93929190613169565b60405180910390a15050505050505050505b5f600f60156101000a81548160ff02191690831515021790555050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611f2d578060025f828254611f219190612c62565b92505081905550611ffb565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015611fb6578381836040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401611fad93929190612e6b565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612042578060025f828254039250508190555061208c565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516120e9919061270f565b60405180910390a3505050565b5f810315612332575f600267ffffffffffffffff81111561211a5761211961319e565b5b6040519080825280602002602001820160405280156121485781602001602082028036833780820191505090505b50905030815f8151811061215f5761215e6131cb565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015612203573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612227919061320c565b8160018151811061223b5761223a6131cb565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506122a13060065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684611196565b60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663791ac947835f8430426040518663ffffffff1660e01b8152600401612303959493929190613327565b5f604051808303815f87803b15801561231a575f80fd5b505af115801561232c573d5f803e3d5ffd5b50505050505b50565b5f82148061234257505f81145b612423576123723060065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684611196565b60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f305d7198230855f806123bc610cd2565b426040518863ffffffff1660e01b81526004016123de9695949392919061337f565b60606040518083038185885af11580156123fa573d5f803e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061241f91906133de565b5050505b5050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6124548261242b565b9050919050565b6124648161244a565b811461246e575f80fd5b50565b5f8135905061247f8161245b565b92915050565b5f6020828403121561249a57612499612427565b5b5f6124a784828501612471565b91505092915050565b5f6124ba8261242b565b9050919050565b6124ca816124b0565b81146124d4575f80fd5b50565b5f813590506124e5816124c1565b92915050565b5f60208284031215612500576124ff612427565b5b5f61250d848285016124d7565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561254d578082015181840152602081019050612532565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61257282612516565b61257c8185612520565b935061258c818560208601612530565b61259581612558565b840191505092915050565b5f6020820190508181035f8301526125b88184612568565b905092915050565b5f819050919050565b5f6125e36125de6125d98461242b565b6125c0565b61242b565b9050919050565b5f6125f4826125c9565b9050919050565b5f612605826125ea565b9050919050565b612615816125fb565b82525050565b5f60208201905061262e5f83018461260c565b92915050565b61263d8161244a565b82525050565b5f6020820190506126565f830184612634565b92915050565b5f819050919050565b61266e8161265c565b8114612678575f80fd5b50565b5f8135905061268981612665565b92915050565b5f80604083850312156126a5576126a4612427565b5b5f6126b285828601612471565b92505060206126c38582860161267b565b9150509250929050565b5f8115159050919050565b6126e1816126cd565b82525050565b5f6020820190506126fa5f8301846126d8565b92915050565b6127098161265c565b82525050565b5f6020820190506127225f830184612700565b92915050565b5f805f6060848603121561273f5761273e612427565b5b5f61274c86828701612471565b935050602061275d86828701612471565b925050604061276e8682870161267b565b9150509250925092565b5f60ff82169050919050565b61278d81612778565b82525050565b5f6020820190506127a65f830184612784565b92915050565b6127b5816126cd565b81146127bf575f80fd5b50565b5f813590506127d0816127ac565b92915050565b5f80604083850312156127ec576127eb612427565b5b5f6127f985828601612471565b925050602061280a858286016127c2565b9150509250929050565b5f806040838503121561282a57612829612427565b5b5f6128378582860161267b565b92505060206128488582860161267b565b9150509250929050565b5f6020828403121561286757612866612427565b5b5f6128748482850161267b565b91505092915050565b5f806040838503121561289357612892612427565b5b5f6128a085828601612471565b92505060206128b185828601612471565b9150509250929050565b5f815190506128c981612665565b92915050565b5f602082840312156128e4576128e3612427565b5b5f6128f1848285016128bb565b91505092915050565b7f4e6f20746f6b656e7320617661696c61626c65000000000000000000000000005f82015250565b5f61292e601383612520565b9150612939826128fa565b602082019050919050565b5f6020820190508181035f83015261295b81612922565b9050919050565b5f6040820190506129755f830185612634565b6129826020830184612700565b9392505050565b7f4e6f2045544820617661696c61626c65000000000000000000000000000000005f82015250565b5f6129bd601083612520565b91506129c882612989565b602082019050919050565b5f6020820190508181035f8301526129ea816129b1565b9050919050565b5f81905092915050565b50565b5f612a095f836129f1565b9150612a14826129fb565b5f82019050919050565b5f612a28826129fe565b9150819050919050565b7f455448207472616e73666572206661696c6564000000000000000000000000005f82015250565b5f612a66601383612520565b9150612a7182612a32565b602082019050919050565b5f6020820190508181035f830152612a9381612a5a565b9050919050565b5f612aa4826125ea565b9050919050565b612ab481612a9a565b82525050565b5f604082019050612acd5f830185612aab565b612ada6020830184612700565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680612b2557607f821691505b602082108103612b3857612b37612ae1565b5b50919050565b7f416c7265616479206163746976650000000000000000000000000000000000005f82015250565b5f612b72600e83612520565b9150612b7d82612b3e565b602082019050919050565b5f6020820190508181035f830152612b9f81612b66565b9050919050565b5f604082019050612bb95f830185612634565b612bc660208301846126d8565b9392505050565b7f496e76616c6964206164647265737300000000000000000000000000000000005f82015250565b5f612c01600f83612520565b9150612c0c82612bcd565b602082019050919050565b5f6020820190508181035f830152612c2e81612bf5565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612c6c8261265c565b9150612c778361265c565b9250828201905080821115612c8f57612c8e612c35565b5b92915050565b7f546f74616c2074617820726174652063616e6e6f74206265207a65726f0000005f82015250565b5f612cc9601d83612520565b9150612cd482612c95565b602082019050919050565b5f6020820190508181035f830152612cf681612cbd565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f612d348261265c565b9150612d3f8361265c565b925082612d4f57612d4e612cfd565b5b828204905092915050565b7f546178206d7573742062652072656475636564000000000000000000000000005f82015250565b5f612d8e601383612520565b9150612d9982612d5a565b602082019050919050565b5f6020820190508181035f830152612dbb81612d82565b9050919050565b5f612dcc8261265c565b9150612dd78361265c565b9250828202612de58161265c565b91508282048414831517612dfc57612dfb612c35565b5b5092915050565b7f496e76616c696420616d6f756e740000000000000000000000000000000000005f82015250565b5f612e37600e83612520565b9150612e4282612e03565b602082019050919050565b5f6020820190508181035f830152612e6481612e2b565b9050919050565b5f606082019050612e7e5f830186612634565b612e8b6020830185612700565b612e986040830184612700565b949350505050565b7f5472616e7366657220616d6f756e74206d7573742062652067726561746572205f8201527f7468616e20300000000000000000000000000000000000000000000000000000602082015250565b5f612efa602683612520565b9150612f0582612ea0565b604082019050919050565b5f6020820190508181035f830152612f2781612eee565b9050919050565b7f54726164696e67206973206e6f742079657420656e61626c65640000000000005f82015250565b5f612f62601a83612520565b9150612f6d82612f2e565b602082019050919050565b5f6020820190508181035f830152612f8f81612f56565b9050919050565b7f54786e2065786365656473206c696d69740000000000000000000000000000005f82015250565b5f612fca601183612520565b9150612fd582612f96565b602082019050919050565b5f6020820190508181035f830152612ff781612fbe565b9050919050565b5f6130088261265c565b91506130138361265c565b925082820390508181111561302b5761302a612c35565b5b92915050565b7f5377617020696e2070726f6772657373000000000000000000000000000000005f82015250565b5f613065601083612520565b915061307082613031565b602082019050919050565b5f6020820190508181035f83015261309281613059565b9050919050565b7f496e76616c6964207461782072617465000000000000000000000000000000005f82015250565b5f6130cd601083612520565b91506130d882613099565b602082019050919050565b5f6020820190508181035f8301526130fa816130c1565b9050919050565b7f5472656173757279207472616e73666572206661696c656400000000000000005f82015250565b5f613135601883612520565b915061314082613101565b602082019050919050565b5f6020820190508181035f83015261316281613129565b9050919050565b5f60608201905061317c5f830186612700565b6131896020830185612700565b6131966040830184612700565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f815190506132068161245b565b92915050565b5f6020828403121561322157613220612427565b5b5f61322e848285016131f8565b91505092915050565b5f819050919050565b5f61325a61325561325084613237565b6125c0565b61265c565b9050919050565b61326a81613240565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6132a28161244a565b82525050565b5f6132b38383613299565b60208301905092915050565b5f602082019050919050565b5f6132d582613270565b6132df818561327a565b93506132ea8361328a565b805f5b8381101561331a57815161330188826132a8565b975061330c836132bf565b9250506001810190506132ed565b5085935050505092915050565b5f60a08201905061333a5f830188612700565b6133476020830187613261565b818103604083015261335981866132cb565b90506133686060830185612634565b6133756080830184612700565b9695505050505050565b5f60c0820190506133925f830189612634565b61339f6020830188612700565b6133ac6040830187613261565b6133b96060830186613261565b6133c66080830185612634565b6133d360a0830184612700565b979650505050505050565b5f805f606084860312156133f5576133f4612427565b5b5f613402868287016128bb565b9350506020613413868287016128bb565b9250506040613424868287016128bb565b915050925092509256fea2646970667358221220be0dd35313c532e00a35eb32a589a23d39314f10e2e7f980130c0f3691440e1a64736f6c634300081400330000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003200000000000000000000000033fab74ee3852d60eb48a430bf7fd4644a786096

Deployed Bytecode

0x6080604052600436106101c4575f3560e01c80635735c7fb116100f6578063ab6a8b1c11610094578063e747f82b11610063578063e747f82b1461060f578063f242ab4114610639578063f2fde38b14610663578063f74568cc1461068b576101cb565b8063ab6a8b1c14610559578063ae1a374014610581578063bd51f245146105ab578063dd62ed3e146105d3576101cb565b8063715018a6116100d0578063715018a6146104b35780638da5cb5b146104c957806395d89b41146104f3578063a9059cbb1461051d576101cb565b80635735c7fb14610425578063681aa3621461044d57806370a0823114610477576101cb565b806318160ddd116101635780633ea6e0711161013d5780633ea6e0711461037f5780633fb0da64146103a75780634ada218b146103d15780634cf1115d146103fb576101cb565b806318160ddd146102ef57806323b872dd14610319578063313ce56714610355576101cb565b80630758d9241161019f5780630758d9241461024957806308b1fd8f14610273578063095ea7b31461029d5780630bd05b69146102d9576101cb565b8062ae3bf8146101cf57806304824e70146101f757806306fdde031461021f576101cb565b366101cb57005b5f80fd5b3480156101da575f80fd5b506101f560048036038101906101f09190612485565b6106b3565b005b348015610202575f80fd5b5061021d600480360381019061021891906124eb565b6107e7565b005b34801561022a575f80fd5b5061023361091b565b60405161024091906125a0565b60405180910390f35b348015610254575f80fd5b5061025d6109ab565b60405161026a919061261b565b60405180910390f35b34801561027e575f80fd5b506102876109d0565b6040516102949190612643565b60405180910390f35b3480156102a8575f80fd5b506102c360048036038101906102be919061268f565b6109f5565b6040516102d091906126e7565b60405180910390f35b3480156102e4575f80fd5b506102ed610a17565b005b3480156102fa575f80fd5b50610303610ac4565b604051610310919061270f565b60405180910390f35b348015610324575f80fd5b5061033f600480360381019061033a9190612728565b610acd565b60405161034c91906126e7565b60405180910390f35b348015610360575f80fd5b50610369610afb565b6040516103769190612793565b60405180910390f35b34801561038a575f80fd5b506103a560048036038101906103a091906127d6565b610b03565b005b3480156103b2575f80fd5b506103bb610b9c565b6040516103c8919061270f565b60405180910390f35b3480156103dc575f80fd5b506103e5610ba2565b6040516103f291906126e7565b60405180910390f35b348015610406575f80fd5b5061040f610bb5565b60405161041c919061270f565b60405180910390f35b348015610430575f80fd5b5061044b60048036038101906104469190612485565b610bbb565b005b348015610458575f80fd5b50610461610c74565b60405161046e919061270f565b60405180910390f35b348015610482575f80fd5b5061049d60048036038101906104989190612485565b610c7a565b6040516104aa919061270f565b60405180910390f35b3480156104be575f80fd5b506104c7610cbf565b005b3480156104d4575f80fd5b506104dd610cd2565b6040516104ea9190612643565b60405180910390f35b3480156104fe575f80fd5b50610507610cfa565b60405161051491906125a0565b60405180910390f35b348015610528575f80fd5b50610543600480360381019061053e919061268f565b610d8a565b60405161055091906126e7565b60405180910390f35b348015610564575f80fd5b5061057f600480360381019061057a9190612814565b610dac565b005b34801561058c575f80fd5b50610595610eb5565b6040516105a2919061270f565b60405180910390f35b3480156105b6575f80fd5b506105d160048036038101906105cc9190612852565b610ebb565b005b3480156105de575f80fd5b506105f960048036038101906105f4919061287d565b610f0f565b604051610606919061270f565b60405180910390f35b34801561061a575f80fd5b50610623610f91565b604051610630919061270f565b60405180910390f35b348015610644575f80fd5b5061064d610f97565b60405161065a9190612643565b60405180910390f35b34801561066e575f80fd5b5061068960048036038101906106849190612485565b610fbc565b005b348015610696575f80fd5b506106b160048036038101906106ac9190612852565b611040565b005b6106bb611089565b5f8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016106f59190612643565b602060405180830381865afa158015610710573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061073491906128cf565b90505f8111610778576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076f90612944565b60405180910390fd5b6107aa610783610cd2565b828473ffffffffffffffffffffffffffffffffffffffff166111109092919063ffffffff16565b7fc5d689286306e39777c305b4285e1bc86363039b612af79f65a09e2d185c3b6382826040516107db929190612962565b60405180910390a15050565b6107ef611089565b5f4790505f8111610835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161082c906129d3565b60405180910390fd5b5f8273ffffffffffffffffffffffffffffffffffffffff168260405161085a90612a1e565b5f6040518083038185875af1925050503d805f8114610894576040519150601f19603f3d011682016040523d82523d5f602084013e610899565b606091505b50509050806108dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d490612a7c565b60405180910390fd5b7f41fdd680478135993bc53fb2ffaf9560951b57ef62ff6badd02b61e018b4f17f838360405161090e929190612aba565b60405180910390a1505050565b60606003805461092a90612b0e565b80601f016020809104026020016040519081016040528092919081815260200182805461095690612b0e565b80156109a15780601f10610978576101008083540402835291602001916109a1565b820191905f5260205f20905b81548152906001019060200180831161098457829003601f168201915b5050505050905090565b60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f806109ff61118f565b9050610a0c818585611196565b600191505092915050565b610a1f611089565b600f60149054906101000a900460ff1615610a6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6690612b88565b60405180910390fd5b6001600f60146101000a81548160ff0219169083151502179055507f10cbdaa9da572a6586325ac920fff5d091e67fb26d94180f7b6376cbcda1a09e6001604051610aba91906126e7565b60405180910390a1565b5f600254905090565b5f80610ad761118f565b9050610ae48582856111a8565b610aef85858561123b565b60019150509392505050565b5f6012905090565b610b0b611089565b8060105f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055507f6c3adfee332544f29232690459f4fe23a1c9573efbaac65c9fc033355fb413f08282604051610b90929190612ba6565b60405180910390a15050565b600b5481565b600f60149054906101000a900460ff1681565b600c5481565b610bc3611089565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c31576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2890612c17565b60405180910390fd5b80600f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60095481565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610cc7611089565b610cd05f6117cb565b565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060048054610d0990612b0e565b80601f0160208091040260200160405190810160405280929190818152602001828054610d3590612b0e565b8015610d805780601f10610d5757610100808354040283529160200191610d80565b820191905f5260205f20905b815481529060010190602001808311610d6357829003601f168201915b5050505050905090565b5f80610d9461118f565b9050610da181858561123b565b600191505092915050565b610db4611089565b5f8183610dc19190612c62565b90505f8111610e05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dfc90612cdf565b60405180910390fd5b6064600a54610e149190612d2a565b811115610e56576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4d90612da4565b60405180910390fd5b82600c8190555081600b81905550606481610e719190612dc2565b600a819055507f82754e7bf8e3395ddb4a767c52b21ed0c3b9da843001b2e07ab46f2580323457600a54604051610ea8919061270f565b60405180910390a1505050565b600a5481565b610ec3611089565b5f8111610f05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610efc90612e4d565b60405180910390fd5b8060088190555050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b60085481565b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610fc4611089565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611034575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161102b9190612643565b60405180910390fd5b61103d816117cb565b50565b611048611089565b806009819055507fa53407ff336a78b145e1a297adce2a5d7a54e6c31d13b4e69e04aad80b07b44b8160405161107e919061270f565b60405180910390a150565b61109161118f565b73ffffffffffffffffffffffffffffffffffffffff166110af610cd2565b73ffffffffffffffffffffffffffffffffffffffff161461110e576110d261118f565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016111059190612643565b60405180910390fd5b565b61118a838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401611143929190612962565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061188e565b505050565b5f33905090565b6111a38383836001611929565b505050565b5f6111b38484610f0f565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8110156112355781811015611226578281836040517ffb8f41b200000000000000000000000000000000000000000000000000000000815260040161121d93929190612e6b565b60405180910390fd5b61123484848484035f611929565b5b50505050565b5f811161127d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127490612f10565b60405180910390fd5b60105f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16158061131a575060105f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16155b1561136f57600f60149054906101000a900460ff1661136e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136590612f78565b60405180910390fd5b5b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148015611419575060065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b801561146c575060105f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16155b156114d65761271060095461147f610ac4565b6114899190612dc2565b6114939190612d2a565b8211156114d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114cc90612fe0565b60405180910390fd5b5b60105f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff161580611573575060105f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16155b80156115ab57503073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614155b801561165a575060075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611659575060075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b5b801561166757505f600a54115b1561169557612710600a548361167d9190612dc2565b6116879190612d2a565b9050611694843083611af8565b5b600f60159054906101000a900460ff161580156116fe575060075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b8015611751575060105f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16155b156117af575f61176030610c7a565b905060085481106117ad575f600560085461177b9190612d2a565b6008546117889190612c62565b905080821061179f5761179a81611be8565b6117ab565b6117aa600854611be8565b5b505b505b6117c5848483856117c09190612ffe565b611af8565b50505050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f8060205f8451602086015f885af1806118ad576040513d5f823e3d81fd5b3d92505f519150505f82146118c65760018114156118e1565b5f8473ffffffffffffffffffffffffffffffffffffffff163b145b1561192357836040517f5274afe700000000000000000000000000000000000000000000000000000000815260040161191a9190612643565b60405180910390fd5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611999575f6040517fe602df050000000000000000000000000000000000000000000000000000000081526004016119909190612643565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611a09575f6040517f94280d62000000000000000000000000000000000000000000000000000000008152600401611a009190612643565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508015611af2578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051611ae9919061270f565b60405180910390a35b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611b68575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401611b5f9190612643565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611bd8575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401611bcf9190612643565b60405180910390fd5b611be3838383611edd565b505050565b600f60159054906101000a900460ff1615611c38576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2f9061307b565b60405180910390fd5b6001600f60156101000a81548160ff0219169083151502179055505f600c54148015611c6557505f600b54145b611ec0575f4790505f6064600a54611c7d9190612d2a565b90505f8111611cc1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cb8906130e3565b60405180910390fd5b5f81600c5485611cd19190612dc2565b611cdb9190612d2a565b90505f82600b5486611ced9190612dc2565b611cf79190612d2a565b90505f600282611d079190612d2a565b83611d129190612c62565b90505f600283611d229190612d2a565b83611d2d9190612ffe565b9050611d38826120f6565b5f8647611d459190612ffe565b90505f808411611d55575f611d79565b83600286611d639190612d2a565b83611d6e9190612dc2565b611d789190612d2a565b5b90505f8183611d889190612ffe565b90505f84118015611d9857505f82115b15611da857611da78483612335565b5b5f811115611e7b575f600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1682604051611df690612a1e565b5f6040518083038185875af1925050503d805f8114611e30576040519150601f19603f3d011682016040523d82523d5f602084013e611e35565b606091505b5050905080611e79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e709061314b565b60405180910390fd5b505b7fc5ab292b8c9ba63f89c2db518001d87ec0d51236f410bfb5c7e733f8022fce8b858584604051611eae93929190613169565b60405180910390a15050505050505050505b5f600f60156101000a81548160ff02191690831515021790555050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611f2d578060025f828254611f219190612c62565b92505081905550611ffb565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015611fb6578381836040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401611fad93929190612e6b565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612042578060025f828254039250508190555061208c565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516120e9919061270f565b60405180910390a3505050565b5f810315612332575f600267ffffffffffffffff81111561211a5761211961319e565b5b6040519080825280602002602001820160405280156121485781602001602082028036833780820191505090505b50905030815f8151811061215f5761215e6131cb565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015612203573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612227919061320c565b8160018151811061223b5761223a6131cb565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506122a13060065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684611196565b60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663791ac947835f8430426040518663ffffffff1660e01b8152600401612303959493929190613327565b5f604051808303815f87803b15801561231a575f80fd5b505af115801561232c573d5f803e3d5ffd5b50505050505b50565b5f82148061234257505f81145b612423576123723060065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684611196565b60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f305d7198230855f806123bc610cd2565b426040518863ffffffff1660e01b81526004016123de9695949392919061337f565b60606040518083038185885af11580156123fa573d5f803e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061241f91906133de565b5050505b5050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6124548261242b565b9050919050565b6124648161244a565b811461246e575f80fd5b50565b5f8135905061247f8161245b565b92915050565b5f6020828403121561249a57612499612427565b5b5f6124a784828501612471565b91505092915050565b5f6124ba8261242b565b9050919050565b6124ca816124b0565b81146124d4575f80fd5b50565b5f813590506124e5816124c1565b92915050565b5f60208284031215612500576124ff612427565b5b5f61250d848285016124d7565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561254d578082015181840152602081019050612532565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61257282612516565b61257c8185612520565b935061258c818560208601612530565b61259581612558565b840191505092915050565b5f6020820190508181035f8301526125b88184612568565b905092915050565b5f819050919050565b5f6125e36125de6125d98461242b565b6125c0565b61242b565b9050919050565b5f6125f4826125c9565b9050919050565b5f612605826125ea565b9050919050565b612615816125fb565b82525050565b5f60208201905061262e5f83018461260c565b92915050565b61263d8161244a565b82525050565b5f6020820190506126565f830184612634565b92915050565b5f819050919050565b61266e8161265c565b8114612678575f80fd5b50565b5f8135905061268981612665565b92915050565b5f80604083850312156126a5576126a4612427565b5b5f6126b285828601612471565b92505060206126c38582860161267b565b9150509250929050565b5f8115159050919050565b6126e1816126cd565b82525050565b5f6020820190506126fa5f8301846126d8565b92915050565b6127098161265c565b82525050565b5f6020820190506127225f830184612700565b92915050565b5f805f6060848603121561273f5761273e612427565b5b5f61274c86828701612471565b935050602061275d86828701612471565b925050604061276e8682870161267b565b9150509250925092565b5f60ff82169050919050565b61278d81612778565b82525050565b5f6020820190506127a65f830184612784565b92915050565b6127b5816126cd565b81146127bf575f80fd5b50565b5f813590506127d0816127ac565b92915050565b5f80604083850312156127ec576127eb612427565b5b5f6127f985828601612471565b925050602061280a858286016127c2565b9150509250929050565b5f806040838503121561282a57612829612427565b5b5f6128378582860161267b565b92505060206128488582860161267b565b9150509250929050565b5f6020828403121561286757612866612427565b5b5f6128748482850161267b565b91505092915050565b5f806040838503121561289357612892612427565b5b5f6128a085828601612471565b92505060206128b185828601612471565b9150509250929050565b5f815190506128c981612665565b92915050565b5f602082840312156128e4576128e3612427565b5b5f6128f1848285016128bb565b91505092915050565b7f4e6f20746f6b656e7320617661696c61626c65000000000000000000000000005f82015250565b5f61292e601383612520565b9150612939826128fa565b602082019050919050565b5f6020820190508181035f83015261295b81612922565b9050919050565b5f6040820190506129755f830185612634565b6129826020830184612700565b9392505050565b7f4e6f2045544820617661696c61626c65000000000000000000000000000000005f82015250565b5f6129bd601083612520565b91506129c882612989565b602082019050919050565b5f6020820190508181035f8301526129ea816129b1565b9050919050565b5f81905092915050565b50565b5f612a095f836129f1565b9150612a14826129fb565b5f82019050919050565b5f612a28826129fe565b9150819050919050565b7f455448207472616e73666572206661696c6564000000000000000000000000005f82015250565b5f612a66601383612520565b9150612a7182612a32565b602082019050919050565b5f6020820190508181035f830152612a9381612a5a565b9050919050565b5f612aa4826125ea565b9050919050565b612ab481612a9a565b82525050565b5f604082019050612acd5f830185612aab565b612ada6020830184612700565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680612b2557607f821691505b602082108103612b3857612b37612ae1565b5b50919050565b7f416c7265616479206163746976650000000000000000000000000000000000005f82015250565b5f612b72600e83612520565b9150612b7d82612b3e565b602082019050919050565b5f6020820190508181035f830152612b9f81612b66565b9050919050565b5f604082019050612bb95f830185612634565b612bc660208301846126d8565b9392505050565b7f496e76616c6964206164647265737300000000000000000000000000000000005f82015250565b5f612c01600f83612520565b9150612c0c82612bcd565b602082019050919050565b5f6020820190508181035f830152612c2e81612bf5565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612c6c8261265c565b9150612c778361265c565b9250828201905080821115612c8f57612c8e612c35565b5b92915050565b7f546f74616c2074617820726174652063616e6e6f74206265207a65726f0000005f82015250565b5f612cc9601d83612520565b9150612cd482612c95565b602082019050919050565b5f6020820190508181035f830152612cf681612cbd565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f612d348261265c565b9150612d3f8361265c565b925082612d4f57612d4e612cfd565b5b828204905092915050565b7f546178206d7573742062652072656475636564000000000000000000000000005f82015250565b5f612d8e601383612520565b9150612d9982612d5a565b602082019050919050565b5f6020820190508181035f830152612dbb81612d82565b9050919050565b5f612dcc8261265c565b9150612dd78361265c565b9250828202612de58161265c565b91508282048414831517612dfc57612dfb612c35565b5b5092915050565b7f496e76616c696420616d6f756e740000000000000000000000000000000000005f82015250565b5f612e37600e83612520565b9150612e4282612e03565b602082019050919050565b5f6020820190508181035f830152612e6481612e2b565b9050919050565b5f606082019050612e7e5f830186612634565b612e8b6020830185612700565b612e986040830184612700565b949350505050565b7f5472616e7366657220616d6f756e74206d7573742062652067726561746572205f8201527f7468616e20300000000000000000000000000000000000000000000000000000602082015250565b5f612efa602683612520565b9150612f0582612ea0565b604082019050919050565b5f6020820190508181035f830152612f2781612eee565b9050919050565b7f54726164696e67206973206e6f742079657420656e61626c65640000000000005f82015250565b5f612f62601a83612520565b9150612f6d82612f2e565b602082019050919050565b5f6020820190508181035f830152612f8f81612f56565b9050919050565b7f54786e2065786365656473206c696d69740000000000000000000000000000005f82015250565b5f612fca601183612520565b9150612fd582612f96565b602082019050919050565b5f6020820190508181035f830152612ff781612fbe565b9050919050565b5f6130088261265c565b91506130138361265c565b925082820390508181111561302b5761302a612c35565b5b92915050565b7f5377617020696e2070726f6772657373000000000000000000000000000000005f82015250565b5f613065601083612520565b915061307082613031565b602082019050919050565b5f6020820190508181035f83015261309281613059565b9050919050565b7f496e76616c6964207461782072617465000000000000000000000000000000005f82015250565b5f6130cd601083612520565b91506130d882613099565b602082019050919050565b5f6020820190508181035f8301526130fa816130c1565b9050919050565b7f5472656173757279207472616e73666572206661696c656400000000000000005f82015250565b5f613135601883612520565b915061314082613101565b602082019050919050565b5f6020820190508181035f83015261316281613129565b9050919050565b5f60608201905061317c5f830186612700565b6131896020830185612700565b6131966040830184612700565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f815190506132068161245b565b92915050565b5f6020828403121561322157613220612427565b5b5f61322e848285016131f8565b91505092915050565b5f819050919050565b5f61325a61325561325084613237565b6125c0565b61265c565b9050919050565b61326a81613240565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6132a28161244a565b82525050565b5f6132b38383613299565b60208301905092915050565b5f602082019050919050565b5f6132d582613270565b6132df818561327a565b93506132ea8361328a565b805f5b8381101561331a57815161330188826132a8565b975061330c836132bf565b9250506001810190506132ed565b5085935050505092915050565b5f60a08201905061333a5f830188612700565b6133476020830187613261565b818103604083015261335981866132cb565b90506133686060830185612634565b6133756080830184612700565b9695505050505050565b5f60c0820190506133925f830189612634565b61339f6020830188612700565b6133ac6040830187613261565b6133b96060830186613261565b6133c66080830185612634565b6133d360a0830184612700565b979650505050505050565b5f805f606084860312156133f5576133f4612427565b5b5f613402868287016128bb565b9350506020613413868287016128bb565b9250506040613424868287016128bb565b915050925092509256fea2646970667358221220be0dd35313c532e00a35eb32a589a23d39314f10e2e7f980130c0f3691440e1a64736f6c63430008140033

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

0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003200000000000000000000000033fab74ee3852d60eb48a430bf7fd4644a786096

-----Decoded View---------------
Arg [0] : _router (address): 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
Arg [1] : _initialTaxRate (uint256): 3000
Arg [2] : _ethFee (uint256): 30
Arg [3] : _liqFee (uint256): 0
Arg [4] : _maxTxn (uint256): 50
Arg [5] : _treasury (address): 0x33FaB74ee3852D60Eb48A430bf7Fd4644A786096

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000bb8
Arg [2] : 000000000000000000000000000000000000000000000000000000000000001e
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000032
Arg [5] : 00000000000000000000000033fab74ee3852d60eb48a430bf7fd4644a786096


Deployed Bytecode Sourcemap

47645:7865:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54690:267;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;54357:325;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;16337:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47721:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48039:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18630:190;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54025:177;;;;;;;;;;;;;:::i;:::-;;17439:99;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;19430:249;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17290:84;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54965:173;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;47913:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48077:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47941:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55322:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;47844:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17601:118;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3532:103;;;;;;;;;;;;;:::i;:::-;;2857:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16547:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17924:182;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53568:449;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;47877:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55146:168;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;18169:142;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47794:43;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47763:22;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3790:220;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;54210:139;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;54690:267;2743:13;:11;:13::i;:::-;54757:11:::1;54778:5;54771:23;;;54803:4;54771:38;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54757:52;;54834:1;54828:3;:7;54820:39;;;;;;;;;;;;:::i;:::-;;;;;;;;;54870:40;54897:7;:5;:7::i;:::-;54906:3;54877:5;54870:26;;;;:40;;;;;:::i;:::-;54926:23;54938:5;54945:3;54926:23;;;;;;;:::i;:::-;;;;;;;;54746:211;54690:267:::0;:::o;54357:325::-;2743:13;:11;:13::i;:::-;54433:11:::1;54447:21;54433:35;;54493:1;54487:3;:7;54479:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;54527:12;54545:9;:14;;54567:3;54545:30;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54526:49;;;54594:7;54586:39;;;;;;;;;;;;:::i;:::-;;;;;;;;;54641:33;54659:9;54670:3;54641:33;;;;;;;:::i;:::-;;;;;;;;54422:260;;54357:325:::0;:::o;16337:91::-;16382:13;16415:5;16408:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16337:91;:::o;47721:35::-;;;;;;;;;;;;;:::o;48039:31::-;;;;;;;;;;;;;:::o;18630:190::-;18703:4;18720:13;18736:12;:10;:12::i;:::-;18720:28;;18759:31;18768:5;18775:7;18784:5;18759:8;:31::i;:::-;18808:4;18801:11;;;18630:190;;;;:::o;54025:177::-;2743:13;:11;:13::i;:::-;54091:14:::1;;;;;;;;;;;54090:15;54082:42;;;;;;;;;;;;:::i;:::-;;;;;;;;;54152:4;54135:14;;:21;;;;;;;;;;;;;;;;;;54172:22;54189:4;54172:22;;;;;;:::i;:::-;;;;;;;;54025:177::o:0;17439:99::-;17491:7;17518:12;;17511:19;;17439:99;:::o;19430:249::-;19517:4;19534:15;19552:12;:10;:12::i;:::-;19534:30;;19575:37;19591:4;19597:7;19606:5;19575:15;:37::i;:::-;19623:26;19633:4;19639:2;19643:5;19623:9;:26::i;:::-;19667:4;19660:11;;;19430:249;;;;;:::o;17290:84::-;17339:5;17364:2;17357:9;;17290:84;:::o;54965:173::-;2743:13;:11;:13::i;:::-;55075:6:::1;55047:16;:25;55064:7;55047:25;;;;;;;;;;;;;;;;:34;;;;;;;;;;;;;;;;;;55097:33;55114:7;55123:6;55097:33;;;;;;;:::i;:::-;;;;;;;;54965:173:::0;;:::o;47913:21::-;;;;:::o;48077:26::-;;;;;;;;;;;;;:::o;47941:21::-;;;;:::o;55322:185::-;2743:13;:11;:13::i;:::-;55436:1:::1;55413:25;;:11;:25;;::::0;55405:53:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;55488:11;55469:16;;:30;;;;;;;;;;;;;;;;;;55322:185:::0;:::o;47844:26::-;;;;:::o;17601:118::-;17666:7;17693:9;:18;17703:7;17693:18;;;;;;;;;;;;;;;;17686:25;;17601:118;;;:::o;3532:103::-;2743:13;:11;:13::i;:::-;3597:30:::1;3624:1;3597:18;:30::i;:::-;3532:103::o:0;2857:87::-;2903:7;2930:6;;;;;;;;;;;2923:13;;2857:87;:::o;16547:95::-;16594:13;16627:7;16620:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16547:95;:::o;17924:182::-;17993:4;18010:13;18026:12;:10;:12::i;:::-;18010:28;;18049:27;18059:5;18066:2;18070:5;18049:9;:27::i;:::-;18094:4;18087:11;;;17924:182;;;;:::o;53568:449::-;2743:13;:11;:13::i;:::-;53685:16:::1;53716:9;53704;:21;;;;:::i;:::-;53685:40;;53755:1;53744:8;:12;53736:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;53837:3;53822:12;;:18;;;;:::i;:::-;53809:8;:32;;53801:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;53887:9;53878:6;:18;;;;53916:9;53907:6;:18;;;;53962:3;53951:8;:14;;;;:::i;:::-;53936:12;:29;;;;53981:28;53996:12;;53981:28;;;;;;:::i;:::-;;;;;;;;53674:343;53568:449:::0;;:::o;47877:27::-;;;;:::o;55146:168::-;2743:13;:11;:13::i;:::-;55247:1:::1;55235:9;:13;55227:40;;;;;;;;;;;;:::i;:::-;;;;;;;;;55297:9;55278:16;:28;;;;55146:168:::0;:::o;18169:142::-;18249:7;18276:11;:18;18288:5;18276:18;;;;;;;;;;;;;;;:27;18295:7;18276:27;;;;;;;;;;;;;;;;18269:34;;18169:142;;;;:::o;47794:43::-;;;;:::o;47763:22::-;;;;;;;;;;;;;:::o;3790:220::-;2743:13;:11;:13::i;:::-;3895:1:::1;3875:22;;:8;:22;;::::0;3871:93:::1;;3949:1;3921:31;;;;;;;;;;;:::i;:::-;;;;;;;;3871:93;3974:28;3993:8;3974:18;:28::i;:::-;3790:220:::0;:::o;54210:139::-;2743:13;:11;:13::i;:::-;54293:8:::1;54279:11;:22;;;;54317:24;54332:8;54317:24;;;;;;:::i;:::-;;;;;;;;54210:139:::0;:::o;3022:166::-;3093:12;:10;:12::i;:::-;3082:23;;:7;:5;:7::i;:::-;:23;;;3078:103;;3156:12;:10;:12::i;:::-;3129:40;;;;;;;;;;;:::i;:::-;;;;;;;;3078:103;3022:166::o;32674:162::-;32757:71;32777:5;32799;:14;;;32816:2;32820:5;32784:43;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32757:19;:71::i;:::-;32674:162;;;:::o;866:98::-;919:7;946:10;939:17;;866:98;:::o;23497:130::-;23582:37;23591:5;23598:7;23607:5;23614:4;23582:8;:37::i;:::-;23497:130;;;:::o;25229:486::-;25329:24;25356:25;25366:5;25373:7;25356:9;:25::i;:::-;25329:52;;25415:17;25396:16;:36;25392:316;;;25472:5;25453:16;:24;25449:132;;;25532:7;25541:16;25559:5;25505:60;;;;;;;;;;;;;:::i;:::-;;;;;;;;25449:132;25624:57;25633:5;25640:7;25668:5;25649:16;:24;25675:5;25624:8;:57::i;:::-;25392:316;25318:397;25229:486;;;:::o;49720:1755::-;49861:1;49852:6;:10;49844:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;49971:16;:22;49988:4;49971:22;;;;;;;;;;;;;;;;;;;;;;;;;49970:23;:48;;;;49998:16;:20;50015:2;49998:20;;;;;;;;;;;;;;;;;;;;;;;;;49997:21;49970:48;49966:134;;;50043:14;;;;;;;;;;;50035:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;49966:134;50112:17;50221:7;;;;;;;;;;;50213:15;;:4;:15;;;:43;;;;;50246:9;;;;;;;;;;;50232:24;;:2;:24;;;;50213:43;:68;;;;;50261:16;:20;50278:2;50261:20;;;;;;;;;;;;;;;;;;;;;;;;;50260:21;50213:68;50195:249;;;50376:3;50361:11;;50345:13;:11;:13::i;:::-;:27;;;;:::i;:::-;50344:35;;;;:::i;:::-;50334:6;:45;;50308:124;;;;;;;;;;;;:::i;:::-;;;;;;;;;50195:249;50549:16;:22;50566:4;50549:22;;;;;;;;;;;;;;;;;;;;;;;;;50548:23;:48;;;;50576:16;:20;50593:2;50576:20;;;;;;;;;;;;;;;;;;;;;;;;;50575:21;50548:48;50547:88;;;;;50630:4;50614:21;;:4;:21;;;;50547:88;:139;;;;;50661:7;;;;;;;;;;;50653:15;;:4;:15;;;:32;;;;50678:7;;;;;;;;;;;50672:13;;:2;:13;;;50653:32;50547:139;:172;;;;;50718:1;50703:12;;:16;50547:172;50529:335;;;50784:6;50768:12;;50759:6;:21;;;;:::i;:::-;50758:32;;;;:::i;:::-;50746:44;;50805:47;50821:4;50835;50842:9;50805:15;:47::i;:::-;50529:335;50929:8;;;;;;;;;;;50928:9;:26;;;;;50947:7;;;;;;;;;;;50941:13;;:2;:13;;;50928:26;:53;;;;;50959:16;:22;50976:4;50959:22;;;;;;;;;;;;;;;;;;;;;;;;;50958:23;50928:53;50924:486;;;50998:23;51024:24;51042:4;51024:9;:24::i;:::-;50998:50;;51086:16;;51067:15;:35;51063:336;;51123:15;51180:1;51161:16;;:20;;;;:::i;:::-;51141:16;;:41;;;;:::i;:::-;51123:59;;51224:7;51205:15;:26;51201:183;;51256:25;51273:7;51256:16;:25::i;:::-;51201:183;;;51330:34;51347:16;;51330;:34::i;:::-;51201:183;51104:295;51063:336;50983:427;50924:486;51422:45;51438:4;51444:2;51457:9;51448:6;:18;;;;:::i;:::-;51422:15;:45::i;:::-;49833:1642;49720:1755;;;:::o;4170:191::-;4244:16;4263:6;;;;;;;;;;;4244:25;;4289:8;4280:6;;:17;;;;;;;;;;;;;;;;;;4344:8;4313:40;;4334:8;4313:40;;;;;;;;;;;;4233:128;4170:191;:::o;39965:738::-;40046:18;40075:19;40215:4;40212:1;40205:4;40199:11;40192:4;40186;40182:15;40179:1;40172:5;40165;40160:60;40274:7;40264:180;;40319:4;40313:11;40365:16;40362:1;40357:3;40342:40;40412:16;40407:3;40400:29;40264:180;40472:16;40458:30;;40523:1;40517:8;40502:23;;40130:406;40566:1;40552:10;:15;:68;;40619:1;40604:11;:16;;40552:68;;;40600:1;40578:5;40570:26;;;:31;40552:68;40548:148;;;40677:5;40644:40;;;;;;;;;;;:::i;:::-;;;;;;;;40548:148;40035:668;;39965:738;;:::o;24494:443::-;24624:1;24607:19;;:5;:19;;;24603:91;;24679:1;24650:32;;;;;;;;;;;:::i;:::-;;;;;;;;24603:91;24727:1;24708:21;;:7;:21;;;24704:92;;24781:1;24753:31;;;;;;;;;;;:::i;:::-;;;;;;;;24704:92;24836:5;24806:11;:18;24818:5;24806:18;;;;;;;;;;;;;;;:27;24825:7;24806:27;;;;;;;;;;;;;;;:35;;;;24856:9;24852:78;;;24903:7;24887:31;;24896:5;24887:31;;;24912:5;24887:31;;;;;;:::i;:::-;;;;;;;;24852:78;24494:443;;;;:::o;20064:316::-;20172:1;20156:18;;:4;:18;;;20152:88;;20225:1;20198:30;;;;;;;;;;;:::i;:::-;;;;;;;;20152:88;20268:1;20254:16;;:2;:16;;;20250:88;;20323:1;20294:32;;;;;;;;;;;:::i;:::-;;;;;;;;20250:88;20348:24;20356:4;20362:2;20366:5;20348:7;:24::i;:::-;20064:316;;;:::o;51483:1210::-;48238:8;;;;;;;;;;;48237:9;48229:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;48289:4;48278:8;;:15;;;;;;;;;;;;;;;;;;51567:1:::1;51557:6;;:11;:26;;;;;51582:1;51572:6;;:11;51557:26;51585:7;51553:39;51604:18;51625:21;51604:42;;51657:19;51694:3;51679:12;;:18;;;;:::i;:::-;51657:40;;51730:1;51716:11;:15;51708:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;51765:13;51801:11;51791:6;;51782;:15;;;;:::i;:::-;51781:31;;;;:::i;:::-;51765:47;;51823:13;51859:11;51849:6;;51840;:15;;;;:::i;:::-;51839:31;;;;:::i;:::-;51823:47;;51883:20;51923:1;51915:5;:9;;;;:::i;:::-;51906:5;:19;;;;:::i;:::-;51883:42;;51936:19;51975:1;51967:5;:9;;;;:::i;:::-;51958:5;:19;;;;:::i;:::-;51936:41;;51990:31;52008:12;51990:17;:31::i;:::-;52032:17;52076:10;52052:21;:34;;;;:::i;:::-;52032:54;;52099:17;52135:1:::0;52120:12:::1;:16;52119:91;;52209:1;52119:91;;;52181:12;52175:1;52167:5;:9;;;;:::i;:::-;52154;:23;;;;:::i;:::-;52153:40;;;;:::i;:::-;52119:91;52099:111;;52221:22;52258:9;52246;:21;;;;:::i;:::-;52221:46;;52298:1;52284:11;:15;:32;;;;;52315:1;52303:9;:13;52284:32;52280:102;;;52333:37;52347:11;52360:9;52333:13;:37::i;:::-;52280:102;52415:1;52398:14;:18;52394:218;;;52434:12;52460:16;;;;;;;;;;;52452:30;;52508:14;52452:89;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52433:108;;;52564:7;52556:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;52418:194;52394:218;52629:56;52648:12;52662:11;52675:9;52629:56;;;;;;;;:::i;:::-;;;;;;;;51542:1151;;;;;;;;;48304:1;48327:5:::0;48316:8;;:16;;;;;;;;;;;;;;;;;;51483:1210;:::o;20704:1135::-;20810:1;20794:18;;:4;:18;;;20790:552;;20948:5;20932:12;;:21;;;;;;;:::i;:::-;;;;;;;;20790:552;;;20986:19;21008:9;:15;21018:4;21008:15;;;;;;;;;;;;;;;;20986:37;;21056:5;21042:11;:19;21038:117;;;21114:4;21120:11;21133:5;21089:50;;;;;;;;;;;;;:::i;:::-;;;;;;;;21038:117;21310:5;21296:11;:19;21278:9;:15;21288:4;21278:15;;;;;;;;;;;;;;;:37;;;;20971:371;20790:552;21372:1;21358:16;;:2;:16;;;21354:435;;21540:5;21524:12;;:21;;;;;;;;;;;21354:435;;;21757:5;21740:9;:13;21750:2;21740:13;;;;;;;;;;;;;;;;:22;;;;;;;;;;;21354:435;21821:2;21806:25;;21815:4;21806:25;;;21825:5;21806:25;;;;;;:::i;:::-;;;;;;;;20704:1135;;;:::o;52701:481::-;52777:1;52767:6;:11;52763:24;52780:7;52763:24;52799:22;52838:1;52824:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52799:41;;52870:4;52851:5;52857:1;52851:8;;;;;;;;:::i;:::-;;;;;;;:24;;;;;;;;;;;52897:9;;;;;;;;;;;:14;;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52886:5;52892:1;52886:8;;;;;;;;:::i;:::-;;;;;;;:27;;;;;;;;;;;52926:51;52943:4;52958:9;;;;;;;;;;;52970:6;52926:8;:51::i;:::-;52988:9;;;;;;;;;;;:60;;;53063:6;53084:1;53100:5;53128:4;53148:15;52988:186;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52752:430;52701:481;;:::o;53190:370::-;53275:1;53265:6;:11;:23;;;;53287:1;53280:3;:8;53265:23;53290:7;53261:36;53309:51;53326:4;53341:9;;;;;;;;;;;53353:6;53309:8;:51::i;:::-;53371:9;;;;;;;;;;;:25;;;53404:3;53431:4;53451:6;53472:1;53488;53504:7;:5;:7::i;:::-;53526:15;53371:181;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;53190:370;;;:::o;88:117:1:-;197:1;194;187:12;334:126;371:7;411:42;404:5;400:54;389:65;;334:126;;;:::o;466:96::-;503:7;532:24;550:5;532:24;:::i;:::-;521:35;;466:96;;;:::o;568:122::-;641:24;659:5;641:24;:::i;:::-;634:5;631:35;621:63;;680:1;677;670:12;621:63;568:122;:::o;696:139::-;742:5;780:6;767:20;758:29;;796:33;823:5;796:33;:::i;:::-;696:139;;;;:::o;841:329::-;900:6;949:2;937:9;928:7;924:23;920:32;917:119;;;955:79;;:::i;:::-;917:119;1075:1;1100:53;1145:7;1136:6;1125:9;1121:22;1100:53;:::i;:::-;1090:63;;1046:117;841:329;;;;:::o;1176:104::-;1221:7;1250:24;1268:5;1250:24;:::i;:::-;1239:35;;1176:104;;;:::o;1286:138::-;1367:32;1393:5;1367:32;:::i;:::-;1360:5;1357:43;1347:71;;1414:1;1411;1404:12;1347:71;1286:138;:::o;1430:155::-;1484:5;1522:6;1509:20;1500:29;;1538:41;1573:5;1538:41;:::i;:::-;1430:155;;;;:::o;1591:345::-;1658:6;1707:2;1695:9;1686:7;1682:23;1678:32;1675:119;;;1713:79;;:::i;:::-;1675:119;1833:1;1858:61;1911:7;1902:6;1891:9;1887:22;1858:61;:::i;:::-;1848:71;;1804:125;1591:345;;;;:::o;1942:99::-;1994:6;2028:5;2022:12;2012:22;;1942:99;;;:::o;2047:169::-;2131:11;2165:6;2160:3;2153:19;2205:4;2200:3;2196:14;2181:29;;2047:169;;;;:::o;2222:246::-;2303:1;2313:113;2327:6;2324:1;2321:13;2313:113;;;2412:1;2407:3;2403:11;2397:18;2393:1;2388:3;2384:11;2377:39;2349:2;2346:1;2342:10;2337:15;;2313:113;;;2460:1;2451:6;2446:3;2442:16;2435:27;2284:184;2222:246;;;:::o;2474:102::-;2515:6;2566:2;2562:7;2557:2;2550:5;2546:14;2542:28;2532:38;;2474:102;;;:::o;2582:377::-;2670:3;2698:39;2731:5;2698:39;:::i;:::-;2753:71;2817:6;2812:3;2753:71;:::i;:::-;2746:78;;2833:65;2891:6;2886:3;2879:4;2872:5;2868:16;2833:65;:::i;:::-;2923:29;2945:6;2923:29;:::i;:::-;2918:3;2914:39;2907:46;;2674:285;2582:377;;;;:::o;2965:313::-;3078:4;3116:2;3105:9;3101:18;3093:26;;3165:9;3159:4;3155:20;3151:1;3140:9;3136:17;3129:47;3193:78;3266:4;3257:6;3193:78;:::i;:::-;3185:86;;2965:313;;;;:::o;3284:60::-;3312:3;3333:5;3326:12;;3284:60;;;:::o;3350:142::-;3400:9;3433:53;3451:34;3460:24;3478:5;3460:24;:::i;:::-;3451:34;:::i;:::-;3433:53;:::i;:::-;3420:66;;3350:142;;;:::o;3498:126::-;3548:9;3581:37;3612:5;3581:37;:::i;:::-;3568:50;;3498:126;;;:::o;3630:153::-;3707:9;3740:37;3771:5;3740:37;:::i;:::-;3727:50;;3630:153;;;:::o;3789:185::-;3903:64;3961:5;3903:64;:::i;:::-;3898:3;3891:77;3789:185;;:::o;3980:276::-;4100:4;4138:2;4127:9;4123:18;4115:26;;4151:98;4246:1;4235:9;4231:17;4222:6;4151:98;:::i;:::-;3980:276;;;;:::o;4262:118::-;4349:24;4367:5;4349:24;:::i;:::-;4344:3;4337:37;4262:118;;:::o;4386:222::-;4479:4;4517:2;4506:9;4502:18;4494:26;;4530:71;4598:1;4587:9;4583:17;4574:6;4530:71;:::i;:::-;4386:222;;;;:::o;4614:77::-;4651:7;4680:5;4669:16;;4614:77;;;:::o;4697:122::-;4770:24;4788:5;4770:24;:::i;:::-;4763:5;4760:35;4750:63;;4809:1;4806;4799:12;4750:63;4697:122;:::o;4825:139::-;4871:5;4909:6;4896:20;4887:29;;4925:33;4952:5;4925:33;:::i;:::-;4825:139;;;;:::o;4970:474::-;5038:6;5046;5095:2;5083:9;5074:7;5070:23;5066:32;5063:119;;;5101:79;;:::i;:::-;5063:119;5221:1;5246:53;5291:7;5282:6;5271:9;5267:22;5246:53;:::i;:::-;5236:63;;5192:117;5348:2;5374:53;5419:7;5410:6;5399:9;5395:22;5374:53;:::i;:::-;5364:63;;5319:118;4970:474;;;;;:::o;5450:90::-;5484:7;5527:5;5520:13;5513:21;5502:32;;5450:90;;;:::o;5546:109::-;5627:21;5642:5;5627:21;:::i;:::-;5622:3;5615:34;5546:109;;:::o;5661:210::-;5748:4;5786:2;5775:9;5771:18;5763:26;;5799:65;5861:1;5850:9;5846:17;5837:6;5799:65;:::i;:::-;5661:210;;;;:::o;5877:118::-;5964:24;5982:5;5964:24;:::i;:::-;5959:3;5952:37;5877:118;;:::o;6001:222::-;6094:4;6132:2;6121:9;6117:18;6109:26;;6145:71;6213:1;6202:9;6198:17;6189:6;6145:71;:::i;:::-;6001:222;;;;:::o;6229:619::-;6306:6;6314;6322;6371:2;6359:9;6350:7;6346:23;6342:32;6339:119;;;6377:79;;:::i;:::-;6339:119;6497:1;6522:53;6567:7;6558:6;6547:9;6543:22;6522:53;:::i;:::-;6512:63;;6468:117;6624:2;6650:53;6695:7;6686:6;6675:9;6671:22;6650:53;:::i;:::-;6640:63;;6595:118;6752:2;6778:53;6823:7;6814:6;6803:9;6799:22;6778:53;:::i;:::-;6768:63;;6723:118;6229:619;;;;;:::o;6854:86::-;6889:7;6929:4;6922:5;6918:16;6907:27;;6854:86;;;:::o;6946:112::-;7029:22;7045:5;7029:22;:::i;:::-;7024:3;7017:35;6946:112;;:::o;7064:214::-;7153:4;7191:2;7180:9;7176:18;7168:26;;7204:67;7268:1;7257:9;7253:17;7244:6;7204:67;:::i;:::-;7064:214;;;;:::o;7284:116::-;7354:21;7369:5;7354:21;:::i;:::-;7347:5;7344:32;7334:60;;7390:1;7387;7380:12;7334:60;7284:116;:::o;7406:133::-;7449:5;7487:6;7474:20;7465:29;;7503:30;7527:5;7503:30;:::i;:::-;7406:133;;;;:::o;7545:468::-;7610:6;7618;7667:2;7655:9;7646:7;7642:23;7638:32;7635:119;;;7673:79;;:::i;:::-;7635:119;7793:1;7818:53;7863:7;7854:6;7843:9;7839:22;7818:53;:::i;:::-;7808:63;;7764:117;7920:2;7946:50;7988:7;7979:6;7968:9;7964:22;7946:50;:::i;:::-;7936:60;;7891:115;7545:468;;;;;:::o;8019:474::-;8087:6;8095;8144:2;8132:9;8123:7;8119:23;8115:32;8112:119;;;8150:79;;:::i;:::-;8112:119;8270:1;8295:53;8340:7;8331:6;8320:9;8316:22;8295:53;:::i;:::-;8285:63;;8241:117;8397:2;8423:53;8468:7;8459:6;8448:9;8444:22;8423:53;:::i;:::-;8413:63;;8368:118;8019:474;;;;;:::o;8499:329::-;8558:6;8607:2;8595:9;8586:7;8582:23;8578:32;8575:119;;;8613:79;;:::i;:::-;8575:119;8733:1;8758:53;8803:7;8794:6;8783:9;8779:22;8758:53;:::i;:::-;8748:63;;8704:117;8499:329;;;;:::o;8834:474::-;8902:6;8910;8959:2;8947:9;8938:7;8934:23;8930:32;8927:119;;;8965:79;;:::i;:::-;8927:119;9085:1;9110:53;9155:7;9146:6;9135:9;9131:22;9110:53;:::i;:::-;9100:63;;9056:117;9212:2;9238:53;9283:7;9274:6;9263:9;9259:22;9238:53;:::i;:::-;9228:63;;9183:118;8834:474;;;;;:::o;9314:143::-;9371:5;9402:6;9396:13;9387:22;;9418:33;9445:5;9418:33;:::i;:::-;9314:143;;;;:::o;9463:351::-;9533:6;9582:2;9570:9;9561:7;9557:23;9553:32;9550:119;;;9588:79;;:::i;:::-;9550:119;9708:1;9733:64;9789:7;9780:6;9769:9;9765:22;9733:64;:::i;:::-;9723:74;;9679:128;9463:351;;;;:::o;9820:169::-;9960:21;9956:1;9948:6;9944:14;9937:45;9820:169;:::o;9995:366::-;10137:3;10158:67;10222:2;10217:3;10158:67;:::i;:::-;10151:74;;10234:93;10323:3;10234:93;:::i;:::-;10352:2;10347:3;10343:12;10336:19;;9995:366;;;:::o;10367:419::-;10533:4;10571:2;10560:9;10556:18;10548:26;;10620:9;10614:4;10610:20;10606:1;10595:9;10591:17;10584:47;10648:131;10774:4;10648:131;:::i;:::-;10640:139;;10367:419;;;:::o;10792:332::-;10913:4;10951:2;10940:9;10936:18;10928:26;;10964:71;11032:1;11021:9;11017:17;11008:6;10964:71;:::i;:::-;11045:72;11113:2;11102:9;11098:18;11089:6;11045:72;:::i;:::-;10792:332;;;;;:::o;11130:166::-;11270:18;11266:1;11258:6;11254:14;11247:42;11130:166;:::o;11302:366::-;11444:3;11465:67;11529:2;11524:3;11465:67;:::i;:::-;11458:74;;11541:93;11630:3;11541:93;:::i;:::-;11659:2;11654:3;11650:12;11643:19;;11302:366;;;:::o;11674:419::-;11840:4;11878:2;11867:9;11863:18;11855:26;;11927:9;11921:4;11917:20;11913:1;11902:9;11898:17;11891:47;11955:131;12081:4;11955:131;:::i;:::-;11947:139;;11674:419;;;:::o;12099:147::-;12200:11;12237:3;12222:18;;12099:147;;;;:::o;12252:114::-;;:::o;12372:398::-;12531:3;12552:83;12633:1;12628:3;12552:83;:::i;:::-;12545:90;;12644:93;12733:3;12644:93;:::i;:::-;12762:1;12757:3;12753:11;12746:18;;12372:398;;;:::o;12776:379::-;12960:3;12982:147;13125:3;12982:147;:::i;:::-;12975:154;;13146:3;13139:10;;12776:379;;;:::o;13161:169::-;13301:21;13297:1;13289:6;13285:14;13278:45;13161:169;:::o;13336:366::-;13478:3;13499:67;13563:2;13558:3;13499:67;:::i;:::-;13492:74;;13575:93;13664:3;13575:93;:::i;:::-;13693:2;13688:3;13684:12;13677:19;;13336:366;;;:::o;13708:419::-;13874:4;13912:2;13901:9;13897:18;13889:26;;13961:9;13955:4;13951:20;13947:1;13936:9;13932:17;13925:47;13989:131;14115:4;13989:131;:::i;:::-;13981:139;;13708:419;;;:::o;14133:134::-;14191:9;14224:37;14255:5;14224:37;:::i;:::-;14211:50;;14133:134;;;:::o;14273:147::-;14368:45;14407:5;14368:45;:::i;:::-;14363:3;14356:58;14273:147;;:::o;14426:348::-;14555:4;14593:2;14582:9;14578:18;14570:26;;14606:79;14682:1;14671:9;14667:17;14658:6;14606:79;:::i;:::-;14695:72;14763:2;14752:9;14748:18;14739:6;14695:72;:::i;:::-;14426:348;;;;;:::o;14780:180::-;14828:77;14825:1;14818:88;14925:4;14922:1;14915:15;14949:4;14946:1;14939:15;14966:320;15010:6;15047:1;15041:4;15037:12;15027:22;;15094:1;15088:4;15084:12;15115:18;15105:81;;15171:4;15163:6;15159:17;15149:27;;15105:81;15233:2;15225:6;15222:14;15202:18;15199:38;15196:84;;15252:18;;:::i;:::-;15196:84;15017:269;14966:320;;;:::o;15292:164::-;15432:16;15428:1;15420:6;15416:14;15409:40;15292:164;:::o;15462:366::-;15604:3;15625:67;15689:2;15684:3;15625:67;:::i;:::-;15618:74;;15701:93;15790:3;15701:93;:::i;:::-;15819:2;15814:3;15810:12;15803:19;;15462:366;;;:::o;15834:419::-;16000:4;16038:2;16027:9;16023:18;16015:26;;16087:9;16081:4;16077:20;16073:1;16062:9;16058:17;16051:47;16115:131;16241:4;16115:131;:::i;:::-;16107:139;;15834:419;;;:::o;16259:320::-;16374:4;16412:2;16401:9;16397:18;16389:26;;16425:71;16493:1;16482:9;16478:17;16469:6;16425:71;:::i;:::-;16506:66;16568:2;16557:9;16553:18;16544:6;16506:66;:::i;:::-;16259:320;;;;;:::o;16585:165::-;16725:17;16721:1;16713:6;16709:14;16702:41;16585:165;:::o;16756:366::-;16898:3;16919:67;16983:2;16978:3;16919:67;:::i;:::-;16912:74;;16995:93;17084:3;16995:93;:::i;:::-;17113:2;17108:3;17104:12;17097:19;;16756:366;;;:::o;17128:419::-;17294:4;17332:2;17321:9;17317:18;17309:26;;17381:9;17375:4;17371:20;17367:1;17356:9;17352:17;17345:47;17409:131;17535:4;17409:131;:::i;:::-;17401:139;;17128:419;;;:::o;17553:180::-;17601:77;17598:1;17591:88;17698:4;17695:1;17688:15;17722:4;17719:1;17712:15;17739:191;17779:3;17798:20;17816:1;17798:20;:::i;:::-;17793:25;;17832:20;17850:1;17832:20;:::i;:::-;17827:25;;17875:1;17872;17868:9;17861:16;;17896:3;17893:1;17890:10;17887:36;;;17903:18;;:::i;:::-;17887:36;17739:191;;;;:::o;17936:179::-;18076:31;18072:1;18064:6;18060:14;18053:55;17936:179;:::o;18121:366::-;18263:3;18284:67;18348:2;18343:3;18284:67;:::i;:::-;18277:74;;18360:93;18449:3;18360:93;:::i;:::-;18478:2;18473:3;18469:12;18462:19;;18121:366;;;:::o;18493:419::-;18659:4;18697:2;18686:9;18682:18;18674:26;;18746:9;18740:4;18736:20;18732:1;18721:9;18717:17;18710:47;18774:131;18900:4;18774:131;:::i;:::-;18766:139;;18493:419;;;:::o;18918:180::-;18966:77;18963:1;18956:88;19063:4;19060:1;19053:15;19087:4;19084:1;19077:15;19104:185;19144:1;19161:20;19179:1;19161:20;:::i;:::-;19156:25;;19195:20;19213:1;19195:20;:::i;:::-;19190:25;;19234:1;19224:35;;19239:18;;:::i;:::-;19224:35;19281:1;19278;19274:9;19269:14;;19104:185;;;;:::o;19295:169::-;19435:21;19431:1;19423:6;19419:14;19412:45;19295:169;:::o;19470:366::-;19612:3;19633:67;19697:2;19692:3;19633:67;:::i;:::-;19626:74;;19709:93;19798:3;19709:93;:::i;:::-;19827:2;19822:3;19818:12;19811:19;;19470:366;;;:::o;19842:419::-;20008:4;20046:2;20035:9;20031:18;20023:26;;20095:9;20089:4;20085:20;20081:1;20070:9;20066:17;20059:47;20123:131;20249:4;20123:131;:::i;:::-;20115:139;;19842:419;;;:::o;20267:410::-;20307:7;20330:20;20348:1;20330:20;:::i;:::-;20325:25;;20364:20;20382:1;20364:20;:::i;:::-;20359:25;;20419:1;20416;20412:9;20441:30;20459:11;20441:30;:::i;:::-;20430:41;;20620:1;20611:7;20607:15;20604:1;20601:22;20581:1;20574:9;20554:83;20531:139;;20650:18;;:::i;:::-;20531:139;20315:362;20267:410;;;;:::o;20683:164::-;20823:16;20819:1;20811:6;20807:14;20800:40;20683:164;:::o;20853:366::-;20995:3;21016:67;21080:2;21075:3;21016:67;:::i;:::-;21009:74;;21092:93;21181:3;21092:93;:::i;:::-;21210:2;21205:3;21201:12;21194:19;;20853:366;;;:::o;21225:419::-;21391:4;21429:2;21418:9;21414:18;21406:26;;21478:9;21472:4;21468:20;21464:1;21453:9;21449:17;21442:47;21506:131;21632:4;21506:131;:::i;:::-;21498:139;;21225:419;;;:::o;21650:442::-;21799:4;21837:2;21826:9;21822:18;21814:26;;21850:71;21918:1;21907:9;21903:17;21894:6;21850:71;:::i;:::-;21931:72;21999:2;21988:9;21984:18;21975:6;21931:72;:::i;:::-;22013;22081:2;22070:9;22066:18;22057:6;22013:72;:::i;:::-;21650:442;;;;;;:::o;22098:225::-;22238:34;22234:1;22226:6;22222:14;22215:58;22307:8;22302:2;22294:6;22290:15;22283:33;22098:225;:::o;22329:366::-;22471:3;22492:67;22556:2;22551:3;22492:67;:::i;:::-;22485:74;;22568:93;22657:3;22568:93;:::i;:::-;22686:2;22681:3;22677:12;22670:19;;22329:366;;;:::o;22701:419::-;22867:4;22905:2;22894:9;22890:18;22882:26;;22954:9;22948:4;22944:20;22940:1;22929:9;22925:17;22918:47;22982:131;23108:4;22982:131;:::i;:::-;22974:139;;22701:419;;;:::o;23126:176::-;23266:28;23262:1;23254:6;23250:14;23243:52;23126:176;:::o;23308:366::-;23450:3;23471:67;23535:2;23530:3;23471:67;:::i;:::-;23464:74;;23547:93;23636:3;23547:93;:::i;:::-;23665:2;23660:3;23656:12;23649:19;;23308:366;;;:::o;23680:419::-;23846:4;23884:2;23873:9;23869:18;23861:26;;23933:9;23927:4;23923:20;23919:1;23908:9;23904:17;23897:47;23961:131;24087:4;23961:131;:::i;:::-;23953:139;;23680:419;;;:::o;24105:167::-;24245:19;24241:1;24233:6;24229:14;24222:43;24105:167;:::o;24278:366::-;24420:3;24441:67;24505:2;24500:3;24441:67;:::i;:::-;24434:74;;24517:93;24606:3;24517:93;:::i;:::-;24635:2;24630:3;24626:12;24619:19;;24278:366;;;:::o;24650:419::-;24816:4;24854:2;24843:9;24839:18;24831:26;;24903:9;24897:4;24893:20;24889:1;24878:9;24874:17;24867:47;24931:131;25057:4;24931:131;:::i;:::-;24923:139;;24650:419;;;:::o;25075:194::-;25115:4;25135:20;25153:1;25135:20;:::i;:::-;25130:25;;25169:20;25187:1;25169:20;:::i;:::-;25164:25;;25213:1;25210;25206:9;25198:17;;25237:1;25231:4;25228:11;25225:37;;;25242:18;;:::i;:::-;25225:37;25075:194;;;;:::o;25275:166::-;25415:18;25411:1;25403:6;25399:14;25392:42;25275:166;:::o;25447:366::-;25589:3;25610:67;25674:2;25669:3;25610:67;:::i;:::-;25603:74;;25686:93;25775:3;25686:93;:::i;:::-;25804:2;25799:3;25795:12;25788:19;;25447:366;;;:::o;25819:419::-;25985:4;26023:2;26012:9;26008:18;26000:26;;26072:9;26066:4;26062:20;26058:1;26047:9;26043:17;26036:47;26100:131;26226:4;26100:131;:::i;:::-;26092:139;;25819:419;;;:::o;26244:166::-;26384:18;26380:1;26372:6;26368:14;26361:42;26244:166;:::o;26416:366::-;26558:3;26579:67;26643:2;26638:3;26579:67;:::i;:::-;26572:74;;26655:93;26744:3;26655:93;:::i;:::-;26773:2;26768:3;26764:12;26757:19;;26416:366;;;:::o;26788:419::-;26954:4;26992:2;26981:9;26977:18;26969:26;;27041:9;27035:4;27031:20;27027:1;27016:9;27012:17;27005:47;27069:131;27195:4;27069:131;:::i;:::-;27061:139;;26788:419;;;:::o;27213:174::-;27353:26;27349:1;27341:6;27337:14;27330:50;27213:174;:::o;27393:366::-;27535:3;27556:67;27620:2;27615:3;27556:67;:::i;:::-;27549:74;;27632:93;27721:3;27632:93;:::i;:::-;27750:2;27745:3;27741:12;27734:19;;27393:366;;;:::o;27765:419::-;27931:4;27969:2;27958:9;27954:18;27946:26;;28018:9;28012:4;28008:20;28004:1;27993:9;27989:17;27982:47;28046:131;28172:4;28046:131;:::i;:::-;28038:139;;27765:419;;;:::o;28190:442::-;28339:4;28377:2;28366:9;28362:18;28354:26;;28390:71;28458:1;28447:9;28443:17;28434:6;28390:71;:::i;:::-;28471:72;28539:2;28528:9;28524:18;28515:6;28471:72;:::i;:::-;28553;28621:2;28610:9;28606:18;28597:6;28553:72;:::i;:::-;28190:442;;;;;;:::o;28638:180::-;28686:77;28683:1;28676:88;28783:4;28780:1;28773:15;28807:4;28804:1;28797:15;28824:180;28872:77;28869:1;28862:88;28969:4;28966:1;28959:15;28993:4;28990:1;28983:15;29010:143;29067:5;29098:6;29092:13;29083:22;;29114:33;29141:5;29114:33;:::i;:::-;29010:143;;;;:::o;29159:351::-;29229:6;29278:2;29266:9;29257:7;29253:23;29249:32;29246:119;;;29284:79;;:::i;:::-;29246:119;29404:1;29429:64;29485:7;29476:6;29465:9;29461:22;29429:64;:::i;:::-;29419:74;;29375:128;29159:351;;;;:::o;29516:85::-;29561:7;29590:5;29579:16;;29516:85;;;:::o;29607:158::-;29665:9;29698:61;29716:42;29725:32;29751:5;29725:32;:::i;:::-;29716:42;:::i;:::-;29698:61;:::i;:::-;29685:74;;29607:158;;;:::o;29771:147::-;29866:45;29905:5;29866:45;:::i;:::-;29861:3;29854:58;29771:147;;:::o;29924:114::-;29991:6;30025:5;30019:12;30009:22;;29924:114;;;:::o;30044:184::-;30143:11;30177:6;30172:3;30165:19;30217:4;30212:3;30208:14;30193:29;;30044:184;;;;:::o;30234:132::-;30301:4;30324:3;30316:11;;30354:4;30349:3;30345:14;30337:22;;30234:132;;;:::o;30372:108::-;30449:24;30467:5;30449:24;:::i;:::-;30444:3;30437:37;30372:108;;:::o;30486:179::-;30555:10;30576:46;30618:3;30610:6;30576:46;:::i;:::-;30654:4;30649:3;30645:14;30631:28;;30486:179;;;;:::o;30671:113::-;30741:4;30773;30768:3;30764:14;30756:22;;30671:113;;;:::o;30820:732::-;30939:3;30968:54;31016:5;30968:54;:::i;:::-;31038:86;31117:6;31112:3;31038:86;:::i;:::-;31031:93;;31148:56;31198:5;31148:56;:::i;:::-;31227:7;31258:1;31243:284;31268:6;31265:1;31262:13;31243:284;;;31344:6;31338:13;31371:63;31430:3;31415:13;31371:63;:::i;:::-;31364:70;;31457:60;31510:6;31457:60;:::i;:::-;31447:70;;31303:224;31290:1;31287;31283:9;31278:14;;31243:284;;;31247:14;31543:3;31536:10;;30944:608;;;30820:732;;;;:::o;31558:831::-;31821:4;31859:3;31848:9;31844:19;31836:27;;31873:71;31941:1;31930:9;31926:17;31917:6;31873:71;:::i;:::-;31954:80;32030:2;32019:9;32015:18;32006:6;31954:80;:::i;:::-;32081:9;32075:4;32071:20;32066:2;32055:9;32051:18;32044:48;32109:108;32212:4;32203:6;32109:108;:::i;:::-;32101:116;;32227:72;32295:2;32284:9;32280:18;32271:6;32227:72;:::i;:::-;32309:73;32377:3;32366:9;32362:19;32353:6;32309:73;:::i;:::-;31558:831;;;;;;;;:::o;32395:807::-;32644:4;32682:3;32671:9;32667:19;32659:27;;32696:71;32764:1;32753:9;32749:17;32740:6;32696:71;:::i;:::-;32777:72;32845:2;32834:9;32830:18;32821:6;32777:72;:::i;:::-;32859:80;32935:2;32924:9;32920:18;32911:6;32859:80;:::i;:::-;32949;33025:2;33014:9;33010:18;33001:6;32949:80;:::i;:::-;33039:73;33107:3;33096:9;33092:19;33083:6;33039:73;:::i;:::-;33122;33190:3;33179:9;33175:19;33166:6;33122:73;:::i;:::-;32395:807;;;;;;;;;:::o;33208:663::-;33296:6;33304;33312;33361:2;33349:9;33340:7;33336:23;33332:32;33329:119;;;33367:79;;:::i;:::-;33329:119;33487:1;33512:64;33568:7;33559:6;33548:9;33544:22;33512:64;:::i;:::-;33502:74;;33458:128;33625:2;33651:64;33707:7;33698:6;33687:9;33683:22;33651:64;:::i;:::-;33641:74;;33596:129;33764:2;33790:64;33846:7;33837:6;33826:9;33822:22;33790:64;:::i;:::-;33780:74;;33735:129;33208:663;;;;;:::o

Swarm Source

ipfs://be0dd35313c532e00a35eb32a589a23d39314f10e2e7f980130c0f3691440e1a
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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