ETH Price: $3,018.20 (+4.54%)
Gas: 2 Gwei

Token

DivisionAR (DAR)
 

Overview

Max Total Supply

100,000,000 DAR

Holders

46

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
416,329.16914650219917769 DAR

Value
$0.00
0xdd01dcfa33bbe5a2f212cfccdc7c635abff85fea
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
DivisionAR

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2024-01-15
*/

/**
 * 
 * Welcome to DivisionAR, an experience that connects augmented reality with social media.
 * 
 * Website: https://divisionar.com
 * TG: https://t.me/DivisionAR
 * X: https://x.com/_DivisionAR
 * 
 */

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

/********************************************************************************************
  LIBRARY
********************************************************************************************/

/**
 * @title Address Library
 *
 * @notice Collection of functions providing utility for interacting with addresses.
 */
library Address {

    // ERROR

    /**
     * @notice Error indicating insufficient balance while performing an operation.
     *
     * @param account Address where the balance is insufficient.
     */
    error AddressInsufficientBalance(address account);

    /**
     * @notice Error indicating an attempt to interact with a contract having empty code.
     *
     * @param target Address of the contract with empty code.
     */
    error AddressEmptyCode(address target);

    /**
     * @notice Error indicating a failed internal call.
     */
    error FailedInnerCall();

    // FUNCTION

    /**
     * @notice Calls a function on a specified address without transferring value.
     *
     * @param target Address on which the function will be called.
     * @param data Encoded data of the function call.
     *
     * @return returndata Result of the function call.
     *
     * @dev The `target` must be a contract address and this function must be calling
     * `target` with `data` not reverting.
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0);
    }

    /**
     * @notice Calls a function on a specified address with a specified value.
     *
     * @param target Address on which the function will be called.
     * @param data Encoded data of the function call.
     * @param value Value to be sent in the call.
     *
     * @return returndata Result of the function call.
     *
     * @dev This function ensure that the calling contract actually have Ether balance
     * of at least `value` and that the called Solidity function is a `payable`. Should
     * throw if caller does have insufficient balance.
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        if (address(this).balance < value) {
            revert AddressInsufficientBalance(address(this));
        }
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @notice Verifies the result of a function call and handles errors if any.
     *
     * @param target Address on which the function was called.
     * @param success Boolean indicating the success of the function call.
     * @param returndata Result data of the function call.
     *
     * @return Result of the function call or reverts with an appropriate error.
     *
     * @dev This help to verify that a low level call to smart-contract was successful
     * and will reverts if the target was not a contract. For unsuccessful call, this
     * will bubble up the revert reason (falling back to {FailedInnerCall}). Should
     * throw if both the returndata and target.code length are 0 when `success` is true.
     */
    function verifyCallResultFromTarget(address target, bool success, bytes memory returndata) internal view returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            if (returndata.length == 0 && target.code.length == 0) {
                revert AddressEmptyCode(target);
            }
            return returndata;
        }
    }

    /**
     * @notice Reverts with decoded revert data or FailedInnerCall if no revert
     * data is available.
     *
     * @param returndata Result data of a failed function call.
     *
     * @dev Should throw if returndata length is 0.
     */
    function _revert(bytes memory returndata) private pure {
        if (returndata.length > 0) {
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert FailedInnerCall();
        }
    }
}

/**
 * @title SafeERC20 Library
 *
 * @notice Collection of functions providing utility for safe operations with
 * ERC20 tokens.
 *
 * @dev This is mainly for the usage of token 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 where non-reverting calls are assumed
 * to be a successful transaction.
 */
