ETH Price: $3,397.65 (-1.78%)
Gas: 5 Gwei

Contract

0x70726f28ec6f462CaC1Fc7c60Cc25281c72630f9
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Approve203084592024-07-15 0:54:474 days ago1721004887IN
0x70726f28...1c72630f9
0 ETH0.000128532.77381473
Approve201975272024-06-29 13:05:2319 days ago1719666323IN
0x70726f28...1c72630f9
0 ETH0.000213714.58453335
Approve196854482024-04-18 22:53:4791 days ago1713480827IN
0x70726f28...1c72630f9
0 ETH0.000318416.87128344
Approve196710302024-04-16 22:31:1193 days ago1713306671IN
0x70726f28...1c72630f9
0 ETH0.000427869.23071332
Transfer196637132024-04-15 21:53:3594 days ago1713218015IN
0x70726f28...1c72630f9
0 ETH0.0059324212.74221995
Approve196138462024-04-08 22:12:47101 days ago1712614367IN
0x70726f28...1c72630f9
0 ETH0.0012785827.42798489
Approve196064262024-04-07 21:15:35102 days ago1712524535IN
0x70726f28...1c72630f9
0 ETH0.0009423920.21608698
Approve195993912024-04-06 21:34:35103 days ago1712439275IN
0x70726f28...1c72630f9
0 ETH0.0005190711.18397547
Approve195993192024-04-06 21:20:11103 days ago1712438411IN
0x70726f28...1c72630f9
0 ETH0.0005302411.42473749
Transfer195993002024-04-06 21:16:23103 days ago1712438183IN
0x70726f28...1c72630f9
0 ETH0.0060633513.34478803
Approve195818752024-04-04 10:41:47105 days ago1712227307IN
0x70726f28...1c72630f9
0 ETH0.0009873521.15345389
Approve195802062024-04-04 5:05:59106 days ago1712207159IN
0x70726f28...1c72630f9
0 ETH0.0008403318.02667163
Approve195779122024-04-03 21:24:59106 days ago1712179499IN
0x70726f28...1c72630f9
0 ETH0.001450631.11821264
Transfer195777702024-04-03 20:56:23106 days ago1712177783IN
0x70726f28...1c72630f9
0 ETH0.0128263628.53087469
Approve195765202024-04-03 16:45:23106 days ago1712162723IN
0x70726f28...1c72630f9
0 ETH0.0023100649.49154815
Approve195764922024-04-03 16:39:35106 days ago1712162375IN
0x70726f28...1c72630f9
0 ETH0.0020820244.60592522
Approve195764822024-04-03 16:37:35106 days ago1712162255IN
0x70726f28...1c72630f9
0 ETH0.0024323952.17949438
Approve195764712024-04-03 16:35:23106 days ago1712162123IN
0x70726f28...1c72630f9
0 ETH0.0022583748.44625715
Approve195760432024-04-03 15:09:23106 days ago1712156963IN
0x70726f28...1c72630f9
0 ETH0.002371850.81433138
Approve195759832024-04-03 14:57:23106 days ago1712156243IN
0x70726f28...1c72630f9
0 ETH0.0017993438.54976684
Approve195759532024-04-03 14:51:23106 days ago1712155883IN
0x70726f28...1c72630f9
0 ETH0.0020946444.87617469
Approve195759122024-04-03 14:42:59106 days ago1712155379IN
0x70726f28...1c72630f9
0 ETH0.0022022947.18254261
Approve195759082024-04-03 14:42:11106 days ago1712155331IN
0x70726f28...1c72630f9
0 ETH0.0021372845.78974383
Approve195759082024-04-03 14:42:11106 days ago1712155331IN
0x70726f28...1c72630f9
0 ETH0.0022773148.78974383
Update Exempt Sh...195758232024-04-03 14:25:11106 days ago1712154311IN
0x70726f28...1c72630f9
0 ETH0.0026953353.5341674
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
196637132024-04-15 21:53:3594 days ago1713218015
0x70726f28...1c72630f9
0.00090552 ETH
196637132024-04-15 21:53:3594 days ago1713218015
0x70726f28...1c72630f9
0.00090552 ETH
196193982024-04-09 16:53:23100 days ago1712681603
0x70726f28...1c72630f9
0.00136028 ETH
196193982024-04-09 16:53:23100 days ago1712681603
0x70726f28...1c72630f9
0.00136028 ETH
196084962024-04-08 4:13:23102 days ago1712549603
0x70726f28...1c72630f9
0.00001493 ETH
196084962024-04-08 4:13:23102 days ago1712549603
0x70726f28...1c72630f9
0.00001493 ETH
195993002024-04-06 21:16:23103 days ago1712438183
0x70726f28...1c72630f9
0.00115317 ETH
195993002024-04-06 21:16:23103 days ago1712438183
0x70726f28...1c72630f9
0.00115317 ETH
195968002024-04-06 12:51:11103 days ago1712407871
0x70726f28...1c72630f9
0.00120534 ETH
195968002024-04-06 12:51:11103 days ago1712407871
0x70726f28...1c72630f9
0.00120534 ETH
195913832024-04-05 18:41:11104 days ago1712342471
0x70726f28...1c72630f9
0.00252533 ETH
195913832024-04-05 18:41:11104 days ago1712342471
0x70726f28...1c72630f9
0.00252533 ETH
195911742024-04-05 17:58:59104 days ago1712339939
0x70726f28...1c72630f9
0.00001234 ETH
195911742024-04-05 17:58:59104 days ago1712339939
0x70726f28...1c72630f9
0.00001234 ETH
195777702024-04-03 20:56:23106 days ago1712177783
0x70726f28...1c72630f9
0.00034728 ETH
195777702024-04-03 20:56:23106 days ago1712177783
0x70726f28...1c72630f9
0.00034728 ETH
195764292024-04-03 16:26:59106 days ago1712161619
0x70726f28...1c72630f9
0.00248089 ETH
195764292024-04-03 16:26:59106 days ago1712161619
0x70726f28...1c72630f9
0.00248089 ETH
195760472024-04-03 15:10:11106 days ago1712157011
0x70726f28...1c72630f9
0.00060259 ETH
195760472024-04-03 15:10:11106 days ago1712157011
0x70726f28...1c72630f9
0.00060259 ETH
195759842024-04-03 14:57:35106 days ago1712156255
0x70726f28...1c72630f9
0.00157141 ETH
195759842024-04-03 14:57:35106 days ago1712156255
0x70726f28...1c72630f9
0.00157141 ETH
195759182024-04-03 14:44:11106 days ago1712155451
0x70726f28...1c72630f9
0.00638628 ETH
195759182024-04-03 14:44:11106 days ago1712155451
0x70726f28...1c72630f9
0.00638628 ETH
195759172024-04-03 14:43:59106 days ago1712155439
0x70726f28...1c72630f9
0.00412418 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
BRO

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
Yes with 10 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2024-03-16
*/

/**
 * ██████  ███████ ██    ██  ██████  ██      ██    ██ ███████ ██  ██████  ███    ██
 * ██   ██ ██      ██    ██ ██    ██ ██      ██    ██     ██  ██ ██    ██ ████   ██
 * ██████  █████   ██    ██ ██    ██ ██      ██    ██   ██    ██ ██    ██ ██ ██  ██
 * ██   ██ ██       ██  ██  ██    ██ ██      ██    ██  ██     ██ ██    ██ ██  ██ ██
 * ██   ██ ███████   ████    ██████  ███████  ██████  ███████ ██  ██████  ██   ████
 *
 * @title BRO
 *
 * @notice This is a smart contract developed by Revoluzion for BRO.
 *
 * @dev This smart contract was developed based on the general
 * OpenZeppelin Contracts guidelines where functions revert instead of
 * returning `false` on failure.
 *
 * @author Revoluzion Ecosystem
 * @custom:email [email protected]
 * @custom:telegram https://t.me/RevoluzionEcosystem
 * @custom:website https://revoluzion.io
 * @custom:dapp https://revoluzion.app
 */

// 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;

    /**
     * @notice Adds liquidity to a pool with ETH and a specified ERC20 token.
     *
     * @param token The address of the ERC20 token.
     * @param amountTokenDesired The desired amount of ERC20 tokens to add to the liquidity pool.
     * @param amountTokenMin The minimum amount of ERC20 tokens to be received.
     * @param amountETHMin The minimum amount of ETH to be provided.
     * @param to The recipient address for the liquidity tokens.
     * @param deadline The deadline timestamp to prevent front-running attacks.
     *
     * @return amountToken The actual amount of ERC20 tokens added.
     * @return amountETH The actual amount of ETH added.
     * @return liquidity The amount of liquidity tokens minted.
     *
     * @dev The `token` must be a valid ERC20 token address. This function emits
     * {AddLiquidityETH} event on successful execution, providing details of the
     * added liquidity.
     *
     */
    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        returns (uint256 amountToken, uint256 amountETH, uint256 liquidity);
}

/**
 * @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);
}

/**
 * @title Revenue Share Interface
 *
 * @notice Interface of the revenue share contract utilised within the ecosystem.
 */
interface IRevenueShare {
    // FUNCTION

    /**
     * @notice Allow deposits to be made along with the creation of new reward pool.
     */
    function deposit() external payable;

    /**
     * @notice Add the share eligible for dividend after token buy transaction.
     *
     * @param holder The address of the holder.
     * @param amount The amount being transacted.
     */
    function addShare(address holder, uint256 amount) external;

    /**
     * @notice Remove the share eligible for dividend after token transfer or sell transaction.
     *
     * @param holder The address of the holder.
     * @param amount The amount being transacted.
     */
    function removeShare(address holder, uint256 amount) external;
}

/********************************************************************************************
  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 BRO Token Contract
 *
 * @notice BRO is an extended version of ERC-20 standard token that includes
 * several additional functionalities.
 *
 * @dev Implements RevenueShare, ERC20Metadata, ERC20Errors, and CommonError
 * interfaces, and extends Ownable contract.
 */