library SafeERC20 {
    
    // LIBRARY

    using Address for address;

    // ERROR

    /**
     * @notice Error indicating a failed operation during an ERC-20 token transfer.
     *
     * @param token Address of the token contract.
     */
    error SafeERC20FailedOperation(address token);

    // FUNCTION

    /**
     * @notice Safely transfers tokens.
     *
     * @param token ERC20 token interface.
     * @param to Address to which the tokens will be transferred.
     * @param value Amount of tokens to be transferred.
     *
     * @dev Transfer `value` amount of `token` from the calling contract to `to` where
     * non-reverting calls are assumed to be successful if `token` returns no value.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
    }

    /**
     * @notice Calls a function on a token contract and reverts if the operation fails.
     *
     * @param token ERC20 token interface.
     * @param data Encoded data of the function call.
     *
     * @dev This imitates a Solidity high-level call such as a regular function call to
     * a contract while relaxing the requirement on the return value.
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        bytes memory returndata = address(token).functionCall(data);
        if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
            revert SafeERC20FailedOperation(address(token));
        }
    }
}

/********************************************************************************************
  INTERFACE
********************************************************************************************/

/**
 * @title Router Interface
 * 
 * @notice Interface of the Router contract, providing functions to interact with
 * Router contract that is derived from Uniswap V2 Router.
 * 
 * @dev See https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02
 */
interface IRouter {

    // FUNCTION

    /**
     * @notice Get the address of the Wrapped Ether (WETH) token.
     * 
     * @return The address of the WETH token.
     */
    function WETH() external pure returns (address);
            
    /**
     * @notice Get the address of the linked Factory contract.
     * 
     * @return The address of the Factory contract.
     */
    function factory() external pure returns (address);

    /**
     * @notice Swaps an exact amount of tokens for ETH, supporting
     * tokens that implement fee-on-transfer mechanisms.
     * 
     * @param amountIn The exact amount of input tokens for the swap.
     * @param amountOutMin The minimum acceptable amount of ETH to receive in the swap.
     * @param path An array of token addresses representing the token swap path.
     * @param to The recipient address that will receive the swapped ETH.
     * @param deadline The timestamp by which the transaction must be executed to be
     * considered valid.
     * 
     * @dev This function swaps a specific amount of tokens for ETH on a specified path, 
     * ensuring a minimum amount of output ETH.
     */
    function swapExactTokensForETHSupportingFeeOnTransferTokens(uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline) external;

    /**
     * @notice Swaps a precise amount of ETH for tokens, supporting tokens with fee-on-transfer mechanisms.
     * 
     * @param amountOutMin The minimum acceptable amount of output tokens expected from the swap.
     * @param path An array of token addresses representing the token swap path.
     * @param to The recipient address that will receive the swapped tokens.
     * @param deadline The timestamp by which the transaction must be executed to be considered valid.
     * 
     * @dev This function performs a direct swap of a specified amount of ETH for tokens based on the provided
     * path and minimum acceptable output token amount.
     */
    function swapExactETHForTokensSupportingFeeOnTransferTokens(uint256 amountOutMin, address[] calldata path, address to, uint256 deadline) external payable;
}

/**
 * @title Factory Interface
 * 
 * @notice Interface of the Factory contract, providing functions to interact with
 * Factory contract that is derived from Uniswap V2 Factory.
 * 
 * @dev See https://docs.uniswap.org/contracts/v2/reference/smart-contracts/factory
 */
interface IFactory {

    // FUNCTION

    /**
     * @notice Create a new token pair for two given tokens on Uniswap V2-based factory.
     * 
     * @param tokenA The address of the first token.
     * @param tokenB The address of the second token.
     * 
     * @return pair The address of the created pair for the given tokens.
     */
    function createPair(address tokenA, address tokenB) external returns (address pair);

    /**
     * @notice Get the address of the pair for two tokens on the decentralized exchange.
     * 
     * @param tokenA The address of the first token.
     * @param tokenB The address of the second token.
     * 
     * @return pair The address of the pair corresponding to the provided tokens.
     */
    function getPair(address tokenA, address tokenB) external view returns (address pair);
}

/**
 * @title Pair Interface
 * 
 * @notice Interface of the Pair contract in a decentralized exchange based on the
 * Pair contract that is derived from Uniswap V2 Pair.
 * 
 * @dev See https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair
 */
interface IPair {

    // FUNCTION

    /**
     * @notice Get the address of the first token in the pair.
     * 
     * @return The address of the first token.
     */
    function token0() external view returns (address);

    /**
     * @notice Get the address of the second token in the pair.
     * 
     * @return The address of the second token.
     */
    function token1() external view returns (address);
}

/**
 * @title ERC20 Token Standard Interface
 * 
 * @notice Interface of the ERC-20 standard token as defined in the ERC.
 * 
 * @dev See https://eips.ethereum.org/EIPS/eip-20
 */
interface IERC20 {
    
    // EVENT
    
    /**
     * @notice Emitted when `value` tokens are transferred from
     * one account (`from`) to another (`to`).
     * 
     * @param from The address tokens are transferred from.
     * @param to The address tokens are transferred to.
     * @param value The amount of tokens transferred.
     * 
     * @dev The `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @notice Emitted when the allowance of a `spender` for an `owner`
     * is set by a call to {approve}.
     * 
     * @param owner The address allowing `spender` to spend on their behalf.
     * @param spender The address allowed to spend tokens on behalf of `owner`.
     * @param value The allowance amount set for `spender`.
     * 
     * @dev The `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    // FUNCTION

    /**
     * @notice Returns the value of tokens in existence.
     * 
     * @return The value of the total supply of tokens.
     * 
     * @dev This should get the total token supply.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @notice Returns the value of tokens owned by `account`.
     * 
     * @param account The address to query the balance for.
     * 
     * @return The token balance of `account`.
     * 
     * @dev This should get the token balance of a specific account.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @notice Moves a `value` amount of tokens from the caller's account to `to`.
     * 
     * @param to The address to transfer tokens to.
     * @param value The amount of tokens to be transferred.
     * 
     * @return A boolean indicating whether the transfer was successful or not.
     * 
     * @dev This should transfer tokens to a specified address and emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @notice Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}.
     * 
     * @param owner The address allowing `spender` to spend on their behalf.
     * @param spender The address allowed to spend tokens on behalf of `owner`.
     * 
     * @return The allowance amount for `spender`.
     * 
     * @dev The return value should be zero by default and
     * changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @notice Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     * 
     * @param spender The address allowed to spend tokens on behalf of the sender.
     * @param value The allowance amount for `spender`.
     * 
     * @return A boolean indicating whether the approval was successful or not.
     * 
     * @dev This should approve `spender` to spend a specified amount of tokens
     * on behalf of the sender and emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @notice Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's allowance.
     * 
     * @param from The address to transfer tokens from.
     * @param to The address to transfer tokens to.
     * @param value The amount of tokens to be transferred.
     * 
     * @return A boolean indicating whether the transfer was successful or not.
     * 
     * @dev This should transfer tokens from one address to another after
     * spending caller's allowance and emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

/**
 * @title ERC20 Token Metadata Interface
 * 
 * @notice Interface for the optional metadata functions of the ERC-20 standard as defined in the ERC.
 * 
 * @dev It extends the IERC20 interface. See https://eips.ethereum.org/EIPS/eip-20
 */
interface IERC20Metadata is IERC20 {

    // FUNCTION
    
    /**
     * @notice Returns the name of the token.
     * 
     * @return The name of the token as a string.
     */
    function name() external view returns (string memory);

    /**
     * @notice Returns the symbol of the token.
     * 
     * @return The symbol of the token as a string.
     */
    function symbol() external view returns (string memory);

    /**
     * @notice Returns the number of decimals used to display the token.
     * 
     * @return The number of decimals as a uint8.
     */
    function decimals() external view returns (uint8);
}

/**
 * @title ERC20 Token Standard Error Interface
 * 
 * @notice Interface of the ERC-6093 custom errors that defined common errors
 * related to the ERC-20 standard token functionalities.
 * 
 * @dev See https://eips.ethereum.org/EIPS/eip-6093
 */
interface IERC20Errors {
    
    // ERROR

    /**
     * @notice Error indicating that the `sender` has inssufficient `balance` for the operation.
     * 
     * @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.
     *
     * @dev The `needed` value is required to inform user on the needed amount.
     */
    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);

    /**
     * @notice Error indicating that the `sender` is invalid for the operation.
     * 
     * @param sender Address whose tokens are being transferred.
     */
    error ERC20InvalidSender(address sender);
    
    /**
     * @notice Error indicating that the `receiver` is invalid for the operation.
     * 
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC20InvalidReceiver(address receiver);
    
    /**
     * @notice Error indicating that the `spender` does not have enough `allowance` for the operation.
     * 
     * @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.
     * 
     * @dev The `needed` value is required to inform user on the needed amount.
     */
    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
    
    /**
     * @notice Error indicating that the `approver` is invalid for the approval operation.
     * 
     * @param approver Address initiating an approval operation.
     */
    error ERC20InvalidApprover(address approver);

    /**
     * @notice Error indicating that the `spender` is invalid for the allowance operation.
     * 
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC20InvalidSpender(address spender);
}

/**
 * @title Common Error Interface
 * 
 * @notice Interface of the common errors not specific to ERC-20 functionalities.
 */
interface ICommonError {

    // ERROR

    /**
     * @notice Error indicating that the `current` address cannot be used in this context.
     * 
     * @param current Address used in the context.
     */
    error CannotUseCurrentAddress(address current);

    /**
     * @notice Error indicating that the `current` value cannot be used in this context.
     * 
     * @param current Value used in the context.
     */
    error CannotUseCurrentValue(uint256 current);

    /**
     * @notice Error indicating that the `current` state cannot be used in this context.
     * 
     * @param current Boolean state used in the context.
     */
    error CannotUseCurrentState(bool current);

    /**
     * @notice Error indicating that the `invalid` address provided is not a valid address for this context.
     * 
     * @param invalid Address used in the context.
     */
    error InvalidAddress(address invalid);

    /**
     * @notice Error indicating that the `invalid` value provided is not a valid value for this context.
     * 
     * @param invalid Value used in the context.
     */
    error InvalidValue(uint256 invalid);
}

/********************************************************************************************
  ACCESS
********************************************************************************************/

/**
 * @title Ownable Contract
 * 
 * @notice Abstract contract module implementing ownership functionality through
 * inheritance as a basic access control mechanism, where there is an owner account
 * that can be granted exclusive access to specific functions.
 * 
 * @dev The initial owner is set to the address provided by the deployer and can
 * later be changed with {transferOwnership}.
 */
abstract contract Ownable {

    // DATA

    address private _owner;

    // MODIFIER

    /**
     * @notice Modifier that allows access only to the contract owner.
     *
     * @dev Should throw if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    // ERROR

    /**
     * @notice Error indicating that the `account` is not authorized to perform an operation.
     * 
     * @param account Address used to perform the operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @notice Error indicating that the provided `owner` address is invalid.
     * 
     * @param owner Address used to perform the operation.
     * 
     * @dev Should throw if called by an invalid owner account such as address(0) as an example.
     */
    error OwnableInvalidOwner(address owner);

    // CONSTRUCTOR

    /**
     * @notice Initializes the contract setting the `initialOwner` address provided by
     * the deployer as the initial owner.
     * 
     * @param initialOwner The address to set as the initial owner.
     *
     * @dev Should throw an error if called with address(0) as the `initialOwner`.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }
    
    // EVENT
    
    /**
     * @notice Emitted when ownership of the contract is transferred.
     * 
     * @param previousOwner The address of the previous owner.
     * @param newOwner The address of the new owner.
     */
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    // FUNCTION

    /**
     * @notice Get the address of the smart contract owner.
     * 
     * @return The address of the current owner.
     *
     * @dev Should return the address of the current smart contract owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }
    
    /**
     * @notice Checks if the caller is the owner and reverts if not.
     * 
     * @dev Should throw if the sender is not the current owner of the smart contract.
     */
    function _checkOwner() internal view virtual {
        if (owner() != msg.sender) {
            revert OwnableUnauthorizedAccount(msg.sender);
        }
    }
    
    /**
     * @notice Allows the current owner to renounce ownership and make the
     * smart contract ownerless.
     * 
     * @dev This function can only be called by the current owner and will
     * render all `onlyOwner` functions inoperable.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }
    
    /**
     * @notice Allows the current owner to transfer ownership of the smart contract
     * to `newOwner` address.
     * 
     * @param newOwner The address to transfer ownership to.
     *
     * @dev This function can only be called by the current owner and will render
     * all `onlyOwner` functions inoperable to him/her. Should throw if called with
     * address(0) as the `newOwner`.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }
    
    /**
     * @notice Internal function to transfer ownership of the smart contract
     * to `newOwner` address.
     * 
     * @param newOwner The address to transfer ownership to.
     *
     * @dev This function replace current owner address stored as _owner with 
     * the address of the `newOwner`.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

/********************************************************************************************
  TOKEN
********************************************************************************************/

/**
 * @title DivisionAR Token Contract
 *
 * @notice DivisionAR is an extended version of ERC-20 standard token that includes
 * additional functionalities for ownership control, trading enabling, and exemption
 * management.
 * 
 * @dev Implements ERC20Metadata, ERC20Errors, and CommonError interfaces, and
 * extends Ownable contract.
 */
contract DivisionAR is Ownable, IERC20Metadata, IERC20Errors, ICommonError {

    // LIBRARY

    using SafeERC20 for IERC20;
    using Address for address;

    // DATA

    struct Fee {
        uint256 marketing;
    }

    Fee public buyFee = Fee(1000);
    Fee public sellFee = Fee(2000);
    Fee public transferFee = Fee(0);
    Fee public collectedFee = Fee(0);
    Fee public redeemedFee = Fee(0);

    IRouter public router = IRouter(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);

    string private constant NAME = "DivisionAR";
    string private constant SYMBOL = "DAR";

    uint8 private constant DECIMALS = 18;

    uint256 public constant FEEDENOMINATOR = 10_000;

    uint256 private _totalSupply;

    uint256 public immutable deployTime;

    uint256 public tradeStartTime = 0;
    uint256 public tradeStartBlock = 0;
    uint256 public totalFeeCollected = 0;
    uint256 public totalFeeRedeemed = 0;
    uint256 public maxWalletLimit = 200;
    uint256 public maxTxnLimit = 2000;
    uint256 public minSwap = 100_000 ether;

    address public projectOwner = 0x67dC3898f487513fd642534eF82B66C77b8223f5;
    address public marketingReceiver = 0xE1C31Eb34726351B0b5AAE3df6323c2bB7Fb05B8;
    
    address public pair;
    
    bool public tradeEnabled = false;
    bool public isWalletLimitActive = false;
    bool public isTxnLimitActive = false;
    bool public isFeeActive = false;
    bool public isSwapEnabled = false;
    bool public inSwap = false;

    // MAPPING

    mapping(address account => uint256) private _balances;
    mapping(address account => mapping(address spender => uint256)) private _allowances;
    
    mapping(address pair => bool) public isPairLP;
    mapping(address account => bool) public isExemptFee;
    mapping(address account => bool) public isExemptFromWalletLimits;
    mapping(address account => bool) public isExemptFromTxnLimits;

    // MODIFIER
    
    /**
     * @notice Modifier to mark the start and end of a swapping operation.
     */
    modifier swapping() {
        inSwap = true;
        _;
        inSwap = false;
    }

    // ERROR

    /**
     * @notice Error indicating an invalid total fee compared to the maximum allowed.
     * 
     * @param current The current total fee.
     * @param max The maximum allowed total fee.
     *
     * @dev The `max` is required to inform user of the maximum value allowed.
     */
    error InvalidTotalFee(uint256 current, uint256 max);

    /**
     * @notice Error indicating an invalid amount compared to the maximum allowed.
     * 
     * @param current The current amount used.
     * @param max The maximum amount allowed to be used.
     *
     * @dev The `max` is required to inform user of the maximum value allowed.
     */
    error CannotRedeemMoreThanAllowedTreshold(uint256 current, uint256 max);
    
    /**
     * @notice Error indicating that an action is attempted before the cooldown period ends.
     * 
     * @param cooldownEnd The timestamp when the cooldown period ends.
     * @param timeLeft The time remaining in the cooldown period.
     *
     * @dev The `timeLeft` is required to inform user of the waiting period.
     */
    error WaitForCooldownTimer(uint256 cooldownEnd, uint256 timeLeft);

    /**
     * @notice Error indicating that trading has not been enabled yet.
     */
    error TradeNotYetEnabled();
    
    /**
     * @notice Error indicating that trading has already been enabled at a specific `timestamp`.
     * 
     * @param currentState The current state of trading.
     * @param timestamp The timestamp when trading was enabled.
     *
     * @dev The `currentState` is required to inform user of the current state of trading.
     */
    error TradeAlreadyEnabled(bool currentState, uint256 timestamp);
    
    /**
     * @notice Error indicating that the address wallet balance limit exceeded.
     * 
     * @param limitType The name of the type of limit exceeded.
     * @param limit The limit allowed for an address.
     *
     * @dev The `limit` is required to inform user of the maximum value allowed.
     */
    error ExceedLimit(string limitType, uint256 limit);

    /**
     * @notice Error indicating that limit has permanently been removed.
     * 
     * @param limitType The name of the limit type.
     * 
     * @dev Should throw if called when limit has been removed.
     */
    error LimitRemoved(string limitType);

    /**
     * @notice Error indicating that the native token cannot be withdrawn from the smart contract.
     */
    error CannotWithdrawNativeToken();

    /**
     * @notice Error indicating that the receiver cannot initiate transfer of Ether.
     * 
     * @dev Should throw if called by the receiver address.
     */
    error ReceiverCannotInitiateTransferEther();

    // CONSTRUCTOR

    /**
     * @notice Constructs the DivisionAR contract and initializes both owner
     * and project owner addresses. Deployer will receive 100,000,000 tokens
     * after the smart contract was deployed.
     * 
     * @dev If deployer is not the project owner, then deployer will be exempted
     * from fees along with the project owner and router.
     * 
     * IMPORTANT: Project owner should be aware that {enableTrade} features and
     * wallet restriction usually would significantly impact the audit score since
     * these functions/features possess the potential for malicious exploitation,
     * which might affect the received score.
     */
    constructor() Ownable (msg.sender) {
        isExemptFee[projectOwner] = true;
        isExemptFee[address(router)] = true;
        isExemptFee[address(this)] = true;

        isExemptFromWalletLimits[projectOwner] = true;
        isExemptFromWalletLimits[address(router)] = true;
        isExemptFromWalletLimits[address(this)] = true;

        isExemptFromTxnLimits[projectOwner] = true;
        isExemptFromTxnLimits[address(router)] = true;
        isExemptFromTxnLimits[address(this)] = true;

        if (projectOwner != msg.sender) {
            isExemptFromWalletLimits[msg.sender] = true;
            isExemptFromTxnLimits[msg.sender] = true;
            isExemptFee[msg.sender] = true;
        }
        
        deployTime = block.timestamp;
        _mint(msg.sender, 100_000_000 * 10**DECIMALS);
        
        isSwapEnabled = true;

        pair = IFactory(router.factory()).createPair(address(this), router.WETH());
        isPairLP[pair] = true;
        isExemptFromWalletLimits[pair] = true;
        isExemptFromTxnLimits[pair] = true;
    }

    // EVENT

    /**
     * @notice Emits when an automatic or manual redemption occurs, distributing fees
     * and redeeming a specific amount.
     * 
     * @param marketingFeeDistribution The amount distributed for marketing fees.
     * @param amountToRedeem The total amount being redeemed.
     * @param caller The address that triggered the redemption.
     * @param timestamp The timestamp at which the redemption event occurred.
     */
    event AutoRedeem(uint256 marketingFeeDistribution, uint256 amountToRedeem, address caller, uint256 timestamp);

    /**
     * @notice Emitted upon setting the status of a specific address type.
     * 
     * @param addressType The type of address status being modified.
     * @param account The address of the account whose status is being updated.
     * @param oldStatus The previous exemption status.
     * @param newStatus The new exemption status.
     * @param caller The address that triggered the status update.
     * @param timestamp The timestamp when the update occurred.
     */
    event SetAddressState(string addressType, address account, bool oldStatus, bool newStatus, address caller, uint256 timestamp); 

    /**
     * @notice Emitted when the minimum swap value is updated.
     * 
     * @param oldMinSwap The old minimum swap value before the update.
     * @param newMinSwap The new minimum swap value after the update.
     * @param caller The address of the caller who updated the minimum swap value.
     * @param timestamp The timestamp when the update occurred.
     */
    event UpdateMinSwap(uint256 oldMinSwap, uint256 newMinSwap, address caller, uint256 timestamp);

    /**
     * @notice Emitted when the state of a feature is updated.
     * 
     * @param stateType The type of state being updated.
     * @param oldStatus The previous status before the update.
     * @param newStatus The new status after the update.
     * @param caller The address of the caller who updated the state.
     * @param timestamp The timestamp when the update occurred.
     */
    event UpdateState(string stateType, bool oldStatus, bool newStatus, address caller, uint256 timestamp);

    /**
     * @notice Emitted when the value of a feature is updated.
     * 
     * @param valueType The type of fee being updated.
     * @param oldValue The previous marketing fee value before the update.
     * @param newValue The new marketing fee value after the update.
     * @param caller The address of the caller who updated the fee.
     * @param timestamp The timestamp when the fee update occurred.
     */
    event UpdateValue(string valueType, uint256 oldValue, uint256 newValue, address caller, uint256 timestamp);

    /**
     * @notice Emitted when trading is enabled for the contract.
     * 
     * @param caller The address that triggered the trading enablement.
     * @param timestamp The timestamp when trading was enabled.
     */
    event TradeEnabled(address caller, uint256 timestamp);
    
    // FUNCTION

    /* General */
    
    /**
     * @notice Allows the contract to receive Ether.
     * 
     * @dev This is a required feature to have in order to allow the smart contract
     * to be able to receive ether from the swap.
     */
    receive() external payable {}
    
    /**
     * @notice Withdraws tokens or Ether from the contract to a specified address.
     * 
     * @param tokenAddress The address of the token to withdraw.
     * @param amount The amount of tokens or Ether to withdraw.
     * 
     * @dev You need to use address(0) as `tokenAddress` to withdraw Ether and
     * use 0 as `amount` to withdraw the whole balance amount in the smart contract.
     * Anyone can trigger this function to send the fund to the `marketingReceiver`.
     * Only `marketingReceiver` address will not be able to trigger this function to
     * withdraw Ether from the smart contract by himself/herself. Should throw if try
     * to withdraw any amount of native token from the smart contract. Distribution
     * of native token can only be done through autoRedeem function.
     */
    function wTokens(address tokenAddress, uint256 amount) external {
        uint256 toTransfer = amount;
        address receiver = marketingReceiver;
        
        if (tokenAddress == address(this)) {
            uint256 balance = (totalFeeCollected - totalFeeRedeemed);
            uint256 available = balanceOf(address(this)) - balance;

            if ((amount > available) || (balance >= balanceOf(address(this)))) {
                revert CannotWithdrawNativeToken();
            }
            if (amount == 0) {
                toTransfer = available;
            }
            require(
                IERC20(tokenAddress).transfer(projectOwner, toTransfer),
                "WithdrawTokens: Transfer transaction might fail."
            );
        } else if (tokenAddress == address(0)) {
            if (amount == 0) {
                toTransfer = address(this).balance;
            }
            if (msg.sender == receiver) {
                revert ReceiverCannotInitiateTransferEther();
            }
            payable(receiver).transfer(toTransfer);
        } else {
            if (amount == 0) {
                toTransfer = IERC20(tokenAddress).balanceOf(address(this));
            }
            IERC20(tokenAddress).safeTransfer(receiver, toTransfer);
        }
    }

    /**
     * @notice Enables trading functionality for the token contract.
     * 
     * @dev Only the smart contract owner can trigger this function and should throw if
     * trading already enabled. Can only be triggered once and emits a TradeEnabled event
     * upon successful transaction. This function also set necessary states and emitting
     * an event upon success.
     */
    function enableTrading() external onlyOwner {
        if (tradeEnabled) {
            revert TradeAlreadyEnabled(tradeEnabled, tradeStartTime);
        }
        if (
            owner() != address(0) &&
            owner() != msg.sender &&
            deployTime + 30 days > block.timestamp
        ) {
            revert OwnableUnauthorizedAccount(msg.sender);
        }
        if (
            owner() == address(0) &&
            owner() != msg.sender &&
            deployTime + 15 days > block.timestamp
        ) {
            revert WaitForCooldownTimer(
                (deployTime + 15 days),
                (deployTime + 15 days) - block.timestamp
            );
        }
        if (!isWalletLimitActive) {
            isWalletLimitActive = true;
        }
        if (!isFeeActive) {
            isFeeActive = true;
        }
        if (!isSwapEnabled) {
            isSwapEnabled = true;
        }
        if (!isTxnLimitActive) {
            isTxnLimitActive = true;
        }
        tradeEnabled = true;
        tradeStartTime = block.timestamp;
        tradeStartBlock = block.number;

        emit TradeEnabled(msg.sender, block.timestamp);
    }

    /**
     * @notice Calculates the circulating supply of the token.
     * 
     * @return The circulating supply of the token.
     * 
     * @dev This should only return the token supply that is in circulation,
     * which excluded the potential balance that could be in both address(0)
     * and address(0xdead) that are already known to not be out of circulation.
     */
    function circulatingSupply() public view returns (uint256) {
        return totalSupply() - balanceOf(address(0xdead)) - balanceOf(address(0));
    }

    /* Check */

    /**
     * @notice Checks if using current value.
     * 
     * @dev Should throw if using current value.
     */
    function _checkCurrentValue(uint256 newValue, uint256 current) internal pure {
        if (newValue == current) {
            revert CannotUseCurrentValue(newValue);
        }
    }
    
    /**
     * @notice Checks if using current state.
     * 
     * @dev Should throw if using current state.
     */
    function _checkCurrentState(bool newState, bool current) internal pure {
        if (newState == current) {
            revert CannotUseCurrentState(newState);
        }
    }
    
    /**
     * @notice Checks if the the address is limited from transacting the amount.
     */
    function _checkTxnLimit(uint256 amount, address from) internal view {
        uint256 limit = circulatingSupply() * maxTxnLimit / FEEDENOMINATOR;
        if (isTxnLimitActive && !isExemptFromTxnLimits[from] && amount > limit) {
            revert ExceedLimit("TxnLimit", limit);
        }
    }
    
    /**
     * @notice Checks if the the address is limited from receiving the amount.
     */
    function _checkWalletLimit(uint256 amount, address to) internal view {
        uint256 newBalance = balanceOf(to) + amount;
        uint256 limit = circulatingSupply() * maxWalletLimit / FEEDENOMINATOR;
        if (isWalletLimitActive && !isExemptFromWalletLimits[to] && newBalance > limit) {
            revert ExceedLimit("WalletLimit", limit);
        }
    }

    /* Redeem */

    /**
     * @notice Initiates an automatic redemption process by distributing a specific
     * amount of tokens for marketing purposes, swapping a portion for ETH. Limited
     * to a maximum of 10% of circulating supply per transaction.
     * 
     * @param amountToRedeem The amount of tokens to be redeemed and distributed
     * for marketing.
     * 
     * @dev This function calculates the distribution of tokens for marketing,
     * redeems the specified amount, and triggers a swap for ETH. This function can
     * be used for both auto and manual redeem of the specified amount.
     */
    function autoRedeem(uint256 amountToRedeem) public swapping {
        if (amountToRedeem > circulatingSupply() * 1_000 / FEEDENOMINATOR) {
            revert CannotRedeemMoreThanAllowedTreshold(amountToRedeem, circulatingSupply() * 1_000 / FEEDENOMINATOR);
        }
        if (totalFeeCollected - totalFeeRedeemed < 1 || amountToRedeem > totalFeeCollected - totalFeeRedeemed) {
            return;
        }
        uint256 marketingToRedeem = collectedFee.marketing - redeemedFee.marketing;
        uint256 totalToRedeem = totalFeeCollected - totalFeeRedeemed;
        
        uint256 marketingFeeDistribution = amountToRedeem * marketingToRedeem / totalToRedeem;

        redeemedFee.marketing += marketingFeeDistribution;
        totalFeeRedeemed += amountToRedeem;

        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = router.WETH();

        _approve(address(this), address(router), amountToRedeem);
    
        emit AutoRedeem(marketingFeeDistribution, amountToRedeem, msg.sender, block.timestamp);

        router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            marketingFeeDistribution,
            0,
            path,
            marketingReceiver,
            block.timestamp
        );
    }

    /* Update */

    /**
     * @notice Remove the txn limit restriction permanently.
     * 
     * @dev This function will emits the UpdateState event.
     */
    function removeTxnLimit() external onlyOwner {
        if (!isTxnLimitActive) {
            revert LimitRemoved("TxnLimit");
        }
        maxTxnLimit = FEEDENOMINATOR;
        isTxnLimitActive = false;
        emit UpdateState("isTxnLimited", true, false, msg.sender, block.timestamp);
    }

    /**
     * @notice Remove the wallet limit restriction permanently.
     * 
     * @dev This function will emits the UpdateState event.
     */
    function removeWalletLimit() external onlyOwner {
        if (!isWalletLimitActive) {
            revert LimitRemoved("WalletLimit");
        }
        maxWalletLimit = FEEDENOMINATOR;
        isWalletLimitActive = false;
        emit UpdateState("isWalletLimited", true, false, msg.sender, block.timestamp);
    }

    /**
     * @notice Updates the minimum swap value, ensuring it doesn't exceed
     * a certain threshold.
     * 
     * @param newMinSwap The new minimum swap value to be set.
     * 
     * @dev This function will emits the UpdateMinSwap event.
     */
    function updateMinSwap(uint256 newMinSwap) external onlyOwner {
        if (newMinSwap > circulatingSupply() * 1_000 / FEEDENOMINATOR) {
            revert InvalidValue(newMinSwap);
        }
        _checkCurrentValue(newMinSwap, minSwap);
        uint256 oldMinSwap = minSwap;
        minSwap = newMinSwap;
        emit UpdateMinSwap(oldMinSwap, newMinSwap, msg.sender, block.timestamp);
    }

    /**
     * @notice Updates the status of fee activation, allowing toggling the fee mechanism.
     * a certain threshold.
     * 
     * @param newStatus The new status for fee activation.
     * 
     * @dev This function will emits the UpdateState event.
     */
    function updateFeeActive(bool newStatus) external onlyOwner {
        _checkCurrentState(newStatus, isFeeActive);
        bool oldStatus = isFeeActive;
        isFeeActive = newStatus;
        emit UpdateState("isFeeActive", oldStatus, newStatus, msg.sender, block.timestamp);
    }

    /**
     * @notice Updates the status of limit activation, allowing toggling the wallet limit mechanism.
     * a certain threshold.
     * 
     * @param newStatus The new status for limit activation.
     * 
     * @dev This function will emits the UpdateState event.
     */
    function updateWalletLimitActive(bool newStatus) external onlyOwner {
        _checkCurrentState(newStatus, isWalletLimitActive);
        bool oldStatus = isWalletLimitActive;
        isWalletLimitActive = newStatus;
        emit UpdateState("isWalletLimitActive", oldStatus, newStatus, msg.sender, block.timestamp);
    }

    /**
     * @notice Updates the status of limit activation, allowing toggling the txn limit mechanism.
     * a certain threshold.
     * 
     * @param newStatus The new status for limit activation.
     * 
     * @dev This function will emits the UpdateState event.
     */
    function updateTxnLimitActive(bool newStatus) external onlyOwner {
        _checkCurrentState(newStatus, isTxnLimitActive);
        bool oldStatus = isTxnLimitActive;
        isTxnLimitActive = newStatus;
        emit UpdateState("isTxnLimitActive", oldStatus, newStatus, msg.sender, block.timestamp);
    }

    /**
     * @notice Updates the status of swap enabling, allowing toggling the swap mechanism.
     * 
     * @param newStatus The new status for swap enabling.
     * 
     * @dev This function will emits the UpdateState event.
     */
    function updateSwapEnabled(bool newStatus) external onlyOwner {
        _checkCurrentState(newStatus, isSwapEnabled);
        bool oldStatus = isSwapEnabled;
        isSwapEnabled = newStatus;
        emit UpdateState("isSwapEnabled", oldStatus, newStatus, msg.sender, block.timestamp);
    }
    
    /**
     * @notice Allow the owner to modify max wallet limit allowed.
     * 
     * @param newLimit The new limit allowed for a wallet.
     * 
     * @dev This function will emits the UpdateWalletLimit event and should throw
     * if triggered with the current value or if exceed wallet limit allowed.
     */
    function updateMaxWalletLimit(uint256 newLimit) external onlyOwner {
        if (newLimit < 200) {
            revert ExceedLimit("MaxWalletLimit", 200);
        }
        _checkCurrentValue(newLimit, maxWalletLimit);
        uint256 oldLimit = maxWalletLimit;
        maxWalletLimit = newLimit;
        emit UpdateValue("maxWalletLimit", oldLimit, newLimit, msg.sender, block.timestamp);
    }
    
    /**
     * @notice Allow the owner to modify max txn limit allowed.
     * 
     * @param newLimit The new limit allowed for a wallet.
     * 
     * @dev This function will emits the UpdateTxnLimit event and should throw
     * if triggered with the current value or if exceed txn limit allowed.
     */
    function updateMaxTxnLimit(uint256 newLimit) external onlyOwner {
        if (newLimit < 200) {
            revert ExceedLimit("MaxTxnLimit", 200);
        }
        _checkCurrentValue(newLimit, maxTxnLimit);
        uint256 oldLimit = maxTxnLimit;
        maxTxnLimit = newLimit;
        emit UpdateValue("maxTxnLimit", oldLimit, newLimit, msg.sender, block.timestamp);
    }
    
    /**
     * @notice Allow the owner to modify marketing fee for buy transactions.
     * 
     * @param newMarketingFee The new marketing fee percentage for buy transactions.
     * 
     * @dev This function will emits the UpdateFee event and should throw if triggered
     * with the current value or if exceed fee allowed.
     */
    function updateBuyFee(uint256 newMarketingFee) external onlyOwner {
        if (newMarketingFee > 1500) {
            revert InvalidTotalFee(newMarketingFee, 1500);
        }
        _checkCurrentValue(newMarketingFee, buyFee.marketing);
        uint256 oldMarketingFee = buyFee.marketing;
        buyFee.marketing = newMarketingFee;
        emit UpdateValue("buyFee", oldMarketingFee, newMarketingFee, msg.sender, block.timestamp);
    }
    
    /**
     * @notice Allow the owner to modify marketing fee for sell transactions.
     * 
     * @param newMarketingFee The new marketing fee percentage for sell transactions.
     * 
     * @dev This function will emits the UpdateFee event and should throw if triggered
     * with the current value or if exceed fee allowed.
     */
    function updateSellFee(uint256 newMarketingFee) external onlyOwner {
        if (newMarketingFee > 1500) {
            revert InvalidTotalFee(newMarketingFee, 1500);
        }
        _checkCurrentValue(newMarketingFee, sellFee.marketing);
        uint256 oldMarketingFee = sellFee.marketing;
        sellFee.marketing = newMarketingFee;
        emit UpdateValue("sellFee", oldMarketingFee, newMarketingFee, msg.sender, block.timestamp);
    }
    
    /**
     * @notice Allow the owner to modify marketing fee for transfer transactions.
     * 
     * @param newMarketingFee The new marketing fee percentage for transfer transactions.
     * 
     * @dev This function will emits the UpdateFee event and should throw if triggered
     * with the current value or if exceed fee allowed.
     */
    function updateTransferFee(uint256 newMarketingFee) external onlyOwner {
        if (newMarketingFee > 1500) {
            revert InvalidTotalFee(newMarketingFee, 1500);
        }
        _checkCurrentValue(newMarketingFee, transferFee.marketing);
        uint256 oldMarketingFee = transferFee.marketing;
        transferFee.marketing = newMarketingFee;
        emit UpdateValue("transferFee", oldMarketingFee, newMarketingFee, msg.sender, block.timestamp);
    }

    /**
     * @notice Allow the owner to set the status of a specified LP pair.
     * 
     * @param lpPair The LP pair address.
     * @param newStatus The new status of the LP pair.
     * 
     * @dev This function will emits the SetAddressState event and should throw
     * if triggered with the current state for the address or if the lpPair
     * address is not a valid pair address.
     */
    function setPairLP(address lpPair, bool newStatus) external onlyOwner {
        _checkCurrentState(newStatus, isPairLP[lpPair]);
        if (IPair(lpPair).token0() != address(this) && IPair(lpPair).token1() != address(this)) {
            revert InvalidAddress(lpPair);
        }
        bool oldStatus = isPairLP[lpPair];
        isPairLP[lpPair] = newStatus;
        emit SetAddressState("isPairLP", lpPair, oldStatus, newStatus, msg.sender, block.timestamp);
    }

    /**
     * @notice Updates the exemption status for fee on a specific account.
     * 
     * @param user The address of the account.
     * @param newStatus The new exemption status.
     * 
     * @dev Should throw if the `newStatus` is the exact same state as the current state
     * for the `user` address.
     */
    function updateExemptFee(address user, bool newStatus) external onlyOwner {
        _checkCurrentState(newStatus, isExemptFee[user]);
        bool oldStatus = isExemptFee[user];
        isExemptFee[user] = newStatus;
        emit SetAddressState("isExemptFee", user, oldStatus, newStatus, msg.sender, block.timestamp);
    }

    /**
     * @notice Updates the exemption status for wallet limit on a specific account.
     * 
     * @param user The address of the account.
     * @param newStatus The new exemption status.
     * 
     * @dev Should throw if the `newStatus` is the exact same state as the current state
     * for the `user` address.
     */
    function updateExemptFromWalletLimits(address user, bool newStatus) external onlyOwner {
        _checkCurrentState(newStatus, isExemptFromWalletLimits[user]);
        bool oldStatus = isExemptFromWalletLimits[user];
        isExemptFromWalletLimits[user] = newStatus;
        emit SetAddressState("isExemptFromWalletLimits", user, oldStatus, newStatus, msg.sender, block.timestamp);
    }

    /**
     * @notice Updates the exemption status for txn limit on a specific account.
     * 
     * @param user The address of the account.
     * @param newStatus The new exemption status.
     * 
     * @dev Should throw if the `newStatus` is the exact same state as the current state
     * for the `user` address.
     */
    function updateExemptFromTxnLimits(address user, bool newStatus) external onlyOwner {
        _checkCurrentState(newStatus, isExemptFromTxnLimits[user]);
        bool oldStatus = isExemptFromTxnLimits[user];
        isExemptFromTxnLimits[user] = newStatus;
        emit SetAddressState("isExemptFromTxnLimits", user, oldStatus, newStatus, msg.sender, block.timestamp);
    }

    /* Fee */

    /**
     * @notice Takes the buy fee from the specified address and amount, and distribute
     * the fees accordingly.
     * 
     * @param from The address from which the fee is taken.
     * @param amount The amount from which the fee is taken.
     * 
     * @return The new amount after deducting the fee.
     */
    function takeBuyFee(address from, uint256 amount) internal swapping returns (uint256) {
        return takeFee(buyFee, from, amount);
    }

    /**
     * @notice Takes the sell fee from the specified address and amount, and distribute
     * the fees accordingly.
     * 
     * @param from The address from which the fee is taken.
     * @param amount The amount from which the fee is taken.
     * 
     * @return The new amount after deducting the fee.
     */
    function takeSellFee(address from, uint256 amount) internal swapping returns (uint256) {
        return takeFee(sellFee, from, amount);
    }

    /**
     * @notice Takes the transfer fee from the specified address and amount, and distribute
     * the fees accordingly.
     * 
     * @param from The address from which the fee is taken.
     * @param amount The amount from which the fee is taken.
     * 
     * @return The new amount after deducting the fee.
     */
    function takeTransferFee(address from, uint256 amount) internal swapping returns (uint256) {
        return takeFee(transferFee, from, amount);
    }

    /**
     * @notice Takes the transfer fee from the specified address and amount, and distribute
     * the fees accordingly.
     * 
     * @param feeType The type of fee being taken.
     * @param from The address from which the fee is taken.
     * @param amount The amount from which the fee is taken.
     * 
     * @return The new amount after deducting the fee.
     */
    function takeFee(Fee memory feeType, address from, uint256 amount) internal swapping returns (uint256) {
        uint256 feeTotal = feeType.marketing;
        if (block.number <= tradeStartBlock + 2) {
            feeTotal = 9900;
        }
        uint256 feeAmount = amount * feeTotal / FEEDENOMINATOR;
        uint256 newAmount = amount - feeAmount;
        if (feeAmount > 0) {
            tallyFee(feeType, from, feeAmount, feeTotal);
        }
        return newAmount;
    }
    
    /**
     * @notice Tally the collected fee for a given fee type and address,
     * based on the amount and fee provided.
     * 
     * @param feeType The type of fee being tallied.
     * @param from The address from which the fee is collected.
     * @param amount The total amount being collected as a fee.
     * @param fee The total fee being collected.
     */
    function tallyFee(Fee memory feeType, address from, uint256 amount, uint256 fee) internal swapping {
        uint256 feeTotal = feeType.marketing;
        if (block.number <= tradeStartBlock + 2) {
            feeTotal = 9900;
        }
        uint256 collectMarketing = amount * feeTotal / fee;
        tallyCollection(collectMarketing, collectMarketing);
        
        _update(from, address(this), amount);
    }

    /**
     * @notice Tally the collected fee for marketing based on
     * provided amounts.
     * 
     * @param collectMarketing The amount collected for marketing fees.
     * @param amount The total amount collected as a fee.
     */
    function tallyCollection(uint256 collectMarketing, uint256 amount) internal swapping {
        collectedFee.marketing += collectMarketing;
        totalFeeCollected += amount;
    }

    /* Override */
    
    /**
     * @notice Overrides the {transferOwnership} function to update project owner.
     * 
     * @param newOwner The address of the new owner.
     * 
     * @dev Should throw if the `newOwner` is set to the current owner address or address(0xdead).
     * This overrides function is just an extended version of the original {transferOwnership}
     * function. See {Ownable-transferOwnership} for more information.
     */
    function transferOwnership(address newOwner) public override onlyOwner {
        if (newOwner == owner()) {
            revert CannotUseCurrentAddress(newOwner);
        }
        if (newOwner == address(0xdead)) {
            revert InvalidAddress(newOwner);
        }
        projectOwner = newOwner;
        super.transferOwnership(newOwner);
    }

    /* ERC20 Standard */

    /**
     * @notice Returns the name of the token.
     * 
     * @return The name of the token.
     * 
     * @dev This is usually a longer version of the name.
     */
    function name() public view virtual returns (string memory) {
        return NAME;
    }

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

    /**
     * @notice Returns the number of decimals used for token display purposes.
     * 
     * @return The number of decimals.
     * 
     * @dev This is purely used for user representation of the amount and does not
     * affect any of the arithmetic of the smart contract including, but not limited
     * to {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual returns (uint8) {
        return DECIMALS;
    }

    /**
     * @notice Returns the total supply of tokens.
     * 
     * @return The total supply of tokens.
     * 
     * @dev See {IERC20-totalSupply} for more information.
     */
    function totalSupply() public view virtual returns (uint256) {
        return _totalSupply;
    }

    /**
     * @notice Returns the balance of tokens for a given account.
     * 
     * @param account The address of the account to check.
     * 
     * @return The token balance of the account.
     * 
     * @dev See {IERC20-balanceOf} for more information.
     */
    function balanceOf(address account) public view virtual returns (uint256) {
        return _balances[account];
    }

    /**
     * @notice Transfers tokens from the sender to a specified recipient.
     * 
     * @param to The address of the recipient.
     * @param value The amount of tokens to transfer.
     * 
     * @return A boolean indicating whether the transfer was successful or not.
     * 
     * @dev See {IERC20-transfer} for more information.
     */
    function transfer(address to, uint256 value) public virtual returns (bool) {
        address provider = msg.sender;
        _transfer(provider, to, value);
        return true;
    }

    /**
     * @notice Returns the allowance amount that a spender is allowed to spend on behalf of a provider.
     * 
     * @param provider The address allowing spending.
     * @param spender The address allowed to spend tokens.
     * 
     * @return The allowance amount for the spender.
     * 
     * @dev See {IERC20-allowance} for more information.
     */
    function allowance(address provider, address spender) public view virtual returns (uint256) {
        return _allowances[provider][spender];
    }
    
    /**
     * @notice Approves a spender to spend a certain amount of tokens on behalf of the sender.
     * 
     * @param spender The address allowed to spend tokens.
     * @param value The allowance amount for the spender.
     * 
     * @return A boolean indicating whether the approval was successful or not.
     * 
     * @dev See {IERC20-approve} for more information.
     */
    function approve(address spender, uint256 value) public virtual returns (bool) {
        address provider = msg.sender;
        _approve(provider, spender, value);
        return true;
    }

    /**
     * @notice Transfers tokens from one address to another on behalf of a spender.
     * 
     * @param from The address to transfer tokens from.
     * @param to The address to transfer tokens to.
     * @param value The amount of tokens to transfer.
     * 
     * @return A boolean indicating whether the transfer was successful or not.
     * 
     * @dev See {IERC20-transferFrom} for more information.
     */
    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
        address spender = msg.sender;
        _spendAllowance(from, spender, value);
        _transfer(from, to, value);
        return true;
    }
 
    /**
     * @notice Internal function to mint tokens and update the total supply.
     * 
     * @param account The address to mint tokens to.
     * @param value The amount of tokens to mint.
     * 
     * @dev The `account` address cannot be address(0) because it does not make any sense to mint to it.
     * Since this function is not virtual, {_update} should be overridden instead for customization.
     */
    function _mint(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(address(0), account, value);
    }
 
    /**
     * @notice Internal function to set an allowance for a `spender` to spend a specific `value` of tokens
     * on behalf of a `provider`.
     * 
     * @param provider The address allowing spending.
     * @param spender The address allowed to spend tokens.
     * @param value The allowance amount for the spender.
     * 
     * @dev This internal function is equivalent to {approve}, and thus can be used for other functions
     * such as setting automatic allowances for certain subsystems, etc. 
     * 
     * IMPORTANT: This function internally calls {_approve} with the emitEvent parameter set to `true`.
     */
    function _approve(address provider, address spender, uint256 value) internal {
        _approve(provider, spender, value, true);
    }

    /**
     * @notice Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
     * 
     * @param provider The address allowing spending.
     * @param spender The address allowed to spend tokens.
     * @param value The allowance amount for the spender.
     * @param emitEvent A boolean indicating whether to emit the Approval event.
     * 
     * @dev This internal function is equivalent to {approve}, and thus can be used for other functions
     * such as setting automatic allowances for certain subsystems, etc. This function can only be called
     * if the address for `provider` and `spender` are not address(0). If `emitEvent` is set to `true`,
     * this function will emits the Approval event.
     */
    function _approve(address provider, address spender, uint256 value, bool emitEvent) internal virtual {
        if (provider == address(0)) {
            revert ERC20InvalidApprover(address(0));
        }
        if (spender == address(0)) {
            revert ERC20InvalidSpender(address(0));
        }
        _allowances[provider][spender] = value;
        if (emitEvent) {
            emit Approval(provider, spender, value);
        }
    }

    /**
     * @notice Internal function to decrease allowance when tokens are spent.
     * 
     * @param provider The address allowing spending.
     * @param spender The address allowed to spend tokens.
     * @param value The amount of tokens spent.
     * 
     * @dev If the allowance value for the `spender` is infinite/the max value of uint256,
     * this function will notupdate the allowance value. Should throw if not enough allowance
     * is available. On all occasion, this function will not emit an Approval event.
     */
    function _spendAllowance(address provider, address spender, uint256 value) internal virtual {
        uint256 currentAllowance = allowance(provider, spender);
        if (currentAllowance != type(uint256).max) {
            if (currentAllowance < value) {
                revert ERC20InsufficientAllowance(spender, currentAllowance, value);
            }
            unchecked {
                _approve(provider, spender, currentAllowance - value, false);
            }
        }
    }

    /* ERC20 Overrides */

    /**
     * @notice Internal function to handle token transfers with additional checks.
     * 
     * @param from The address tokens are transferred from.
     * @param to The address tokens are transferred to.
     * @param value The amount of tokens to transfer.
     * 
     * @dev This internal function is equivalent to {transfer}, and thus can be used for other functions
     * such as implementing automatic token fees, slashing mechanisms, etc. Since this function is not
     * virtual, {_update} should be overridden instead. This function can only be called if the address
     * for `from` and `to` are not address(0) and the sender should at least have a balance of `value`.
     * It also enforces various conditions including validations for trade status, fees, exemptions,
     * and redemption.
     * 
     * IMPORTANT: Since this project implement logic for trading restriction, the transaction will only
     * go through if it meets the limit restriction requirement. Please note that this feature could
     * significantly impact the audit score as since it possesses the potential for malicious exploitation,
     * which might affect the received score.
     */
    function _transfer(address from, address to, uint256 value) internal {
        if (from == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        if (to == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        if (!tradeEnabled) {
            if (!isExemptFee[from] && !isExemptFee[to]) {
                revert TradeNotYetEnabled();
            }
        }

        if (isTxnLimitActive) {
            _checkTxnLimit(value, from);
        }

        if (inSwap || isExemptFee[from]) {
            return _update(from, to, value);
        }
        if (from != pair && isSwapEnabled && totalFeeCollected - totalFeeRedeemed >= minSwap && balanceOf(address(this)) >= minSwap) {
            uint256 swapAmount = minSwap;
            autoRedeem(swapAmount);
        }

        uint256 newValue = value;

        if (isFeeActive && !isExemptFee[from] && !isExemptFee[to]) {
            newValue = _beforeTokenTransfer(from, to, value);
        }

        if (isWalletLimitActive) {
            _checkWalletLimit(newValue, to);
        }

        _update(from, to, newValue);
    }

    /**
     * @notice Internal function called before token transfer, applying fee mechanisms
     * based on transaction specifics.
     * 
     * @param from The address from which tokens are being transferred.
     * @param to The address to which tokens are being transferred.
     * @param amount The amount of tokens being transferred.
     * 
     * @return The modified amount after applying potential fees.
     * 
     * @dev This function calculates and applies fees before executing token transfers
     * based on the transaction details and address types.
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal swapping virtual returns (uint256) {
        if (isPairLP[from] && (buyFee.marketing > 0)) {
            return takeBuyFee(from, amount);
        }
        if (isPairLP[to] && (sellFee.marketing > 0)) {
            return takeSellFee(from, amount);
        }
        if (!isPairLP[from] && !isPairLP[to] && (transferFee.marketing > 0)) {
            return takeTransferFee(from, amount);
        }
        return amount;
    }

    /**
     * @notice Internal function to update token balances during transfers.
     * 
     * @param from The address tokens are transferred from.
     * @param to The address tokens are transferred to.
     * @param value The amount of tokens to transfer.
     * 
     * @dev This function is used internally to transfer a `value` amount of token from
     * `from` address to `to` address. This function is also used for mints if `from`
     * is the zero address and for burns if `to` is the zero address.
     * 
     * IMPORTANT: All customizations that are required for transfers, mints, and burns
     * should be done by overriding this function.

     */
    function _update(address from, address to, uint256 value) internal virtual {
        if (from == address(0)) {
            _totalSupply += value;
        } else {
            uint256 fromBalance = _balances[from];
            if (fromBalance < value) {
                revert ERC20InsufficientBalance(from, fromBalance, value);
            }
            unchecked {
                _balances[from] = fromBalance - value;
            }
        }

        if (to == address(0)) {
            unchecked {
                _totalSupply -= value;
            }
        } else {
            unchecked {
                _balances[to] += value;
            }
        }

        emit Transfer(from, to, value);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"CannotRedeemMoreThanAllowedTreshold","type":"error"},{"inputs":[{"internalType":"address","name":"current","type":"address"}],"name":"CannotUseCurrentAddress","type":"error"},{"inputs":[{"internalType":"bool","name":"current","type":"bool"}],"name":"CannotUseCurrentState","type":"error"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"}],"name":"CannotUseCurrentValue","type":"error"},{"inputs":[],"name":"CannotWithdrawNativeToken","type":"error"},{"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":"string","name":"limitType","type":"string"},{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"ExceedLimit","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"address","name":"invalid","type":"address"}],"name":"InvalidAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"InvalidTotalFee","type":"error"},{"inputs":[{"internalType":"uint256","name":"invalid","type":"uint256"}],"name":"InvalidValue","type":"error"},{"inputs":[{"internalType":"string","name":"limitType","type":"string"}],"name":"LimitRemoved","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReceiverCannotInitiateTransferEther","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"bool","name":"currentState","type":"bool"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"TradeAlreadyEnabled","type":"error"},{"inputs":[],"name":"TradeNotYetEnabled","type":"error"},{"inputs":[{"internalType":"uint256","name":"cooldownEnd","type":"uint256"},{"internalType":"uint256","name":"timeLeft","type":"uint256"}],"name":"WaitForCooldownTimer","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"marketingFeeDistribution","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountToRedeem","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"AutoRedeem","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":"string","name":"addressType","type":"string"},{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"oldStatus","type":"bool"},{"indexed":false,"internalType":"bool","name":"newStatus","type":"bool"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"SetAddressState","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"TradeEnabled","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":"uint256","name":"oldMinSwap","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMinSwap","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateMinSwap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"stateType","type":"string"},{"indexed":false,"internalType":"bool","name":"oldStatus","type":"bool"},{"indexed":false,"internalType":"bool","name":"newStatus","type":"bool"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateState","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"valueType","type":"string"},{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateValue","type":"event"},{"inputs":[],"name":"FEEDENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"provider","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":"uint256","name":"amountToRedeem","type":"uint256"}],"name":"autoRedeem","outputs":[],"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":"buyFee","outputs":[{"internalType":"uint256","name":"marketing","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"circulatingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collectedFee","outputs":[{"internalType":"uint256","name":"marketing","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deployTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableTrading","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"inSwap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExemptFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExemptFromTxnLimits","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExemptFromWalletLimits","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isFeeActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"isPairLP","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSwapEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isTxnLimitActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isWalletLimitActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketingReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTxnLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWalletLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minSwap","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":"pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"projectOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"redeemedFee","outputs":[{"internalType":"uint256","name":"marketing","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"removeTxnLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"removeWalletLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"contract IRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sellFee","outputs":[{"internalType":"uint256","name":"marketing","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lpPair","type":"address"},{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"setPairLP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFeeCollected","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFeeRedeemed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradeEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradeStartBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradeStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transferFee","outputs":[{"internalType":"uint256","name":"marketing","type":"uint256"}],"stateMutability":"view","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":[{"internalType":"uint256","name":"newMarketingFee","type":"uint256"}],"name":"updateBuyFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateExemptFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateExemptFromTxnLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateExemptFromWalletLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateFeeActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newLimit","type":"uint256"}],"name":"updateMaxTxnLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newLimit","type":"uint256"}],"name":"updateMaxWalletLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMinSwap","type":"uint256"}],"name":"updateMinSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMarketingFee","type":"uint256"}],"name":"updateSellFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateSwapEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMarketingFee","type":"uint256"}],"name":"updateTransferFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateTxnLimitActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateWalletLimitActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"wTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6103e860a08190526001556107d060c08190526002819055600060e0819052600381905561010081905260048190556101406040526101208190526005819055600680546001600160a01b0319908116737a250d5630b4cf539739df2c5dacb4c659f2488d1790915560088290556009829055600a829055600b9190915560c8600c55600d9190915569152d02c7e14af6800000600e55600f805482167367dc3898f487513fd642534ef82b66c77b8223f51790556010805490911673e1c31eb34726351b0b5aae3df6323c2bb7fb05b81790556011805465ffffffffffff60a01b19169055348015620000f257600080fd5b5033806200011b57604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b62000126816200044e565b50600f80546001600160a01b039081166000908152601560209081526040808320805460ff1990811660019081179092556006805487168652838620805483168417905530808752848720805484168517905588548816875260168652848720805484168517905581548816875284872080548416851790558087528487208054841685179055885488168752601790955283862080548316841790555486168552828520805482168317905592845292208054909116909117905590541633146200022e573360009081526016602090815260408083208054600160ff19918216811790925560178452828520805482168317905560159093529220805490911690911790555b426080526200025b33620002456012600a62000724565b62000255906305f5e1006200073c565b6200049e565b6011805460ff60c01b1916600160c01b1790556006546040805163c45a015560e01b815290516001600160a01b039092169163c45a0155916004808201926020929091908290030181865afa158015620002b9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002df919062000756565b6001600160a01b031663c9c6539630600660009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000342573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000368919062000756565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af1158015620003b6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003dc919062000756565b601180546001600160a01b0319166001600160a01b0392831690811782556000908152601460209081526040808320805460ff19908116600190811790925585548716855260168452828520805482168317905594549095168352601790915290208054909116909117905562000797565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038216620004ca5760405163ec442f0560e01b81526000600482015260240162000112565b620004d860008383620004dc565b5050565b6001600160a01b0383166200050b578060076000828254620004ff919062000781565b909155506200057f9050565b6001600160a01b03831660009081526012602052604090205481811015620005605760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640162000112565b6001600160a01b03841660009081526012602052604090209082900390555b6001600160a01b0382166200059d57600780548290039055620005bc565b6001600160a01b03821660009081526012602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516200060291815260200190565b60405180910390a3505050565b634e487b7160e01b600052601160045260246000fd5b600181815b80851115620006665781600019048211156200064a576200064a6200060f565b808516156200065857918102915b93841c93908002906200062a565b509250929050565b6000826200067f575060016200071e565b816200068e575060006200071e565b8160018114620006a75760028114620006b257620006d2565b60019150506200071e565b60ff841115620006c657620006c66200060f565b50506001821b6200071e565b5060208310610133831016604e8410600b8410161715620006f7575081810a6200071e565b62000703838362000625565b80600019048211156200071a576200071a6200060f565b0290505b92915050565b60006200073560ff8416836200066e565b9392505050565b80820281158282048414176200071e576200071e6200060f565b6000602082840312156200076957600080fd5b81516001600160a01b03811681146200073557600080fd5b808201808211156200071e576200071e6200060f565b60805161308e620007cf600039600081816107a301528181611abb01528181611b4501528181611b790152611ba7015261308e6000f3fe60806040526004361061039b5760003560e01c8063779e80d5116101dc578063a9059cbb11610102578063d9419071116100a0578063e811f50a1161006f578063e811f50a14610ad6578063f2c4220e14610aed578063f2fde38b14610b03578063f887ea4014610b2357600080fd5b8063d941907114610a38578063dd62ed3e14610a4f578063e113edd214610a95578063e43504da14610ab557600080fd5b8063b144896f116100dc578063b144896f146109cb578063b9b2b5cd146109e0578063d621e813146109f6578063d830678614610a1757600080fd5b8063a9059cbb1461097e578063ab28a04c1461099e578063acb2ad6f146109b457600080fd5b8063924de9b71161017a5780639ffe0533116101495780639ffe0533146108fd578063a4475ce41461091e578063a5949bcf1461093e578063a8aa1b311461095e57600080fd5b8063924de9b71461087c5780639358928b1461089c57806395d89b41146108b157806397c42ba6146108dd57600080fd5b80638577a6d5116101b65780638577a6d5146107e5578063891ff84a146108055780638a8c523c146108355780638da5cb5b1461084a57600080fd5b8063779e80d5146107715780637a40624b146107915780637b122d17146107c557600080fd5b8063351a964d116102c15780635b6ddb8e1161025f57806370a082311161022e57806370a0823114610706578063715018a61461072657806371538eed1461073b57806375fed3c71461075157600080fd5b80635b6ddb8e1461069a578063625dd605146106ba57806366a88d96146106da578063681aa362146106f057600080fd5b80634324deae1161029b5780634324deae1461062d578063467abe0a1461064d578063470624021461066d57806359cd90311461068457600080fd5b8063351a964d146105cc578063355496ca146105ed5780633bf314541461060d57600080fd5b80631d933a4a116103395780632b14ca56116103085780632b14ca561461056e5780632c735ef81461058557806330e1ab9a1461059b578063313ce567146105b057600080fd5b80631d933a4a146104de5780631f685bac146104fe57806322a422011461051e57806323b872dd1461054e57600080fd5b8063095ea7b311610375578063095ea7b31461044e578063096c932a1461046e5780631363b29e1461048f57806318160ddd146104bf57600080fd5b806301295143146103a757806306fdde03146103c957806308c436501461040e57600080fd5b366103a257005b600080fd5b3480156103b357600080fd5b506103c76103c2366004612c38565b610b43565b005b3480156103d557600080fd5b5060408051808201909152600a8152692234bb34b9b4b7b720a960b11b60208201525b6040516104059190612c75565b60405180910390f35b34801561041a57600080fd5b5061043e610429366004612cbd565b60146020526000908152604090205460ff1681565b6040519015158152602001610405565b34801561045a57600080fd5b5061043e610469366004612cda565b610e1f565b34801561047a57600080fd5b5060115461043e90600160b01b900460ff1681565b34801561049b57600080fd5b5061043e6104aa366004612cbd565b60166020526000908152604090205460ff1681565b3480156104cb57600080fd5b506007545b604051908152602001610405565b3480156104ea57600080fd5b506103c76104f9366004612c38565b610e39565b34801561050a57600080fd5b506103c7610519366004612cda565b610ede565b34801561052a57600080fd5b5061043e610539366004612cbd565b60176020526000908152604090205460ff1681565b34801561055a57600080fd5b5061043e610569366004612d06565b611153565b34801561057a57600080fd5b506002546104d09081565b34801561059157600080fd5b506104d060085481565b3480156105a757600080fd5b506103c7611179565b3480156105bc57600080fd5b5060405160128152602001610405565b3480156105d857600080fd5b5060115461043e90600160c01b900460ff1681565b3480156105f957600080fd5b506103c7610608366004612d55565b61121c565b34801561061957600080fd5b506103c7610628366004612d8e565b6112e4565b34801561063957600080fd5b506103c7610648366004612c38565b61137c565b34801561065957600080fd5b506103c7610668366004612c38565b61143b565b34801561067957600080fd5b506001546104d09081565b34801561069057600080fd5b506104d0600e5481565b3480156106a657600080fd5b506103c76106b5366004612d8e565b6114d7565b3480156106c657600080fd5b506103c76106d5366004612d55565b611574565b3480156106e657600080fd5b506104d0600c5481565b3480156106fc57600080fd5b506104d0600d5481565b34801561071257600080fd5b506104d0610721366004612cbd565b61174f565b34801561073257600080fd5b506103c761176a565b34801561074757600080fd5b506104d0600b5481565b34801561075d57600080fd5b506103c761076c366004612c38565b61177e565b34801561077d57600080fd5b506103c761078c366004612d8e565b611824565b34801561079d57600080fd5b506104d07f000000000000000000000000000000000000000000000000000000000000000081565b3480156107d157600080fd5b506103c76107e0366004612d55565b6118c4565b3480156107f157600080fd5b506103c7610800366004612c38565b61198d565b34801561081157600080fd5b5061043e610820366004612cbd565b60156020526000908152604090205460ff1681565b34801561084157600080fd5b506103c7611a2e565b34801561085657600080fd5b506000546001600160a01b03165b6040516001600160a01b039091168152602001610405565b34801561088857600080fd5b506103c7610897366004612d8e565b611ce3565b3480156108a857600080fd5b506104d0611d7d565b3480156108bd57600080fd5b506040805180820190915260038152622220a960e91b60208201526103f8565b3480156108e957600080fd5b506103c76108f8366004612d55565b611db0565b34801561090957600080fd5b5060115461043e90600160a81b900460ff1681565b34801561092a57600080fd5b50600f54610864906001600160a01b031681565b34801561094a57600080fd5b50601054610864906001600160a01b031681565b34801561096a57600080fd5b50601154610864906001600160a01b031681565b34801561098a57600080fd5b5061043e610999366004612cda565b611e81565b3480156109aa57600080fd5b506104d061271081565b3480156109c057600080fd5b506003546104d09081565b3480156109d757600080fd5b506103c7611e8f565b3480156109ec57600080fd5b506104d0600a5481565b348015610a0257600080fd5b5060115461043e90600160a01b900460ff1681565b348015610a2357600080fd5b5060115461043e90600160c81b900460ff1681565b348015610a4457600080fd5b506005546104d09081565b348015610a5b57600080fd5b506104d0610a6a366004612dab565b6001600160a01b03918216600090815260136020908152604080832093909416825291909152205490565b348015610aa157600080fd5b506103c7610ab0366004612c38565b611f2f565b348015610ac157600080fd5b5060115461043e90600160b81b900460ff1681565b348015610ae257600080fd5b506004546104d09081565b348015610af957600080fd5b506104d060095481565b348015610b0f57600080fd5b506103c7610b1e366004612cbd565b611fe8565b348015610b2f57600080fd5b50600654610864906001600160a01b031681565b6011805460ff60c81b1916600160c81b179055612710610b61611d7d565b610b6d906103e8612def565b610b779190612e06565b811115610bc75780612710610b8a611d7d565b610b96906103e8612def565b610ba09190612e06565b60405163179b4ccd60e31b8152600481019290925260248201526044015b60405180910390fd5b6001600b54600a54610bd99190612e28565b1080610bf35750600b54600a54610bf09190612e28565b81115b610e0f57600554600454600091610c0991612e28565b90506000600b54600a54610c1d9190612e28565b9050600081610c2c8486612def565b610c369190612e06565b90508060056000016000828254610c4d9190612e3b565b9250508190555083600b6000828254610c669190612e3b565b90915550506040805160028082526060820183526000926020830190803683370190505090503081600081518110610ca057610ca0612e4e565b6001600160a01b03928316602091820292909201810191909152600654604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa158015610cf9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1d9190612e64565b81600181518110610d3057610d30612e4e565b6001600160a01b039283166020918202929092010152600654610d569130911687612096565b6040805183815260208101879052338183015242606082015290517fb933c1b294702108551eddf782a9c7d1a018b57f68ecf63bc59a1247daa19c309181900360800190a160065460105460405163791ac94760e01b81526001600160a01b039283169263791ac94792610dd892879260009288929116904290600401612e81565b600060405180830381600087803b158015610df257600080fd5b505af1158015610e06573d6000803e3d6000fd5b50505050505050505b506011805460ff60c81b19169055565b600033610e2d818585612096565b60019150505b92915050565b610e416120a8565b6105dc811115610e6f5760405163211a907760e11b8152600481018290526105dc6024820152604401610bbe565b610e7e816002600001546120e4565b60028054908290556040805160a08082526007908201526673656c6c46656560c81b60c0820152602081018390529081018390523360608201524260808201526000805160206130198339815191529060e0015b60405180910390a15050565b60105481906001600160a01b03908116903090851603611047576000600b54600a54610f0a9190612e28565b9050600081610f183061174f565b610f229190612e28565b905080851180610f3a5750610f363061174f565b8210155b15610f58576040516315ea636560e31b815260040160405180910390fd5b84600003610f64578093505b600f5460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018690529087169063a9059cbb906044016020604051808303816000875af1158015610fb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fdb9190612ef2565b6110405760405162461bcd60e51b815260206004820152603060248201527f5769746864726177546f6b656e733a205472616e73666572207472616e73616360448201526f3a34b7b71036b4b3b43a103330b4b61760811b6064820152608401610bbe565b505061114d565b6001600160a01b0384166110c65782600003611061574791505b6001600160a01b038116330361108a5760405163a5eb0da960e01b815260040160405180910390fd5b6040516001600160a01b0382169083156108fc029084906000818181858888f193505050501580156110c0573d6000803e3d6000fd5b5061114d565b82600003611139576040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015611112573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111369190612f0f565b91505b61114d6001600160a01b038516828461210b565b50505050565b60003361116185828561215d565b61116c8585856121d5565b60019150505b9392505050565b6111816120a8565b601154600160b01b900460ff166111ab576040516381e0e3d160e01b8152600401610bbe90612f28565b612710600d556011805460ff60b01b191690556040805160a0808252600c908201526b1a5cd51e1b931a5b5a5d195960a21b60c0820152600160208201526000918101919091523360608201524260808201526000805160206130398339815191529060e0015b60405180910390a1565b6112246120a8565b6001600160a01b03821660009081526015602052604090205461124b90829060ff166123f6565b6001600160a01b038216600081815260156020908152604091829020805485151560ff1982168117909255835160c0808252600b908201526a69734578656d707446656560a81b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a083015290600080516020612ff983398151915290610100015b60405180910390a1505050565b6112ec6120a8565b601154611304908290600160b81b900460ff166123f6565b60118054821515600160b81b81810260ff60b81b198416179093556040805160a0808252600b908201526a697346656541637469766560a81b60c082015260ff94909304939093168015156020840152928201523360608201524260808201526000805160206130398339815191529060e001610ed2565b6113846120a8565b60c88110156113d05760408051639bc7434d60e01b81526004810191909152600e60448201526d13585e15d85b1b195d131a5b5a5d60921b606482015260c86024820152608401610bbe565b6113dc81600c546120e4565b600c8054908290556040805160a0808252600e908201526d1b585e15d85b1b195d131a5b5a5d60921b60c0820152602081018390529081018390523360608201524260808201526000805160206130198339815191529060e001610ed2565b6114436120a8565b6105dc8111156114715760405163211a907760e11b8152600481018290526105dc6024820152604401610bbe565b611480816001600001546120e4565b60018054908290556040805160a08082526006908201526562757946656560d01b60c0820152602081018390529081018390523360608201524260808201526000805160206130198339815191529060e001610ed2565b6114df6120a8565b6011546114f7908290600160b01b900460ff166123f6565b60118054821515600160b01b81810260ff60b01b198416179093556040805160a08082526010908201526f697354786e4c696d697441637469766560801b60c082015260ff94909304939093168015156020840152928201523360608201524260808201526000805160206130398339815191529060e001610ed2565b61157c6120a8565b6001600160a01b0382166000908152601460205260409020546115a390829060ff166123f6565b306001600160a01b0316826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160f9190612e64565b6001600160a01b0316141580156116995750306001600160a01b0316826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611669573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061168d9190612e64565b6001600160a01b031614155b156116c257604051634726455360e11b81526001600160a01b0383166004820152602401610bbe565b6001600160a01b038216600081815260146020908152604091829020805485151560ff1982168117909255835160c08082526008908201526706973506169724c560c41b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a083015290600080516020612ff983398151915290610100016112d7565b6001600160a01b031660009081526012602052604090205490565b6117726120a8565b61177c600061241d565b565b6117866120a8565b612710611791611d7d565b61179d906103e8612def565b6117a79190612e06565b8111156117ca5760405163181c9d0b60e21b815260048101829052602401610bbe565b6117d681600e546120e4565b600e805490829055604080518281526020810184905233918101919091524260608201527f9a9f4704ac409fe039e92a996e415370980275aaff2992936ed5b432886c55c590608001610ed2565b61182c6120a8565b601154611844908290600160a81b900460ff166123f6565b60118054821515600160a81b81810260ff60a81b198416179093556040805160a080825260139082015272697357616c6c65744c696d697441637469766560681b60c082015260ff94909304939093168015156020840152928201523360608201524260808201526000805160206130398339815191529060e001610ed2565b6118cc6120a8565b6001600160a01b0382166000908152601760205260409020546118f390829060ff166123f6565b6001600160a01b038216600081815260176020908152604091829020805485151560ff1982168117909255835160c08082526015908201527469734578656d707446726f6d54786e4c696d69747360581b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a083015290600080516020612ff983398151915290610100016112d7565b6119956120a8565b6105dc8111156119c35760405163211a907760e11b8152600481018290526105dc6024820152604401610bbe565b6119d2816003600001546120e4565b60038054908290556040805160a0808252600b908201526a7472616e7366657246656560a81b60c0820152602081018390529081018390523360608201524260808201526000805160206130198339815191529060e001610ed2565b611a366120a8565b601154600160a01b900460ff1615611a7a5760115460085460405163e39c1e8760e01b8152600160a01b90920460ff16151560048301526024820152604401610bbe565b6000546001600160a01b031615801590611aae575033611aa26000546001600160a01b031690565b6001600160a01b031614155b8015611ae5575042611ae37f000000000000000000000000000000000000000000000000000000000000000062278d00612e3b565b115b15611b055760405163118cdaa760e01b8152336004820152602401610bbe565b6000546001600160a01b0316158015611b38575033611b2c6000546001600160a01b031690565b6001600160a01b031614155b8015611b6f575042611b6d7f00000000000000000000000000000000000000000000000000000000000000006213c680612e3b565b115b15611bfb57611ba17f00000000000000000000000000000000000000000000000000000000000000006213c680612e3b565b42611bcf7f00000000000000000000000000000000000000000000000000000000000000006213c680612e3b565b611bd99190612e28565b604051636ddcad9f60e01b815260048101929092526024820152604401610bbe565b601154600160a81b900460ff16611c20576011805460ff60a81b1916600160a81b1790555b601154600160b81b900460ff16611c45576011805460ff60b81b1916600160b81b1790555b601154600160c01b900460ff16611c6a576011805460ff60c01b1916600160c01b1790555b601154600160b01b900460ff16611c8f576011805460ff60b01b1916600160b01b1790555b6011805460ff60a01b1916600160a01b179055426008819055436009556040805133815260208101929092527f8b70aa279b24da71d8a874fa0b0ee8f1a587c4fb32b80d87e95cdbdae01b7b4f9101611212565b611ceb6120a8565b601154611d03908290600160c01b900460ff166123f6565b60118054821515600160c01b81810260ff60c01b198416179093556040805160a0808252600d908201526c1a5cd4ddd85c115b98589b1959609a1b60c082015260ff94909304939093168015156020840152928201523360608201524260808201526000805160206130398339815191529060e001610ed2565b6000611d89600061174f565b611d9461dead61174f565b600754611da19190612e28565b611dab9190612e28565b905090565b611db86120a8565b6001600160a01b038216600090815260166020526040902054611ddf90829060ff166123f6565b6001600160a01b038216600081815260166020908152604091829020805485151560ff1982168117909255835160c08082526018908201527f69734578656d707446726f6d57616c6c65744c696d697473000000000000000060e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a083015290600080516020612ff983398151915290610100016112d7565b600033610e2d8185856121d5565b611e976120a8565b601154600160a81b900460ff16611ec1576040516381e0e3d160e01b8152600401610bbe90612f50565b612710600c556011805460ff60a81b191690556040805160a0808252600f908201526e1a5cd5d85b1b195d131a5b5a5d1959608a1b60c0820152600160208201526000918101919091523360608201524260808201526000805160206130398339815191529060e001611212565b611f376120a8565b60c8811015611f805760408051639bc7434d60e01b81526004810191909152600b60448201526a13585e151e1b931a5b5a5d60aa1b606482015260c86024820152608401610bbe565b611f8c81600d546120e4565b600d8054908290556040805160a0808252600b908201526a1b585e151e1b931a5b5a5d60aa1b60c0820152602081018390529081018390523360608201524260808201526000805160206130198339815191529060e001610ed2565b611ff06120a8565b6000546001600160a01b03166001600160a01b0316816001600160a01b0316036120385760405163a936636960e01b81526001600160a01b0382166004820152602401610bbe565b61deac196001600160a01b0382160161206f57604051634726455360e11b81526001600160a01b0382166004820152602401610bbe565b600f80546001600160a01b0319166001600160a01b0383161790556120938161246d565b50565b6120a383838360016124a8565b505050565b336120bb6000546001600160a01b031690565b6001600160a01b03161461177c5760405163118cdaa760e01b8152336004820152602401610bbe565b8082036121075760405163657e16cf60e01b815260048101839052602401610bbe565b5050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526120a390849061257d565b6001600160a01b03838116600090815260136020908152604080832093861683529290522054600019811461114d57818110156121c657604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610bbe565b61114d848484840360006124a8565b6001600160a01b0383166121ff57604051634b637e8f60e11b815260006004820152602401610bbe565b6001600160a01b0382166122295760405163ec442f0560e01b815260006004820152602401610bbe565b601154600160a01b900460ff1661229a576001600160a01b03831660009081526015602052604090205460ff1615801561227c57506001600160a01b03821660009081526015602052604090205460ff16155b1561229a5760405163ab9827ff60e01b815260040160405180910390fd5b601154600160b01b900460ff16156122b6576122b681846125e0565b601154600160c81b900460ff16806122e657506001600160a01b03831660009081526015602052604090205460ff165b156122f6576120a3838383612664565b6011546001600160a01b0384811691161480159061231d5750601154600160c01b900460ff165b801561233a5750600e54600b54600a546123379190612e28565b10155b80156123505750600e5461234d3061174f565b10155b1561236357600e5461236181610b43565b505b6011548190600160b81b900460ff16801561239757506001600160a01b03841660009081526015602052604090205460ff16155b80156123bc57506001600160a01b03831660009081526015602052604090205460ff16155b156123cf576123cc84848461278e565b90505b601154600160a81b900460ff16156123eb576123eb818461288d565b61114d848483612664565b801515821515036121075760405162a7e72d60e41b81528215156004820152602401610bbe565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6124756120a8565b6001600160a01b03811661249f57604051631e4fbdf760e01b815260006004820152602401610bbe565b6120938161241d565b6001600160a01b0384166124d25760405163e602df0560e01b815260006004820152602401610bbe565b6001600160a01b0383166124fc57604051634a1406b160e11b815260006004820152602401610bbe565b6001600160a01b038085166000908152601360209081526040808320938716835292905220829055801561114d57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161256f91815260200190565b60405180910390a350505050565b60006125926001600160a01b03841683612929565b905080516000141580156125b75750808060200190518101906125b59190612ef2565b155b156120a357604051635274afe760e01b81526001600160a01b0384166004820152602401610bbe565b6000612710600d546125f0611d7d565b6125fa9190612def565b6126049190612e06565b601154909150600160b01b900460ff16801561263957506001600160a01b03821660009081526017602052604090205460ff16155b801561264457508083115b156120a35780604051639bc7434d60e01b8152600401610bbe9190612f7b565b6001600160a01b03831661268f5780600760008282546126849190612e3b565b909155506127019050565b6001600160a01b038316600090815260126020526040902054818110156126e25760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610bbe565b6001600160a01b03841660009081526012602052604090209082900390555b6001600160a01b03821661271d5760078054829003905561273c565b6001600160a01b03821660009081526012602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161278191815260200190565b60405180910390a3505050565b6011805460ff60c81b1916600160c81b1790556001600160a01b03831660009081526014602052604081205460ff1680156127ca575060015415155b156127e0576127d98483612937565b9050612879565b6001600160a01b03831660009081526014602052604090205460ff168015612809575060025415155b15612818576127d98483612968565b6001600160a01b03841660009081526014602052604090205460ff1615801561285a57506001600160a01b03831660009081526014602052604090205460ff16155b8015612867575060035415155b15612876576127d98483612999565b50805b6011805460ff60c81b191690559392505050565b6000826128998361174f565b6128a39190612e3b565b90506000612710600c546128b5611d7d565b6128bf9190612def565b6128c99190612e06565b601154909150600160a81b900460ff1680156128fe57506001600160a01b03831660009081526016602052604090205460ff16155b801561290957508082115b1561114d5780604051639bc7434d60e01b8152600401610bbe9190612fb1565b6060611172838360006129ca565b6011805460ff60c81b1916600160c81b17905560408051602081019091526001548152600090612879908484612a67565b6011805460ff60c81b1916600160c81b17905560408051602081019091526002548152600090612879908484612a67565b6011805460ff60c81b1916600160c81b17905560408051602081019091526003548152600090612879908484612a67565b6060814710156129ef5760405163cd78605960e01b8152306004820152602401610bbe565b600080856001600160a01b03168486604051612a0b9190612fdc565b60006040518083038185875af1925050503d8060008114612a48576040519150601f19603f3d011682016040523d82523d6000602084013e612a4d565b606091505b5091509150612a5d868383612aeb565b9695505050505050565b6011805460ff60c81b1916600160c81b179055825160095460009190612a8e906002612e3b565b4311612a9957506126ac5b6000612710612aa88386612def565b612ab29190612e06565b90506000612ac08286612e28565b90508115612ad457612ad487878486612b47565b6011805460ff60c81b191690559695505050505050565b606082612b0057612afb82612bb8565b611172565b8151158015612b1757506001600160a01b0384163b155b15612b4057604051639996b31560e01b81526001600160a01b0385166004820152602401610bbe565b5080611172565b6011805460ff60c81b1916600160c81b1790558351600954612b6a906002612e3b565b4311612b7557506126ac5b600082612b828386612def565b612b8c9190612e06565b9050612b988182612be1565b612ba3853086612664565b50506011805460ff60c81b1916905550505050565b805115612bc85780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6011805460ff60c81b1916600160c81b17905560048054839190600090612c09908490612e3b565b9250508190555080600a6000828254612c229190612e3b565b90915550506011805460ff60c81b191690555050565b600060208284031215612c4a57600080fd5b5035919050565b60005b83811015612c6c578181015183820152602001612c54565b50506000910152565b6020815260008251806020840152612c94816040850160208701612c51565b601f01601f19169190910160400192915050565b6001600160a01b038116811461209357600080fd5b600060208284031215612ccf57600080fd5b813561117281612ca8565b60008060408385031215612ced57600080fd5b8235612cf881612ca8565b946020939093013593505050565b600080600060608486031215612d1b57600080fd5b8335612d2681612ca8565b92506020840135612d3681612ca8565b929592945050506040919091013590565b801515811461209357600080fd5b60008060408385031215612d6857600080fd5b8235612d7381612ca8565b91506020830135612d8381612d47565b809150509250929050565b600060208284031215612da057600080fd5b813561117281612d47565b60008060408385031215612dbe57600080fd5b8235612dc981612ca8565b91506020830135612d8381612ca8565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e3357610e33612dd9565b600082612e2357634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610e3357610e33612dd9565b80820180821115610e3357610e33612dd9565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612e7657600080fd5b815161117281612ca8565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b81811015612ed15784516001600160a01b031683529383019391830191600101612eac565b50506001600160a01b03969096166060850152505050608001529392505050565b600060208284031215612f0457600080fd5b815161117281612d47565b600060208284031215612f2157600080fd5b5051919050565b602081526000610e33602083016008815267151e1b931a5b5a5d60c21b602082015260400190565b602081526000610e3360208301600b81526a15d85b1b195d131a5b5a5d60aa1b602082015260400190565b604081526000612fa3604083016008815267151e1b931a5b5a5d60c21b602082015260400190565b905082602083015292915050565b604081526000612fa360408301600b81526a15d85b1b195d131a5b5a5d60aa1b602082015260400190565b60008251612fee818460208701612c51565b919091019291505056fe59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea2dc908b86b38cfca773aadc8861ff9f24d2b644be4f8a6c2024cd71e120e5ef5da986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf3a2646970667358221220a11c4a06f91aefc4e382c9310ed3c3d14b12450dd5181bf24e8a51ab88374cd264736f6c63430008120033