contract BRO is Ownable, IERC20Metadata, IERC20Errors, ICommonError {
    // LIBRARY

    using SafeERC20 for IERC20;
    using Address for address;

    // DATA

    struct Fee {
        uint256 liquidity;
        uint256 revenue;
        uint256 team;
    }

    Fee public buyFee = Fee(2_000, 0, 0);
    Fee public sellFee = Fee(0, 2_000, 2_000);
    Fee public transferFee = Fee(0, 0, 0);
    Fee public collectedFee = Fee(0, 0, 0);
    Fee public redeemedFee = Fee(0, 0, 0);

    IRevenueShare public distributor;

    IRouter public router = IRouter(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);

    string private constant NAME = "BRO";
    string private constant SYMBOL = "$BRO";

    uint8 private constant DECIMALS = 18;

    uint256 public constant FEEDENOMINATOR = 100_000;

    uint256 private _totalSupply;

    uint256 public tradeStartTime = 0;
    uint256 public totalTriggerZeusBuyback = 0;
    uint256 public lastTriggerZeusTimestamp = 0;
    uint256 public totalFeeCollected = 0;
    uint256 public totalFeeRedeemed = 0;
    uint256 public minSwap = 1_000 ether;

    address public projectOwner = 0x37950C488Cd8f0f58AA661B7560D1Ba03a608b93;
    address public feeReceiver = 0x04aeD281632c2007Fd1a86d384A660b7b1668Bdd;

    address public pair;

    bool public isFeeActive = false;
    bool public isRevenueShareActive = false;
    bool public isReceiverLocked = 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 isExemptShare;

    // 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 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 the native token cannot be withdrawn from the smart contract.
     */
    error CannotWithdrawNativeToken();

    /**
     * @notice Error indicating that presale has been finalized and cannot be modified.
     */
    error AlreadyFinalized();

    /**
     * @notice Error indicating that presale has yet to be finalized.
     */
    error PresaleNotYetFinalized();

    /**
     * @notice Error indicating that receivers have been locked and cannot be modified.
     */
    error ReceiverLocked();

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

    /**
     * @notice Error indicating that only a wallet address is allowed to perform the action.
     *
     * @dev Should throw if called to use an address that is not believed to be a wallet.
     */
    error OnlyWalletAddressAllowed();

    // CONSTRUCTOR

    /**
     * @notice Constructs the BRO contract and initializes both owner and
     * project owner addresses. Deployer will receive 1,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.
     */
    constructor() Ownable(msg.sender) {
        isExemptFee[projectOwner] = true;
        isExemptShare[projectOwner] = true;
        isExemptFee[address(this)] = true;
        isExemptShare[address(this)] = true;
        isExemptFee[address(router)] = true;
        isExemptShare[address(router)] = true;

        if (projectOwner != msg.sender) {
            isExemptFee[msg.sender] = true;
            isExemptShare[msg.sender] = true;
        }

        _mint(msg.sender, 1_000_000 * 10 ** DECIMALS);

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

    // EVENT

    /**
     * @notice Emits when an automatic or manual redemption occurs, distributing fees
     * and redeeming a specific amount.
     *
     * @param liquidityFeeDistribution The amount distributed for liquidity fees.
     * @param revenueFeeDistribution The amount distributed for revenue fees.
     * @param teamFeeDistribution The amount distributed for team 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 liquidityFeeDistribution,
        uint256 revenueFeeDistribution,
        uint256 teamFeeDistribution,
        uint256 amountToRedeem,
        address caller,
        uint256 timestamp
    );

    /**
     * @notice Emitted when the router address is updated.
     *
     * @param oldRouter The address of the old router.
     * @param newRouter The address of the new router.
     * @param caller The address that triggered the router update.
     * @param timestamp The timestamp when the update occurred.
     */
    event UpdateRouter(
        address oldRouter,
        address newRouter,
        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 presale is finalized for the contract.
     *
     * @param caller The address that triggered the presale finalization.
     * @param timestamp The timestamp when presale was finalized.
     */
    event FinalizedPresale(address caller, uint256 timestamp);

    /**
     * @notice Emitted when a lock is applied.
     *
     * @param lockType The type of lock applied.
     * @param caller The address of the caller who applied the lock.
     * @param timestamp The timestamp when the lock was applied.
     */
    event Lock(string lockType, 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 upon updating an address.
     *
     * @param addressType The type of address being updated.
     * @param oldAddress The previous address before the update.
     * @param newAddress The new address after the update.
     * @param caller The address of the caller who updated the address.
     * @param timestamp The timestamp when the address was updated.
     */
    event UpdateAddress(
        string addressType,
        address oldAddress,
        address newAddress,
        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 Send ether stucked in the contract to a revenue share distributor address.
     *
     * @param amount The amount of tokens or Ether to be sent.
     *
     * @dev This is a failsafe in case the transaction reverted or the fund stucked is to
     * be used for the revenue share.
     */
    function sendEtherToDistributor(uint256 amount) external {
        uint256 amountToSend = amount;
        if (amount == 0) {
            amountToSend = address(this).balance;
        }
        payable(address(distributor)).transfer(amountToSend);
    }

    /**
     * @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 `feeReceiver`.
     * Only `feeReceiver` 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 allocated = totalFeeCollected - totalFeeRedeemed;
        uint256 toTransfer = amount;
        address receiver = feeReceiver;

        if (tokenAddress == address(this)) {
            if (allocated >= balanceOf(address(this))) {
                revert CannotWithdrawNativeToken();
            }
            if (amount > balanceOf(address(this)) - allocated) {
                revert ERC20InsufficientBalance(
                    address(this),
                    balanceOf(address(this)) - allocated,
                    amount
                );
            }
            if (amount == 0) {
                toTransfer = balanceOf(address(this)) - allocated;
            }
            _update(address(this), receiver, toTransfer);
        } 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 Finallizes presale and activate functionality for the token contract.
     *
     * @dev Only the smart contract owner can trigger this function and should throw if
     * presale already finalized. Can only be triggered once and emits a FinalizedPresale
     * event upon successful transaction. This function also set necessary states and
     * emitting an event upon success.
     */
    function finalizePresale(
        address revenueShareDistributor
    ) external onlyOwner {
        if (tradeStartTime != 0) {
            revert AlreadyFinalized();
        }
        if (
            revenueShareDistributor == address(0) ||
            revenueShareDistributor == address(0xdead)
        ) {
            revert InvalidAddress(revenueShareDistributor);
        }
        if (!isFeeActive) {
            isFeeActive = true;
        }
        if (!isRevenueShareActive) {
            isRevenueShareActive = true;
            distributor = IRevenueShare(revenueShareDistributor);
        }
        if (!isSwapEnabled) {
            isSwapEnabled = true;
        }
        tradeStartTime = block.timestamp;

        emit FinalizedPresale(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));
    }

    /* Redeem */

    /**
     * @notice Initiates a manual redemption process by distributing a specific
     * amount of tokens for fee purposes, swapping a portion for ETH.
     *
     * @param amountToRedeem The amount of tokens to be redeemed and distributed
     * for fee.
     *
     * @dev This function calculates the distribution of tokens for fee redeems
     * the specified amount, and triggers a swap for ETH. This function can only
     * be used to manual redeem specified amount by the owner.
     */
    function manualRedeem(uint256 amountToRedeem) external swapping onlyOwner {
        autoRedeem(amountToRedeem);
    }

    /**
     * @notice Initiates an automatic redemption process by distributing a specific
     * amount of tokens for fee purposes, swapping a portion for ETH.
     *
     * @param amountToRedeem The amount of tokens to be redeemed and distributed
     * for fee.
     *
     * @dev This function calculates the distribution of tokens for fee 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) internal swapping {
        uint256 totalToRedeem = totalFeeCollected - totalFeeRedeemed;

        if (amountToRedeem > totalToRedeem) {
            return;
        }
        uint256 liquidityToRedeem = collectedFee.liquidity -
            redeemedFee.liquidity;
        uint256 revenueToRedeem = collectedFee.revenue - redeemedFee.revenue;

        uint256 liquidityFeeDistribution = (amountToRedeem *
            liquidityToRedeem) / totalToRedeem;
        uint256 revenueFeeDistribution = (amountToRedeem * revenueToRedeem) /
            totalToRedeem;
        uint256 teamFeeDistribution = amountToRedeem -
            liquidityFeeDistribution -
            revenueFeeDistribution;

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

        _approve(address(this), address(router), amountToRedeem);

        emit AutoRedeem(
            liquidityFeeDistribution,
            revenueFeeDistribution,
            teamFeeDistribution,
            amountToRedeem,
            msg.sender,
            block.timestamp
        );

        totalFeeRedeemed += amountToRedeem;

        if (liquidityFeeDistribution > 0) {
            redeemedFee.liquidity += liquidityFeeDistribution;

            uint256 initialBalance = address(this).balance;
            uint256 firstLiquidityHalf = liquidityFeeDistribution / 2;
            uint256 secondLiquidityHalf = liquidityFeeDistribution -
                firstLiquidityHalf;

            router.swapExactTokensForETHSupportingFeeOnTransferTokens(
                firstLiquidityHalf,
                0,
                path,
                address(this),
                block.timestamp
            );

            router.addLiquidityETH{
                value: address(this).balance - initialBalance
            }(
                address(this),
                secondLiquidityHalf,
                0,
                0,
                feeReceiver,
                block.timestamp + 1_200
            );
        }

        if (teamFeeDistribution > 0) {
            redeemedFee.team += teamFeeDistribution;

            router.swapExactTokensForETHSupportingFeeOnTransferTokens(
                teamFeeDistribution,
                0,
                path,
                feeReceiver,
                block.timestamp
            );
        }

        if (revenueFeeDistribution > 0) {
            redeemedFee.revenue += revenueFeeDistribution;

            router.swapExactTokensForETHSupportingFeeOnTransferTokens(
                revenueFeeDistribution,
                0,
                path,
                address(this),
                block.timestamp
            );

            try
                distributor.deposit{value: address(this).balance}()
            {} catch {}
        }
    }

    /* Update */

    /**
     * @notice Locks the receivers, preventing further changes once locked.
     *
     * @dev This function will emits the Lock event.
     */
    function lockReceivers() external onlyOwner {
        if (isReceiverLocked) {
            revert ReceiverLocked();
        }
        isReceiverLocked = true;
        emit Lock("isReceiverLocked", msg.sender, block.timestamp);
    }

    /**
     * @notice Updates the minimum swap value, ensuring it doesn't exceed
     *
     * @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() * 5_000) / FEEDENOMINATOR) {
            revert InvalidValue(newMinSwap);
        }
        if (minSwap == newMinSwap) {
            revert CannotUseCurrentValue(newMinSwap);
        }
        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.
     *
     * @param newStatus The new status for fee activation.
     *
     * @dev This function will emits the UpdateState event.
     */
    function updateFeeActive(bool newStatus) external onlyOwner {
        if (isFeeActive == newStatus) {
            revert CannotUseCurrentState(newStatus);
        }
        bool oldStatus = isFeeActive;
        isFeeActive = newStatus;
        emit UpdateState(
            "isFeeActive",
            oldStatus,
            newStatus,
            msg.sender,
            block.timestamp
        );
    }

    /**
     * @notice Updates the status of revenue share activation, allowing toggling
     * the revenue share mechanism.
     *
     * @param newStatus The new status for revenue share activation.
     *
     * @dev This function will emits the UpdateState event.
     */
    function updateRevenueShareActive(bool newStatus) external onlyOwner {
        if (isRevenueShareActive == newStatus) {
            revert CannotUseCurrentState(newStatus);
        }
        bool oldStatus = isRevenueShareActive;
        isRevenueShareActive = newStatus;
        emit UpdateState(
            "isRevenueShareActive",
            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 {
        if (isSwapEnabled == newStatus) {
            revert CannotUseCurrentState(newStatus);
        }
        bool oldStatus = isSwapEnabled;
        isSwapEnabled = newStatus;
        emit UpdateState(
            "isSwapEnabled",
            oldStatus,
            newStatus,
            msg.sender,
            block.timestamp
        );
    }

    /**
     * @notice Allow the owner to change the address receiving fees.
     *
     * @param newFeeReceiver The new address to receive fees.
     *
     * @dev This function will emits the UpdateReceiver event and should throw
     * if triggered with the current address or if the receiver was locked.
     */
    function updateFeeReceiver(address newFeeReceiver) external onlyOwner {
        if (isReceiverLocked) {
            revert ReceiverLocked();
        }
        if (newFeeReceiver == address(0)) {
            revert InvalidAddress(address(0));
        }
        if (feeReceiver == newFeeReceiver) {
            revert CannotUseCurrentAddress(newFeeReceiver);
        }
        if (newFeeReceiver.code.length > 0) {
            revert OnlyWalletAddressAllowed();
        }
        address oldFeeReceiver = feeReceiver;
        feeReceiver = newFeeReceiver;
        emit UpdateAddress(
            "feeReceiver",
            oldFeeReceiver,
            newFeeReceiver,
            msg.sender,
            block.timestamp
        );
    }

    /**
     * @notice Allow the owner to change the address of revenue share distributor.
     *
     * @param newDistributor The new address for revenue share distributor.
     *
     * @dev This function will emits the UpdateDistributor event and should throw
     * if triggered with the current address.
     */
    function updateRevenueShareDistributor(
        IRevenueShare newDistributor
    ) external onlyOwner {
        if (address(newDistributor) == address(0)) {
            revert InvalidAddress(address(0));
        }
        if (distributor == newDistributor) {
            revert CannotUseCurrentAddress(address(newDistributor));
        }
        IRevenueShare oldDistributor = distributor;
        distributor = newDistributor;
        emit UpdateAddress(
            "distributor",
            address(oldDistributor),
            address(newDistributor),
            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 {
        if (isPairLP[lpPair] == newStatus) {
            revert CannotUseCurrentState(newStatus);
        }
        if (
            IPair(lpPair).token0() != address(this) &&
            IPair(lpPair).token1() != address(this)
        ) {
            revert InvalidAddress(lpPair);
        }
        bool oldStatus = isPairLP[lpPair];
        isPairLP[lpPair] = newStatus;
        if (newStatus && !isExemptShare[lpPair]) {
            isExemptShare[lpPair] = true;
        }
        emit SetAddressState(
            "isPairLP",
            lpPair,
            oldStatus,
            newStatus,
            msg.sender,
            block.timestamp
        );
    }

    /**
     * @notice Updates the router address used for token swaps.
     *
     * @param newRouter The address of the new router contract.
     *
     * @dev This should also generate the pair address using the factory of the `newRouter` if
     * the address of the pair on the new router's factory is address(0).If the new pair address's
     * isPairLP status is not yet set to true, this function will automatically set it to true.
     */
    function updateRouter(address newRouter) external onlyOwner {
        if (newRouter == address(router)) {
            revert CannotUseCurrentAddress(newRouter);
        }

        address oldRouter = address(router);
        router = IRouter(newRouter);

        emit UpdateRouter(oldRouter, newRouter, msg.sender, block.timestamp);

        if (
            address(
                IFactory(router.factory()).getPair(address(this), router.WETH())
            ) == address(0)
        ) {
            pair = IFactory(router.factory()).createPair(
                address(this),
                router.WETH()
            );
            if (!isPairLP[pair]) {
                isPairLP[pair] = true;
            }
            if (!isExemptShare[pair]) {
                isExemptShare[pair] = true;
            }
        }
    }

    /**
     * @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 {
        if (isExemptFee[user] == newStatus) {
            revert CannotUseCurrentState(newStatus);
        }
        bool oldStatus = isExemptFee[user];
        isExemptFee[user] = newStatus;
        emit SetAddressState(
            "isExemptFee",
            user,
            oldStatus,
            newStatus,
            msg.sender,
            block.timestamp
        );
    }

    /**
     * @notice Updates the exemption status for revenue share.
     *
     * @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 updateExemptShare(
        address user,
        bool newStatus
    ) external onlyOwner {
        if (isExemptShare[user] == newStatus) {
            revert CannotUseCurrentState(newStatus);
        }
        bool oldStatus = isExemptShare[user];
        isExemptShare[user] = newStatus;
        emit SetAddressState(
            "isExemptShare",
            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.liquidity + feeType.revenue + feeType.team;
        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 liquidityFee = feeType.liquidity;
        uint256 revenueFee = feeType.revenue;
        if (!isRevenueShareActive) {
            revenueFee = 0;
        }
        uint256 collectLiquidity = (amount * liquidityFee) / fee;
        uint256 collectRevenue = (amount * revenueFee) / fee;
        uint256 collectTeam = amount - collectLiquidity - collectRevenue;
        tallyCollection(collectLiquidity, collectRevenue, collectTeam, amount);

        _update(from, address(this), amount);
    }

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

    /* Buyback */

    /**
     * @notice Triggers a buyback with a specified amount,
     * limited to 5 ether per transaction.
     *
     * @param amount The amount of ETH to be used for the buyback.
     *
     * @dev This can only be triggered by the smart contract owner.
     */
    function triggerZeusBuyback(uint256 amount) external onlyOwner {
        if (amount > 5 ether) {
            revert InvalidValue(5 ether);
        }
        totalTriggerZeusBuyback += amount;
        lastTriggerZeusTimestamp = block.timestamp;
        buyTokens(amount, address(0xdead));
    }

    /**
     * @notice Initiates a buyback by swapping ETH for tokens.
     *
     * @param amount The amount of ETH to be used for the buyback.
     * @param to The address to which the bought tokens will be sent.
     */
    function buyTokens(uint256 amount, address to) internal swapping {
        if (msg.sender == address(0xdead)) {
            revert InvalidAddress(address(0xdead));
        }
        address[] memory path = new address[](2);
        path[0] = router.WETH();
        path[1] = address(this);

        router.swapExactETHForTokensSupportingFeeOnTransferTokens{
            value: amount
        }(0, path, to, block.timestamp);
    }

    /* 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 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.
     */
    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 (tradeStartTime == 0) {
            if (!isExemptFee[from] && !isExemptFee[to]) {
                revert PresaleNotYetFinalized();
            }
        }

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

        uint256 newValue = value;

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

        if (isRevenueShareActive) {
            if (from == pair && !isExemptShare[to]) {
                try distributor.addShare(to, newValue) {} catch {}
            }
            if (to == pair && !isExemptShare[from]) {
                try distributor.removeShare(from, newValue) {} catch {}
            }
            if (from != pair && to != pair) {
                if (!isExemptShare[from]) {
                    try distributor.removeShare(from, newValue) {} catch {}
                }
                if (!isExemptShare[to]) {
                    try distributor.addShare(to, newValue) {} catch {}
                }
            }
        }

        _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 virtual swapping returns (uint256) {
        if (
            isPairLP[from] &&
            (buyFee.liquidity + buyFee.revenue + buyFee.team > 0)
        ) {
            return takeBuyFee(from, amount);
        }
        if (
            isPairLP[to] &&
            (sellFee.liquidity + sellFee.revenue + sellFee.team > 0)
        ) {
            return takeSellFee(from, amount);
        }
        if (
            !isPairLP[from] &&
            !isPairLP[to] &&
            (transferFee.liquidity + transferFee.revenue + transferFee.team > 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);
    }

    /**
     * @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 Extended */

    /**
     * @notice Increases the allowance granted by the message sender to the spender.
     *
     * @param spender The address to whom the allowance is being increased.
     * @param value The additional amount by which the allowance is increased.
     *
     * @return A boolean indicating whether the operation was successful or not.
     *
     * @dev Allow a spender to spend more tokens on behalf of the message sender and
     * update the allowance accordingly.
     */
    function increaseAllowance(
        address spender,
        uint256 value
    ) external virtual returns (bool) {
        address provider = msg.sender;
        uint256 currentAllowance = allowance(provider, spender);
        _approve(provider, spender, currentAllowance + value, true);
        return true;
    }

    /**
     * @notice Decreases the allowance granted by the message sender to the spender.
     *
     * @param spender The address whose allowance is being decreased.
     * @param value The amount by which the allowance is decreased.
     *
     * @return A boolean indicating whether the operation was successful or not.
     *
     * @dev Reduce the spender's allowance by a specified amount. Should throw if the
     * current allowance is insufficient.
     */
    function decreaseAllowance(
        address spender,
        uint256 value
    ) external virtual returns (bool) {
        address provider = msg.sender;
        uint256 currentAllowance = allowance(provider, spender);
        if (currentAllowance < value) {
            revert ERC20InsufficientAllowance(spender, currentAllowance, value);
        }
        unchecked {
            _approve(provider, spender, currentAllowance - value, true);
        }
        return true;
    }
}

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":[],"name":"AlreadyFinalized","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":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"address","name":"invalid","type":"address"}],"name":"InvalidAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"invalid","type":"uint256"}],"name":"InvalidValue","type":"error"},{"inputs":[],"name":"OnlyWalletAddressAllowed","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":"PresaleNotYetFinalized","type":"error"},{"inputs":[],"name":"ReceiverCannotInitiateTransferEther","type":"error"},{"inputs":[],"name":"ReceiverLocked","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"liquidityFeeDistribution","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"revenueFeeDistribution","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"teamFeeDistribution","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":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"FinalizedPresale","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"lockType","type":"string"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Lock","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":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":"string","name":"addressType","type":"string"},{"indexed":false,"internalType":"address","name":"oldAddress","type":"address"},{"indexed":false,"internalType":"address","name":"newAddress","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateAddress","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":"address","name":"oldRouter","type":"address"},{"indexed":false,"internalType":"address","name":"newRouter","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateRouter","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"},{"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":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyFee","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"revenue","type":"uint256"},{"internalType":"uint256","name":"team","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":"liquidity","type":"uint256"},{"internalType":"uint256","name":"revenue","type":"uint256"},{"internalType":"uint256","name":"team","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distributor","outputs":[{"internalType":"contract IRevenueShare","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"revenueShareDistributor","type":"address"}],"name":"finalizePresale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"inSwap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","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":"isExemptShare","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":"isReceiverLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isRevenueShareActive","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":"lastTriggerZeusTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockReceivers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountToRedeem","type":"uint256"}],"name":"manualRedeem","outputs":[],"stateMutability":"nonpayable","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":"liquidity","type":"uint256"},{"internalType":"uint256","name":"revenue","type":"uint256"},{"internalType":"uint256","name":"team","type":"uint256"}],"stateMutability":"view","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":"liquidity","type":"uint256"},{"internalType":"uint256","name":"revenue","type":"uint256"},{"internalType":"uint256","name":"team","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sendEtherToDistributor","outputs":[],"stateMutability":"nonpayable","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":"totalTriggerZeusBuyback","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":"liquidity","type":"uint256"},{"internalType":"uint256","name":"revenue","type":"uint256"},{"internalType":"uint256","name":"team","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":"amount","type":"uint256"}],"name":"triggerZeusBuyback","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":"updateExemptShare","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateFeeActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newFeeReceiver","type":"address"}],"name":"updateFeeReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMinSwap","type":"uint256"}],"name":"updateMinSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateRevenueShareActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IRevenueShare","name":"newDistributor","type":"address"}],"name":"updateRevenueShareDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRouter","type":"address"}],"name":"updateRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateSwapEnabled","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"}]

6107d06080819052600060a081905260c081905260018290556002819055600381905560e0819052610100829052610120829052600481905560058290556006919091556101408190526101608190526101808190526007819055600881905560098190556101a08190526101c08190526101e0819052600a819055600b819055600c819055610260604052610200819052610220819052610240819052600d819055600e819055600f819055601180546001600160a01b0319908116737a250d5630b4cf539739df2c5dacb4c659f2488d179091556013829055601482905560158290556016829055601791909155683635c9adc5dea000006018556019805482167337950c488cd8f0f58aa661b7560d1ba03a608b93179055601a80549091167304aed281632c2007fd1a86d384a660b7b1668bdd179055601b805464ffffffffff60a01b191690553480156200015757600080fd5b5033806200018057604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6200018b8162000450565b50601980546001600160a01b039081166000908152601f60208181526040808420805460ff199081166001908117909255875487168652838052828620805482168317905530865284845282862080548216831790558380528286208054821683179055601180548816875294845282862080548216831790559354861685529180529092208054909116909117905590541633146200025657336000908152601f602090815260408083208054600160ff1991821681179092559280529220805490911690911790555b6200027e33620002696012600a62000726565b6200027890620f42406200073e565b620004a0565b601160009054906101000a90046001600160a01b03166001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f8919062000758565b6001600160a01b031663c9c6539630601160009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200035b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000381919062000758565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af1158015620003cf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003f5919062000758565b601b80546001600160a01b0319166001600160a01b0392831690811782556000908152601e60209081526040808320805460ff1990811660019081179092559454909516835290805290208054909116909117905562000799565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038216620004cc5760405163ec442f0560e01b81526000600482015260240162000177565b620004da60008383620004de565b5050565b6001600160a01b0383166200050d57806012600082825462000501919062000783565b90915550620005819050565b6001600160a01b0383166000908152601c602052604090205481811015620005625760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640162000177565b6001600160a01b0384166000908152601c602052604090209082900390555b6001600160a01b0382166200059f57601280548290039055620005be565b6001600160a01b0382166000908152601c602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516200060491815260200190565b60405180910390a3505050565b634e487b7160e01b600052601160045260246000fd5b600181815b80851115620006685781600019048211156200064c576200064c62000611565b808516156200065a57918102915b93841c93908002906200062c565b509250929050565b600082620006815750600162000720565b81620006905750600062000720565b8160018114620006a95760028114620006b457620006d4565b600191505062000720565b60ff841115620006c857620006c862000611565b50506001821b62000720565b5060208310610133831016604e8410600b8410161715620006f9575081810a62000720565b62000705838362000627565b80600019048211156200071c576200071c62000611565b0290505b92915050565b60006200073760ff84168362000670565b9392505050565b808202811582820484141762000720576200072062000611565b6000602082840312156200076b57600080fd5b81516001600160a01b03811681146200073757600080fd5b8082018082111562000720576200072062000611565b6135b280620007a96000396000f3fe60806040526004361061027f5760003560e01c806306fdde031461028b57806308c43650146102c9578063095ea7b3146103095780630b5695971461032957806318160ddd1461034b5780631f685bac1461036a57806323b872dd1461038a5780632b14ca56146103aa5780632c735ef8146103e4578063313ce567146103fa578063351a964d14610416578063355496ca1461043757806339509351146104575780633bf3145414610477578063470624021461049757806359cd9031146104b6578063625dd605146104cc57806363a95492146104ec57806370a082311461050c578063715018a61461052c57806371538eed1461054157806375fed3c714610557578063891ff84a146105775780638da5cb5b146105a7578063924de9b7146105c9578063927c4151146105e95780639358928b1461060957806395d89b411461061e57806397e1b9d31461064b5780639d48fde9146106615780639dce820e14610681578063a0103061146106a1578063a4475ce4146106c1578063a457c2d7146106e1578063a8aa1b3114610701578063a9059cbb14610721578063ab28a04c14610741578063acb2ad6f14610758578063b120548714610777578063b3f00674146107a6578063b9b2b5cd146107c6578063bfe10928146107dc578063c69bebe4146107fc578063c851cc321461081c578063cf9769fd1461083c578063d830678614610851578063d898f3d414610872578063d941907114610892578063da4daf71146108b1578063dd62ed3e146108c7578063e2924cd1146108e7578063e43504da14610908578063e811f50a14610929578063eb6be25014610948578063f2fde38b14610969578063f887ea401461098957600080fd5b3661028657005b600080fd5b34801561029757600080fd5b5060408051808201909152600381526242524f60e81b60208201525b6040516102c0919061315a565b60405180910390f35b3480156102d557600080fd5b506102f96102e43660046131a2565b601e6020526000908152604090205460ff1681565b60405190151581526020016102c0565b34801561031557600080fd5b506102f96103243660046131bf565b6109a9565b34801561033557600080fd5b506103496103443660046131eb565b6109c3565b005b34801561035757600080fd5b506012545b6040519081526020016102c0565b34801561037657600080fd5b506103496103853660046131bf565b610a0f565b34801561039657600080fd5b506102f96103a5366004613204565b610bfd565b3480156103b657600080fd5b506004546005546006546103c992919083565b604080519384526020840192909252908201526060016102c0565b3480156103f057600080fd5b5061035c60135481565b34801561040657600080fd5b50604051601281526020016102c0565b34801561042257600080fd5b50601b546102f990600160b81b900460ff1681565b34801561044357600080fd5b50610349610452366004613253565b610c23565b34801561046357600080fd5b506102f96104723660046131bf565b610d08565b34801561048357600080fd5b5061034961049236600461328c565b610d39565b3480156104a357600080fd5b506001546002546003546103c992919083565b3480156104c257600080fd5b5061035c60185481565b3480156104d857600080fd5b506103496104e7366004613253565b610df7565b3480156104f857600080fd5b506103496105073660046131eb565b611036565b34801561051857600080fd5b5061035c6105273660046131a2565b61109b565b34801561053857600080fd5b506103496110b6565b34801561054d57600080fd5b5061035c60175481565b34801561056357600080fd5b506103496105723660046131eb565b6110ca565b34801561058357600080fd5b506102f96105923660046131a2565b601f6020526000908152604090205460ff1681565b3480156105b357600080fd5b506105bc61118a565b6040516102c091906132a9565b3480156105d557600080fd5b506103496105e436600461328c565b611199565b3480156105f557600080fd5b506103496106043660046131a2565b611251565b34801561061557600080fd5b5061035c611388565b34801561062a57600080fd5b506040805180820190915260048152632442524f60e01b60208201526102b3565b34801561065757600080fd5b5061035c60155481565b34801561066d57600080fd5b5061034961067c3660046131eb565b6113bb565b34801561068d57600080fd5b5061034961069c366004613253565b6113ef565b3480156106ad57600080fd5b506103496106bc36600461328c565b6114ca565b3480156106cd57600080fd5b506019546105bc906001600160a01b031681565b3480156106ed57600080fd5b506102f96106fc3660046131bf565b611589565b34801561070d57600080fd5b50601b546105bc906001600160a01b031681565b34801561072d57600080fd5b506102f961073c3660046131bf565b6115cf565b34801561074d57600080fd5b5061035c620186a081565b34801561076457600080fd5b506007546008546009546103c992919083565b34801561078357600080fd5b506102f96107923660046131a2565b602080526000908152604090205460ff1681565b3480156107b257600080fd5b50601a546105bc906001600160a01b031681565b3480156107d257600080fd5b5061035c60165481565b3480156107e857600080fd5b506010546105bc906001600160a01b031681565b34801561080857600080fd5b506103496108173660046131a2565b6115dd565b34801561082857600080fd5b506103496108373660046131a2565b61170a565b34801561084857600080fd5b50610349611b12565b34801561085d57600080fd5b50601b546102f990600160c01b900460ff1681565b34801561087e57600080fd5b5061034961088d3660046131a2565b611bba565b34801561089e57600080fd5b50600d54600e54600f546103c992919083565b3480156108bd57600080fd5b5061035c60145481565b3480156108d357600080fd5b5061035c6108e23660046132bd565b611c93565b3480156108f357600080fd5b50601b546102f990600160b01b900460ff1681565b34801561091457600080fd5b50601b546102f990600160a01b900460ff1681565b34801561093557600080fd5b50600a54600b54600c546103c992919083565b34801561095457600080fd5b50601b546102f990600160a81b900460ff1681565b34801561097557600080fd5b506103496109843660046131a2565b611cbe565b34801561099557600080fd5b506011546105bc906001600160a01b031681565b6000336109b7818585611d53565b60019150505b92915050565b8060008190036109d05750475b6010546040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015610a0a573d6000803e3d6000fd5b505050565b6000601754601654610a219190613301565b601a5490915082906001600160a01b03908116903090861603610aeb57610a473061109b565b8310610a66576040516315ea636560e31b815260040160405180910390fd5b82610a703061109b565b610a7a9190613301565b841115610abc573083610a8c3061109b565b610a969190613301565b8560405163391434e360e21b8152600401610ab393929190613314565b60405180910390fd5b83600003610adb5782610ace3061109b565b610ad89190613301565b91505b610ae6308284611d60565b610bf6565b6001600160a01b038516610b6a5783600003610b05574791505b6001600160a01b0381163303610b2e5760405163a5eb0da960e01b815260040160405180910390fd5b6040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015610b64573d6000803e3d6000fd5b50610bf6565b83600003610be2576040516370a0823160e01b81526001600160a01b038616906370a0823190610b9e9030906004016132a9565b602060405180830381865afa158015610bbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bdf9190613335565b91505b610bf66001600160a01b0386168284611e77565b5050505050565b600033610c0b858285611ecf565b610c16858585611f22565b60019150505b9392505050565b610c2b612392565b6001600160a01b0382166000908152601f602052604090205481151560ff909116151503610c6f5760405162a7e72d60e41b81528115156004820152602401610ab3565b6001600160a01b0382166000818152601f6020908152604091829020805485151560ff1982168117909255835160c0808252600b908201526a69734578656d707446656560a81b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a08301529060008051602061351d83398151915290610100015b60405180910390a1505050565b60003381610d168286611c93565b9050610d2e8286610d27878561334e565b60016123c4565b506001949350505050565b610d41612392565b801515601b60149054906101000a900460ff16151503610d775760405162a7e72d60e41b81528115156004820152602401610ab3565b601b8054821515600160a01b81810260ff60a01b198416179093556040805160a0808252600b908201526a697346656541637469766560a81b60c082015260ff949093049390931680151560208401529282015233606082015242608082015260008051602061355d8339815191529060e0015b60405180910390a15050565b610dff612392565b6001600160a01b0382166000908152601e602052604090205481151560ff909116151503610e435760405162a7e72d60e41b81528115156004820152602401610ab3565b306001600160a01b0316826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eaf9190613361565b6001600160a01b031614158015610f395750306001600160a01b0316826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2d9190613361565b6001600160a01b031614155b15610f595781604051634726455360e11b8152600401610ab391906132a9565b6001600160a01b0382166000908152601e6020526040902080548215801560ff1983161790925560ff16908290610fa857506001600160a01b038316600090815260208052604090205460ff16155b15610fd0576001600160a01b03831660009081526020805260409020805460ff191660011790555b6040805160c08082526008908201526706973506169724c560c41b60e08201526001600160a01b03851660208201528215159181019190915282151560608201523360808201524260a082015260008051602061351d8339815191529061010001610cfb565b61103e612392565b674563918244f400008111156110715760405163181c9d0b60e21b8152674563918244f400006004820152602401610ab3565b8060146000828254611083919061334e565b9091555050426015556110988161dead612499565b50565b6001600160a01b03166000908152601c602052604090205490565b6110be612392565b6110c86000612632565b565b6110d2612392565b620186a06110de611388565b6110ea9061138861337e565b6110f49190613395565b8111156111175760405163181c9d0b60e21b815260048101829052602401610ab3565b806018540361113c5760405163657e16cf60e01b815260048101829052602401610ab3565b6018805490829055604080518281526020810184905233918101919091524260608201527f9a9f4704ac409fe039e92a996e415370980275aaff2992936ed5b432886c55c590608001610deb565b6000546001600160a01b031690565b6111a1612392565b801515601b60179054906101000a900460ff161515036111d75760405162a7e72d60e41b81528115156004820152602401610ab3565b601b8054821515600160b81b81810260ff60b81b198416179093556040805160a0808252600d908201526c1a5cd4ddd85c115b98589b1959609a1b60c082015260ff949093049390931680151560208401529282015233606082015242608082015260008051602061355d8339815191529060e001610deb565b611259612392565b6013541561127a5760405163475a253560e01b815260040160405180910390fd5b6001600160a01b038116158061129a57506001600160a01b03811661dead145b156112ba5780604051634726455360e11b8152600401610ab391906132a9565b601b54600160a01b900460ff166112df57601b805460ff60a01b1916600160a01b1790555b601b54600160a81b900460ff1661132157601b805460ff60a81b1916600160a81b179055601080546001600160a01b0383166001600160a01b03199091161790555b601b54600160b81b900460ff1661134657601b805460ff60b81b1916600160b81b1790555b4260138190556040517f7111af66182bdf8afd5e1cfa53fdb90ebba682d2cc11a7dfead27fcbf50bea829161137d913391906133b7565b60405180910390a150565b6000611394600061109b565b61139f61dead61109b565b6012546113ac9190613301565b6113b69190613301565b905090565b601b805460ff60c01b1916600160c01b1790556113d6612392565b6113df81612682565b50601b805460ff60c01b19169055565b6113f7612392565b6001600160a01b038216600090815260208052604090205481151560ff90911615150361143a5760405162a7e72d60e41b81528115156004820152602401610ab3565b6001600160a01b03821660008181526020808052604091829020805485151560ff1982168117909255835160c0808252600d908201526c69734578656d7074536861726560981b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a08301529060008051602061351d8339815191529061010001610cfb565b6114d2612392565b801515601b60159054906101000a900460ff161515036115085760405162a7e72d60e41b81528115156004820152602401610ab3565b601b8054821515600160a81b81810260ff60a81b198416179093556040805160a0808252601490820152736973526576656e7565536861726541637469766560601b60c082015260ff949093049390931680151560208401529282015233606082015242608082015260008051602061355d8339815191529060e001610deb565b600033816115978286611c93565b9050838110156115c057848185604051637dc7a0d960e11b8152600401610ab393929190613314565b610d2e828686840360016123c4565b6000336109b7818585611f22565b6115e5612392565b601b54600160b01b900460ff16156116105760405163341e380d60e11b815260040160405180910390fd5b6001600160a01b03811661163a576000604051634726455360e11b8152600401610ab391906132a9565b601a546001600160a01b0380831691160361166a578060405163a936636960e01b8152600401610ab391906132a9565b6001600160a01b0381163b156116935760405163259f1ec560e01b815260040160405180910390fd5b601a80546001600160a01b031981166001600160a01b038481169182179093556040805160a0808252600b908201526a3332b2a932b1b2b4bb32b960a91b60c08201529390921660208401819052918301523360608301524260808301529060008051602061353d8339815191529060e001610deb565b611712612392565b6011546001600160a01b0390811690821603611743578060405163a936636960e01b8152600401610ab391906132a9565b601180546001600160a01b038381166001600160a01b0319831681179093556040805191909216808252602082019390935233918101919091524260608201527fe1cb783288eddc7b22c25642a832d886a558be0dd900747310a34156b9fdcbbb9060800160405180910390a16011546040805163c45a015560e01b815290516000926001600160a01b03169163c45a01559160048083019260209291908290030181865afa1580156117fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181e9190613361565b6001600160a01b031663e6a4390530601160009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611880573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118a49190613361565b6040518363ffffffff1660e01b81526004016118c19291906133d0565b602060405180830381865afa1580156118de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119029190613361565b6001600160a01b031603611b0e57601160009054906101000a90046001600160a01b03166001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015611963573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119879190613361565b6001600160a01b031663c9c6539630601160009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119e9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0d9190613361565b6040518363ffffffff1660e01b8152600401611a2a9291906133d0565b6020604051808303816000875af1158015611a49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6d9190613361565b601b80546001600160a01b0319166001600160a01b039290921691821790556000908152601e602052604090205460ff16611ac857601b546001600160a01b03166000908152601e60205260409020805460ff191660011790555b601b546001600160a01b0316600090815260208052604090205460ff16611b0e57601b546001600160a01b031660009081526020805260409020805460ff191660011790555b5050565b611b1a612392565b601b54600160b01b900460ff1615611b455760405163341e380d60e11b815260040160405180910390fd5b601b805460ff60b01b1916600160b01b1790556040805160608082526010908201526f1a5cd49958d95a5d995c931bd8dad95960821b6080820152336020820152428183015290517f611312486a6540001c2b69bc849753e64cdefc853bbbc7a576d987821aec28b49160a0908290030190a1565b611bc2612392565b6001600160a01b038116611bec576000604051634726455360e11b8152600401610ab391906132a9565b6010546001600160a01b03808316911603611c1c578060405163a936636960e01b8152600401610ab391906132a9565b601080546001600160a01b031981166001600160a01b038481169182179093556040805160a0808252600b908201526a3234b9ba3934b13aba37b960a91b60c08201529390921660208401819052918301523360608301524260808301529060008051602061353d8339815191529060e001610deb565b6001600160a01b039182166000908152601d6020908152604080832093909416825291909152205490565b611cc6612392565b611cce61118a565b6001600160a01b0316816001600160a01b031603611d01578060405163a936636960e01b8152600401610ab391906132a9565b61deac196001600160a01b03821601611d2f5780604051634726455360e11b8152600401610ab391906132a9565b601980546001600160a01b0319166001600160a01b03831617905561109881612b9b565b610a0a83838360016123c4565b6001600160a01b038316611d8b578060126000828254611d80919061334e565b90915550611dea9050565b6001600160a01b0383166000908152601c602052604090205481811015611dcb5783818360405163391434e360e21b8152600401610ab393929190613314565b6001600160a01b0384166000908152601c602052604090209082900390555b6001600160a01b038216611e0657601280548290039055611e25565b6001600160a01b0382166000908152601c602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611e6a91815260200190565b60405180910390a3505050565b610a0a83846001600160a01b031663a9059cbb8585604051602401611e9d9291906133b7565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050612bd6565b6000611edb8484611c93565b90506000198114611f1c5781811015611f0d57828183604051637dc7a0d960e11b8152600401610ab393929190613314565b611f1c848484840360006123c4565b50505050565b6001600160a01b038316611f4c576000604051634b637e8f60e11b8152600401610ab391906132a9565b6001600160a01b038216611f7657600060405163ec442f0560e01b8152600401610ab391906132a9565b601354600003611fe0576001600160a01b0383166000908152601f602052604090205460ff16158015611fc257506001600160a01b0382166000908152601f602052604090205460ff16155b15611fe0576040516303a7aa8760e51b815260040160405180910390fd5b601b54600160c01b900460ff168061201057506001600160a01b0383166000908152601f602052604090205460ff165b8061203357506001600160a01b0382166000908152601f602052604090205460ff165b1561204357610a0a838383611d60565b601b546001600160a01b0384811691161480159061206a5750601b54600160b81b900460ff165b801561208d575061207a3061109b565b60175460165461208a9190613301565b11155b156120aa576120aa6017546016546120a59190613301565b612682565b601b548190600160a01b900460ff1680156120de57506001600160a01b0384166000908152601f602052604090205460ff16155b801561210357506001600160a01b0383166000908152601f602052604090205460ff16155b1561211657612113848484612c30565b90505b601b54600160a81b900460ff161561238757601b546001600160a01b03858116911614801561215d57506001600160a01b038316600090815260208052604090205460ff16155b156121c157601054604051630a1e9f3f60e31b81526001600160a01b03909116906350f4f9f89061219490869085906004016133b7565b600060405180830381600087803b1580156121ae57600080fd5b505af19250505080156121bf575060015b505b601b546001600160a01b0384811691161480156121f657506001600160a01b038416600090815260208052604090205460ff16155b1561225a5760105460405163060323a760e51b81526001600160a01b039091169063c06474e09061222d90879085906004016133b7565b600060405180830381600087803b15801561224757600080fd5b505af1925050508015612258575060015b505b601b546001600160a01b038581169116148015906122865750601b546001600160a01b03848116911614155b15612387576001600160a01b038416600090815260208052604090205460ff166123095760105460405163060323a760e51b81526001600160a01b039091169063c06474e0906122dc90879085906004016133b7565b600060405180830381600087803b1580156122f657600080fd5b505af1925050508015612307575060015b505b6001600160a01b038316600090815260208052604090205460ff1661238757601054604051630a1e9f3f60e31b81526001600160a01b03909116906350f4f9f89061235a90869085906004016133b7565b600060405180830381600087803b15801561237457600080fd5b505af1925050508015612385575060015b505b611f1c848483611d60565b3361239b61118a565b6001600160a01b0316146110c8573360405163118cdaa760e01b8152600401610ab391906132a9565b6001600160a01b0384166123ee57600060405163e602df0560e01b8152600401610ab391906132a9565b6001600160a01b038316612418576000604051634a1406b160e11b8152600401610ab391906132a9565b6001600160a01b038085166000908152601d602090815260408083209387168352929052208290558015611f1c57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161248b91815260200190565b60405180910390a350505050565b601b805460ff60c01b1916600160c01b17905561deac1933016124d35761dead604051634726455360e11b8152600401610ab391906132a9565b6040805160028082526060820183526000926020830190803683375050601154604080516315ab88c960e31b815290519394506001600160a01b039091169263ad5c4648925060048083019260209291908290030181865afa15801561253d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125619190613361565b81600081518110612574576125746133ea565b60200260200101906001600160a01b031690816001600160a01b03168152505030816001815181106125a8576125a86133ea565b6001600160a01b03928316602091820292909201015260115460405163b6f9de9560e01b815291169063b6f9de959085906125ee90600090869088904290600401613444565b6000604051808303818588803b15801561260757600080fd5b505af115801561261b573d6000803e3d6000fd5b5050601b805460ff60c01b19169055505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b601b805460ff60c01b1916600160c01b1790556017546016546000916126a791613301565b9050808211156126b757506113df565b600d54600a546000916126c991613301565b600e54600b549192506000916126df9190613301565b90506000836126ee848761337e565b6126f89190613395565b9050600084612707848861337e565b6127119190613395565b90506000816127208489613301565b61272a9190613301565b60408051600280825260608201835292935060009290916020830190803683370190505090503081600081518110612764576127646133ea565b6001600160a01b03928316602091820292909201810191909152601154604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa1580156127bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127e19190613361565b816001815181106127f4576127f46133ea565b6001600160a01b03928316602091820292909201015260115461281a913091168a611d53565b6040805185815260208101859052908101839052606081018990523360808201524260a08201527f095046c58a377d54685857e96b2bbfd471ec5fe130ece4bd1fbf1369b1be25e49060c00160405180910390a18760176000828254612880919061334e565b90915550508315612a055783600d60000160008282546128a0919061334e565b9091555047905060006128b4600287613395565b905060006128c28288613301565b60115460405163791ac94760e01b81529192506001600160a01b03169063791ac947906128fc908590600090899030904290600401613479565b600060405180830381600087803b15801561291657600080fd5b505af115801561292a573d6000803e3d6000fd5b50506011546001600160a01b0316915063f305d719905061294b8547613301565b601a543090859060009081906001600160a01b031661296c426104b061334e565b60405160e089901b6001600160e01b03191681526001600160a01b039687166004820152602481019590955260448501939093526064840191909152909216608482015260a481019190915260c40160606040518083038185885af11580156129d9573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906129fe91906134b5565b5050505050505b8115612a955781600d6002016000828254612a20919061334e565b9091555050601154601a5460405163791ac94760e01b81526001600160a01b039283169263791ac94792612a6292879260009288929116904290600401613479565b600060405180830381600087803b158015612a7c57600080fd5b505af1158015612a90573d6000803e3d6000fd5b505050505b8215612b845782600d6001016000828254612ab0919061334e565b909155505060115460405163791ac94760e01b81526001600160a01b039091169063791ac94790612aee908690600090869030904290600401613479565b600060405180830381600087803b158015612b0857600080fd5b505af1158015612b1c573d6000803e3d6000fd5b50505050601060009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0476040518263ffffffff1660e01b81526004016000604051808303818588803b158015612b7057600080fd5b505af193505050508015612b82575060015b505b5050505050505050601b805460ff60c01b19169055565b612ba3612392565b6001600160a01b038116612bcd576000604051631e4fbdf760e01b8152600401610ab391906132a9565b61109881612632565b6000612beb6001600160a01b03841683612d83565b90508051600014158015612c10575080806020019051810190612c0e91906134e3565b155b15610a0a5782604051635274afe760e01b8152600401610ab391906132a9565b601b805460ff60c01b1916600160c01b1790556001600160a01b0383166000908152601e602052604081205460ff168015612c88575060035460025460015460009291612c7c9161334e565b612c86919061334e565b115b15612c9e57612c978483612d91565b9050612d6f565b6001600160a01b0383166000908152601e602052604090205460ff168015612ce3575060065460055460045460009291612cd79161334e565b612ce1919061334e565b115b15612cf257612c978483612dd3565b6001600160a01b0384166000908152601e602052604090205460ff16158015612d3457506001600160a01b0383166000908152601e602052604090205460ff16155b8015612d5d575060095460085460075460009291612d519161334e565b612d5b919061334e565b115b15612d6c57612c978483612e15565b50805b601b805460ff60c01b191690559392505050565b6060610c1c83836000612e57565b601b805460ff60c01b1916600160c01b179055604080516060810182526001548152600254602082015260035491810191909152600090612d6f908484612ef4565b601b805460ff60c01b1916600160c01b179055604080516060810182526004548152600554602082015260065491810191909152600090612d6f908484612ef4565b601b805460ff60c01b1916600160c01b179055604080516060810182526007548152600854602082015260095491810191909152600090612d6f908484612ef4565b606081471015612e7c573060405163cd78605960e01b8152600401610ab391906132a9565b600080856001600160a01b03168486604051612e989190613500565b60006040518083038185875af1925050503d8060008114612ed5576040519150601f19603f3d011682016040523d82523d6000602084013e612eda565b606091505b5091509150612eea868383612f83565b9695505050505050565b601b805460ff60c01b1916600160c01b17905560408301516020840151845160009283929091612f24919061334e565b612f2e919061334e565b90506000620186a0612f40838661337e565b612f4a9190613395565b90506000612f588286613301565b90508115612f6c57612f6c87878486612fd6565b601b805460ff60c01b191690559695505050505050565b606082612f9857612f9382613080565b610c1c565b8151158015612faf57506001600160a01b0384163b155b15612fcf5783604051639996b31560e01b8152600401610ab391906132a9565b5080610c1c565b601b805460ff60c01b1916600160c01b1790819055845160208601519091600160a81b900460ff16613006575060005b600083613013848761337e565b61301d9190613395565b905060008461302c848861337e565b6130369190613395565b90506000816130458489613301565b61304f9190613301565b905061305d8383838a6130a9565b613068883089611d60565b5050601b805460ff60c01b1916905550505050505050565b8051156130905780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b601b805460ff60c01b1916600160c01b179055600a80548591906000906130d190849061334e565b9091555050600b80548491906000906130eb90849061334e565b9091555050600c805483919060009061310590849061334e565b92505081905550806016600082825461311e919061334e565b9091555050601b805460ff60c01b1916905550505050565b60005b83811015613151578181015183820152602001613139565b50506000910152565b6020815260008251806020840152613179816040850160208701613136565b601f01601f19169190910160400192915050565b6001600160a01b038116811461109857600080fd5b6000602082840312156131b457600080fd5b8135610c1c8161318d565b600080604083850312156131d257600080fd5b82356131dd8161318d565b946020939093013593505050565b6000602082840312156131fd57600080fd5b5035919050565b60008060006060848603121561321957600080fd5b83356132248161318d565b925060208401356132348161318d565b929592945050506040919091013590565b801515811461109857600080fd5b6000806040838503121561326657600080fd5b82356132718161318d565b9150602083013561328181613245565b809150509250929050565b60006020828403121561329e57600080fd5b8135610c1c81613245565b6001600160a01b0391909116815260200190565b600080604083850312156132d057600080fd5b82356132db8161318d565b915060208301356132818161318d565b634e487b7160e01b600052601160045260246000fd5b818103818111156109bd576109bd6132eb565b6001600160a01b039390931683526020830191909152604082015260600190565b60006020828403121561334757600080fd5b5051919050565b808201808211156109bd576109bd6132eb565b60006020828403121561337357600080fd5b8151610c1c8161318d565b80820281158282048414176109bd576109bd6132eb565b6000826133b257634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0392831681529116602082015260400190565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b838110156134395781516001600160a01b031687529582019590820190600101613414565b509495945050505050565b84815260806020820152600061345d6080830186613400565b6001600160a01b03949094166040830152506060015292915050565b85815284602082015260a06040820152600061349860a0830186613400565b6001600160a01b0394909416606083015250608001529392505050565b6000806000606084860312156134ca57600080fd5b8351925060208401519150604084015190509250925092565b6000602082840312156134f557600080fd5b8151610c1c81613245565b60008251613512818460208701613136565b919091019291505056fe59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea511cc7bccdda7b7a529371ee25fbde79ba816cacfcb33ec4e285b0b034d1dafada986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf3a264697066735822122087c54452b526c8a1f599e640c1901df063a7b28059c7d621ab8c3c11f56e48c164736f6c63430008120033