Deployed Bytecode

0x60806040526004361061039b5760003560e01c8063779e80d5116101dc578063a9059cbb11610102578063d9419071116100a0578063e811f50a1161006f578063e811f50a14610ad6578063f2c4220e14610aed578063f2fde38b14610b03578063f887ea4014610b2357600080fd5b8063d941907114610a38578063dd62ed3e14610a4f578063e113edd214610a95578063e43504da14610ab557600080fd5b8063b144896f116100dc578063b144896f146109cb578063b9b2b5cd146109e0578063d621e813146109f6578063d830678614610a1757600080fd5b8063a9059cbb1461097e578063ab28a04c1461099e578063acb2ad6f146109b457600080fd5b8063924de9b71161017a5780639ffe0533116101495780639ffe0533146108fd578063a4475ce41461091e578063a5949bcf1461093e578063a8aa1b311461095e57600080fd5b8063924de9b71461087c5780639358928b1461089c57806395d89b41146108b157806397c42ba6146108dd57600080fd5b80638577a6d5116101b65780638577a6d5146107e5578063891ff84a146108055780638a8c523c146108355780638da5cb5b1461084a57600080fd5b8063779e80d5146107715780637a40624b146107915780637b122d17146107c557600080fd5b8063351a964d116102c15780635b6ddb8e1161025f57806370a082311161022e57806370a0823114610706578063715018a61461072657806371538eed1461073b57806375fed3c71461075157600080fd5b80635b6ddb8e1461069a578063625dd605146106ba57806366a88d96146106da578063681aa362146106f057600080fd5b80634324deae1161029b5780634324deae1461062d578063467abe0a1461064d578063470624021461066d57806359cd90311461068457600080fd5b8063351a964d146105cc578063355496ca146105ed5780633bf314541461060d57600080fd5b80631d933a4a116103395780632b14ca56116103085780632b14ca561461056e5780632c735ef81461058557806330e1ab9a1461059b578063313ce567146105b057600080fd5b80631d933a4a146104de5780631f685bac146104fe57806322a422011461051e57806323b872dd1461054e57600080fd5b8063095ea7b311610375578063095ea7b31461044e578063096c932a1461046e5780631363b29e1461048f57806318160ddd146104bf57600080fd5b806301295143146103a757806306fdde03146103c957806308c436501461040e57600080fd5b366103a257005b600080fd5b3480156103b357600080fd5b506103c76103c2366004612c38565b610b43565b005b3480156103d557600080fd5b5060408051808201909152600a8152692234bb34b9b4b7b720a960b11b60208201525b6040516104059190612c75565b60405180910390f35b34801561041a57600080fd5b5061043e610429366004612cbd565b60146020526000908152604090205460ff1681565b6040519015158152602001610405565b34801561045a57600080fd5b5061043e610469366004612cda565b610e1f565b34801561047a57600080fd5b5060115461043e90600160b01b900460ff1681565b34801561049b57600080fd5b5061043e6104aa366004612cbd565b60166020526000908152604090205460ff1681565b3480156104cb57600080fd5b506007545b604051908152602001610405565b3480156104ea57600080fd5b506103c76104f9366004612c38565b610e39565b34801561050a57600080fd5b506103c7610519366004612cda565b610ede565b34801561052a57600080fd5b5061043e610539366004612cbd565b60176020526000908152604090205460ff1681565b34801561055a57600080fd5b5061043e610569366004612d06565b611153565b34801561057a57600080fd5b506002546104d09081565b34801561059157600080fd5b506104d060085481565b3480156105a757600080fd5b506103c7611179565b3480156105bc57600080fd5b5060405160128152602001610405565b3480156105d857600080fd5b5060115461043e90600160c01b900460ff1681565b3480156105f957600080fd5b506103c7610608366004612d55565b61121c565b34801561061957600080fd5b506103c7610628366004612d8e565b6112e4565b34801561063957600080fd5b506103c7610648366004612c38565b61137c565b34801561065957600080fd5b506103c7610668366004612c38565b61143b565b34801561067957600080fd5b506001546104d09081565b34801561069057600080fd5b506104d0600e5481565b3480156106a657600080fd5b506103c76106b5366004612d8e565b6114d7565b3480156106c657600080fd5b506103c76106d5366004612d55565b611574565b3480156106e657600080fd5b506104d0600c5481565b3480156106fc57600080fd5b506104d0600d5481565b34801561071257600080fd5b506104d0610721366004612cbd565b61174f565b34801561073257600080fd5b506103c761176a565b34801561074757600080fd5b506104d0600b5481565b34801561075d57600080fd5b506103c761076c366004612c38565b61177e565b34801561077d57600080fd5b506103c761078c366004612d8e565b611824565b34801561079d57600080fd5b506104d07f0000000000000000000000000000000000000000000000000000000065a54edb81565b3480156107d157600080fd5b506103c76107e0366004612d55565b6118c4565b3480156107f157600080fd5b506103c7610800366004612c38565b61198d565b34801561081157600080fd5b5061043e610820366004612cbd565b60156020526000908152604090205460ff1681565b34801561084157600080fd5b506103c7611a2e565b34801561085657600080fd5b506000546001600160a01b03165b6040516001600160a01b039091168152602001610405565b34801561088857600080fd5b506103c7610897366004612d8e565b611ce3565b3480156108a857600080fd5b506104d0611d7d565b3480156108bd57600080fd5b506040805180820190915260038152622220a960e91b60208201526103f8565b3480156108e957600080fd5b506103c76108f8366004612d55565b611db0565b34801561090957600080fd5b5060115461043e90600160a81b900460ff1681565b34801561092a57600080fd5b50600f54610864906001600160a01b031681565b34801561094a57600080fd5b50601054610864906001600160a01b031681565b34801561096a57600080fd5b50601154610864906001600160a01b031681565b34801561098a57600080fd5b5061043e610999366004612cda565b611e81565b3480156109aa57600080fd5b506104d061271081565b3480156109c057600080fd5b506003546104d09081565b3480156109d757600080fd5b506103c7611e8f565b3480156109ec57600080fd5b506104d0600a5481565b348015610a0257600080fd5b5060115461043e90600160a01b900460ff1681565b348015610a2357600080fd5b5060115461043e90600160c81b900460ff1681565b348015610a4457600080fd5b506005546104d09081565b348015610a5b57600080fd5b506104d0610a6a366004612dab565b6001600160a01b03918216600090815260136020908152604080832093909416825291909152205490565b348015610aa157600080fd5b506103c7610ab0366004612c38565b611f2f565b348015610ac157600080fd5b5060115461043e90600160b81b900460ff1681565b348015610ae257600080fd5b506004546104d09081565b348015610af957600080fd5b506104d060095481565b348015610b0f57600080fd5b506103c7610b1e366004612cbd565b611fe8565b348015610b2f57600080fd5b50600654610864906001600160a01b031681565b6011805460ff60c81b1916600160c81b179055612710610b61611d7d565b610b6d906103e8612def565b610b779190612e06565b811115610bc75780612710610b8a611d7d565b610b96906103e8612def565b610ba09190612e06565b60405163179b4ccd60e31b8152600481019290925260248201526044015b60405180910390fd5b6001600b54600a54610bd99190612e28565b1080610bf35750600b54600a54610bf09190612e28565b81115b610e0f57600554600454600091610c0991612e28565b90506000600b54600a54610c1d9190612e28565b9050600081610c2c8486612def565b610c369190612e06565b90508060056000016000828254610c4d9190612e3b565b9250508190555083600b6000828254610c669190612e3b565b90915550506040805160028082526060820183526000926020830190803683370190505090503081600081518110610ca057610ca0612e4e565b6001600160a01b03928316602091820292909201810191909152600654604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa158015610cf9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1d9190612e64565b81600181518110610d3057610d30612e4e565b6001600160a01b039283166020918202929092010152600654610d569130911687612096565b6040805183815260208101879052338183015242606082015290517fb933c1b294702108551eddf782a9c7d1a018b57f68ecf63bc59a1247daa19c309181900360800190a160065460105460405163791ac94760e01b81526001600160a01b039283169263791ac94792610dd892879260009288929116904290600401612e81565b600060405180830381600087803b158015610df257600080fd5b505af1158015610e06573d6000803e3d6000fd5b50505050505050505b506011805460ff60c81b19169055565b600033610e2d818585612096565b60019150505b92915050565b610e416120a8565b6105dc811115610e6f5760405163211a907760e11b8152600481018290526105dc6024820152604401610bbe565b610e7e816002600001546120e4565b60028054908290556040805160a08082526007908201526673656c6c46656560c81b60c0820152602081018390529081018390523360608201524260808201526000805160206130198339815191529060e0015b60405180910390a15050565b60105481906001600160a01b03908116903090851603611047576000600b54600a54610f0a9190612e28565b9050600081610f183061174f565b610f229190612e28565b905080851180610f3a5750610f363061174f565b8210155b15610f58576040516315ea636560e31b815260040160405180910390fd5b84600003610f64578093505b600f5460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018690529087169063a9059cbb906044016020604051808303816000875af1158015610fb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fdb9190612ef2565b6110405760405162461bcd60e51b815260206004820152603060248201527f5769746864726177546f6b656e733a205472616e73666572207472616e73616360448201526f3a34b7b71036b4b3b43a103330b4b61760811b6064820152608401610bbe565b505061114d565b6001600160a01b0384166110c65782600003611061574791505b6001600160a01b038116330361108a5760405163a5eb0da960e01b815260040160405180910390fd5b6040516001600160a01b0382169083156108fc029084906000818181858888f193505050501580156110c0573d6000803e3d6000fd5b5061114d565b82600003611139576040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015611112573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111369190612f0f565b91505b61114d6001600160a01b038516828461210b565b50505050565b60003361116185828561215d565b61116c8585856121d5565b60019150505b9392505050565b6111816120a8565b601154600160b01b900460ff166111ab576040516381e0e3d160e01b8152600401610bbe90612f28565b612710600d556011805460ff60b01b191690556040805160a0808252600c908201526b1a5cd51e1b931a5b5a5d195960a21b60c0820152600160208201526000918101919091523360608201524260808201526000805160206130398339815191529060e0015b60405180910390a1565b6112246120a8565b6001600160a01b03821660009081526015602052604090205461124b90829060ff166123f6565b6001600160a01b038216600081815260156020908152604091829020805485151560ff1982168117909255835160c0808252600b908201526a69734578656d707446656560a81b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a083015290600080516020612ff983398151915290610100015b60405180910390a1505050565b6112ec6120a8565b601154611304908290600160b81b900460ff166123f6565b60118054821515600160b81b81810260ff60b81b198416179093556040805160a0808252600b908201526a697346656541637469766560a81b60c082015260ff94909304939093168015156020840152928201523360608201524260808201526000805160206130398339815191529060e001610ed2565b6113846120a8565b60c88110156113d05760408051639bc7434d60e01b81526004810191909152600e60448201526d13585e15d85b1b195d131a5b5a5d60921b606482015260c86024820152608401610bbe565b6113dc81600c546120e4565b600c8054908290556040805160a0808252600e908201526d1b585e15d85b1b195d131a5b5a5d60921b60c0820152602081018390529081018390523360608201524260808201526000805160206130198339815191529060e001610ed2565b6114436120a8565b6105dc8111156114715760405163211a907760e11b8152600481018290526105dc6024820152604401610bbe565b611480816001600001546120e4565b60018054908290556040805160a08082526006908201526562757946656560d01b60c0820152602081018390529081018390523360608201524260808201526000805160206130198339815191529060e001610ed2565b6114df6120a8565b6011546114f7908290600160b01b900460ff166123f6565b60118054821515600160b01b81810260ff60b01b198416179093556040805160a08082526010908201526f697354786e4c696d697441637469766560801b60c082015260ff94909304939093168015156020840152928201523360608201524260808201526000805160206130398339815191529060e001610ed2565b61157c6120a8565b6001600160a01b0382166000908152601460205260409020546115a390829060ff166123f6565b306001600160a01b0316826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160f9190612e64565b6001600160a01b0316141580156116995750306001600160a01b0316826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611669573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061168d9190612e64565b6001600160a01b031614155b156116c257604051634726455360e11b81526001600160a01b0383166004820152602401610bbe565b6001600160a01b038216600081815260146020908152604091829020805485151560ff1982168117909255835160c08082526008908201526706973506169724c560c41b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a083015290600080516020612ff983398151915290610100016112d7565b6001600160a01b031660009081526012602052604090205490565b6117726120a8565b61177c600061241d565b565b6117866120a8565b612710611791611d7d565b61179d906103e8612def565b6117a79190612e06565b8111156117ca5760405163181c9d0b60e21b815260048101829052602401610bbe565b6117d681600e546120e4565b600e805490829055604080518281526020810184905233918101919091524260608201527f9a9f4704ac409fe039e92a996e415370980275aaff2992936ed5b432886c55c590608001610ed2565b61182c6120a8565b601154611844908290600160a81b900460ff166123f6565b60118054821515600160a81b81810260ff60a81b198416179093556040805160a080825260139082015272697357616c6c65744c696d697441637469766560681b60c082015260ff94909304939093168015156020840152928201523360608201524260808201526000805160206130398339815191529060e001610ed2565b6118cc6120a8565b6001600160a01b0382166000908152601760205260409020546118f390829060ff166123f6565b6001600160a01b038216600081815260176020908152604091829020805485151560ff1982168117909255835160c08082526015908201527469734578656d707446726f6d54786e4c696d69747360581b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a083015290600080516020612ff983398151915290610100016112d7565b6119956120a8565b6105dc8111156119c35760405163211a907760e11b8152600481018290526105dc6024820152604401610bbe565b6119d2816003600001546120e4565b60038054908290556040805160a0808252600b908201526a7472616e7366657246656560a81b60c0820152602081018390529081018390523360608201524260808201526000805160206130198339815191529060e001610ed2565b611a366120a8565b601154600160a01b900460ff1615611a7a5760115460085460405163e39c1e8760e01b8152600160a01b90920460ff16151560048301526024820152604401610bbe565b6000546001600160a01b031615801590611aae575033611aa26000546001600160a01b031690565b6001600160a01b031614155b8015611ae5575042611ae37f0000000000000000000000000000000000000000000000000000000065a54edb62278d00612e3b565b115b15611b055760405163118cdaa760e01b8152336004820152602401610bbe565b6000546001600160a01b0316158015611b38575033611b2c6000546001600160a01b031690565b6001600160a01b031614155b8015611b6f575042611b6d7f0000000000000000000000000000000000000000000000000000000065a54edb6213c680612e3b565b115b15611bfb57611ba17f0000000000000000000000000000000000000000000000000000000065a54edb6213c680612e3b565b42611bcf7f0000000000000000000000000000000000000000000000000000000065a54edb6213c680612e3b565b611bd99190612e28565b604051636ddcad9f60e01b815260048101929092526024820152604401610bbe565b601154600160a81b900460ff16611c20576011805460ff60a81b1916600160a81b1790555b601154600160b81b900460ff16611c45576011805460ff60b81b1916600160b81b1790555b601154600160c01b900460ff16611c6a576011805460ff60c01b1916600160c01b1790555b601154600160b01b900460ff16611c8f576011805460ff60b01b1916600160b01b1790555b6011805460ff60a01b1916600160a01b179055426008819055436009556040805133815260208101929092527f8b70aa279b24da71d8a874fa0b0ee8f1a587c4fb32b80d87e95cdbdae01b7b4f9101611212565b611ceb6120a8565b601154611d03908290600160c01b900460ff166123f6565b60118054821515600160c01b81810260ff60c01b198416179093556040805160a0808252600d908201526c1a5cd4ddd85c115b98589b1959609a1b60c082015260ff94909304939093168015156020840152928201523360608201524260808201526000805160206130398339815191529060e001610ed2565b6000611d89600061174f565b611d9461dead61174f565b600754611da19190612e28565b611dab9190612e28565b905090565b611db86120a8565b6001600160a01b038216600090815260166020526040902054611ddf90829060ff166123f6565b6001600160a01b038216600081815260166020908152604091829020805485151560ff1982168117909255835160c08082526018908201527f69734578656d707446726f6d57616c6c65744c696d697473000000000000000060e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a083015290600080516020612ff983398151915290610100016112d7565b600033610e2d8185856121d5565b611e976120a8565b601154600160a81b900460ff16611ec1576040516381e0e3d160e01b8152600401610bbe90612f50565b612710600c556011805460ff60a81b191690556040805160a0808252600f908201526e1a5cd5d85b1b195d131a5b5a5d1959608a1b60c0820152600160208201526000918101919091523360608201524260808201526000805160206130398339815191529060e001611212565b611f376120a8565b60c8811015611f805760408051639bc7434d60e01b81526004810191909152600b60448201526a13585e151e1b931a5b5a5d60aa1b606482015260c86024820152608401610bbe565b611f8c81600d546120e4565b600d8054908290556040805160a0808252600b908201526a1b585e151e1b931a5b5a5d60aa1b60c0820152602081018390529081018390523360608201524260808201526000805160206130198339815191529060e001610ed2565b611ff06120a8565b6000546001600160a01b03166001600160a01b0316816001600160a01b0316036120385760405163a936636960e01b81526001600160a01b0382166004820152602401610bbe565b61deac196001600160a01b0382160161206f57604051634726455360e11b81526001600160a01b0382166004820152602401610bbe565b600f80546001600160a01b0319166001600160a01b0383161790556120938161246d565b50565b6120a383838360016124a8565b505050565b336120bb6000546001600160a01b031690565b6001600160a01b03161461177c5760405163118cdaa760e01b8152336004820152602401610bbe565b8082036121075760405163657e16cf60e01b815260048101839052602401610bbe565b5050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526120a390849061257d565b6001600160a01b03838116600090815260136020908152604080832093861683529290522054600019811461114d57818110156121c657604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610bbe565b61114d848484840360006124a8565b6001600160a01b0383166121ff57604051634b637e8f60e11b815260006004820152602401610bbe565b6001600160a01b0382166122295760405163ec442f0560e01b815260006004820152602401610bbe565b601154600160a01b900460ff1661229a576001600160a01b03831660009081526015602052604090205460ff1615801561227c57506001600160a01b03821660009081526015602052604090205460ff16155b1561229a5760405163ab9827ff60e01b815260040160405180910390fd5b601154600160b01b900460ff16156122b6576122b681846125e0565b601154600160c81b900460ff16806122e657506001600160a01b03831660009081526015602052604090205460ff165b156122f6576120a3838383612664565b6011546001600160a01b0384811691161480159061231d5750601154600160c01b900460ff165b801561233a5750600e54600b54600a546123379190612e28565b10155b80156123505750600e5461234d3061174f565b10155b1561236357600e5461236181610b43565b505b6011548190600160b81b900460ff16801561239757506001600160a01b03841660009081526015602052604090205460ff16155b80156123bc57506001600160a01b03831660009081526015602052604090205460ff16155b156123cf576123cc84848461278e565b90505b601154600160a81b900460ff16156123eb576123eb818461288d565b61114d848483612664565b801515821515036121075760405162a7e72d60e41b81528215156004820152602401610bbe565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6124756120a8565b6001600160a01b03811661249f57604051631e4fbdf760e01b815260006004820152602401610bbe565b6120938161241d565b6001600160a01b0384166124d25760405163e602df0560e01b815260006004820152602401610bbe565b6001600160a01b0383166124fc57604051634a1406b160e11b815260006004820152602401610bbe565b6001600160a01b038085166000908152601360209081526040808320938716835292905220829055801561114d57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161256f91815260200190565b60405180910390a350505050565b60006125926001600160a01b03841683612929565b905080516000141580156125b75750808060200190518101906125b59190612ef2565b155b156120a357604051635274afe760e01b81526001600160a01b0384166004820152602401610bbe565b6000612710600d546125f0611d7d565b6125fa9190612def565b6126049190612e06565b601154909150600160b01b900460ff16801561263957506001600160a01b03821660009081526017602052604090205460ff16155b801561264457508083115b156120a35780604051639bc7434d60e01b8152600401610bbe9190612f7b565b6001600160a01b03831661268f5780600760008282546126849190612e3b565b909155506127019050565b6001600160a01b038316600090815260126020526040902054818110156126e25760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610bbe565b6001600160a01b03841660009081526012602052604090209082900390555b6001600160a01b03821661271d5760078054829003905561273c565b6001600160a01b03821660009081526012602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161278191815260200190565b60405180910390a3505050565b6011805460ff60c81b1916600160c81b1790556001600160a01b03831660009081526014602052604081205460ff1680156127ca575060015415155b156127e0576127d98483612937565b9050612879565b6001600160a01b03831660009081526014602052604090205460ff168015612809575060025415155b15612818576127d98483612968565b6001600160a01b03841660009081526014602052604090205460ff1615801561285a57506001600160a01b03831660009081526014602052604090205460ff16155b8015612867575060035415155b15612876576127d98483612999565b50805b6011805460ff60c81b191690559392505050565b6000826128998361174f565b6128a39190612e3b565b90506000612710600c546128b5611d7d565b6128bf9190612def565b6128c99190612e06565b601154909150600160a81b900460ff1680156128fe57506001600160a01b03831660009081526016602052604090205460ff16155b801561290957508082115b1561114d5780604051639bc7434d60e01b8152600401610bbe9190612fb1565b6060611172838360006129ca565b6011805460ff60c81b1916600160c81b17905560408051602081019091526001548152600090612879908484612a67565b6011805460ff60c81b1916600160c81b17905560408051602081019091526002548152600090612879908484612a67565b6011805460ff60c81b1916600160c81b17905560408051602081019091526003548152600090612879908484612a67565b6060814710156129ef5760405163cd78605960e01b8152306004820152602401610bbe565b600080856001600160a01b03168486604051612a0b9190612fdc565b60006040518083038185875af1925050503d8060008114612a48576040519150601f19603f3d011682016040523d82523d6000602084013e612a4d565b606091505b5091509150612a5d868383612aeb565b9695505050505050565b6011805460ff60c81b1916600160c81b179055825160095460009190612a8e906002612e3b565b4311612a9957506126ac5b6000612710612aa88386612def565b612ab29190612e06565b90506000612ac08286612e28565b90508115612ad457612ad487878486612b47565b6011805460ff60c81b191690559695505050505050565b606082612b0057612afb82612bb8565b611172565b8151158015612b1757506001600160a01b0384163b155b15612b4057604051639996b31560e01b81526001600160a01b0385166004820152602401610bbe565b5080611172565b6011805460ff60c81b1916600160c81b1790558351600954612b6a906002612e3b565b4311612b7557506126ac5b600082612b828386612def565b612b8c9190612e06565b9050612b988182612be1565b612ba3853086612664565b50506011805460ff60c81b1916905550505050565b805115612bc85780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6011805460ff60c81b1916600160c81b17905560048054839190600090612c09908490612e3b565b9250508190555080600a6000828254612c229190612e3b565b90915550506011805460ff60c81b191690555050565b600060208284031215612c4a57600080fd5b5035919050565b60005b83811015612c6c578181015183820152602001612c54565b50506000910152565b6020815260008251806020840152612c94816040850160208701612c51565b601f01601f19169190910160400192915050565b6001600160a01b038116811461209357600080fd5b600060208284031215612ccf57600080fd5b813561117281612ca8565b60008060408385031215612ced57600080fd5b8235612cf881612ca8565b946020939093013593505050565b600080600060608486031215612d1b57600080fd5b8335612d2681612ca8565b92506020840135612d3681612ca8565b929592945050506040919091013590565b801515811461209357600080fd5b60008060408385031215612d6857600080fd5b8235612d7381612ca8565b91506020830135612d8381612d47565b809150509250929050565b600060208284031215612da057600080fd5b813561117281612d47565b60008060408385031215612dbe57600080fd5b8235612dc981612ca8565b91506020830135612d8381612ca8565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e3357610e33612dd9565b600082612e2357634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610e3357610e33612dd9565b80820180821115610e3357610e33612dd9565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612e7657600080fd5b815161117281612ca8565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b81811015612ed15784516001600160a01b031683529383019391830191600101612eac565b50506001600160a01b03969096166060850152505050608001529392505050565b600060208284031215612f0457600080fd5b815161117281612d47565b600060208284031215612f2157600080fd5b5051919050565b602081526000610e33602083016008815267151e1b931a5b5a5d60c21b602082015260400190565b602081526000610e3360208301600b81526a15d85b1b195d131a5b5a5d60aa1b602082015260400190565b604081526000612fa3604083016008815267151e1b931a5b5a5d60c21b602082015260400190565b905082602083015292915050565b604081526000612fa360408301600b81526a15d85b1b195d131a5b5a5d60aa1b602082015260400190565b60008251612fee818460208701612c51565b919091019291505056fe59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea2dc908b86b38cfca773aadc8861ff9f24d2b644be4f8a6c2024cd71e120e5ef5da986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf3a2646970667358221220a11c4a06f91aefc4e382c9310ed3c3d14b12450dd5181bf24e8a51ab88374cd264736f6c63430008120033