Deployed Bytecode

0x60806040526004361061027f5760003560e01c806306fdde031461028b57806308c43650146102c9578063095ea7b3146103095780630b5695971461032957806318160ddd1461034b5780631f685bac1461036a57806323b872dd1461038a5780632b14ca56146103aa5780632c735ef8146103e4578063313ce567146103fa578063351a964d14610416578063355496ca1461043757806339509351146104575780633bf3145414610477578063470624021461049757806359cd9031146104b6578063625dd605146104cc57806363a95492146104ec57806370a082311461050c578063715018a61461052c57806371538eed1461054157806375fed3c714610557578063891ff84a146105775780638da5cb5b146105a7578063924de9b7146105c9578063927c4151146105e95780639358928b1461060957806395d89b411461061e57806397e1b9d31461064b5780639d48fde9146106615780639dce820e14610681578063a0103061146106a1578063a4475ce4146106c1578063a457c2d7146106e1578063a8aa1b3114610701578063a9059cbb14610721578063ab28a04c14610741578063acb2ad6f14610758578063b120548714610777578063b3f00674146107a6578063b9b2b5cd146107c6578063bfe10928146107dc578063c69bebe4146107fc578063c851cc321461081c578063cf9769fd1461083c578063d830678614610851578063d898f3d414610872578063d941907114610892578063da4daf71146108b1578063dd62ed3e146108c7578063e2924cd1146108e7578063e43504da14610908578063e811f50a14610929578063eb6be25014610948578063f2fde38b14610969578063f887ea401461098957600080fd5b3661028657005b600080fd5b34801561029757600080fd5b5060408051808201909152600381526242524f60e81b60208201525b6040516102c0919061315a565b60405180910390f35b3480156102d557600080fd5b506102f96102e43660046131a2565b601e6020526000908152604090205460ff1681565b60405190151581526020016102c0565b34801561031557600080fd5b506102f96103243660046131bf565b6109a9565b34801561033557600080fd5b506103496103443660046131eb565b6109c3565b005b34801561035757600080fd5b506012545b6040519081526020016102c0565b34801561037657600080fd5b506103496103853660046131bf565b610a0f565b34801561039657600080fd5b506102f96103a5366004613204565b610bfd565b3480156103b657600080fd5b506004546005546006546103c992919083565b604080519384526020840192909252908201526060016102c0565b3480156103f057600080fd5b5061035c60135481565b34801561040657600080fd5b50604051601281526020016102c0565b34801561042257600080fd5b50601b546102f990600160b81b900460ff1681565b34801561044357600080fd5b50610349610452366004613253565b610c23565b34801561046357600080fd5b506102f96104723660046131bf565b610d08565b34801561048357600080fd5b5061034961049236600461328c565b610d39565b3480156104a357600080fd5b506001546002546003546103c992919083565b3480156104c257600080fd5b5061035c60185481565b3480156104d857600080fd5b506103496104e7366004613253565b610df7565b3480156104f857600080fd5b506103496105073660046131eb565b611036565b34801561051857600080fd5b5061035c6105273660046131a2565b61109b565b34801561053857600080fd5b506103496110b6565b34801561054d57600080fd5b5061035c60175481565b34801561056357600080fd5b506103496105723660046131eb565b6110ca565b34801561058357600080fd5b506102f96105923660046131a2565b601f6020526000908152604090205460ff1681565b3480156105b357600080fd5b506105bc61118a565b6040516102c091906132a9565b3480156105d557600080fd5b506103496105e436600461328c565b611199565b3480156105f557600080fd5b506103496106043660046131a2565b611251565b34801561061557600080fd5b5061035c611388565b34801561062a57600080fd5b506040805180820190915260048152632442524f60e01b60208201526102b3565b34801561065757600080fd5b5061035c60155481565b34801561066d57600080fd5b5061034961067c3660046131eb565b6113bb565b34801561068d57600080fd5b5061034961069c366004613253565b6113ef565b3480156106ad57600080fd5b506103496106bc36600461328c565b6114ca565b3480156106cd57600080fd5b506019546105bc906001600160a01b031681565b3480156106ed57600080fd5b506102f96106fc3660046131bf565b611589565b34801561070d57600080fd5b50601b546105bc906001600160a01b031681565b34801561072d57600080fd5b506102f961073c3660046131bf565b6115cf565b34801561074d57600080fd5b5061035c620186a081565b34801561076457600080fd5b506007546008546009546103c992919083565b34801561078357600080fd5b506102f96107923660046131a2565b602080526000908152604090205460ff1681565b3480156107b257600080fd5b50601a546105bc906001600160a01b031681565b3480156107d257600080fd5b5061035c60165481565b3480156107e857600080fd5b506010546105bc906001600160a01b031681565b34801561080857600080fd5b506103496108173660046131a2565b6115dd565b34801561082857600080fd5b506103496108373660046131a2565b61170a565b34801561084857600080fd5b50610349611b12565b34801561085d57600080fd5b50601b546102f990600160c01b900460ff1681565b34801561087e57600080fd5b5061034961088d3660046131a2565b611bba565b34801561089e57600080fd5b50600d54600e54600f546103c992919083565b3480156108bd57600080fd5b5061035c60145481565b3480156108d357600080fd5b5061035c6108e23660046132bd565b611c93565b3480156108f357600080fd5b50601b546102f990600160b01b900460ff1681565b34801561091457600080fd5b50601b546102f990600160a01b900460ff1681565b34801561093557600080fd5b50600a54600b54600c546103c992919083565b34801561095457600080fd5b50601b546102f990600160a81b900460ff1681565b34801561097557600080fd5b506103496109843660046131a2565b611cbe565b34801561099557600080fd5b506011546105bc906001600160a01b031681565b6000336109b7818585611d53565b60019150505b92915050565b8060008190036109d05750475b6010546040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015610a0a573d6000803e3d6000fd5b505050565b6000601754601654610a219190613301565b601a5490915082906001600160a01b03908116903090861603610aeb57610a473061109b565b8310610a66576040516315ea636560e31b815260040160405180910390fd5b82610a703061109b565b610a7a9190613301565b841115610abc573083610a8c3061109b565b610a969190613301565b8560405163391434e360e21b8152600401610ab393929190613314565b60405180910390fd5b83600003610adb5782610ace3061109b565b610ad89190613301565b91505b610ae6308284611d60565b610bf6565b6001600160a01b038516610b6a5783600003610b05574791505b6001600160a01b0381163303610b2e5760405163a5eb0da960e01b815260040160405180910390fd5b6040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015610b64573d6000803e3d6000fd5b50610bf6565b83600003610be2576040516370a0823160e01b81526001600160a01b038616906370a0823190610b9e9030906004016132a9565b602060405180830381865afa158015610bbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bdf9190613335565b91505b610bf66001600160a01b0386168284611e77565b5050505050565b600033610c0b858285611ecf565b610c16858585611f22565b60019150505b9392505050565b610c2b612392565b6001600160a01b0382166000908152601f602052604090205481151560ff909116151503610c6f5760405162a7e72d60e41b81528115156004820152602401610ab3565b6001600160a01b0382166000818152601f6020908152604091829020805485151560ff1982168117909255835160c0808252600b908201526a69734578656d707446656560a81b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a08301529060008051602061351d83398151915290610100015b60405180910390a1505050565b60003381610d168286611c93565b9050610d2e8286610d27878561334e565b60016123c4565b506001949350505050565b610d41612392565b801515601b60149054906101000a900460ff16151503610d775760405162a7e72d60e41b81528115156004820152602401610ab3565b601b8054821515600160a01b81810260ff60a01b198416179093556040805160a0808252600b908201526a697346656541637469766560a81b60c082015260ff949093049390931680151560208401529282015233606082015242608082015260008051602061355d8339815191529060e0015b60405180910390a15050565b610dff612392565b6001600160a01b0382166000908152601e602052604090205481151560ff909116151503610e435760405162a7e72d60e41b81528115156004820152602401610ab3565b306001600160a01b0316826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eaf9190613361565b6001600160a01b031614158015610f395750306001600160a01b0316826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2d9190613361565b6001600160a01b031614155b15610f595781604051634726455360e11b8152600401610ab391906132a9565b6001600160a01b0382166000908152601e6020526040902080548215801560ff1983161790925560ff16908290610fa857506001600160a01b038316600090815260208052604090205460ff16155b15610fd0576001600160a01b03831660009081526020805260409020805460ff191660011790555b6040805160c08082526008908201526706973506169724c560c41b60e08201526001600160a01b03851660208201528215159181019190915282151560608201523360808201524260a082015260008051602061351d8339815191529061010001610cfb565b61103e612392565b674563918244f400008111156110715760405163181c9d0b60e21b8152674563918244f400006004820152602401610ab3565b8060146000828254611083919061334e565b9091555050426015556110988161dead612499565b50565b6001600160a01b03166000908152601c602052604090205490565b6110be612392565b6110c86000612632565b565b6110d2612392565b620186a06110de611388565b6110ea9061138861337e565b6110f49190613395565b8111156111175760405163181c9d0b60e21b815260048101829052602401610ab3565b806018540361113c5760405163657e16cf60e01b815260048101829052602401610ab3565b6018805490829055604080518281526020810184905233918101919091524260608201527f9a9f4704ac409fe039e92a996e415370980275aaff2992936ed5b432886c55c590608001610deb565b6000546001600160a01b031690565b6111a1612392565b801515601b60179054906101000a900460ff161515036111d75760405162a7e72d60e41b81528115156004820152602401610ab3565b601b8054821515600160b81b81810260ff60b81b198416179093556040805160a0808252600d908201526c1a5cd4ddd85c115b98589b1959609a1b60c082015260ff949093049390931680151560208401529282015233606082015242608082015260008051602061355d8339815191529060e001610deb565b611259612392565b6013541561127a5760405163475a253560e01b815260040160405180910390fd5b6001600160a01b038116158061129a57506001600160a01b03811661dead145b156112ba5780604051634726455360e11b8152600401610ab391906132a9565b601b54600160a01b900460ff166112df57601b805460ff60a01b1916600160a01b1790555b601b54600160a81b900460ff1661132157601b805460ff60a81b1916600160a81b179055601080546001600160a01b0383166001600160a01b03199091161790555b601b54600160b81b900460ff1661134657601b805460ff60b81b1916600160b81b1790555b4260138190556040517f7111af66182bdf8afd5e1cfa53fdb90ebba682d2cc11a7dfead27fcbf50bea829161137d913391906133b7565b60405180910390a150565b6000611394600061109b565b61139f61dead61109b565b6012546113ac9190613301565b6113b69190613301565b905090565b601b805460ff60c01b1916600160c01b1790556113d6612392565b6113df81612682565b50601b805460ff60c01b19169055565b6113f7612392565b6001600160a01b038216600090815260208052604090205481151560ff90911615150361143a5760405162a7e72d60e41b81528115156004820152602401610ab3565b6001600160a01b03821660008181526020808052604091829020805485151560ff1982168117909255835160c0808252600d908201526c69734578656d7074536861726560981b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a08301529060008051602061351d8339815191529061010001610cfb565b6114d2612392565b801515601b60159054906101000a900460ff161515036115085760405162a7e72d60e41b81528115156004820152602401610ab3565b601b8054821515600160a81b81810260ff60a81b198416179093556040805160a0808252601490820152736973526576656e7565536861726541637469766560601b60c082015260ff949093049390931680151560208401529282015233606082015242608082015260008051602061355d8339815191529060e001610deb565b600033816115978286611c93565b9050838110156115c057848185604051637dc7a0d960e11b8152600401610ab393929190613314565b610d2e828686840360016123c4565b6000336109b7818585611f22565b6115e5612392565b601b54600160b01b900460ff16156116105760405163341e380d60e11b815260040160405180910390fd5b6001600160a01b03811661163a576000604051634726455360e11b8152600401610ab391906132a9565b601a546001600160a01b0380831691160361166a578060405163a936636960e01b8152600401610ab391906132a9565b6001600160a01b0381163b156116935760405163259f1ec560e01b815260040160405180910390fd5b601a80546001600160a01b031981166001600160a01b038481169182179093556040805160a0808252600b908201526a3332b2a932b1b2b4bb32b960a91b60c08201529390921660208401819052918301523360608301524260808301529060008051602061353d8339815191529060e001610deb565b611712612392565b6011546001600160a01b0390811690821603611743578060405163a936636960e01b8152600401610ab391906132a9565b601180546001600160a01b038381166001600160a01b0319831681179093556040805191909216808252602082019390935233918101919091524260608201527fe1cb783288eddc7b22c25642a832d886a558be0dd900747310a34156b9fdcbbb9060800160405180910390a16011546040805163c45a015560e01b815290516000926001600160a01b03169163c45a01559160048083019260209291908290030181865afa1580156117fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181e9190613361565b6001600160a01b031663e6a4390530601160009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611880573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118a49190613361565b6040518363ffffffff1660e01b81526004016118c19291906133d0565b602060405180830381865afa1580156118de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119029190613361565b6001600160a01b031603611b0e57601160009054906101000a90046001600160a01b03166001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015611963573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119879190613361565b6001600160a01b031663c9c6539630601160009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119e9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0d9190613361565b6040518363ffffffff1660e01b8152600401611a2a9291906133d0565b6020604051808303816000875af1158015611a49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6d9190613361565b601b80546001600160a01b0319166001600160a01b039290921691821790556000908152601e602052604090205460ff16611ac857601b546001600160a01b03166000908152601e60205260409020805460ff191660011790555b601b546001600160a01b0316600090815260208052604090205460ff16611b0e57601b546001600160a01b031660009081526020805260409020805460ff191660011790555b5050565b611b1a612392565b601b54600160b01b900460ff1615611b455760405163341e380d60e11b815260040160405180910390fd5b601b805460ff60b01b1916600160b01b1790556040805160608082526010908201526f1a5cd49958d95a5d995c931bd8dad95960821b6080820152336020820152428183015290517f611312486a6540001c2b69bc849753e64cdefc853bbbc7a576d987821aec28b49160a0908290030190a1565b611bc2612392565b6001600160a01b038116611bec576000604051634726455360e11b8152600401610ab391906132a9565b6010546001600160a01b03808316911603611c1c578060405163a936636960e01b8152600401610ab391906132a9565b601080546001600160a01b031981166001600160a01b038481169182179093556040805160a0808252600b908201526a3234b9ba3934b13aba37b960a91b60c08201529390921660208401819052918301523360608301524260808301529060008051602061353d8339815191529060e001610deb565b6001600160a01b039182166000908152601d6020908152604080832093909416825291909152205490565b611cc6612392565b611cce61118a565b6001600160a01b0316816001600160a01b031603611d01578060405163a936636960e01b8152600401610ab391906132a9565b61deac196001600160a01b03821601611d2f5780604051634726455360e11b8152600401610ab391906132a9565b601980546001600160a01b0319166001600160a01b03831617905561109881612b9b565b610a0a83838360016123c4565b6001600160a01b038316611d8b578060126000828254611d80919061334e565b90915550611dea9050565b6001600160a01b0383166000908152601c602052604090205481811015611dcb5783818360405163391434e360e21b8152600401610ab393929190613314565b6001600160a01b0384166000908152601c602052604090209082900390555b6001600160a01b038216611e0657601280548290039055611e25565b6001600160a01b0382166000908152601c602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611e6a91815260200190565b60405180910390a3505050565b610a0a83846001600160a01b031663a9059cbb8585604051602401611e9d9291906133b7565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050612bd6565b6000611edb8484611c93565b90506000198114611f1c5781811015611f0d57828183604051637dc7a0d960e11b8152600401610ab393929190613314565b611f1c848484840360006123c4565b50505050565b6001600160a01b038316611f4c576000604051634b637e8f60e11b8152600401610ab391906132a9565b6001600160a01b038216611f7657600060405163ec442f0560e01b8152600401610ab391906132a9565b601354600003611fe0576001600160a01b0383166000908152601f602052604090205460ff16158015611fc257506001600160a01b0382166000908152601f602052604090205460ff16155b15611fe0576040516303a7aa8760e51b815260040160405180910390fd5b601b54600160c01b900460ff168061201057506001600160a01b0383166000908152601f602052604090205460ff165b8061203357506001600160a01b0382166000908152601f602052604090205460ff165b1561204357610a0a838383611d60565b601b546001600160a01b0384811691161480159061206a5750601b54600160b81b900460ff165b801561208d575061207a3061109b565b60175460165461208a9190613301565b11155b156120aa576120aa6017546016546120a59190613301565b612682565b601b548190600160a01b900460ff1680156120de57506001600160a01b0384166000908152601f602052604090205460ff16155b801561210357506001600160a01b0383166000908152601f602052604090205460ff16155b1561211657612113848484612c30565b90505b601b54600160a81b900460ff161561238757601b546001600160a01b03858116911614801561215d57506001600160a01b038316600090815260208052604090205460ff16155b156121c157601054604051630a1e9f3f60e31b81526001600160a01b03909116906350f4f9f89061219490869085906004016133b7565b600060405180830381600087803b1580156121ae57600080fd5b505af19250505080156121bf575060015b505b601b546001600160a01b0384811691161480156121f657506001600160a01b038416600090815260208052604090205460ff16155b1561225a5760105460405163060323a760e51b81526001600160a01b039091169063c06474e09061222d90879085906004016133b7565b600060405180830381600087803b15801561224757600080fd5b505af1925050508015612258575060015b505b601b546001600160a01b038581169116148015906122865750601b546001600160a01b03848116911614155b15612387576001600160a01b038416600090815260208052604090205460ff166123095760105460405163060323a760e51b81526001600160a01b039091169063c06474e0906122dc90879085906004016133b7565b600060405180830381600087803b1580156122f657600080fd5b505af1925050508015612307575060015b505b6001600160a01b038316600090815260208052604090205460ff1661238757601054604051630a1e9f3f60e31b81526001600160a01b03909116906350f4f9f89061235a90869085906004016133b7565b600060405180830381600087803b15801561237457600080fd5b505af1925050508015612385575060015b505b611f1c848483611d60565b3361239b61118a565b6001600160a01b0316146110c8573360405163118cdaa760e01b8152600401610ab391906132a9565b6001600160a01b0384166123ee57600060405163e602df0560e01b8152600401610ab391906132a9565b6001600160a01b038316612418576000604051634a1406b160e11b8152600401610ab391906132a9565b6001600160a01b038085166000908152601d602090815260408083209387168352929052208290558015611f1c57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161248b91815260200190565b60405180910390a350505050565b601b805460ff60c01b1916600160c01b17905561deac1933016124d35761dead604051634726455360e11b8152600401610ab391906132a9565b6040805160028082526060820183526000926020830190803683375050601154604080516315ab88c960e31b815290519394506001600160a01b039091169263ad5c4648925060048083019260209291908290030181865afa15801561253d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125619190613361565b81600081518110612574576125746133ea565b60200260200101906001600160a01b031690816001600160a01b03168152505030816001815181106125a8576125a86133ea565b6001600160a01b03928316602091820292909201015260115460405163b6f9de9560e01b815291169063b6f9de959085906125ee90600090869088904290600401613444565b6000604051808303818588803b15801561260757600080fd5b505af115801561261b573d6000803e3d6000fd5b5050601b805460ff60c01b19169055505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b601b805460ff60c01b1916600160c01b1790556017546016546000916126a791613301565b9050808211156126b757506113df565b600d54600a546000916126c991613301565b600e54600b549192506000916126df9190613301565b90506000836126ee848761337e565b6126f89190613395565b9050600084612707848861337e565b6127119190613395565b90506000816127208489613301565b61272a9190613301565b60408051600280825260608201835292935060009290916020830190803683370190505090503081600081518110612764576127646133ea565b6001600160a01b03928316602091820292909201810191909152601154604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa1580156127bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127e19190613361565b816001815181106127f4576127f46133ea565b6001600160a01b03928316602091820292909201015260115461281a913091168a611d53565b6040805185815260208101859052908101839052606081018990523360808201524260a08201527f095046c58a377d54685857e96b2bbfd471ec5fe130ece4bd1fbf1369b1be25e49060c00160405180910390a18760176000828254612880919061334e565b90915550508315612a055783600d60000160008282546128a0919061334e565b9091555047905060006128b4600287613395565b905060006128c28288613301565b60115460405163791ac94760e01b81529192506001600160a01b03169063791ac947906128fc908590600090899030904290600401613479565b600060405180830381600087803b15801561291657600080fd5b505af115801561292a573d6000803e3d6000fd5b50506011546001600160a01b0316915063f305d719905061294b8547613301565b601a543090859060009081906001600160a01b031661296c426104b061334e565b60405160e089901b6001600160e01b03191681526001600160a01b039687166004820152602481019590955260448501939093526064840191909152909216608482015260a481019190915260c40160606040518083038185885af11580156129d9573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906129fe91906134b5565b5050505050505b8115612a955781600d6002016000828254612a20919061334e565b9091555050601154601a5460405163791ac94760e01b81526001600160a01b039283169263791ac94792612a6292879260009288929116904290600401613479565b600060405180830381600087803b158015612a7c57600080fd5b505af1158015612a90573d6000803e3d6000fd5b505050505b8215612b845782600d6001016000828254612ab0919061334e565b909155505060115460405163791ac94760e01b81526001600160a01b039091169063791ac94790612aee908690600090869030904290600401613479565b600060405180830381600087803b158015612b0857600080fd5b505af1158015612b1c573d6000803e3d6000fd5b50505050601060009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0476040518263ffffffff1660e01b81526004016000604051808303818588803b158015612b7057600080fd5b505af193505050508015612b82575060015b505b5050505050505050601b805460ff60c01b19169055565b612ba3612392565b6001600160a01b038116612bcd576000604051631e4fbdf760e01b8152600401610ab391906132a9565b61109881612632565b6000612beb6001600160a01b03841683612d83565b90508051600014158015612c10575080806020019051810190612c0e91906134e3565b155b15610a0a5782604051635274afe760e01b8152600401610ab391906132a9565b601b805460ff60c01b1916600160c01b1790556001600160a01b0383166000908152601e602052604081205460ff168015612c88575060035460025460015460009291612c7c9161334e565b612c86919061334e565b115b15612c9e57612c978483612d91565b9050612d6f565b6001600160a01b0383166000908152601e602052604090205460ff168015612ce3575060065460055460045460009291612cd79161334e565b612ce1919061334e565b115b15612cf257612c978483612dd3565b6001600160a01b0384166000908152601e602052604090205460ff16158015612d3457506001600160a01b0383166000908152601e602052604090205460ff16155b8015612d5d575060095460085460075460009291612d519161334e565b612d5b919061334e565b115b15612d6c57612c978483612e15565b50805b601b805460ff60c01b191690559392505050565b6060610c1c83836000612e57565b601b805460ff60c01b1916600160c01b179055604080516060810182526001548152600254602082015260035491810191909152600090612d6f908484612ef4565b601b805460ff60c01b1916600160c01b179055604080516060810182526004548152600554602082015260065491810191909152600090612d6f908484612ef4565b601b805460ff60c01b1916600160c01b179055604080516060810182526007548152600854602082015260095491810191909152600090612d6f908484612ef4565b606081471015612e7c573060405163cd78605960e01b8152600401610ab391906132a9565b600080856001600160a01b03168486604051612e989190613500565b60006040518083038185875af1925050503d8060008114612ed5576040519150601f19603f3d011682016040523d82523d6000602084013e612eda565b606091505b5091509150612eea868383612f83565b9695505050505050565b601b805460ff60c01b1916600160c01b17905560408301516020840151845160009283929091612f24919061334e565b612f2e919061334e565b90506000620186a0612f40838661337e565b612f4a9190613395565b90506000612f588286613301565b90508115612f6c57612f6c87878486612fd6565b601b805460ff60c01b191690559695505050505050565b606082612f9857612f9382613080565b610c1c565b8151158015612faf57506001600160a01b0384163b155b15612fcf5783604051639996b31560e01b8152600401610ab391906132a9565b5080610c1c565b601b805460ff60c01b1916600160c01b1790819055845160208601519091600160a81b900460ff16613006575060005b600083613013848761337e565b61301d9190613395565b905060008461302c848861337e565b6130369190613395565b90506000816130458489613301565b61304f9190613301565b905061305d8383838a6130a9565b613068883089611d60565b5050601b805460ff60c01b1916905550505050505050565b8051156130905780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b601b805460ff60c01b1916600160c01b179055600a80548591906000906130d190849061334e565b9091555050600b80548491906000906130eb90849061334e565b9091555050600c805483919060009061310590849061334e565b92505081905550806016600082825461311e919061334e565b9091555050601b805460ff60c01b1916905550505050565b60005b83811015613151578181015183820152602001613139565b50506000910152565b6020815260008251806020840152613179816040850160208701613136565b601f01601f19169190910160400192915050565b6001600160a01b038116811461109857600080fd5b6000602082840312156131b457600080fd5b8135610c1c8161318d565b600080604083850312156131d257600080fd5b82356131dd8161318d565b946020939093013593505050565b6000602082840312156131fd57600080fd5b5035919050565b60008060006060848603121561321957600080fd5b83356132248161318d565b925060208401356132348161318d565b929592945050506040919091013590565b801515811461109857600080fd5b6000806040838503121561326657600080fd5b82356132718161318d565b9150602083013561328181613245565b809150509250929050565b60006020828403121561329e57600080fd5b8135610c1c81613245565b6001600160a01b0391909116815260200190565b600080604083850312156132d057600080fd5b82356132db8161318d565b915060208301356132818161318d565b634e487b7160e01b600052601160045260246000fd5b818103818111156109bd576109bd6132eb565b6001600160a01b039390931683526020830191909152604082015260600190565b60006020828403121561334757600080fd5b5051919050565b808201808211156109bd576109bd6132eb565b60006020828403121561337357600080fd5b8151610c1c8161318d565b80820281158282048414176109bd576109bd6132eb565b6000826133b257634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0392831681529116602082015260400190565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b838110156134395781516001600160a01b031687529582019590820190600101613414565b509495945050505050565b84815260806020820152600061345d6080830186613400565b6001600160a01b03949094166040830152506060015292915050565b85815284602082015260a06040820152600061349860a0830186613400565b6001600160a01b0394909416606083015250608001529392505050565b6000806000606084860312156134ca57600080fd5b8351925060208401519150604084015190509250925092565b6000602082840312156134f557600080fd5b8151610c1c81613245565b60008251613512818460208701613136565b919091019291505056fe59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea511cc7bccdda7b7a529371ee25fbde79ba816cacfcb33ec4e285b0b034d1dafada986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf3a264697066735822122087c54452b526c8a1f599e640c1901df063a7b28059c7d621ab8c3c11f56e48c164736f6c63430008120033

Deployed Bytecode Sourcemap

28683:48993:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62592:90;;;;;;;;;;-1:-1:-1;62670:4:0;;;;;;;;;;;;-1:-1:-1;;;62670:4:0;;;;62592:90;;;;;;;:::i;:::-;;;;;;;;30381:45;;;;;;;;;;-1:-1:-1;30381:45:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;1223:14:1;;1216:22;1198:41;;1186:2;1171:18;30381:45:0;1058:187:1;65652:219:0;;;;;;;;;;-1:-1:-1;65652:219:0;;;;;:::i;:::-;;:::i;38247:258::-;;;;;;;;;;-1:-1:-1;38247:258:0;;;;;:::i;:::-;;:::i;:::-;;63641:99;;;;;;;;;;-1:-1:-1;63720:12:0;;63641:99;;;1901:25:1;;;1889:2;1874:18;63641:99:0;1755:177:1;39330:1387:0;;;;;;;;;;-1:-1:-1;39330:1387:0;;;;;:::i;:::-;;:::i;66313:281::-;;;;;;;;;;-1:-1:-1;66313:281:0;;;;;:::i;:::-;;:::i;29005:41::-;;;;;;;;;;-1:-1:-1;29005:41:0;;;;;;;;;;;;;;;;2600:25:1;;;2656:2;2641:18;;2634:34;;;;2684:18;;;2677:34;2588:2;2573:18;29005:41:0;2398:319:1;29543:33:0;;;;;;;;;;;;;;;;63353:90;;;;;;;;;;-1:-1:-1;63353:90:0;;29438:2;2864:36:1;;2852:2;2837:18;63353:90:0;2722:184:1;30127:33:0;;;;;;;;;;-1:-1:-1;30127:33:0;;;;-1:-1:-1;;;30127:33:0;;;;;;54769:471;;;;;;;;;;-1:-1:-1;54769:471:0;;;;;:::i;:::-;;:::i;76371:322::-;;;;;;;;;;-1:-1:-1;76371:322:0;;;;;:::i;:::-;;:::i;48026:416::-;;;;;;;;;;-1:-1:-1;48026:416:0;;;;;:::i;:::-;;:::i;28962:36::-;;;;;;;;;;-1:-1:-1;28962:36:0;;;;;;;;;;;;29767;;;;;;;;;;;;;;;;52355:760;;;;;;;;;;-1:-1:-1;52355:760:0;;;;;:::i;:::-;;:::i;60569:300::-;;;;;;;;;;-1:-1:-1;60569:300:0;;;;;:::i;:::-;;:::i;64025:118::-;;;;;;;;;;-1:-1:-1;64025:118:0;;;;;:::i;:::-;;:::i;26914:103::-;;;;;;;;;;;;;:::i;29725:35::-;;;;;;;;;;;;;;;;47313:459;;;;;;;;;;-1:-1:-1;47313:459:0;;;;;:::i;:::-;;:::i;30433:51::-;;;;;;;;;;-1:-1:-1;30433:51:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;26200:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;49448:426::-;;;;;;;;;;-1:-1:-1;49448:426:0;;;;;:::i;:::-;;:::i;41144:811::-;;;;;;;;;;-1:-1:-1;41144:811:0;;;;;:::i;:::-;;:::i;42351:164::-;;;;;;;;;;;;;:::i;62874:94::-;;;;;;;;;;-1:-1:-1;62954:6:0;;;;;;;;;;;;-1:-1:-1;;;62954:6:0;;;;62874:94;;29632:43;;;;;;;;;;;;;;;;43055:119;;;;;;;;;;-1:-1:-1;43055:119:0;;;;;:::i;:::-;;:::i;55567:506::-;;;;;;;;;;-1:-1:-1;55567:506:0;;;;;:::i;:::-;;:::i;48734:461::-;;;;;;;;;;-1:-1:-1;48734:461:0;;;;;:::i;:::-;;:::i;29812:72::-;;;;;;;;;;-1:-1:-1;29812:72:0;;;;-1:-1:-1;;;;;29812:72:0;;;77181:492;;;;;;;;;;-1:-1:-1;77181:492:0;;;;;:::i;:::-;;:::i;29971:19::-;;;;;;;;;;-1:-1:-1;29971:19:0;;;;-1:-1:-1;;;;;29971:19:0;;;64509:186;;;;;;;;;;-1:-1:-1;64509:186:0;;;;;:::i;:::-;;:::i;29449:48::-;;;;;;;;;;;;29490:7;29449:48;;29053:37;;;;;;;;;;-1:-1:-1;29053:37:0;;;;;;;;;;;;30491:53;;;;;;;;;;-1:-1:-1;30491:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;29891:71;;;;;;;;;;-1:-1:-1;29891:71:0;;;;-1:-1:-1;;;;;29891:71:0;;;29682:36;;;;;;;;;;;;;;;;29188:32;;;;;;;;;;-1:-1:-1;29188:32:0;;;;-1:-1:-1;;;;;29188:32:0;;;50206:755;;;;;;;;;;-1:-1:-1;50206:755:0;;;;;:::i;:::-;;:::i;53580:850::-;;;;;;;;;;-1:-1:-1;53580:850:0;;;;;:::i;:::-;;:::i;46832:237::-;;;;;;;;;;;;;:::i;30167:26::-;;;;;;;;;;-1:-1:-1;30167:26:0;;;;-1:-1:-1;;;30167:26:0;;;;;;51294:643;;;;;;;;;;-1:-1:-1;51294:643:0;;;;;:::i;:::-;;:::i;29142:37::-;;;;;;;;;;-1:-1:-1;29142:37:0;;;;;;;;;;;;29583:42;;;;;;;;;;;;;;;;65077:173;;;;;;;;;;-1:-1:-1;65077:173:0;;;;;:::i;:::-;;:::i;30084:36::-;;;;;;;;;;-1:-1:-1;30084:36:0;;;;-1:-1:-1;;;30084:36:0;;;;;;29999:31;;;;;;;;;;-1:-1:-1;29999:31:0;;;;-1:-1:-1;;;29999:31:0;;;;;;29097:38;;;;;;;;;;-1:-1:-1;29097:38:0;;;;;;;;;;;;30037:40;;;;;;;;;;-1:-1:-1;30037:40:0;;;;-1:-1:-1;;;30037:40:0;;;;;;62017:360;;;;;;;;;;-1:-1:-1;62017:360:0;;;;;:::i;:::-;;:::i;29229:75::-;;;;;;;;;;-1:-1:-1;29229:75:0;;;;-1:-1:-1;;;;;29229:75:0;;;65652:219;65750:4;65786:10;65807:34;65786:10;65826:7;65835:5;65807:8;:34::i;:::-;65859:4;65852:11;;;65652:219;;;;;:::o;38247:258::-;38338:6;38315:20;38359:11;;;38355:80;;-1:-1:-1;38402:21:0;38355:80;38461:11;;38445:52;;-1:-1:-1;;;;;38461:11:0;;;;38445:52;;;;;38484:12;;38461:11;38445:52;38461:11;38445:52;38484:12;38461:11;38445:52;;;;;;;;;;;;;;;;;;;;;38304:201;38247:258;:::o;39330:1387::-;39405:17;39445:16;;39425:17;;:36;;;;:::i;:::-;39529:11;;39405:56;;-1:-1:-1;39493:6:0;;-1:-1:-1;;;;;39529:11:0;;;;39581:4;39557:29;;;;39553:1157;;39620:24;39638:4;39620:9;:24::i;:::-;39607:9;:37;39603:112;;39672:27;;-1:-1:-1;;;39672:27:0;;;;;;;;;;;39603:112;39769:9;39742:24;39760:4;39742:9;:24::i;:::-;:36;;;;:::i;:::-;39733:6;:45;39729:260;;;39861:4;39916:9;39889:24;39907:4;39889:9;:24::i;:::-;:36;;;;:::i;:::-;39948:6;39806:167;;-1:-1:-1;;;39806:167:0;;;;;;;;;;:::i;:::-;;;;;;;;39729:260;40007:6;40017:1;40007:11;40003:101;;40079:9;40052:24;40070:4;40052:9;:24::i;:::-;:36;;;;:::i;:::-;40039:49;;40003:101;40118:44;40134:4;40141:8;40151:10;40118:7;:44::i;:::-;39553:1157;;;-1:-1:-1;;;;;40184:26:0;;40180:530;;40231:6;40241:1;40231:11;40227:86;;40276:21;40263:34;;40227:86;-1:-1:-1;;;;;40331:22:0;;:10;:22;40327:107;;40381:37;;-1:-1:-1;;;40381:37:0;;;;;;;;;;;40327:107;40448:38;;-1:-1:-1;;;;;40448:26:0;;;:38;;;;;40475:10;;40448:38;;;;40475:10;40448:26;:38;;;;;;;;;;;;;;;;;;;;;40180:530;;;40523:6;40533:1;40523:11;40519:110;;40568:45;;-1:-1:-1;;;40568:45:0;;-1:-1:-1;;;;;40568:30:0;;;;;:45;;40607:4;;40568:45;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40555:58;;40519:110;40643:55;-1:-1:-1;;;;;40643:33:0;;40677:8;40687:10;40643:33;:55::i;:::-;39394:1323;;;39330:1387;;:::o;66313:281::-;66434:4;66469:10;66490:37;66506:4;66469:10;66521:5;66490:15;:37::i;:::-;66538:26;66548:4;66554:2;66558:5;66538:9;:26::i;:::-;66582:4;66575:11;;;66313:281;;;;;;:::o;54769:471::-;24454:13;:11;:13::i;:::-;-1:-1:-1;;;;;54858:17:0;::::1;;::::0;;;:11:::1;:17;::::0;;;;;:30;::::1;;:17;::::0;;::::1;:30;;::::0;54854:102:::1;;54912:32;::::0;-1:-1:-1;;;54912:32:0;;1223:14:1;;1216:22;54912:32:0::1;::::0;::::1;1198:41:1::0;1171:18;;54912:32:0::1;1058:187:1::0;54854:102:0::1;-1:-1:-1::0;;;;;54983:17:0;::::1;54966:14;54983:17:::0;;;:11:::1;:17;::::0;;;;;;;;;;55011:29;::::1;;-1:-1:-1::0;;55011:29:0;::::1;::::0;::::1;::::0;;;55056:176;;6127:3:1;6109:22;;;6168:2;6147:19;;;6140:31;-1:-1:-1;;;6202:3:1;6187:19;;6180:42;6312:20;;;6305:45;;;;54983:17:0::1;::::0;;::::1;6393:14:1::0;;6386:22;6366:18;;;6359:50;;;;6440:2;6425:18;;6418:50;;;;55181:10:0::1;-1:-1:-1::0;6484:19:1;;6477:44;55206:15:0::1;-1:-1:-1::0;6537:19:1;;6530:35;54983:17:0;-1:-1:-1;;;;;;;;;;;55056:176:0;6254:3:1;6239:19;55056:176:0::1;;;;;;;;54843:397;54769:471:::0;;:::o;76371:322::-;76481:4;76517:10;76481:4;76565:28;76517:10;76585:7;76565:9;:28::i;:::-;76538:55;-1:-1:-1;76604:59:0;76613:8;76623:7;76632:24;76651:5;76538:55;76632:24;:::i;:::-;76658:4;76604:8;:59::i;:::-;-1:-1:-1;76681:4:0;;76371:322;-1:-1:-1;;;;76371:322:0:o;48026:416::-;24454:13;:11;:13::i;:::-;48116:9:::1;48101:24;;:11;;;;;;;;;;;:24;;::::0;48097:96:::1;;48149:32;::::0;-1:-1:-1;;;48149:32:0;;1223:14:1;;1216:22;48149:32:0::1;::::0;::::1;1198:41:1::0;1171:18;;48149:32:0::1;1058:187:1::0;48097:96:0::1;48220:11;::::0;;48242:23;::::1;;-1:-1:-1::0;;;48242:23:0;;::::1;-1:-1:-1::0;;;;48242:23:0;::::1;;::::0;;;48281:153:::1;::::0;;7008:3:1;6990:22;;;7049:2;7028:19;;;7021:31;-1:-1:-1;;;7083:3:1;7068:19;;7061:42;48220:11:0::1;::::0;;;::::1;::::0;;;::::1;7184:14:1::0;;7177:22;7170:4;7155:20;;7148:52;7216:18;;;7209:50;48383:10:0::1;-1:-1:-1::0;7275:18:1;;7268:60;48408:15:0::1;-1:-1:-1::0;7344:19:1;;7337:35;-1:-1:-1;;;;;;;;;;;48281:153:0;7135:3:1;7120:19;48281:153:0::1;;;;;;;;48086:356;48026:416:::0;:::o;52355:760::-;24454:13;:11;:13::i;:::-;-1:-1:-1;;;;;52440:16:0;::::1;;::::0;;;:8:::1;:16;::::0;;;;;:29;::::1;;:16;::::0;;::::1;:29;;::::0;52436:101:::1;;52493:32;::::0;-1:-1:-1;;;52493:32:0;;1223:14:1;;1216:22;52493:32:0::1;::::0;::::1;1198:41:1::0;1171:18;;52493:32:0::1;1058:187:1::0;52436:101:0::1;52599:4;-1:-1:-1::0;;;;;52565:39:0::1;52571:6;-1:-1:-1::0;;;;;52565:20:0::1;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;52565:39:0::1;;;:95;;;;;52655:4;-1:-1:-1::0;;;;;52621:39:0::1;52627:6;-1:-1:-1::0;;;;;52621:20:0::1;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;52621:39:0::1;;;52565:95;52547:181;;;52709:6;52694:22;;-1:-1:-1::0;;;52694:22:0::1;;;;;;;;:::i;52547:181::-;-1:-1:-1::0;;;;;52755:16:0;::::1;52738:14;52755:16:::0;;;:8:::1;:16;::::0;;;;;;52782:28;::::1;::::0;::::1;-1:-1:-1::0;;52782:28:0;::::1;;::::0;;;52755:16:::1;;::::0;52801:9;;52825:35:::1;;-1:-1:-1::0;;;;;;52839:21:0;::::1;;::::0;;;:13:::1;:21:::0;;;;;;::::1;;52838:22;52825:35;52821:96;;;-1:-1:-1::0;;;;;52877:21:0;::::1;;::::0;;;:13:::1;:21:::0;;;;;:28;;-1:-1:-1;;52877:28:0::1;52901:4;52877:28;::::0;;52821:96:::1;52932:175;::::0;;7969:3:1;7951:22;;;8010:1;7989:19;;;7982:30;-1:-1:-1;;;8043:3:1;8028:19;;8021:39;-1:-1:-1;;;;;8172:15:1;;8165:4;8150:20;;8143:45;8231:14;;8224:22;8204:18;;;8197:50;;;;8290:14;;8283:22;8278:2;8263:18;;8256:50;53056:10:0::1;-1:-1:-1::0;8322:19:1;;8315:44;53081:15:0::1;-1:-1:-1::0;8375:19:1;;8368:35;-1:-1:-1;;;;;;;;;;;52932:175:0;8092:3:1;8077:19;52932:175:0::1;7639:770:1::0;60569:300:0;24454:13;:11;:13::i;:::-;60656:7:::1;60647:6;:16;60643:77;;;60687:21;::::0;-1:-1:-1;;;60687:21:0;;60700:7:::1;60687:21;::::0;::::1;1901:25:1::0;1874:18;;60687:21:0::1;1755:177:1::0;60643:77:0::1;60757:6;60730:23;;:33;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;60801:15:0::1;60774:24;:42:::0;60827:34:::1;60837:6:::0;60853::::1;60827:9;:34::i;:::-;60569:300:::0;:::o;64025:118::-;-1:-1:-1;;;;;64117:18:0;64090:7;64117:18;;;:9;:18;;;;;;;64025:118::o;26914:103::-;24454:13;:11;:13::i;:::-;26979:30:::1;27006:1;26979:18;:30::i;:::-;26914:103::o:0;47313:459::-;24454:13;:11;:13::i;:::-;29490:7:::1;47404:19;:17;:19::i;:::-;:27;::::0;47426:5:::1;47404:27;:::i;:::-;47403:46;;;;:::i;:::-;47390:10;:59;47386:123;;;47473:24;::::0;-1:-1:-1;;;47473:24:0;;::::1;::::0;::::1;1901:25:1::0;;;1874:18;;47473:24:0::1;1755:177:1::0;47386:123:0::1;47534:10;47523:7;;:21:::0;47519:94:::1;;47568:33;::::0;-1:-1:-1;;;47568:33:0;;::::1;::::0;::::1;1901:25:1::0;;;1874:18;;47568:33:0::1;1755:177:1::0;47519:94:0::1;47644:7;::::0;;47662:20;;;;47698:66:::1;::::0;;9248:25:1;;;9304:2;9289:18;;9282:34;;;47736:10:0::1;9332:18:1::0;;;9325:60;;;;47748:15:0::1;9416:2:1::0;9401:18;;9394:34;47698:66:0::1;::::0;9235:3:1;9220:19;47698:66:0::1;9017:417:1::0;26200:87:0;26246:7;26273:6;-1:-1:-1;;;;;26273:6:0;;26200:87::o;49448:426::-;24454:13;:11;:13::i;:::-;49542:9:::1;49525:26;;:13;;;;;;;;;;;:26;;::::0;49521:98:::1;;49575:32;::::0;-1:-1:-1;;;49575:32:0;;1223:14:1;;1216:22;49575:32:0::1;::::0;::::1;1198:41:1::0;1171:18;;49575:32:0::1;1058:187:1::0;49521:98:0::1;49646:13;::::0;;49670:25;::::1;;-1:-1:-1::0;;;49670:25:0;;::::1;-1:-1:-1::0;;;;49670:25:0;::::1;;::::0;;;49711:155:::1;::::0;;9741:3:1;9723:22;;;9782:2;9761:19;;;9754:31;-1:-1:-1;;;9816:3:1;9801:19;;9794:44;49646:13:0::1;::::0;;;::::1;::::0;;;::::1;9919:14:1::0;;9912:22;9905:4;9890:20;;9883:52;9951:18;;;9944:50;49815:10:0::1;-1:-1:-1::0;10010:18:1;;10003:60;49840:15:0::1;-1:-1:-1::0;10079:19:1;;10072:35;-1:-1:-1;;;;;;;;;;;49711:155:0;9870:3:1;9855:19;49711:155:0::1;9439:674:1::0;41144:811:0;24454:13;:11;:13::i;:::-;41252:14:::1;::::0;:19;41248:77:::1;;41295:18;;-1:-1:-1::0;;;41295:18:0::1;;;;;;;;;;;41248:77;-1:-1:-1::0;;;;;41353:37:0;::::1;::::0;;:96:::1;;-1:-1:-1::0;;;;;;41407:42:0;::::1;41442:6;41407:42;41353:96;41335:199;;;41498:23;41483:39;;-1:-1:-1::0;;;41483:39:0::1;;;;;;;;:::i;41335:199::-;41549:11;::::0;-1:-1:-1;;;41549:11:0;::::1;;;41544:63;;41577:11;:18:::0;;-1:-1:-1;;;;41577:18:0::1;-1:-1:-1::0;;;41577:18:0::1;::::0;;41544:63:::1;41622:20;::::0;-1:-1:-1;;;41622:20:0;::::1;;;41617:148;;41659:20;:27:::0;;-1:-1:-1;;;;41659:27:0::1;-1:-1:-1::0;;;41659:27:0::1;::::0;;41701:11:::1;:52:::0;;-1:-1:-1;;;;;41701:52:0;::::1;-1:-1:-1::0;;;;;;41701:52:0;;::::1;;::::0;;41617:148:::1;41780:13;::::0;-1:-1:-1;;;41780:13:0;::::1;;;41775:67;;41810:13;:20:::0;;-1:-1:-1;;;;41810:20:0::1;-1:-1:-1::0;;;41810:20:0::1;::::0;;41775:67:::1;41869:15;41852:14;:32:::0;;;41902:45:::1;::::0;::::1;::::0;::::1;::::0;41919:10:::1;::::0;41869:15;41902:45:::1;:::i;:::-;;;;;;;;41144:811:::0;:::o;42351:164::-;42401:7;42486:21;42504:1;42486:9;:21::i;:::-;42457:26;42475:6;42457:9;:26::i;:::-;63720:12;;42441:42;;;;:::i;:::-;:66;;;;:::i;:::-;42421:86;;42351:164;:::o;43055:119::-;30697:6;:13;;-1:-1:-1;;;;30697:13:0;-1:-1:-1;;;30697:13:0;;;24454::::1;:11;:13::i;:::-;43140:26:::2;43151:14;43140:10;:26::i;:::-;-1:-1:-1::0;30733:6:0;:14;;-1:-1:-1;;;;30733:14:0;;;43055:119::o;55567:506::-;24454:13;:11;:13::i;:::-;-1:-1:-1;;;;;55683:19:0;::::1;;::::0;;;:13:::1;:19:::0;;;;;;:32;::::1;;:19;::::0;;::::1;:32;;::::0;55679:104:::1;;55739:32;::::0;-1:-1:-1;;;55739:32:0;;1223:14:1;;1216:22;55739:32:0::1;::::0;::::1;1198:41:1::0;1171:18;;55739:32:0::1;1058:187:1::0;55679:104:0::1;-1:-1:-1::0;;;;;55810:19:0;::::1;55793:14;55810:19:::0;;;:13:::1;:19:::0;;;;;;;;;;55840:31;::::1;;-1:-1:-1::0;;55840:31:0;::::1;::::0;::::1;::::0;;;55887:178;;10727:3:1;10709:22;;;10768:2;10747:19;;;10740:31;-1:-1:-1;;;10802:3:1;10787:19;;10780:44;10914:20;;;10907:45;;;;55810:19:0::1;::::0;;::::1;10995:14:1::0;;10988:22;10968:18;;;10961:50;;;;11042:2;11027:18;;11020:50;;;;56014:10:0::1;-1:-1:-1::0;11086:19:1;;11079:44;56039:15:0::1;-1:-1:-1::0;11139:19:1;;11132:35;55810:19:0;-1:-1:-1;;;;;;;;;;;55887:178:0;10856:3:1;10841:19;55887:178:0::1;10397:776:1::0;48734:461:0;24454:13;:11;:13::i;:::-;48842:9:::1;48818:33;;:20;;;;;;;;;;;:33;;::::0;48814:105:::1;;48875:32;::::0;-1:-1:-1;;;48875:32:0;;1223:14:1;;1216:22;48875:32:0::1;::::0;::::1;1198:41:1::0;1171:18;;48875:32:0::1;1058:187:1::0;48814:105:0::1;48946:20;::::0;;48977:32;::::1;;-1:-1:-1::0;;;48977:32:0;;::::1;-1:-1:-1::0;;;;48977:32:0;::::1;;::::0;;;49025:162:::1;::::0;;11480:3:1;11462:22;;;11521:2;11500:19;;;11493:31;-1:-1:-1;;;11555:3:1;11540:19;;11533:51;48946:20:0::1;::::0;;;::::1;::::0;;;::::1;11665:14:1::0;;11658:22;11651:4;11636:20;;11629:52;11697:18;;;11690:50;49136:10:0::1;-1:-1:-1::0;11756:18:1;;11749:60;49161:15:0::1;-1:-1:-1::0;11825:19:1;;11818:35;-1:-1:-1;;;;;;;;;;;49025:162:0;11616:3:1;11601:19;49025:162:0::1;11178:681:1::0;77181:492:0;77291:4;77327:10;77291:4;77375:28;77327:10;77395:7;77375:9;:28::i;:::-;77348:55;;77437:5;77418:16;:24;77414:124;;;77493:7;77502:16;77520:5;77466:60;;-1:-1:-1;;;77466:60:0;;;;;;;;;;:::i;77414:124::-;77573:59;77582:8;77592:7;77620:5;77601:16;:24;77627:4;77573:8;:59::i;64509:186::-;64578:4;64614:10;64635:30;64614:10;64655:2;64659:5;64635:9;:30::i;50206:755::-;24454:13;:11;:13::i;:::-;50291:16:::1;::::0;-1:-1:-1;;;50291:16:0;::::1;;;50287:72;;;50331:16;;-1:-1:-1::0;;;50331:16:0::1;;;;;;;;;;;50287:72;-1:-1:-1::0;;;;;50373:28:0;::::1;50369:94;;50448:1;50425:26;;-1:-1:-1::0;;;50425:26:0::1;;;;;;;;:::i;50369:94::-;50477:11;::::0;-1:-1:-1;;;;;50477:29:0;;::::1;:11:::0;::::1;:29:::0;50473:108:::1;;50554:14;50530:39;;-1:-1:-1::0;;;50530:39:0::1;;;;;;;;:::i;50473:108::-;-1:-1:-1::0;;;;;50595:26:0;::::1;;:30:::0;50591:96:::1;;50649:26;;-1:-1:-1::0;;;50649:26:0::1;;;;;;;;;;;50591:96;50722:11;::::0;;-1:-1:-1;;;;;;50744:28:0;::::1;-1:-1:-1::0;;;;;50744:28:0;;::::1;::::0;;::::1;::::0;;;50788:165:::1;::::0;;12178:3:1;12160:22;;;12219:2;12198:19;;;12191:31;-1:-1:-1;;;12253:3:1;12238:19;;12231:42;50722:11:0;;;::::1;12378:4:1::0;12363:20;;12356:45;;;12417:18;;;12410:43;50902:10:0::1;-1:-1:-1::0;12469:18:1;;12462:43;50927:15:0::1;-1:-1:-1::0;12521:19:1;;12514:35;50722:11:0;-1:-1:-1;;;;;;;;;;;50788:165:0;12305:3:1;12290:19;50788:165:0::1;11864:691:1::0;53580:850:0;24454:13;:11;:13::i;:::-;53676:6:::1;::::0;-1:-1:-1;;;;;53676:6:0;;::::1;53655:28:::0;;::::1;::::0;53651:102:::1;;53731:9;53707:34;;-1:-1:-1::0;;;53707:34:0::1;;;;;;;;:::i;53651:102::-;53793:6;::::0;;-1:-1:-1;;;;;53811:27:0;;::::1;-1:-1:-1::0;;;;;;53811:27:0;::::1;::::0;::::1;::::0;;;53856:63:::1;::::0;;53793:6;;;::::1;12829:34:1::0;;;12894:2;12879:18;;12872:43;;;;53891:10:0::1;12931:18:1::0;;;12924:43;;;;53903:15:0::1;12998:2:1::0;12983:18;;12976:34;53856:63:0::1;::::0;12778:3:1;12763:19;53856:63:0::1;;;;;;;53985:6;::::0;:16:::1;::::0;;-1:-1:-1;;;53985:16:0;;;;54067:1:::1;::::0;-1:-1:-1;;;;;53985:6:0::1;::::0;:14:::1;::::0;:16:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:6;:16:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;53976:34:0::1;;54019:4;54026:6;;;;;;;;;-1:-1:-1::0;;;;;54026:6:0::1;-1:-1:-1::0;;;;;54026:11:0::1;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53976:64;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;53950:119:0::1;::::0;53932:491:::1;;54112:6;;;;;;;;;-1:-1:-1::0;;;;;54112:6:0::1;-1:-1:-1::0;;;;;54112:14:0::1;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;54103:37:0::1;;54167:4;54191:6;;;;;;;;;-1:-1:-1::0;;;;;54191:6:0::1;-1:-1:-1::0;;;;;54191:11:0::1;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54103:116;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54096:4;:123:::0;;-1:-1:-1;;;;;;54096:123:0::1;-1:-1:-1::0;;;;;54096:123:0;;;::::1;::::0;;::::1;::::0;;-1:-1:-1;54239:14:0;;;:8:::1;:14;::::0;;;;;::::1;;54234:77;;54283:4;::::0;-1:-1:-1;;;;;54283:4:0::1;54274:14;::::0;;;:8:::1;:14;::::0;;;;:21;;-1:-1:-1;;54274:21:0::1;54291:4;54274:21;::::0;;54234:77:::1;54344:4;::::0;-1:-1:-1;;;;;54344:4:0::1;54330:19;::::0;;;:13:::1;:19:::0;;;;;;::::1;;54325:87;;54384:4;::::0;-1:-1:-1;;;;;54384:4:0::1;54370:19;::::0;;;:13:::1;:19:::0;;;;;:26;;-1:-1:-1;;54370:26:0::1;54392:4;54370:26;::::0;;54325:87:::1;53640:790;53580:850:::0;:::o;46832:237::-;24454:13;:11;:13::i;:::-;46891:16:::1;::::0;-1:-1:-1;;;46891:16:0;::::1;;;46887:72;;;46931:16;;-1:-1:-1::0;;;46931:16:0::1;;;;;;;;;;;46887:72;46969:16;:23:::0;;-1:-1:-1;;;;46969:23:0::1;-1:-1:-1::0;;;46969:23:0::1;::::0;;47008:53:::1;::::0;;13588:2:1;13570:21;;;13627:2;13607:18;;;13600:30;-1:-1:-1;;;13661:3:1;13646:19;;13639:47;47033:10:0::1;13753:4:1::0;13738:20;;13731:62;47045:15:0::1;13809:18:1::0;;;13802:34;47008:53:0;;::::1;::::0;13718:3:1;47008:53:0;;;;;;::::1;46832:237::o:0;51294:643::-;24454:13;:11;:13::i;:::-;-1:-1:-1;;;;;51413:37:0;::::1;51409:103;;51497:1;51474:26;;-1:-1:-1::0;;;51474:26:0::1;;;;;;;;:::i;51409:103::-;51526:11;::::0;-1:-1:-1;;;;;51526:29:0;;::::1;:11:::0;::::1;:29:::0;51522:117:::1;;51611:14;51579:48;;-1:-1:-1::0;;;51579:48:0::1;;;;;;;;:::i;51522:117::-;51680:11;::::0;;-1:-1:-1;;;;;;51702:28:0;::::1;-1:-1:-1::0;;;;;51702:28:0;;::::1;::::0;;::::1;::::0;;;51746:183:::1;::::0;;14161:3:1;14143:22;;;14202:2;14181:19;;;14174:31;-1:-1:-1;;;14236:3:1;14221:19;;14214:42;51680:11:0;;;::::1;14361:4:1::0;14346:20;;14339:45;;;14400:18;;;14393:43;51878:10:0::1;-1:-1:-1::0;14452:18:1;;14445:43;51903:15:0::1;-1:-1:-1::0;14504:19:1;;14497:35;51680:11:0;-1:-1:-1;;;;;;;;;;;51746:183:0;14288:3:1;14273:19;51746:183:0::1;13847:691:1::0;65077:173:0;-1:-1:-1;;;;;65212:21:0;;;65185:7;65212:21;;;:11;:21;;;;;;;;:30;;;;;;;;;;;;;65077:173::o;62017:360::-;24454:13;:11;:13::i;:::-;62115:7:::1;:5;:7::i;:::-;-1:-1:-1::0;;;;;62103:19:0::1;:8;-1:-1:-1::0;;;;;62103:19:0::1;::::0;62099:92:::1;;62170:8;62146:33;;-1:-1:-1::0;;;62146:33:0::1;;;;;;;;:::i;62099:92::-;-1:-1:-1::0;;;;;;;62205:27:0;::::1;::::0;62201:91:::1;;62271:8;62256:24;;-1:-1:-1::0;;;62256:24:0::1;;;;;;;;:::i;62201:91::-;62302:12;:23:::0;;-1:-1:-1;;;;;;62302:23:0::1;-1:-1:-1::0;;;;;62302:23:0;::::1;;::::0;;62336:33:::1;62302:23:::0;62336::::1;:33::i;73231:170::-:0;73353:40;73362:8;73372:7;73381:5;73388:4;73353:8;:40::i;71204:730::-;-1:-1:-1;;;;;71294:18:0;;71290:369;;71345:5;71329:12;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;71290:369:0;;-1:-1:-1;71290:369:0;;-1:-1:-1;;;;;71405:15:0;;71383:19;71405:15;;;:9;:15;;;;;;71439:19;;;71435:117;;;71511:4;71517:11;71530:5;71486:50;;-1:-1:-1;;;71486:50:0;;;;;;;;;;:::i;71435:117::-;-1:-1:-1;;;;;71595:15:0;;;;;;:9;:15;;;;;71613:19;;;;71595:37;;71290:369;-1:-1:-1;;;;;71675:16:0;;71671:213;;71737:12;:21;;;;;;;71671:213;;;-1:-1:-1;;;;;71835:13:0;;;;;;:9;:13;;;;;:22;;;;;;71671:213;71916:2;-1:-1:-1;;;;;71901:25:0;71910:4;-1:-1:-1;;;;;71901:25:0;;71920:5;71901:25;;;;1901::1;;1889:2;1874:18;;1755:177;71901:25:0;;;;;;;;71204:730;;;:::o;6982:162::-;7065:71;7085:5;7107;-1:-1:-1;;;;;7107:14:0;;7124:2;7128:5;7092:43;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;7092:43:0;;;;;;;;;;;7065:19;:71::i;75228:612::-;75365:24;75392:28;75402:8;75412:7;75392:9;:28::i;:::-;75365:55;;-1:-1:-1;;75435:16:0;:37;75431:402;;75512:5;75493:16;:24;75489:214;;;75594:7;75624:16;75663:5;75545:142;;-1:-1:-1;;;75545:142:0;;;;;;;;;;:::i;75489:214::-;75746:60;75755:8;75765:7;75793:5;75774:16;:24;75800:5;75746:8;:60::i;:::-;75354:486;75228:612;;;:::o;67439:1695::-;-1:-1:-1;;;;;67523:18:0;;67519:88;;67592:1;67565:30;;-1:-1:-1;;;67565:30:0;;;;;;;;:::i;67519:88::-;-1:-1:-1;;;;;67621:16:0;;67617:88;;67690:1;67661:32;;-1:-1:-1;;;67661:32:0;;;;;;;;:::i;67617:88::-;67719:14;;67737:1;67719:19;67715:161;;-1:-1:-1;;;;;67760:17:0;;;;;;:11;:17;;;;;;;;67759:18;:38;;;;-1:-1:-1;;;;;;67782:15:0;;;;;;:11;:15;;;;;;;;67781:16;67759:38;67755:110;;;67825:24;;-1:-1:-1;;;67825:24:0;;;;;;;;;;;67755:110;67892:6;;-1:-1:-1;;;67892:6:0;;;;;:27;;-1:-1:-1;;;;;;67902:17:0;;;;;;:11;:17;;;;;;;;67892:27;:46;;;-1:-1:-1;;;;;;67923:15:0;;;;;;:11;:15;;;;;;;;67892:46;67888:110;;;67962:24;67970:4;67976:2;67980:5;67962:7;:24::i;67888:110::-;68034:4;;-1:-1:-1;;;;;68026:12:0;;;68034:4;;68026:12;;;;:42;;-1:-1:-1;68055:13:0;;-1:-1:-1;;;68055:13:0;;;;68026:42;:123;;;;;68125:24;68143:4;68125:9;:24::i;:::-;68105:16;;68085:17;;:36;;;;:::i;:::-;:64;;68026:123;68008:228;;;68176:48;68207:16;;68187:17;;:36;;;;:::i;:::-;68176:10;:48::i;:::-;68289:11;;68267:5;;-1:-1:-1;;;68289:11:0;;;;:33;;;;-1:-1:-1;;;;;;68305:17:0;;;;;;:11;:17;;;;;;;;68304:18;68289:33;:53;;;;-1:-1:-1;;;;;;68327:15:0;;;;;;:11;:15;;;;;;;;68326:16;68289:53;68285:134;;;68370:37;68391:4;68397:2;68401:5;68370:20;:37::i;:::-;68359:48;;68285:134;68435:20;;-1:-1:-1;;;68435:20:0;;;;68431:656;;;68484:4;;-1:-1:-1;;;;;68476:12:0;;;68484:4;;68476:12;:34;;;;-1:-1:-1;;;;;;68493:17:0;;;;;;:13;:17;;;;;;;;68492:18;68476:34;68472:124;;;68535:11;;:34;;-1:-1:-1;;;68535:34:0;;-1:-1:-1;;;;;68535:11:0;;;;:20;;:34;;68556:2;;68560:8;;68535:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68531:50;;68620:4;;-1:-1:-1;;;;;68614:10:0;;;68620:4;;68614:10;:34;;;;-1:-1:-1;;;;;;68629:19:0;;;;;;:13;:19;;;;;;;;68628:20;68614:34;68610:129;;;68673:11;;:39;;-1:-1:-1;;;68673:39:0;;-1:-1:-1;;;;;68673:11:0;;;;:23;;:39;;68697:4;;68703:8;;68673:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68669:55;;68765:4;;-1:-1:-1;;;;;68757:12:0;;;68765:4;;68757:12;;;;:26;;-1:-1:-1;68779:4:0;;-1:-1:-1;;;;;68773:10:0;;;68779:4;;68773:10;;68757:26;68753:323;;;-1:-1:-1;;;;;68809:19:0;;;;;;:13;:19;;;;;;;;68804:123;;68857:11;;:39;;-1:-1:-1;;;68857:39:0;;-1:-1:-1;;;;;68857:11:0;;;;:23;;:39;;68881:4;;68887:8;;68857:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68853:55;;-1:-1:-1;;;;;68950:17:0;;;;;;:13;:17;;;;;;;;68945:116;;68996:11;;:34;;-1:-1:-1;;;68996:34:0;;-1:-1:-1;;;;;68996:11:0;;;;:20;;:34;;69017:2;;69021:8;;68996:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68992:50;;69099:27;69107:4;69113:2;69117:8;69099:7;:27::i;26479:162::-;26550:10;26539:7;:5;:7::i;:::-;-1:-1:-1;;;;;26539:21:0;;26535:99;;26611:10;26584:38;;-1:-1:-1;;;26584:38:0;;;;;;;;:::i;74172:498::-;-1:-1:-1;;;;;74331:22:0;;74327:94;;74406:1;74377:32;;-1:-1:-1;;;74377:32:0;;;;;;;;:::i;74327:94::-;-1:-1:-1;;;;;74435:21:0;;74431:92;;74508:1;74480:31;;-1:-1:-1;;;74480:31:0;;;;;;;;:::i;74431:92::-;-1:-1:-1;;;;;74533:21:0;;;;;;;:11;:21;;;;;;;;:30;;;;;;;;;:38;;;74582:81;;;;74636:7;-1:-1:-1;;;;;74617:34:0;74626:8;-1:-1:-1;;;;;74617:34:0;;74645:5;74617:34;;;;1901:25:1;;1889:2;1874:18;;1755:177;74617:34:0;;;;;;;;74172:498;;;;:::o;61106:441::-;30697:6;:13;;-1:-1:-1;;;;30697:13:0;-1:-1:-1;;;30697:13:0;;;-1:-1:-1;;61186:10:0::1;:29:::0;61182:100:::1;;61262:6;61239:31;;-1:-1:-1::0;;;61239:31:0::1;;;;;;;;:::i;61182:100::-;61316:16;::::0;;61330:1:::1;61316:16:::0;;;;;::::1;::::0;;61292:21:::1;::::0;61316:16:::1;::::0;::::1;::::0;;::::1;::::0;::::1;-1:-1:-1::0;;61353:6:0::1;::::0;:13:::1;::::0;;-1:-1:-1;;;61353:13:0;;;;61292:40;;-1:-1:-1;;;;;;61353:6:0;;::::1;::::0;:11:::1;::::0;-1:-1:-1;61353:13:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:6;:13:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61343:4;61348:1;61343:7;;;;;;;;:::i;:::-;;;;;;:23;-1:-1:-1::0;;;;;61343:23:0::1;;;-1:-1:-1::0;;;;;61343:23:0::1;;;::::0;::::1;61395:4;61377;61382:1;61377:7;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;61377:23:0;;::::1;:7;::::0;;::::1;::::0;;;;;:23;61413:6:::1;::::0;:126:::1;::::0;-1:-1:-1;;;61413:126:0;;:6;::::1;::::0;:57:::1;::::0;61492:6;;61413:126:::1;::::0;:6:::1;::::0;61513:4;;61519:2;;61523:15:::1;::::0;61413:126:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;30733:6:0;:14;;-1:-1:-1;;;;30733:14:0;;;-1:-1:-1;;;;;;61106:441:0:o;27994:191::-;28068:16;28087:6;;-1:-1:-1;;;;;28104:17:0;;;-1:-1:-1;;;;;;28104:17:0;;;;;;28137:40;;28087:6;;;;;;;28137:40;;28068:16;28137:40;28057:128;27994:191;:::o;43702:2945::-;30697:6;:13;;-1:-1:-1;;;;30697:13:0;-1:-1:-1;;;30697:13:0;;;43819:16:::1;::::0;43799:17:::1;::::0;30697:13;;43799:36:::1;::::0;::::1;:::i;:::-;43775:60;;43869:13;43852:14;:30;43848:69;;;43899:7;;;43848:69;43993:11;:21:::0;43955:12:::1;:22:::0;43927:25:::1;::::0;43955:59:::1;::::0;::::1;:::i;:::-;44074:19:::0;;44051:20;;43927:87;;-1:-1:-1;44025:23:0::1;::::0;44051:42:::1;::::0;44074:19;44051:42:::1;:::i;:::-;44025:68:::0;-1:-1:-1;44106:32:0::1;44193:13:::0;44142:47:::1;44172:17:::0;44142:14;:47:::1;:::i;:::-;44141:65;;;;:::i;:::-;44106:100:::0;-1:-1:-1;44217:30:0::1;44300:13:::0;44251:32:::1;44268:15:::0;44251:14;:32:::1;:::i;:::-;44250:63;;;;:::i;:::-;44217:96:::0;-1:-1:-1;44324:27:0::1;44217:96:::0;44354:54:::1;44384:24:::0;44354:14;:54:::1;:::i;:::-;:92;;;;:::i;:::-;44483:16;::::0;;44497:1:::1;44483:16:::0;;;;;::::1;::::0;;44324:122;;-1:-1:-1;44459:21:0::1;::::0;44483:16;;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;44483:16:0::1;44459:40;;44528:4;44510;44515:1;44510:7;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;44510:23:0;;::::1;:7;::::0;;::::1;::::0;;;;;;:23;;;;44554:6:::1;::::0;:13:::1;::::0;;-1:-1:-1;;;44554:13:0;;;;:6;;;::::1;::::0;:11:::1;::::0;:13:::1;::::0;;::::1;::::0;44510:7;;44554:13;;;;;:6;:13:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44544:4;44549:1;44544:7;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;44544:23:0;;::::1;:7;::::0;;::::1;::::0;;;;;:23;44612:6:::1;::::0;44580:56:::1;::::0;44597:4:::1;::::0;44612:6:::1;44621:14:::0;44580:8:::1;:56::i;:::-;44654:215;::::0;;16075:25:1;;;16131:2;16116:18;;16109:34;;;16159:18;;;16152:34;;;16217:2;16202:18;;16195:34;;;44818:10:0::1;16260:3:1::0;16245:19;;16238:61;44843:15:0::1;16286:3:1::0;16315:19;;16308:35;44654:215:0::1;::::0;16062:3:1;16047:19;44654:215:0::1;;;;;;;44902:14;44882:16;;:34;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;44933:28:0;;44929:902:::1;;45003:24;44978:11;:21;;;:49;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;45069:21:0::1;::::0;-1:-1:-1;45044:22:0::1;45134:28;45161:1;45134:24:::0;:28:::1;:::i;:::-;45105:57:::0;-1:-1:-1;45177:27:0::1;45207:62;45105:57:::0;45207:24;:62:::1;:::i;:::-;45286:6;::::0;:218:::1;::::0;-1:-1:-1;;;45286:218:0;;45177:92;;-1:-1:-1;;;;;;45286:6:0::1;::::0;:57:::1;::::0;:218:::1;::::0;45362:18;;45286:6:::1;::::0;45419:4;;45450::::1;::::0;45474:15:::1;::::0;45286:218:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;45521:6:0::1;::::0;-1:-1:-1;;;;;45521:6:0::1;::::0;-1:-1:-1;45521:22:0::1;::::0;-1:-1:-1;45569:38:0::1;45593:14:::0;45569:21:::1;:38;:::i;:::-;45751:11;::::0;45649:4:::1;::::0;45673:19;;45711:1:::1;::::0;;;-1:-1:-1;;;;;45751:11:0::1;45781:23;:15;45799:5;45781:23;:::i;:::-;45521:298;::::0;::::1;::::0;;;-1:-1:-1;;;;;;45521:298:0;;;-1:-1:-1;;;;;17300:15:1;;;45521:298:0::1;::::0;::::1;17282:34:1::0;17332:18;;;17325:34;;;;17375:18;;;17368:34;;;;17418:18;;;17411:34;;;;17482:15;;;17461:19;;;17454:44;17514:19;;;17507:35;;;;17216:19;;45521:298:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;44963:868;;;44929:902;45847:23:::0;;45843:329:::1;;45907:19;45887:11;:16;;;:39;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;45943:6:0::1;::::0;46100:11:::1;::::0;45943:217:::1;::::0;-1:-1:-1;;;45943:217:0;;-1:-1:-1;;;;;45943:6:0;;::::1;::::0;:57:::1;::::0;:217:::1;::::0;46019:19;;45943:6:::1;::::0;46077:4;;46100:11;::::1;::::0;46130:15:::1;::::0;45943:217:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;45843:329;46188:26:::0;;46184:456:::1;;46254:22;46231:11;:19;;;:45;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;46293:6:0::1;::::0;:222:::1;::::0;-1:-1:-1;;;46293:222:0;;-1:-1:-1;;;;;46293:6:0;;::::1;::::0;:57:::1;::::0;:222:::1;::::0;46369:22;;46293:6:::1;::::0;46430:4;;46461::::1;::::0;46485:15:::1;::::0;46293:222:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;46553:11;;;;;;;;;-1:-1:-1::0;;;;;46553:11:0::1;-1:-1:-1::0;;;;;46553:19:0::1;;46580:21;46553:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;46532:97:::0;::::1;43764:2883;;;;;;;-1:-1:-1::0;30733:6:0;:14;;-1:-1:-1;;;;30733:14:0;;;43702:2945::o;27443:220::-;24454:13;:11;:13::i;:::-;-1:-1:-1;;;;;27528:22:0;::::1;27524:93;;27602:1;27574:31;;-1:-1:-1::0;;;27574:31:0::1;;;;;;;;:::i;27524:93::-;27627:28;27646:8;27627:18;:28::i;7534:295::-:0;7615:23;7641:33;-1:-1:-1;;;;;7641:27:0;;7669:4;7641:27;:33::i;:::-;7615:59;;7689:10;:17;7710:1;7689:22;;:57;;;;;7727:10;7716:30;;;;;;;;;;;;:::i;:::-;7715:31;7689:57;7685:137;;;7803:5;7770:40;;-1:-1:-1;;;7770:40:0;;;;;;;;:::i;69731:781::-;30697:6;:13;;-1:-1:-1;;;;30697:13:0;-1:-1:-1;;;30697:13:0;;;-1:-1:-1;;;;;69910:14:0;::::1;69872:7:::0;69910:14;;;:8:::1;:14;::::0;;;;;30697:13;69910:14:::1;:84:::0;::::1;;;-1:-1:-1::0;69978:11:0;;::::1;69961:14:::0;69978:6:::1;69942:16:::0;69992:1:::1;::::0;69978:11;69942:33:::1;::::0;::::1;:::i;:::-;:47;;;;:::i;:::-;:51;69910:84;69892:172;;;70028:24;70039:4;70045:6;70028:10;:24::i;:::-;70021:31;;;;69892:172;-1:-1:-1::0;;;;;70092:12:0;::::1;;::::0;;;:8:::1;:12;::::0;;;;;::::1;;:85:::0;::::1;;;-1:-1:-1::0;70160:12:0;;70142:15;;70160:7:::1;70122:17:::0;70175:1:::1;::::0;70160:12;70122:35:::1;::::0;::::1;:::i;:::-;:50;;;;:::i;:::-;:54;70092:85;70074:174;;;70211:25;70223:4;70229:6;70211:11;:25::i;70074:174::-;-1:-1:-1::0;;;;;70277:14:0;::::1;;::::0;;;:8:::1;:14;::::0;;;;;::::1;;70276:15;:45:::0;::::1;;;-1:-1:-1::0;;;;;;70309:12:0;::::1;;::::0;;;:8:::1;:12;::::0;;;;;::::1;;70308:13;70276:45;:130;;;;-1:-1:-1::0;70385:16:0;;70363:19;;70385:11:::1;70339:21:::0;70404:1:::1;::::0;70385:16;70339:43:::1;::::0;::::1;:::i;:::-;:62;;;;:::i;:::-;:66;70276:130;70258:223;;;70440:29;70456:4;70462:6;70440:15;:29::i;70258:223::-;-1:-1:-1::0;70498:6:0;30721:1:::1;30733:6:::0;:14;;-1:-1:-1;;;;30733:14:0;;;69731:781;;-1:-1:-1;;;69731:781:0:o;2793:178::-;2893:12;2925:38;2947:6;2955:4;2961:1;2925:21;:38::i;56429:166::-;30697:6;:13;;-1:-1:-1;;;;30697:13:0;-1:-1:-1;;;30697:13:0;;;56558:29:::1;::::0;;::::1;::::0;::::1;::::0;;30706:4;56558:29;;;;;::::1;::::0;::::1;::::0;;;;;;;;;;56531:7;;56558:29:::1;::::0;56574:4;56580:6;56558:7:::1;:29::i;56935:168::-:0;30697:6;:13;;-1:-1:-1;;;;30697:13:0;-1:-1:-1;;;30697:13:0;;;57065:30:::1;::::0;;::::1;::::0;::::1;::::0;;57073:7:::1;57065:30:::0;;;;;::::1;::::0;::::1;::::0;;;;;;;;;;57038:7;;57065:30:::1;::::0;57082:4;57088:6;57065:7:::1;:30::i;57447:176::-:0;30697:6;:13;;-1:-1:-1;;;;30697:13:0;-1:-1:-1;;;30697:13:0;;;57581:34:::1;::::0;;::::1;::::0;::::1;::::0;;57589:11:::1;57581:34:::0;;;;;::::1;::::0;::::1;::::0;;;;;;;;;;57554:7;;57581:34:::1;::::0;57602:4;57608:6;57581:7:::1;:34::i;3564:456::-:0;3697:12;3750:5;3726:21;:29;3722:110;;;3814:4;3779:41;;-1:-1:-1;;;3779:41:0;;;;;;;;:::i;3722:110::-;3843:12;3857:23;3884:6;-1:-1:-1;;;;;3884:11:0;3903:5;3924:4;3884:55;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3842:97;;;;3957:55;3984:6;3992:7;4001:10;3957:26;:55::i;:::-;3950:62;3564:456;-1:-1:-1;;;;;;3564:456:0:o;58019:468::-;30697:6;:13;;-1:-1:-1;;;;30697:13:0;-1:-1:-1;;;30697:13:0;;;58224:12:::1;::::0;::::1;::::0;58206:15:::1;::::0;::::1;::::0;58186:17;;58147:7;;;;58224:12;;58186:35:::1;::::0;58206:15;58186:35:::1;:::i;:::-;:50;;;;:::i;:::-;58167:69:::0;-1:-1:-1;58247:17:0::1;29490:7;58268:17;58167:69:::0;58268:6;:17:::1;:::i;:::-;58267:36;;;;:::i;:::-;58247:56:::0;-1:-1:-1;58314:17:0::1;58334:18;58247:56:::0;58334:6;:18:::1;:::i;:::-;58314:38:::0;-1:-1:-1;58367:13:0;;58363:90:::1;;58397:44;58406:7;58415:4;58421:9;58432:8;58397;:44::i;:::-;30733:6:::0;:14;;-1:-1:-1;;;;30733:14:0;;;58470:9;58019:468;-1:-1:-1;;;;;;58019:468:0:o;4784:425::-;4932:12;4962:7;4957:245;;4986:19;4994:10;4986:7;:19::i;:::-;4957:245;;;5042:17;;:22;:49;;;;-1:-1:-1;;;;;;5068:18:0;;;:23;5042:49;5038:121;;;5136:6;5119:24;;-1:-1:-1;;;5119:24:0;;;;;;;;:::i;5038:121::-;-1:-1:-1;5180:10:0;5173:17;;58875:661;30697:6;:13;;-1:-1:-1;;;;30697:13:0;-1:-1:-1;;;30697:13:0;;;;;59051:17;;59100:15:::1;::::0;::::1;::::0;59051:17;;-1:-1:-1;;;59131:20:0;::::1;30697:13:::0;59131:20:::1;59126:68;;-1:-1:-1::0;59181:1:0::1;59126:68;59204:24;59257:3:::0;59232:21:::1;59241:12:::0;59232:6;:21:::1;:::i;:::-;59231:29;;;;:::i;:::-;59204:56:::0;-1:-1:-1;59271:22:0::1;59320:3:::0;59297:19:::1;59306:10:::0;59297:6;:19:::1;:::i;:::-;59296:27;;;;:::i;:::-;59271:52:::0;-1:-1:-1;59334:19:0::1;59271:52:::0;59356:25:::1;59365:16:::0;59356:6;:25:::1;:::i;:::-;:42;;;;:::i;:::-;59334:64;;59409:70;59425:16;59443:14;59459:11;59472:6;59409:15;:70::i;:::-;59492:36;59500:4;59514;59521:6;59492:7;:36::i;:::-;-1:-1:-1::0;;30733:6:0;:14;;-1:-1:-1;;;;30733:14:0;;;-1:-1:-1;;;;;;;58875:661:0:o;5477:328::-;5547:17;;:21;5543:255;;5642:10;5636:17;5699:15;5686:10;5682:2;5678:19;5671:44;5543:255;5769:17;;-1:-1:-1;;;5769:17:0;;;;;;;;;;;59901:364;30697:6;:13;;-1:-1:-1;;;;30697:13:0;-1:-1:-1;;;30697:13:0;;;60085:12:::1;:42:::0;;60111:16;;60085:12;30697:13;;60085:42:::1;::::0;60111:16;;60085:42:::1;:::i;:::-;::::0;;;-1:-1:-1;;60138:20:0;:38;;60162:14;;60138:20;::::1;::::0;:38:::1;::::0;60162:14;;60138:38:::1;:::i;:::-;::::0;;;-1:-1:-1;;60187:17:0;:32;;60208:11;;60187:17;::::1;::::0;:32:::1;::::0;60208:11;;60187:32:::1;:::i;:::-;;;;;;;;60251:6;60230:17;;:27;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;30733:6:0;:14;;-1:-1:-1;;;;30733:14:0;;;-1:-1:-1;;;;59901:364:0:o;14:250:1:-;99:1;109:113;123:6;120:1;117:13;109:113;;;199:11;;;193:18;180:11;;;173:39;145:2;138:10;109:113;;;-1:-1:-1;;256:1:1;238:16;;231:27;14:250::o;269:396::-;418:2;407:9;400:21;381:4;450:6;444:13;493:6;488:2;477:9;473:18;466:34;509:79;581:6;576:2;565:9;561:18;556:2;548:6;544:15;509:79;:::i;:::-;649:2;628:15;-1:-1:-1;;624:29:1;609:45;;;;656:2;605:54;;269:396;-1:-1:-1;;269:396:1:o;670:131::-;-1:-1:-1;;;;;745:31:1;;735:42;;725:70;;791:1;788;781:12;806:247;865:6;918:2;906:9;897:7;893:23;889:32;886:52;;;934:1;931;924:12;886:52;973:9;960:23;992:31;1017:5;992:31;:::i;1250:315::-;1318:6;1326;1379:2;1367:9;1358:7;1354:23;1350:32;1347:52;;;1395:1;1392;1385:12;1347:52;1434:9;1421:23;1453:31;1478:5;1453:31;:::i;:::-;1503:5;1555:2;1540:18;;;;1527:32;;-1:-1:-1;;;1250:315:1:o;1570:180::-;1629:6;1682:2;1670:9;1661:7;1657:23;1653:32;1650:52;;;1698:1;1695;1688:12;1650:52;-1:-1:-1;1721:23:1;;1570:180;-1:-1:-1;1570:180: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;2911:118::-;2997:5;2990:13;2983:21;2976:5;2973:32;2963:60;;3019:1;3016;3009:12;3034:382;3099:6;3107;3160:2;3148:9;3139:7;3135:23;3131:32;3128:52;;;3176:1;3173;3166:12;3128:52;3215:9;3202:23;3234:31;3259:5;3234:31;:::i;:::-;3284:5;-1:-1:-1;3341:2:1;3326:18;;3313:32;3354:30;3313:32;3354:30;:::i;:::-;3403:7;3393:17;;;3034:382;;;;;:::o;3421:241::-;3477:6;3530:2;3518:9;3509:7;3505:23;3501:32;3498:52;;;3546:1;3543;3536:12;3498:52;3585:9;3572:23;3604:28;3626:5;3604:28;:::i;3667:203::-;-1:-1:-1;;;;;3831:32:1;;;;3813:51;;3801:2;3786:18;;3667:203::o;4377:388::-;4445:6;4453;4506:2;4494:9;4485:7;4481:23;4477:32;4474:52;;;4522:1;4519;4512:12;4474:52;4561:9;4548:23;4580:31;4605:5;4580:31;:::i;:::-;4630:5;-1:-1:-1;4687:2:1;4672:18;;4659:32;4700:33;4659:32;4700:33;:::i;4993:127::-;5054:10;5049:3;5045:20;5042:1;5035:31;5085:4;5082:1;5075:15;5109:4;5106:1;5099:15;5125:128;5192:9;;;5213:11;;;5210:37;;;5227:18;;:::i;5258:345::-;-1:-1:-1;;;;;5478:32:1;;;;5460:51;;5542:2;5527:18;;5520:34;;;;5585:2;5570:18;;5563:34;5448:2;5433:18;;5258:345::o;5608:184::-;5678:6;5731:2;5719:9;5710:7;5706:23;5702:32;5699:52;;;5747:1;5744;5737:12;5699:52;-1:-1:-1;5770:16:1;;5608:184;-1:-1:-1;5608:184:1:o;6576:125::-;6641:9;;;6662:10;;;6659:36;;;6675:18;;:::i;7383:251::-;7453:6;7506:2;7494:9;7485:7;7481:23;7477:32;7474:52;;;7522:1;7519;7512:12;7474:52;7554:9;7548:16;7573:31;7598:5;7573:31;:::i;8622:168::-;8695:9;;;8726;;8743:15;;;8737:22;;8723:37;8713:71;;8764:18;;:::i;8795:217::-;8835:1;8861;8851:132;;8905:10;8900:3;8896:20;8893:1;8886:31;8940:4;8937:1;8930:15;8968:4;8965:1;8958:15;8851:132;-1:-1:-1;8997:9:1;;8795:217::o;10118:274::-;-1:-1:-1;;;;;10310:32:1;;;;10292:51;;10374:2;10359:18;;10352:34;10280:2;10265:18;;10118:274::o;13021:304::-;-1:-1:-1;;;;;13251:15:1;;;13233:34;;13303:15;;13298:2;13283:18;;13276:43;13183:2;13168:18;;13021:304::o;14675:127::-;14736:10;14731:3;14727:20;14724:1;14717:31;14767:4;14764:1;14757:15;14791:4;14788:1;14781:15;14807:461;14860:3;14898:5;14892:12;14925:6;14920:3;14913:19;14951:4;14980:2;14975:3;14971:12;14964:19;;15017:2;15010:5;15006:14;15038:1;15048:195;15062:6;15059:1;15056:13;15048:195;;;15127:13;;-1:-1:-1;;;;;15123:39:1;15111:52;;15183:12;;;;15218:15;;;;15159:1;15077:9;15048:195;;;-1:-1:-1;15259:3:1;;14807:461;-1:-1:-1;;;;;14807:461:1:o;15273:510::-;15544:6;15533:9;15526:25;15587:3;15582:2;15571:9;15567:18;15560:31;15507:4;15608:57;15660:3;15649:9;15645:19;15637:6;15608:57;:::i;:::-;-1:-1:-1;;;;;15701:32:1;;;;15696:2;15681:18;;15674:60;-1:-1:-1;15765:2:1;15750:18;15743:34;15600:65;15273:510;-1:-1:-1;;15273:510:1:o;16354:582::-;16653:6;16642:9;16635:25;16696:6;16691:2;16680:9;16676:18;16669:34;16739:3;16734:2;16723:9;16719:18;16712:31;16616:4;16760:57;16812:3;16801:9;16797:19;16789:6;16760:57;:::i;:::-;-1:-1:-1;;;;;16853:32:1;;;;16848:2;16833:18;;16826:60;-1:-1:-1;16917:3:1;16902:19;16895:35;16752:65;16354:582;-1:-1:-1;;;16354:582:1:o;17553:306::-;17641:6;17649;17657;17710:2;17698:9;17689:7;17685:23;17681:32;17678:52;;;17726:1;17723;17716:12;17678:52;17755:9;17749:16;17739:26;;17805:2;17794:9;17790:18;17784:25;17774:35;;17849:2;17838:9;17834:18;17828:25;17818:35;;17553:306;;;;;:::o;17864:245::-;17931:6;17984:2;17972:9;17963:7;17959:23;17955:32;17952:52;;;18000:1;17997;17990:12;17952:52;18032:9;18026:16;18051:28;18073:5;18051:28;:::i;18114:287::-;18243:3;18281:6;18275:13;18297:66;18356:6;18351:3;18344:4;18336:6;18332:17;18297:66;:::i;:::-;18379:16;;;;;18114:287;-1:-1:-1;;18114:287:1:o

Swarm Source

ipfs://87c54452b526c8a1f599e640c1901df063a7b28059c7d621ab8c3c11f56e48c1

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.