Deployed Bytecode Sourcemap

25161:46136:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41747:1301;;;;;;;;;;-1:-1:-1;41747:1301:0;;;;;:::i;:::-;;:::i;:::-;;58668:90;;;;;;;;;;-1:-1:-1;58746:4:0;;;;;;;;;;;;-1:-1:-1;;;58746:4:0;;;;58668:90;;;;;;;:::i;:::-;;;;;;;;26864:45;;;;;;;;;;-1:-1:-1;26864:45:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;1408:14:1;;1401:22;1383:41;;1371:2;1356:18;26864:45:0;1243:187:1;61725:194:0;;;;;;;;;;-1:-1:-1;61725:194:0;;;;;:::i;:::-;;:::i;26534:36::-;;;;;;;;;;-1:-1:-1;26534:36:0;;;;-1:-1:-1;;;26534:36:0;;;;;;26974:64;;;;;;;;;;-1:-1:-1;26974:64:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;59723:99;;;;;;;;;;-1:-1:-1;59802:12:0;;59723:99;;;1901:25:1;;;1889:2;1874:18;59723:99:0;1755:177:1;49660:451:0;;;;;;;;;;-1:-1:-1;49660:451:0;;;;;:::i;:::-;;:::i;36081:1320::-;;;;;;;;;;-1:-1:-1;36081:1320:0;;;;;:::i;:::-;;:::i;27045:61::-;;;;;;;;;;-1:-1:-1;27045:61:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;62364:247;;;;;;;;;;-1:-1:-1;62364:247:0;;;;;:::i;:::-;;:::i;25436:30::-;;;;;;;;;;-1:-1:-1;25436:30:0;;;;;;25953:33;;;;;;;;;;;;;;;;43226:303;;;;;;;;;;;;;:::i;59433:90::-;;;;;;;;;;-1:-1:-1;59433:90:0;;25805:2;2540:36:1;;2528:2;2513:18;59433:90:0;2398:184:1;26615:33:0;;;;;;;;;;-1:-1:-1;26615:33:0;;;;-1:-1:-1;;;26615:33:0;;;;;;52185:329;;;;;;;;;;-1:-1:-1;52185:329:0;;;;;:::i;:::-;;:::i;44974:287::-;;;;;;;;;;-1:-1:-1;44974:287:0;;;;;:::i;:::-;;:::i;47383:402::-;;;;;;;;;;-1:-1:-1;47383:402:0;;;;;:::i;:::-;;:::i;48855:446::-;;;;;;;;;;-1:-1:-1;48855:446:0;;;;;:::i;:::-;;:::i;25400:29::-;;;;;;;;;;-1:-1:-1;25400:29:0;;;;;;26201:38;;;;;;;;;;;;;;;;46181:312;;;;;;;;;;-1:-1:-1;46181:312:0;;;;;:::i;:::-;;:::i;51369:475::-;;;;;;;;;;-1:-1:-1;51369:475:0;;;;;:::i;:::-;;:::i;26119:35::-;;;;;;;;;;;;;;;;26161:33;;;;;;;;;;;;;;;;60110:118;;;;;;;;;;-1:-1:-1;60110:118:0;;;;;:::i;:::-;;:::i;23318:103::-;;;;;;;;;;;;;:::i;26077:35::-;;;;;;;;;;;;;;;;44286:403;;;;;;;;;;-1:-1:-1;44286:403:0;;;;;:::i;:::-;;:::i;45559:327::-;;;;;;;;;;-1:-1:-1;45559:327:0;;;;;:::i;:::-;;:::i;25909:35::-;;;;;;;;;;;;;;;53605:379;;;;;;;;;;-1:-1:-1;53605:379:0;;;;;:::i;:::-;;:::i;50478:471::-;;;;;;;;;;-1:-1:-1;50478:471:0;;;;;:::i;:::-;;:::i;26916:51::-;;;;;;;;;;-1:-1:-1;26916:51:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;37807:1207;;;;;;;;;;;;;:::i;22594:87::-;;;;;;;;;;-1:-1:-1;22640:7:0;22667:6;-1:-1:-1;;;;;22667:6:0;22594:87;;;-1:-1:-1;;;;;3507:32:1;;;3489:51;;3477:2;3462:18;22594:87:0;3343:203:1;46748:297:0;;;;;;;;;;-1:-1:-1;46748:297:0;;;;;:::i;:::-;;:::i;39412:151::-;;;;;;;;;;;;;:::i;58952:94::-;;;;;;;;;;-1:-1:-1;59032:6:0;;;;;;;;;;;;-1:-1:-1;;;59032:6:0;;;;58952:94;;52864:394;;;;;;;;;;-1:-1:-1;52864:394:0;;;;;:::i;:::-;;:::i;26488:39::-;;;;;;;;;;-1:-1:-1;26488:39:0;;;;-1:-1:-1;;;26488:39:0;;;;;;26248:72;;;;;;;;;;-1:-1:-1;26248:72:0;;;;-1:-1:-1;;;;;26248:72:0;;;26327:77;;;;;;;;;;-1:-1:-1;26327:77:0;;;;-1:-1:-1;;;;;26327:77:0;;;26417:19;;;;;;;;;;-1:-1:-1;26417:19:0;;;;-1:-1:-1;;;;;26417:19:0;;;60597:186;;;;;;;;;;-1:-1:-1;60597:186:0;;;;;:::i;:::-;;:::i;25816:47::-;;;;;;;;;;;;25857:6;25816:47;;25473:31;;;;;;;;;;-1:-1:-1;25473:31:0;;;;;;43690:321;;;;;;;;;;;;;:::i;26034:36::-;;;;;;;;;;;;;;;;26449:32;;;;;;;;;;-1:-1:-1;26449:32:0;;;;-1:-1:-1;;;26449:32:0;;;;;;26655:26;;;;;;;;;;-1:-1:-1;26655:26:0;;;;-1:-1:-1;;;26655:26:0;;;;;;25550:31;;;;;;;;;;-1:-1:-1;25550:31:0;;;;;;61168:148;;;;;;;;;;-1:-1:-1;61168:148:0;;;;;:::i;:::-;-1:-1:-1;;;;;61278:21:0;;;61251:7;61278:21;;;:11;:21;;;;;;;;:30;;;;;;;;;;;;;61168:148;48114:384;;;;;;;;;;-1:-1:-1;48114:384:0;;;;;:::i;:::-;;:::i;26577:31::-;;;;;;;;;;-1:-1:-1;26577:31:0;;;;-1:-1:-1;;;26577:31:0;;;;;;25511:32;;;;;;;;;;-1:-1:-1;25511:32:0;;;;;;25993:34;;;;;;;;;;;;;;;;58091:360;;;;;;;;;;-1:-1:-1;58091:360:0;;;;;:::i;:::-;;:::i;25590:75::-;;;;;;;;;;-1:-1:-1;25590:75:0;;;;-1:-1:-1;;;;;25590:75:0;;;41747:1301;27263:6;:13;;-1:-1:-1;;;;27263:13:0;-1:-1:-1;;;27263:13:0;;;25857:6:::1;41839:19;:17;:19::i;:::-;:27;::::0;41861:5:::1;41839:27;:::i;:::-;:44;;;;:::i;:::-;41822:14;:61;41818:198;;;41943:14;25857:6;41959:19;:17;:19::i;:::-;:27;::::0;41981:5:::1;41959:27;:::i;:::-;:44;;;;:::i;:::-;41907:97;::::0;-1:-1:-1;;;41907:97:0;;::::1;::::0;::::1;4868:25:1::0;;;;4909:18;;;4902:34;4841:18;;41907:97:0::1;;;;;;;;41818:198;42069:1;42050:16;;42030:17;;:36;;;;:::i;:::-;:40;:97;;;;42111:16;;42091:17;;:36;;;;:::i;:::-;42074:14;:53;42030:97;42144:7;42026:136;42225:11;:21:::0;42200:12:::1;:22:::0;42172:25:::1;::::0;42200:46:::1;::::0;::::1;:::i;:::-;42172:74;;42257:21;42301:16;;42281:17;;:36;;;;:::i;:::-;42257:60:::0;-1:-1:-1;42338:32:0::1;42257:60:::0;42373:34:::1;42390:17:::0;42373:14;:34:::1;:::i;:::-;:50;;;;:::i;:::-;42338:85;;42461:24;42436:11;:21;;;:49;;;;;;;:::i;:::-;;;;;;;;42516:14;42496:16;;:34;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;42567:16:0::1;::::0;;42581:1:::1;42567:16:::0;;;;;::::1;::::0;;42543:21:::1;::::0;42567:16:::1;::::0;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;42567:16:0::1;42543:40;;42612:4;42594;42599:1;42594:7;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;42594:23:0;;::::1;:7;::::0;;::::1;::::0;;;;;;:23;;;;42638:6:::1;::::0;:13:::1;::::0;;-1:-1:-1;;;42638:13:0;;;;:6;;;::::1;::::0;:11:::1;::::0;:13:::1;::::0;;::::1;::::0;42594:7;;42638:13;;;;;:6;:13:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42628:4;42633:1;42628:7;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;42628:23:0;;::::1;:7;::::0;;::::1;::::0;;;;;:23;42696:6:::1;::::0;42664:56:::1;::::0;42681:4:::1;::::0;42696:6:::1;42705:14:::0;42664:8:::1;:56::i;:::-;42742:81;::::0;;5961:25:1;;;6017:2;6002:18;;5995:34;;;42795:10:0::1;6045:18:1::0;;;6038:60;42807:15:0::1;6129:2:1::0;6114:18;;6107:34;42742:81:0;;::::1;::::0;;;;5948:3:1;42742:81:0;;::::1;42836:6;::::0;42982:17:::1;::::0;42836:204:::1;::::0;-1:-1:-1;;;42836:204:0;;-1:-1:-1;;;;;42836:6:0;;::::1;::::0;:57:::1;::::0;:204:::1;::::0;42908:24;;42836:6:::1;::::0;42963:4;;42982:17;::::1;::::0;43014:15:::1;::::0;42836:204:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;41807:1241;;;;27287:1;-1:-1:-1::0;27299:6:0;:14;;-1:-1:-1;;;;27299:14:0;;;41747:1301::o;61725:194::-;61798:4;61834:10;61855:34;61834:10;61874:7;61883:5;61855:8;:34::i;:::-;61907:4;61900:11;;;61725:194;;;;;:::o;49660:451::-;20859:13;:11;:13::i;:::-;49760:4:::1;49742:15;:22;49738:100;;;49788:38;::::0;-1:-1:-1;;;49788:38:0;;::::1;::::0;::::1;4868:25:1::0;;;49821:4:0::1;4909:18:1::0;;;4902:34;4841:18;;49788:38:0::1;4694:248:1::0;49738:100:0::1;49848:54;49867:15;49884:7;:17;;;49848:18;:54::i;:::-;49939:7;:17:::0;;49967:35;;;;50018:85:::1;::::0;;7715:3:1;7697:22;;;7756:1;7735:19;;;7728:30;-1:-1:-1;;;7789:3:1;7774:19;;7767:38;7872:4;7857:20;;7850:36;;;7902:18;;;7895:34;;;50075:10:0::1;-1:-1:-1::0;7945:18:1;;7938:60;50087:15:0::1;-1:-1:-1::0;8014:19:1;;8007:35;-1:-1:-1;;;;;;;;;;;50018:85:0;7837:3:1;7822:19;50018:85:0::1;;;;;;;;49727:384;49660:451:::0;:::o;36081:1320::-;36213:17;;36177:6;;-1:-1:-1;;;;;36213:17:0;;;;36279:4;36255:29;;;;36251:1143;;36301:15;36340:16;;36320:17;;:36;;;;:::i;:::-;36301:56;;36372:17;36419:7;36392:24;36410:4;36392:9;:24::i;:::-;:34;;;;:::i;:::-;36372:54;;36457:9;36448:6;:18;36447:61;;;;36483:24;36501:4;36483:9;:24::i;:::-;36472:7;:35;;36447:61;36443:136;;;36536:27;;-1:-1:-1;;;36536:27:0;;;;;;;;;;;36443:136;36597:6;36607:1;36597:11;36593:74;;36642:9;36629:22;;36593:74;36737:12;;36707:55;;-1:-1:-1;;;36707:55:0;;-1:-1:-1;;;;;36737:12:0;;;36707:55;;;8227:51:1;8294:18;;;8287:34;;;36707:29:0;;;;;;8200:18:1;;36707:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;36681:165;;;;-1:-1:-1;;;36681:165:0;;8784:2:1;36681:165:0;;;8766:21:1;8823:2;8803:18;;;8796:30;8862:34;8842:18;;;8835:62;-1:-1:-1;;;8913:18:1;;;8906:46;8969:19;;36681:165:0;8582:412:1;36681:165:0;36286:572;;36251:1143;;;-1:-1:-1;;;;;36868:26:0;;36864:530;;36915:6;36925:1;36915:11;36911:86;;36960:21;36947:34;;36911:86;-1:-1:-1;;;;;37015:22:0;;:10;:22;37011:107;;37065:37;;-1:-1:-1;;;37065:37:0;;;;;;;;;;;37011:107;37132:38;;-1:-1:-1;;;;;37132:26:0;;;:38;;;;;37159:10;;37132:38;;;;37159:10;37132:26;:38;;;;;;;;;;;;;;;;;;;;;36864:530;;;37207:6;37217:1;37207:11;37203:110;;37252:45;;-1:-1:-1;;;37252:45:0;;37291:4;37252:45;;;3489:51:1;-1:-1:-1;;;;;37252:30:0;;;;;3462:18:1;;37252:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;37239:58;;37203:110;37327:55;-1:-1:-1;;;;;37327:33:0;;37361:8;37371:10;37327:33;:55::i;:::-;36145:1256;;36081:1320;;:::o;62364:247::-;62451:4;62486:10;62507:37;62523:4;62486:10;62538:5;62507:15;:37::i;:::-;62555:26;62565:4;62571:2;62575:5;62555:9;:26::i;:::-;62599:4;62592:11;;;62364:247;;;;;;:::o;43226:303::-;20859:13;:11;:13::i;:::-;43287:16:::1;::::0;-1:-1:-1;;;43287:16:0;::::1;;;43282:81;;43327:24;;-1:-1:-1::0;;;43327:24:0::1;;;;;;;:::i;43282:81::-;25857:6;43373:11;:28:::0;43412:16:::1;:24:::0;;-1:-1:-1;;;;43412:24:0::1;::::0;;43452:69:::1;::::0;;9933:3:1;9915:22;;;9974:2;9953:19;;;9946:31;-1:-1:-1;;;10008:3:1;9993:19;;9986:43;-1:-1:-1;10096:4:1;10081:20;;10074:52;-1:-1:-1;10142:18:1;;;10135:50;;;;43493:10:0::1;-1:-1:-1::0;10201:18:1;;10194:60;43505:15:0::1;-1:-1:-1::0;10270:19:1;;10263:35;-1:-1:-1;;;;;;;;;;;43452:69:0;10061:3:1;10046:19;43452:69:0::1;;;;;;;;43226:303::o:0;52185:329::-;20859:13;:11;:13::i;:::-;-1:-1:-1;;;;;52300:17:0;::::1;;::::0;;;:11:::1;:17;::::0;;;;;52270:48:::1;::::0;52289:9;;52300:17:::1;;52270:18;:48::i;:::-;-1:-1:-1::0;;;;;52346:17:0;::::1;52329:14;52346:17:::0;;;:11:::1;:17;::::0;;;;;;;;;;52374:29;::::1;;-1:-1:-1::0;;52374:29:0;::::1;::::0;::::1;::::0;;;52419:87;;10639:3:1;10621:22;;;10680:2;10659:19;;;10652:31;-1:-1:-1;;;10714:3:1;10699:19;;10692:42;10824:20;;;10817:45;;;;52346:17:0::1;::::0;;::::1;10905:14:1::0;;10898:22;10878:18;;;10871:50;;;;10952:2;10937:18;;10930:50;;;;52478:10:0::1;-1:-1:-1::0;10996:19:1;;10989:44;52490:15:0::1;-1:-1:-1::0;11049:19:1;;11042:35;52346:17:0;-1:-1:-1;;;;;;;;;;;52419:87:0;10766:3:1;10751:19;52419:87:0::1;;;;;;;;52259:255;52185:329:::0;;:::o;44974:287::-;20859:13;:11;:13::i;:::-;45075:11:::1;::::0;45045:42:::1;::::0;45064:9;;-1:-1:-1;;;45075:11:0;::::1;;;45045:18;:42::i;:::-;45115:11;::::0;;45137:23;::::1;;-1:-1:-1::0;;;45137:23:0;;::::1;-1:-1:-1::0;;;;45137:23:0;::::1;;::::0;;;45176:77:::1;::::0;;11390:3:1;11372:22;;;11431:2;11410:19;;;11403:31;-1:-1:-1;;;11465:3:1;11450:19;;11443:42;45115:11:0::1;::::0;;;::::1;::::0;;;::::1;11566:14:1::0;;11559:22;11552:4;11537:20;;11530:52;11598:18;;;11591:50;45225:10:0::1;-1:-1:-1::0;11657:18:1;;11650:60;45237:15:0::1;-1:-1:-1::0;11726:19:1;;11719:35;-1:-1:-1;;;;;;;;;;;45176:77:0;11517:3:1;11502:19;45176:77:0::1;11088:672:1::0;47383:402:0;20859:13;:11;:13::i;:::-;47476:3:::1;47465:8;:14;47461:88;;;47503:34;::::0;;-1:-1:-1;;;47503:34:0;;::::1;::::0;::::1;11987:21:1::0;;;;12044:2;12024:18;;;12017:30;-1:-1:-1;;;12063:18:1;;;12056:44;47533:3:0::1;12152:20:1::0;;;12145:36;12117:19;;47503:34:0::1;11765:422:1::0;47461:88:0::1;47559:44;47578:8;47588:14;;47559:18;:44::i;:::-;47633:14;::::0;;47658:25;;;;47699:78:::1;::::0;;12506:3:1;12488:22;;;12547:2;12526:19;;;12519:31;-1:-1:-1;;;12581:3:1;12566:19;;12559:45;12671:4;12656:20;;12649:36;;;12701:18;;;12694:34;;;47749:10:0::1;-1:-1:-1::0;12744:18:1;;12737:60;47761:15:0::1;-1:-1:-1::0;12813:19:1;;12806:35;-1:-1:-1;;;;;;;;;;;47699:78:0;12636:3:1;12621:19;47699:78:0::1;12192:655:1::0;48855:446:0;20859:13;:11;:13::i;:::-;48954:4:::1;48936:15;:22;48932:100;;;48982:38;::::0;-1:-1:-1;;;48982:38:0;;::::1;::::0;::::1;4868:25:1::0;;;49015:4:0::1;4909:18:1::0;;;4902:34;4841:18;;48982:38:0::1;4694:248:1::0;48932:100:0::1;49042:53;49061:15;49078:6;:16;;;49042:18;:53::i;:::-;49132:6;:16:::0;;49159:34;;;;49209:84:::1;::::0;;13166:3:1;13148:22;;;13207:1;13186:19;;;13179:30;-1:-1:-1;;;13240:3:1;13225:19;;13218:37;13322:4;13307:20;;13300:36;;;13352:18;;;13345:34;;;49265:10:0::1;-1:-1:-1::0;13395:18:1;;13388:60;49277:15:0::1;-1:-1:-1::0;13464:19:1;;13457:35;-1:-1:-1;;;;;;;;;;;49209:84:0;13287:3:1;13272:19;49209:84:0::1;12852:646:1::0;46181:312:0;20859:13;:11;:13::i;:::-;46287:16:::1;::::0;46257:47:::1;::::0;46276:9;;-1:-1:-1;;;46287:16:0;::::1;;;46257:18;:47::i;:::-;46332:16;::::0;;46359:28;::::1;;-1:-1:-1::0;;;46359:28:0;;::::1;-1:-1:-1::0;;;;46359:28:0;::::1;;::::0;;;46403:82:::1;::::0;;13805:3:1;13787:22;;;13846:2;13825:19;;;13818:31;-1:-1:-1;;;13880:3:1;13865:19;;13858:47;46332:16:0::1;::::0;;;::::1;::::0;;;::::1;13986:14:1::0;;13979:22;13972:4;13957:20;;13950:52;14018:18;;;14011:50;46457:10:0::1;-1:-1:-1::0;14077:18:1;;14070:60;46469:15:0::1;-1:-1:-1::0;14146:19:1;;14139:35;-1:-1:-1;;;;;;;;;;;46403:82:0;13937:3:1;13922:19;46403:82:0::1;13503:677:1::0;51369:475:0;20859:13;:11;:13::i;:::-;-1:-1:-1;;;;;51480:16:0;::::1;;::::0;;;:8:::1;:16;::::0;;;;;51450:47:::1;::::0;51469:9;;51480:16:::1;;51450:18;:47::i;:::-;51546:4;-1:-1:-1::0;;;;;51512:39:0::1;51518:6;-1:-1:-1::0;;;;;51512:20:0::1;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;51512:39:0::1;;;:82;;;;;51589:4;-1:-1:-1::0;;;;;51555:39:0::1;51561:6;-1:-1:-1::0;;;;;51555:20:0::1;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;51555:39:0::1;;;51512:82;51508:144;;;51618:22;::::0;-1:-1:-1;;;51618:22:0;;-1:-1:-1;;;;;3507:32:1;;51618:22:0::1;::::0;::::1;3489:51:1::0;3462:18;;51618:22:0::1;3343:203:1::0;51508:144:0::1;-1:-1:-1::0;;;;;51679:16:0;::::1;51662:14;51679:16:::0;;;:8:::1;:16;::::0;;;;;;;;;;51706:28;::::1;;-1:-1:-1::0;;51706:28:0;::::1;::::0;::::1;::::0;;;51750:86;;14515:3:1;14497:22;;;14556:1;14535:19;;;14528:30;-1:-1:-1;;;14589:3:1;14574:19;;14567:39;14696:20;;;14689:45;;;;51679:16:0::1;::::0;;::::1;14777:14:1::0;;14770:22;14750:18;;;14743:50;;;;14824:2;14809:18;;14802:50;;;;51808:10:0::1;-1:-1:-1::0;14868:19:1;;14861:44;51820:15:0::1;-1:-1:-1::0;14921:19:1;;14914:35;51679:16:0;-1:-1:-1;;;;;;;;;;;51750:86:0;14638:3:1;14623:19;51750:86:0::1;14185:770:1::0;60110:118:0;-1:-1:-1;;;;;60202:18:0;60175:7;60202:18;;;:9;:18;;;;;;;60110:118::o;23318:103::-;20859:13;:11;:13::i;:::-;23383:30:::1;23410:1;23383:18;:30::i;:::-;23318:103::o:0;44286:403::-;20859:13;:11;:13::i;:::-;25857:6:::1;44376:19;:17;:19::i;:::-;:27;::::0;44398:5:::1;44376:27;:::i;:::-;:44;;;;:::i;:::-;44363:10;:57;44359:121;;;44444:24;::::0;-1:-1:-1;;;44444:24:0;;::::1;::::0;::::1;1901:25:1::0;;;1874:18;;44444:24:0::1;1755:177:1::0;44359:121:0::1;44490:39;44509:10;44521:7;;44490:18;:39::i;:::-;44561:7;::::0;;44579:20;;;;44615:66:::1;::::0;;5961:25:1;;;6017:2;6002:18;;5995:34;;;44653:10:0::1;6045:18:1::0;;;6038:60;;;;44665:15:0::1;6129:2:1::0;6114:18;;6107:34;44615:66:0::1;::::0;5948:3:1;5933:19;44615:66:0::1;5730:417:1::0;45559:327:0;20859:13;:11;:13::i;:::-;45668:19:::1;::::0;45638:50:::1;::::0;45657:9;;-1:-1:-1;;;45668:19:0;::::1;;;45638:18;:50::i;:::-;45716:19;::::0;;45746:31;::::1;;-1:-1:-1::0;;;45746:31:0;;::::1;-1:-1:-1::0;;;;45746:31:0;::::1;;::::0;;;45793:85:::1;::::0;;15262:3:1;15244:22;;;15303:2;15282:19;;;15275:31;-1:-1:-1;;;15337:3:1;15322:19;;15315:50;45716:19:0::1;::::0;;;::::1;::::0;;;::::1;15446:14:1::0;;15439:22;15432:4;15417:20;;15410:52;15478:18;;;15471:50;45850:10:0::1;-1:-1:-1::0;15537:18:1;;15530:60;45862:15:0::1;-1:-1:-1::0;15606:19:1;;15599:35;-1:-1:-1;;;;;;;;;;;45793:85:0;15397:3:1;15382:19;45793:85:0::1;14960:680:1::0;53605:379:0;20859:13;:11;:13::i;:::-;-1:-1:-1;;;;;53730:27:0;::::1;;::::0;;;:21:::1;:27;::::0;;;;;53700:58:::1;::::0;53719:9;;53730:27:::1;;53700:18;:58::i;:::-;-1:-1:-1::0;;;;;53786:27:0;::::1;53769:14;53786:27:::0;;;:21:::1;:27;::::0;;;;;;;;;;53824:39;::::1;;-1:-1:-1::0;;53824:39:0;::::1;::::0;::::1;::::0;;;53879:97;;15975:3:1;15957:22;;;16016:2;15995:19;;;15988:31;-1:-1:-1;;;16050:3:1;16035:19;;16028:52;16170:20;;;16163:45;;;;53786:27:0::1;::::0;;::::1;16251:14:1::0;;16244:22;16224:18;;;16217:50;;;;16298:2;16283:18;;16276:50;;;;53948:10:0::1;-1:-1:-1::0;16342:19:1;;16335:44;53960:15:0::1;-1:-1:-1::0;16395:19:1;;16388:35;53786:27:0;-1:-1:-1;;;;;;;;;;;53879:97:0;16112:3:1;16097:19;53879:97:0::1;15645:784:1::0;50478:471:0;20859:13;:11;:13::i;:::-;50582:4:::1;50564:15;:22;50560:100;;;50610:38;::::0;-1:-1:-1;;;50610:38:0;;::::1;::::0;::::1;4868:25:1::0;;;50643:4:0::1;4909:18:1::0;;;4902:34;4841:18;;50610:38:0::1;4694:248:1::0;50560:100:0::1;50670:58;50689:15;50706:11;:21;;;50670:18;:58::i;:::-;50765:11;:21:::0;;50797:39;;;;50852:89:::1;::::0;;16748:3:1;16730:22;;;16789:2;16768:19;;;16761:31;-1:-1:-1;;;16823:3:1;16808:19;;16801:42;16910:4;16895:20;;16888:36;;;16940:18;;;16933:34;;;50913:10:0::1;-1:-1:-1::0;16983:18:1;;16976:60;50925:15:0::1;-1:-1:-1::0;17052:19:1;;17045:35;-1:-1:-1;;;;;;;;;;;50852:89:0;16875:3:1;16860:19;50852:89:0::1;16434:652:1::0;37807:1207:0;20859:13;:11;:13::i;:::-;37866:12:::1;::::0;-1:-1:-1;;;37866:12:0;::::1;;;37862:101;;;37922:12;::::0;37936:14:::1;::::0;37902:49:::1;::::0;-1:-1:-1;;;37902:49:0;;-1:-1:-1;;;37922:12:0;;::::1;;;17284:14:1::0;17277:22;37902:49:0::1;::::0;::::1;17259:41:1::0;17316:18;;;17309:34;17232:18;;37902:49:0::1;17091:258:1::0;37862:101:0::1;38010:1;22667:6:::0;-1:-1:-1;;;;;22667:6:0;37991:21;;::::1;::::0;:59:::1;;-1:-1:-1::0;38040:10:0::1;38029:7;22640::::0;22667:6;-1:-1:-1;;;;;22667:6:0;;22594:87;38029:7:::1;-1:-1:-1::0;;;;;38029:21:0::1;;;37991:59;:114;;;;-1:-1:-1::0;38090:15:0::1;38067:20;:10;38080:7;38067:20;:::i;:::-;:38;37991:114;37973:216;;;38139:38;::::0;-1:-1:-1;;;38139:38:0;;38166:10:::1;38139:38;::::0;::::1;3489:51:1::0;3462:18;;38139:38:0::1;3343:203:1::0;37973:216:0::1;38236:1;22667:6:::0;-1:-1:-1;;;;;22667:6:0;38217:21;:59;::::1;;;-1:-1:-1::0;38266:10:0::1;38255:7;22640::::0;22667:6;-1:-1:-1;;;;;22667:6:0;;22594:87;38255:7:::1;-1:-1:-1::0;;;;;38255:21:0::1;;;38217:59;:114;;;;-1:-1:-1::0;38316:15:0::1;38293:20;:10;38306:7;38293:20;:::i;:::-;:38;38217:114;38199:313;;;38405:20;:10;38418:7;38405:20;:::i;:::-;38470:15;38446:20;:10;38459:7;38446:20;:::i;:::-;38445:40;;;;:::i;:::-;38365:135;::::0;-1:-1:-1;;;38365:135:0;;::::1;::::0;::::1;4868:25:1::0;;;;4909:18;;;4902:34;4841:18;;38365:135:0::1;4694:248:1::0;38199:313:0::1;38527:19;::::0;-1:-1:-1;;;38527:19:0;::::1;;;38522:79;;38563:19;:26:::0;;-1:-1:-1;;;;38563:26:0::1;-1:-1:-1::0;;;38563:26:0::1;::::0;;38522:79:::1;38616:11;::::0;-1:-1:-1;;;38616:11:0;::::1;;;38611:63;;38644:11;:18:::0;;-1:-1:-1;;;;38644:18:0::1;-1:-1:-1::0;;;38644:18:0::1;::::0;;38611:63:::1;38689:13;::::0;-1:-1:-1;;;38689:13:0;::::1;;;38684:67;;38719:13;:20:::0;;-1:-1:-1;;;;38719:20:0::1;-1:-1:-1::0;;;38719:20:0::1;::::0;;38684:67:::1;38766:16;::::0;-1:-1:-1;;;38766:16:0;::::1;;;38761:73;;38799:16;:23:::0;;-1:-1:-1;;;;38799:23:0::1;-1:-1:-1::0;;;38799:23:0::1;::::0;;38761:73:::1;38844:12;:19:::0;;-1:-1:-1;;;;38844:19:0::1;-1:-1:-1::0;;;38844:19:0::1;::::0;;38891:15:::1;38874:14;:32:::0;;;38935:12:::1;-1:-1:-1::0;38917:30:0;38965:41:::1;::::0;;38978:10:::1;8227:51:1::0;;8309:2;8294:18;;8287:34;;;;38965:41:0::1;::::0;8200:18:1;38965:41:0::1;8053:274:1::0;46748:297:0;20859:13;:11;:13::i;:::-;46851::::1;::::0;46821:44:::1;::::0;46840:9;;-1:-1:-1;;;46851:13:0;::::1;;;46821:18;:44::i;:::-;46893:13;::::0;;46917:25;::::1;;-1:-1:-1::0;;;46917:25:0;;::::1;-1:-1:-1::0;;;;46917:25:0;::::1;;::::0;;;46958:79:::1;::::0;;17656:3:1;17638:22;;;17697:2;17676:19;;;17669:31;-1:-1:-1;;;17731:3:1;17716:19;;17709:44;46893:13:0::1;::::0;;;::::1;::::0;;;::::1;17834:14:1::0;;17827:22;17820:4;17805:20;;17798:52;17866:18;;;17859:50;47009:10:0::1;-1:-1:-1::0;17925:18:1;;17918:60;47021:15:0::1;-1:-1:-1::0;17994:19:1;;17987:35;-1:-1:-1;;;;;;;;;;;46958:79:0;17785:3:1;17770:19;46958:79:0::1;17354:674:1::0;39412:151:0;39462:7;39534:21;39552:1;39534:9;:21::i;:::-;39505:26;39523:6;39505:9;:26::i;:::-;59802:12;;39489:42;;;;:::i;:::-;:66;;;;:::i;:::-;39482:73;;39412:151;:::o;52864:394::-;20859:13;:11;:13::i;:::-;-1:-1:-1;;;;;52992:30:0;::::1;;::::0;;;:24:::1;:30;::::0;;;;;52962:61:::1;::::0;52981:9;;52992:30:::1;;52962:18;:61::i;:::-;-1:-1:-1::0;;;;;53051:30:0;::::1;53034:14;53051:30:::0;;;:24:::1;:30;::::0;;;;;;;;;;53092:42;::::1;;-1:-1:-1::0;;53092:42:0;::::1;::::0;::::1;::::0;;;53150:100;;18363:3:1;18345:22;;;18404:2;18383:19;;;18376:31;18444:26;18438:3;18423:19;;18416:55;18561:20;;;18554:45;;;;53051:30:0::1;::::0;;::::1;18642:14:1::0;;18635:22;18615:18;;;18608:50;;;;18689:2;18674:18;;18667:50;;;;53222:10:0::1;-1:-1:-1::0;18733:19:1;;18726:44;53234:15:0::1;-1:-1:-1::0;18786:19:1;;18779:35;53051:30:0;-1:-1:-1;;;;;;;;;;;53150:100:0;18503:3:1;18488:19;53150:100:0::1;18033:787:1::0;60597:186:0;60666:4;60702:10;60723:30;60702:10;60743:2;60747:5;60723:9;:30::i;43690:321::-;20859:13;:11;:13::i;:::-;43754:19:::1;::::0;-1:-1:-1;;;43754:19:0;::::1;;;43749:87;;43797:27;;-1:-1:-1::0;;;43797:27:0::1;;;;;;;:::i;43749:87::-;25857:6;43846:14;:31:::0;43888:19:::1;:27:::0;;-1:-1:-1;;;;43888:27:0::1;::::0;;43931:72:::1;::::0;;19564:3:1;19546:22;;;19605:2;19584:19;;;19577:31;-1:-1:-1;;;19639:3:1;19624:19;;19617:46;-1:-1:-1;19730:4:1;19715:20;;19708:52;-1:-1:-1;19776:18:1;;;19769:50;;;;43975:10:0::1;-1:-1:-1::0;19835:18:1;;19828:60;43987:15:0::1;-1:-1:-1::0;19904:19:1;;19897:35;-1:-1:-1;;;;;;;;;;;43931:72:0;19695:3:1;19680:19;43931:72:0::1;19262:676:1::0;48114:384:0;20859:13;:11;:13::i;:::-;48204:3:::1;48193:8;:14;48189:85;;;48231:31;::::0;;-1:-1:-1;;;48231:31:0;;::::1;::::0;::::1;20165:21:1::0;;;;20222:2;20202:18;;;20195:30;-1:-1:-1;;;20241:18:1;;;20234:41;48258:3:0::1;20327:20:1::0;;;20320:36;20292:19;;48231:31:0::1;19943:419:1::0;48189:85:0::1;48284:41;48303:8;48313:11;;48284:18;:41::i;:::-;48355:11;::::0;;48377:22;;;;48415:75:::1;::::0;;20681:3:1;20663:22;;;20722:2;20701:19;;;20694:31;-1:-1:-1;;;20756:3:1;20741:19;;20734:42;20843:4;20828:20;;20821:36;;;20873:18;;;20866:34;;;48462:10:0::1;-1:-1:-1::0;20916:18:1;;20909:60;48474:15:0::1;-1:-1:-1::0;20985:19:1;;20978:35;-1:-1:-1;;;;;;;;;;;48415:75:0;20808:3:1;20793:19;48415:75:0::1;20367:652:1::0;58091:360:0;20859:13;:11;:13::i;:::-;22640:7;22667:6;-1:-1:-1;;;;;22667:6:0;-1:-1:-1;;;;;58177:19:0::1;:8;-1:-1:-1::0;;;;;58177:19:0::1;::::0;58173:92:::1;;58220:33;::::0;-1:-1:-1;;;58220:33:0;;-1:-1:-1;;;;;3507:32:1;;58220:33:0::1;::::0;::::1;3489:51:1::0;3462:18;;58220:33:0::1;3343:203:1::0;58173:92:0::1;-1:-1:-1::0;;;;;;;58279:27:0;::::1;::::0;58275:91:::1;;58330:24;::::0;-1:-1:-1;;;58330:24:0;;-1:-1:-1;;;;;3507:32:1;;58330:24:0::1;::::0;::::1;3489:51:1::0;3462:18;;58330:24:0::1;3343:203:1::0;58275:91:0::1;58376:12;:23:::0;;-1:-1:-1;;;;;;58376:23:0::1;-1:-1:-1::0;;;;;58376:23:0;::::1;;::::0;;58410:33:::1;58376:23:::0;58410::::1;:33::i;:::-;58091:360:::0;:::o;63916:136::-;64004:40;64013:8;64023:7;64032:5;64039:4;64004:8;:40::i;:::-;63916:136;;;:::o;22878:162::-;22949:10;22938:7;22640;22667:6;-1:-1:-1;;;;;22667:6:0;;22594:87;22938:7;-1:-1:-1;;;;;22938:21:0;;22934:99;;22983:38;;-1:-1:-1;;;22983:38:0;;23010:10;22983:38;;;3489:51:1;3462:18;;22983:38:0;3343:203:1;39714:185:0;39818:7;39806:8;:19;39802:90;;39849:31;;-1:-1:-1;;;39849:31:0;;;;;1901:25:1;;;1874:18;;39849:31:0;1755:177:1;39802:90:0;39714:185;;:::o;5754:162::-;5864:43;;;-1:-1:-1;;;;;8245:32:1;;5864:43:0;;;8227:51:1;8294:18;;;;8287:34;;;5864:43:0;;;;;;;;;;8200:18:1;;;;5864:43:0;;;;;;;;-1:-1:-1;;;;;5864:43:0;-1:-1:-1;;;5864:43:0;;;5837:71;;5857:5;;5837:19;:71::i;65840:496::-;-1:-1:-1;;;;;61278:21:0;;;65943:24;61278:21;;;:11;:21;;;;;;;;:30;;;;;;;;;;-1:-1:-1;;66013:37:0;;66009:320;;66090:5;66071:16;:24;66067:132;;;66123:60;;-1:-1:-1;;;66123:60:0;;-1:-1:-1;;;;;21244:32:1;;66123:60:0;;;21226:51:1;21293:18;;;21286:34;;;21336:18;;;21329:34;;;21199:18;;66123:60:0;21024:345:1;66067:132:0;66242:60;66251:8;66261:7;66289:5;66270:16;:24;66296:5;66242:8;:60::i;67584:1170::-;-1:-1:-1;;;;;67668:18:0;;67664:88;;67710:30;;-1:-1:-1;;;67710:30:0;;67737:1;67710:30;;;3489:51:1;3462:18;;67710:30:0;3343:203:1;67664:88:0;-1:-1:-1;;;;;67766:16:0;;67762:88;;67806:32;;-1:-1:-1;;;67806:32:0;;67835:1;67806:32;;;3489:51:1;3462:18;;67806:32:0;3343:203:1;67762:88:0;67865:12;;-1:-1:-1;;;67865:12:0;;;;67860:151;;-1:-1:-1;;;;;67899:17:0;;;;;;:11;:17;;;;;;;;67898:18;:38;;;;-1:-1:-1;;;;;;67921:15:0;;;;;;:11;:15;;;;;;;;67920:16;67898:38;67894:106;;;67964:20;;-1:-1:-1;;;67964:20:0;;;;;;;;;;;67894:106;68027:16;;-1:-1:-1;;;68027:16:0;;;;68023:76;;;68060:27;68075:5;68082:4;68060:14;:27::i;:::-;68115:6;;-1:-1:-1;;;68115:6:0;;;;;:27;;-1:-1:-1;;;;;;68125:17:0;;;;;;:11;:17;;;;;;;;68115:27;68111:91;;;68166:24;68174:4;68180:2;68184:5;68166:7;:24::i;68111:91::-;68224:4;;-1:-1:-1;;;;;68216:12:0;;;68224:4;;68216:12;;;;:29;;-1:-1:-1;68232:13:0;;-1:-1:-1;;;68232:13:0;;;;68216:29;:80;;;;;68289:7;;68269:16;;68249:17;;:36;;;;:::i;:::-;:47;;68216:80;:119;;;;;68328:7;;68300:24;68318:4;68300:9;:24::i;:::-;:35;;68216:119;68212:217;;;68373:7;;68395:22;68373:7;68395:10;:22::i;:::-;68337:92;68212:217;68482:11;;68460:5;;-1:-1:-1;;;68482:11:0;;;;:33;;;;-1:-1:-1;;;;;;68498:17:0;;;;;;:11;:17;;;;;;;;68497:18;68482:33;:53;;;;-1:-1:-1;;;;;;68520:15:0;;;;;;:11;:15;;;;;;;;68519:16;68482:53;68478:134;;;68563:37;68584:4;68590:2;68594:5;68563:20;:37::i;:::-;68552:48;;68478:134;68628:19;;-1:-1:-1;;;68628:19:0;;;;68624:83;;;68664:31;68682:8;68692:2;68664:17;:31::i;:::-;68719:27;68727:4;68733:2;68737:8;68719:7;:27::i;40035:179::-;40133:7;40121:19;;:8;:19;;;40117:90;;40164:31;;-1:-1:-1;;;40164:31:0;;1408:14:1;;1401:22;40164:31:0;;;1383:41:1;1356:18;;40164:31:0;1243:187:1;24409:191:0;24483:16;24502:6;;-1:-1:-1;;;;;24519:17:0;;;-1:-1:-1;;;;;;24519:17:0;;;;;;24552:40;;24502:6;;;;;;;24552:40;;24483:16;24552:40;24472:128;24409:191;:::o;23852:220::-;20859:13;:11;:13::i;:::-;-1:-1:-1;;;;;23937:22:0;::::1;23933:93;;23983:31;::::0;-1:-1:-1;;;23983:31:0;;24011:1:::1;23983:31;::::0;::::1;3489:51:1::0;3462:18;;23983:31:0::1;3343:203:1::0;23933:93:0::1;24036:28;24055:8;24036:18;:28::i;64825:455::-:0;-1:-1:-1;;;;;64941:22:0;;64937:94;;64987:32;;-1:-1:-1;;;64987:32:0;;65016:1;64987:32;;;3489:51:1;3462:18;;64987:32:0;3343:203:1;64937:94:0;-1:-1:-1;;;;;65045:21:0;;65041:92;;65090:31;;-1:-1:-1;;;65090:31:0;;65118:1;65090:31;;;3489:51:1;3462:18;;65090:31:0;3343:203:1;65041:92:0;-1:-1:-1;;;;;65143:21:0;;;;;;;:11;:21;;;;;;;;:30;;;;;;;;;:38;;;65192:81;;;;65246:7;-1:-1:-1;;;;;65227:34:0;65236:8;-1:-1:-1;;;;;65227:34:0;;65255:5;65227:34;;;;1901:25:1;;1889:2;1874:18;;1755:177;65227:34:0;;;;;;;;64825:455;;;;:::o;6306:295::-;6387:23;6413:33;-1:-1:-1;;;;;6413:27:0;;6441:4;6413:27;:33::i;:::-;6387:59;;6461:10;:17;6482:1;6461:22;;:57;;;;;6499:10;6488:30;;;;;;;;;;;;:::i;:::-;6487:31;6461:57;6457:137;;;6542:40;;-1:-1:-1;;;6542:40:0;;-1:-1:-1;;;;;3507:32:1;;6542:40:0;;;3489:51:1;3462:18;;6542:40:0;3343:203:1;40326:299:0;40405:13;25857:6;40443:11;;40421:19;:17;:19::i;:::-;:33;;;;:::i;:::-;:50;;;;:::i;:::-;40486:16;;40405:66;;-1:-1:-1;;;;40486:16:0;;;;:48;;;;-1:-1:-1;;;;;;40507:27:0;;;;;;:21;:27;;;;;;;;40506:28;40486:48;:66;;;;;40547:5;40538:6;:14;40486:66;40482:136;;;40600:5;40576:30;;-1:-1:-1;;;40576:30:0;;;;;;;;:::i;70564:730::-;-1:-1:-1;;;;;70654:18:0;;70650:369;;70705:5;70689:12;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;70650:369:0;;-1:-1:-1;70650:369:0;;-1:-1:-1;;;;;70765:15:0;;70743:19;70765:15;;;:9;:15;;;;;;70799:19;;;70795:117;;;70846:50;;-1:-1:-1;;;70846:50:0;;-1:-1:-1;;;;;21244:32:1;;70846:50:0;;;21226:51:1;21293:18;;;21286:34;;;21336:18;;;21329:34;;;21199:18;;70846:50:0;21024:345:1;70795:117:0;-1:-1:-1;;;;;70955:15:0;;;;;;:9;:15;;;;;70973:19;;;;70955:37;;70650:369;-1:-1:-1;;;;;71035:16:0;;71031:213;;71097:12;:21;;;;;;;71031:213;;;-1:-1:-1;;;;;71195:13:0;;;;;;:9;:13;;;;;:22;;;;;;71031:213;71276:2;-1:-1:-1;;;;;71261:25:0;71270:4;-1:-1:-1;;;;;71261:25:0;;71280:5;71261:25;;;;1901::1;;1889:2;1874:18;;1755:177;71261:25:0;;;;;;;;70564:730;;;:::o;69354:518::-;27263:6;:13;;-1:-1:-1;;;;27263:13:0;-1:-1:-1;;;27263:13:0;;;-1:-1:-1;;;;;69485:14:0;::::1;69461:7:::0;69485:14;;;:8:::1;:14;::::0;;;;;27263:13;69485:14:::1;:40:::0;::::1;;;-1:-1:-1::0;69504:6:0::1;:16:::0;:20;;69485:40:::1;69481:104;;;69549:24;69560:4;69566:6;69549:10;:24::i;:::-;69542:31;;;;69481:104;-1:-1:-1::0;;;;;69599:12:0;::::1;;::::0;;;:8:::1;:12;::::0;;;;;::::1;;:39:::0;::::1;;;-1:-1:-1::0;69616:7:0::1;:17:::0;:21;;69599:39:::1;69595:104;;;69662:25;69674:4;69680:6;69662:11;:25::i;69595:104::-;-1:-1:-1::0;;;;;69714:14:0;::::1;;::::0;;;:8:::1;:14;::::0;;;;;::::1;;69713:15;:32:::0;::::1;;;-1:-1:-1::0;;;;;;69733:12:0;::::1;;::::0;;;:8:::1;:12;::::0;;;;;::::1;;69732:13;69713:32;:63;;;;-1:-1:-1::0;69750:11:0::1;:21:::0;:25;;69713:63:::1;69709:132;;;69800:29;69816:4;69822:6;69800:15;:29::i;69709:132::-;-1:-1:-1::0;69858:6:0;27287:1:::1;27299:6:::0;:14;;-1:-1:-1;;;;27299:14:0;;;69354:518;;-1:-1:-1;;;69354:518:0:o;40735:368::-;40815:18;40852:6;40836:13;40846:2;40836:9;:13::i;:::-;:22;;;;:::i;:::-;40815:43;;40869:13;25857:6;40907:14;;40885:19;:17;:19::i;:::-;:36;;;;:::i;:::-;:53;;;;:::i;:::-;40953:19;;40869:69;;-1:-1:-1;;;;40953:19:0;;;;:52;;;;-1:-1:-1;;;;;;40977:28:0;;;;;;:24;:28;;;;;;;;40976:29;40953:52;:74;;;;;41022:5;41009:10;:18;40953:74;40949:147;;;41078:5;41051:33;;-1:-1:-1;;;41051:33:0;;;;;;;;:::i;1676:153::-;1751:12;1783:38;1805:6;1813:4;1819:1;1783:21;:38::i;54342:141::-;27263:6;:13;;-1:-1:-1;;;;27263:13:0;-1:-1:-1;;;27263:13:0;;;54446:29:::1;::::0;;::::1;::::0;::::1;::::0;;;27272:4;54446:29;;;54419:7;;54446:29:::1;::::0;54462:4;54468:6;54446:7:::1;:29::i;54825:143::-:0;27263:6;:13;;-1:-1:-1;;;;27263:13:0;-1:-1:-1;;;27263:13:0;;;54930:30:::1;::::0;;::::1;::::0;::::1;::::0;;;54938:7:::1;54930:30:::0;;;54903:7;;54930:30:::1;::::0;54947:4;54953:6;54930:7:::1;:30::i;55314:151::-:0;27263:6;:13;;-1:-1:-1;;;;27263:13:0;-1:-1:-1;;;27263:13:0;;;55423:34:::1;::::0;;::::1;::::0;::::1;::::0;;;55431:11:::1;55423:34:::0;;;55396:7;;55423:34:::1;::::0;55444:4;55450:6;55423:7:::1;:34::i;2422:398::-:0;2521:12;2574:5;2550:21;:29;2546:110;;;2603:41;;-1:-1:-1;;;2603:41:0;;2638:4;2603:41;;;3489:51:1;3462:18;;2603:41:0;3343:203:1;2546:110:0;2667:12;2681:23;2708:6;-1:-1:-1;;;;;2708:11:0;2727:5;2734:4;2708:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2666:73;;;;2757:55;2784:6;2792:7;2801:10;2757:26;:55::i;:::-;2750:62;2422:398;-1:-1:-1;;;;;;2422:398:0:o;55863:492::-;27263:6;:13;;-1:-1:-1;;;;27263:13:0;-1:-1:-1;;;27263:13:0;;;55996:17;;56044:15:::1;::::0;55957:7;;55996:17;56044:19:::1;::::0;56062:1:::1;56044:19;:::i;:::-;56028:12;:35;56024:83;;-1:-1:-1::0;56091:4:0::1;56024:83;56117:17;25857:6;56137:17;56146:8:::0;56137:6;:17:::1;:::i;:::-;:34;;;;:::i;:::-;56117:54:::0;-1:-1:-1;56182:17:0::1;56202:18;56117:54:::0;56202:6;:18:::1;:::i;:::-;56182:38:::0;-1:-1:-1;56235:13:0;;56231:90:::1;;56265:44;56274:7;56283:4;56289:9;56300:8;56265;:44::i;:::-;27299:6:::0;:14;;-1:-1:-1;;;;27299:14:0;;;56338:9;55863:492;-1:-1:-1;;;;;;55863:492:0:o;3584:391::-;3698:12;3728:7;3723:245;;3752:19;3760:10;3752:7;:19::i;:::-;3723:245;;;3808:17;;:22;:49;;;;-1:-1:-1;;;;;;3834:18:0;;;:23;3808:49;3804:121;;;3885:24;;-1:-1:-1;;;3885:24:0;;-1:-1:-1;;;;;3507:32:1;;3885:24:0;;;3489:51:1;3462:18;;3885:24:0;3343:203:1;3804:121:0;-1:-1:-1;3946:10:0;3939:17;;56748:427;27263:6;:13;;-1:-1:-1;;;;27263:13:0;-1:-1:-1;;;27263:13:0;;;56877:17;;56925:15:::1;::::0;:19:::1;::::0;56943:1:::1;56925:19;:::i;:::-;56909:12;:35;56905:83;;-1:-1:-1::0;56972:4:0::1;56905:83;56998:24;57045:3:::0;57025:17:::1;57034:8:::0;57025:6;:17:::1;:::i;:::-;:23;;;;:::i;:::-;56998:50;;57059:51;57075:16;57093;57059:15;:51::i;:::-;57131:36;57139:4;57153;57160:6;57131:7;:36::i;:::-;-1:-1:-1::0;;27299:6:0;:14;;-1:-1:-1;;;;27299:14:0;;;-1:-1:-1;;;;56748:427:0:o;4243:328::-;4313:17;;:21;4309:255;;4408:10;4402:17;4465:15;4452:10;4448:2;4444:19;4437:44;4309:255;4535:17;;-1:-1:-1;;;4535:17:0;;;;;;;;;;;57431:184;27263:6;:13;;-1:-1:-1;;;;27263:13:0;-1:-1:-1;;;27263:13:0;;;57527:12:::1;:42:::0;;57553:16;;57527:12;27263:13;;57527:42:::1;::::0;57553:16;;57527:42:::1;:::i;:::-;;;;;;;;57601:6;57580:17;;:27;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;27299:6:0;:14;;-1:-1:-1;;;;27299:14:0;;;-1:-1:-1;;57431:184:0:o;14:180:1:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:1;;14:180;-1:-1:-1;14:180:1:o;199:250::-;284:1;294:113;308:6;305:1;302:13;294:113;;;384:11;;;378:18;365:11;;;358:39;330:2;323:10;294:113;;;-1:-1:-1;;441:1:1;423:16;;416:27;199:250::o;454:396::-;603:2;592:9;585:21;566:4;635:6;629:13;678:6;673:2;662:9;658:18;651:34;694:79;766:6;761:2;750:9;746:18;741:2;733:6;729:15;694:79;:::i;:::-;834:2;813:15;-1:-1:-1;;809:29:1;794:45;;;;841:2;790:54;;454:396;-1:-1:-1;;454:396:1:o;855:131::-;-1:-1:-1;;;;;930:31:1;;920:42;;910:70;;976:1;973;966:12;991:247;1050:6;1103:2;1091:9;1082:7;1078:23;1074:32;1071:52;;;1119:1;1116;1109:12;1071:52;1158:9;1145:23;1177:31;1202:5;1177:31;:::i;1435:315::-;1503:6;1511;1564:2;1552:9;1543:7;1539:23;1535:32;1532:52;;;1580:1;1577;1570:12;1532:52;1619:9;1606:23;1638:31;1663:5;1638:31;:::i;:::-;1688:5;1740:2;1725:18;;;;1712:32;;-1:-1:-1;;;1435:315:1:o;1937:456::-;2014:6;2022;2030;2083:2;2071:9;2062:7;2058:23;2054:32;2051:52;;;2099:1;2096;2089:12;2051:52;2138:9;2125:23;2157:31;2182:5;2157:31;:::i;:::-;2207:5;-1:-1:-1;2264:2:1;2249:18;;2236:32;2277:33;2236:32;2277:33;:::i;:::-;1937:456;;2329:7;;-1:-1:-1;;;2383:2:1;2368:18;;;;2355:32;;1937:456::o;2587:118::-;2673:5;2666:13;2659:21;2652:5;2649:32;2639:60;;2695:1;2692;2685:12;2710:382;2775:6;2783;2836:2;2824:9;2815:7;2811:23;2807:32;2804:52;;;2852:1;2849;2842:12;2804:52;2891:9;2878:23;2910:31;2935:5;2910:31;:::i;:::-;2960:5;-1:-1:-1;3017:2:1;3002:18;;2989:32;3030:30;2989:32;3030:30;:::i;:::-;3079:7;3069:17;;;2710:382;;;;;:::o;3097:241::-;3153:6;3206:2;3194:9;3185:7;3181:23;3177:32;3174:52;;;3222:1;3219;3212:12;3174:52;3261:9;3248:23;3280:28;3302:5;3280:28;:::i;3551:388::-;3619:6;3627;3680:2;3668:9;3659:7;3655:23;3651:32;3648:52;;;3696:1;3693;3686:12;3648:52;3735:9;3722:23;3754:31;3779:5;3754:31;:::i;:::-;3804:5;-1:-1:-1;3861:2:1;3846:18;;3833:32;3874:33;3833:32;3874:33;:::i;4167:127::-;4228:10;4223:3;4219:20;4216:1;4209:31;4259:4;4256:1;4249:15;4283:4;4280:1;4273:15;4299:168;4372:9;;;4403;;4420:15;;;4414:22;;4400:37;4390:71;;4441:18;;:::i;4472:217::-;4512:1;4538;4528:132;;4582:10;4577:3;4573:20;4570:1;4563:31;4617:4;4614:1;4607:15;4645:4;4642:1;4635:15;4528:132;-1:-1:-1;4674:9:1;;4472:217::o;4947:128::-;5014:9;;;5035:11;;;5032:37;;;5049:18;;:::i;5080:125::-;5145:9;;;5166:10;;;5163:36;;;5179:18;;:::i;5342:127::-;5403:10;5398:3;5394:20;5391:1;5384:31;5434:4;5431:1;5424:15;5458:4;5455:1;5448:15;5474:251;5544:6;5597:2;5585:9;5576:7;5572:23;5568:32;5565:52;;;5613:1;5610;5603:12;5565:52;5645:9;5639:16;5664:31;5689:5;5664:31;:::i;6152:980::-;6414:4;6462:3;6451:9;6447:19;6493:6;6482:9;6475:25;6519:2;6557:6;6552:2;6541:9;6537:18;6530:34;6600:3;6595:2;6584:9;6580:18;6573:31;6624:6;6659;6653:13;6690:6;6682;6675:22;6728:3;6717:9;6713:19;6706:26;;6767:2;6759:6;6755:15;6741:29;;6788:1;6798:195;6812:6;6809:1;6806:13;6798:195;;;6877:13;;-1:-1:-1;;;;;6873:39:1;6861:52;;6968:15;;;;6933:12;;;;6909:1;6827:9;6798:195;;;-1:-1:-1;;;;;;;7049:32:1;;;;7044:2;7029:18;;7022:60;-1:-1:-1;;;7113:3:1;7098:19;7091:35;7010:3;6152:980;-1:-1:-1;;;6152:980:1:o;8332:245::-;8399:6;8452:2;8440:9;8431:7;8427:23;8423:32;8420:52;;;8468:1;8465;8458:12;8420:52;8500:9;8494:16;8519:28;8541:5;8519:28;:::i;8999:184::-;9069:6;9122:2;9110:9;9101:7;9097:23;9093:32;9090:52;;;9138:1;9135;9128:12;9090:52;-1:-1:-1;9161:16:1;;8999:184;-1:-1:-1;8999:184:1:o;9349:277::-;9551:2;9540:9;9533:21;9514:4;9571:49;9616:2;9605:9;9601:18;9265:1;9253:14;;-1:-1:-1;;;9292:4:1;9283:14;;9276:34;9335:2;9326:12;;9188:156;18985:272;19187:2;19176:9;19169:21;19150:4;19207:44;19247:2;19236:9;19232:18;18897:2;18885:15;;-1:-1:-1;;;18925:4:1;18916:14;;18909:37;18971:2;18962:12;;18825:155;21374:348;21604:2;21593:9;21586:21;21567:4;21624:49;21669:2;21658:9;21654:18;9265:1;9253:14;;-1:-1:-1;;;9292:4:1;9283:14;;9276:34;9335:2;9326:12;;9188:156;21624:49;21616:57;;21709:6;21704:2;21693:9;21689:18;21682:34;21374:348;;;;:::o;21727:343::-;21957:2;21946:9;21939:21;21920:4;21977:44;22017:2;22006:9;22002:18;18897:2;18885:15;;-1:-1:-1;;;18925:4:1;18916:14;;18909:37;18971:2;18962:12;;18825:155;22075:287;22204:3;22242:6;22236:13;22258:66;22317:6;22312:3;22305:4;22297:6;22293:17;22258:66;:::i;:::-;22340:16;;;;;22075:287;-1:-1:-1;;22075:287:1:o

Swarm Source

ipfs://a11c4a06f91aefc4e382c9310ed3c3d14b12450dd5181bf24e8a51ab88374cd2
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.