ETH Price: $2,912.52 (-10.13%)
Gas: 22 Gwei

Token

Rare FiND (FND)
 

Overview

Max Total Supply

500,000,000,000,000,000,000 FND

Holders

120

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 0 Decimals)

Balance
426,971,196,979,265,674 FND

Value
$0.00
0x7101adcf8d03725eb927a1ddd2987d70154f165a
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
RareFiND

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

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

// File: interfaces/ILERC20.sol


pragma solidity ^0.8.0;

interface ILERC20 {
    function name() external view returns (string memory);

    function admin() external view returns (address);

    function getAdmin() external view returns (address);

    function symbol() external view returns (string memory);

    function decimals() external view returns (uint8);

    function totalSupply() external view returns (uint256);

    function balanceOf(address _account) external view returns (uint256);

    function transfer(
        address _recipient,
        uint256 _amount
    ) external returns (bool);

    function allowance(
        address _owner,
        address _spender
    ) external view returns (uint256);

    function approve(address _spender, uint256 _amount) external returns (bool);

    function transferFrom(
        address _sender,
        address _recipient,
        uint256 _amount
    ) external returns (bool);

    function increaseAllowance(
        address _spender,
        uint256 _addedValue
    ) external returns (bool);

    function decreaseAllowance(
        address _spender,
        uint256 _subtractedValue
    ) external returns (bool);

    function transferOutBlacklistedFunds(address[] calldata _from) external;

    function setLosslessAdmin(address _newAdmin) external;

    function transferRecoveryAdminOwnership(
        address _candidate,
        bytes32 _keyHash
    ) external;

    function acceptRecoveryAdminOwnership(bytes memory _key) external;

    function proposeLosslessTurnOff() external;

    function executeLosslessTurnOff() external;

    function executeLosslessTurnOn() external;

    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(
        address indexed _owner,
        address indexed _spender,
        uint256 _value
    );
    event NewAdmin(address indexed _newAdmin);
    event NewRecoveryAdminProposal(address indexed _candidate);
    event NewRecoveryAdmin(address indexed _newAdmin);
    event LosslessTurnOffProposal(uint256 _turnOffDate);
    event LosslessOff();
    event LosslessOn();
}

// File: interfaces/IRareDex.sol


pragma solidity ^0.8.0;

interface IRARESwapFactory {
    event PairCreated(
        address indexed token0,
        address indexed token1,
        address pair,
        uint256
    );

    function feeTo() external view returns (address);

    function feeToSetter() external view returns (address);

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

    function allPairs(uint256) external view returns (address pair);

    function allPairsLength() external view returns (uint256);

    function pairExist(address pair) external view returns (bool);

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

    function setFeeTo(address) external;

    function setFeeToSetter(address) external;

    function routerInitialize(address) external;

    function routerAddress() external view returns (address);
}

interface IRARESwapPair {
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
    event Transfer(address indexed from, address indexed to, uint256 value);

    function baseToken() external view returns (address);

    function getTotalFee() external view returns (uint256);

    function name() external pure returns (string memory);

    function symbol() external pure returns (string memory);

    function decimals() external pure returns (uint8);

    function totalSupply() external view returns (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(
        address owner,
        address spender
    ) external view returns (uint256);

    function updateTotalFee(uint256 totalFee) external returns (bool);

    function approve(address spender, uint256 value) external returns (bool);

    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);

    function PERMIT_TYPEHASH() external pure returns (bytes32);

    function nonces(address owner) external view returns (uint256);

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    event Mint(address indexed sender, uint256 amount0, uint256 amount1);
    event Burn(
        address indexed sender,
        uint256 amount0,
        uint256 amount1,
        address indexed to
    );
    event Swap(
        address indexed sender,
        uint256 amount0In,
        uint256 amount1In,
        uint256 amount0Out,
        uint256 amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint256);

    function factory() external view returns (address);

    function token0() external view returns (address);

    function token1() external view returns (address);

    function getReserves()
        external
        view
        returns (
            uint112 reserve0,
            uint112 reserve1,
            uint32 blockTimestampLast,
            address _baseToken
        );

    function price0CumulativeLast() external view returns (uint256);

    function price1CumulativeLast() external view returns (uint256);

    function kLast() external view returns (uint256);

    function mint(address to) external returns (uint256 liquidity);

    function burn(
        address to
    ) external returns (uint256 amount0, uint256 amount1);

    function swap(
        uint256 amount0Out,
        uint256 amount1Out,
        uint256 amount0Fee,
        uint256 amount1Fee,
        address to,
        bytes calldata data
    ) external;

    function skim(address to) external;

    function sync() external;

    function initialize(address, address) external;

    function setBaseToken(address _baseToken) external;
}

interface IRARESwapRouter01 {
    function factory() external pure returns (address);

    function WETH() external pure returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB, uint256 liquidity);

    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        returns (uint256 amountToken, uint256 amountETH, uint256 liquidity);

    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETH(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountToken, uint256 amountETH);

    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETHWithPermit(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountToken, uint256 amountETH);

    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapTokensForExactTokens(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactETHForTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function swapTokensForExactETH(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactTokensForETH(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapETHForExactTokens(
        uint256 amountOut,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function quote(
        uint256 amountA,
        uint256 reserveA,
        uint256 reserveB
    ) external pure returns (uint256 amountB);

    function getAmountOut(
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut
    ) external pure returns (uint256 amountOut);

    function getAmountIn(
        uint256 amountOut,
        uint256 reserveIn,
        uint256 reserveOut
    ) external pure returns (uint256 amountIn);

    function getAmountsOut(
        uint256 amountIn,
        address[] calldata path
    ) external view returns (uint256[] memory amounts);

    function getAmountsIn(
        uint256 amountOut,
        address[] calldata path
    ) external view returns (uint256[] memory amounts);
}

interface IRARESwapRouter is IRARESwapRouter01 {
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountETH);

    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountETH);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable;

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    function pairFeeAddress(address pair) external view returns (address);

    function adminFee() external view returns (uint256);

    function feeAddressGet() external view returns (address);
}

// File: @openzeppelin/[email protected]/utils/Address.sol


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

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

// File: @openzeppelin/[email protected]/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

// File: @openzeppelin/[email protected]/token/ERC20/extensions/IERC20Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

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

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

// File: @openzeppelin/[email protected]/utils/introspection/IERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

// File: @openzeppelin/[email protected]/utils/introspection/ERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;


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

// File: @openzeppelin/[email protected]/utils/math/Math.sol


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

pragma solidity ^0.8.0;

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

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

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

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

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

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

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: @openzeppelin/[email protected]/utils/Strings.sol


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

pragma solidity ^0.8.0;


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

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

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

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

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

// File: @openzeppelin/[email protected]/utils/Context.sol


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

// File: @openzeppelin/[email protected]/metatx/ERC2771Context.sol


// OpenZeppelin Contracts (last updated v4.7.0) (metatx/ERC2771Context.sol)

pragma solidity ^0.8.9;


/**
 * @dev Context variant with ERC2771 support.
 */
abstract contract ERC2771Context is Context {
    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
    address private immutable _trustedForwarder;

    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor(address trustedForwarder) {
        _trustedForwarder = trustedForwarder;
    }

    function isTrustedForwarder(address forwarder) public view virtual returns (bool) {
        return forwarder == _trustedForwarder;
    }

    function _msgSender() internal view virtual override returns (address sender) {
        if (isTrustedForwarder(msg.sender)) {
            // The assembly code is more direct than the Solidity version using `abi.decode`.
            /// @solidity memory-safe-assembly
            assembly {
                sender := shr(96, calldataload(sub(calldatasize(), 20)))
            }
        } else {
            return super._msgSender();
        }
    }

    function _msgData() internal view virtual override returns (bytes calldata) {
        if (isTrustedForwarder(msg.sender)) {
            return msg.data[:msg.data.length - 20];
        } else {
            return super._msgData();
        }
    }
}

// File: @openzeppelin/[email protected]/token/ERC20/ERC20.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;




/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

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

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

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

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

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

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

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

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

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

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
            // decrementing then incrementing.
            _balances[to] += amount;
        }

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        unchecked {
            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
            _balances[account] += amount;
        }
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
            // Overflow not possible: amount <= accountBalance <= totalSupply.
            _totalSupply -= amount;
        }

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

// File: @openzeppelin/[email protected]/access/Ownable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;


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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

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

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

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

// File: @openzeppelin/[email protected]/access/IAccessControl.sol


// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}

// File: @openzeppelin/[email protected]/access/AccessControl.sol


// OpenZeppelin Contracts (last updated v4.8.0) (access/AccessControl.sol)

pragma solidity ^0.8.0;





/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role);
        _;
    }

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

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `_msgSender()` is missing `role`.
     * Overriding this function changes the behavior of the {onlyRole} modifier.
     *
     * Format of the revert message is described in {_checkRole}.
     *
     * _Available since v4.6._
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(account),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleGranted} event.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleRevoked} event.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     *
     * May emit a {RoleRevoked} event.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * May emit a {RoleGranted} event.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     *
     * NOTE: This function is deprecated in favor of {_grantRole}.
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleGranted} event.
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleRevoked} event.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

// File: contracts/RareFiND.sol

/*
    Website: https://rareswap.com/
    Contract Name: Rare FiND
    Instagram: https://www.instagram.com/rarefnd/
    Twitter: https://twitter.com/rare_fnd
    Telegram: https://t.me/RareFnd
    Contract Version: 2.0
    removed safemath
    fixed storage
    fixed swc
    fixed Libraries.
    fixed documentation of code.


*/
//SPDX-License-Identifier: UNLICENSED

pragma solidity 0.8.17;
//Libraries from OpenZeppelin to be included in the code, these Libraries are secured and used here without modification.









contract RareFiND is
    ERC2771Context,
    ILERC20,
    AccessControl,
    Ownable
{
    // Roles
    // Roles can only be added by members of the same role
    // Owner can set the role, ONLY when the role is not setup
    bytes32 public constant FEE_ROLE = keccak256("FEE");
    bytes32 public constant WALLET_ROLE = keccak256("WALLET");
    bytes32 public constant LOSSLESS_ROLE = keccak256("LOSSLESS");
    bytes32 public constant MAX_ROLE = keccak256("MAX");
    bytes32 public constant BOT_ROLE = keccak256("BOT");
    //Inclusion of address library into our code for simplicity.
    using Address for address;
    ///all mappings documented in this section
    mapping(address => uint256) private _rOwned;
    mapping(address => uint256) private _tOwned;
    mapping(address => mapping(address => uint256)) private _allowances;
    mapping(address => bool) private _isExcludedFromFee;
    mapping(address => bool) private _isExcluded;
    mapping(address => bool) private botWallets;
    //events documented here so they are recorded in the chain, later this are called on the functions.
    event Log(string, uint256);
    event AuditLog(string, address);

    //Wrapped Token from chain defined and wallets definition for code.
    address public immutable WETH;
    address public marketingWallet; // marketing wallet address
    address public antiquitiesWallet; // antiquities Wallet address
    address public gasWallet; // gas Wallet address
    address public immutable depWallet; // dep Wallet address

    // Exclusion amounts
    uint private excludedT;
    uint private excludedR;
    //Trade Definition
    bool public canTrade = false;
    //Token Information, including name, symbol and supply
    uint256 private constant MAX = ~uint256(0);
    uint256 private _tTotal = 500_000_000_000 gwei;
    uint256 private _rTotal = (MAX - (MAX % _tTotal));
    uint256 private _tFeeTotal;
    string public constant name = "Rare FiND";
    string public constant symbol = "FND";
    uint8 public constant decimals = 9;
    uint16 public constant MIN_TAX = 100;
    uint16 public constant MAX_TAX = 1500;
    uint16 public constant TAX_DIVISOR = 10_000;
    //Tax Definition for code and public reference.
    uint256 private _taxFee = 100; // reflection tax in BPS
    uint256 private _previousTaxFee = _taxFee;

    uint256 private _liquidityFee; // liquidity tax in BPS
    uint256 private _previousLiquidityFee = _liquidityFee;

    uint256 private _marketingFee = 200; // marketing tax in BPS | 200 = 2%
    uint256 private _antiquitiesFee = 300; // antiquities tax in BPS
    uint256 private _gasFee = 100; // gas tax in BPS

    uint256 public _totalTax =
        _taxFee + _marketingFee + _antiquitiesFee + _gasFee; //Total Tax to be collected.
    //Swap and Router definition for the code and pair creation.addmod
    IRARESwapRouter public immutable rareSwapRouter;
    address public immutable rareSwapPair;
    //Max Limits Definition
    uint256 public _maxTxAmount = 500_000_000_000 gwei; // total supply by default, can be changed at will
    uint256 public _maxWallet = 5_000_000_000 gwei; // 1% max wallet by default, can be changed at will

    /// Lossless Compliance
    //You can read more on https://docs.lossless.io/protocol/technical-reference/hack-mitigation-protocol
    address public admin;
    address public recoveryAdmin;
    address private recoveryAdminCandidate;
    bytes32 private recoveryAdminKeyHash;
    uint256 public timelockPeriod = 30 days;
    uint256 public losslessTurnOffTimestamp;
    bool public isLosslessOn = false;
    ILssController public lossless;
    //Modifier to identify pair and ensure is only RareSwap
    modifier onlyExchange() {
        bool isPair = false;
        if (msg.sender == rareSwapPair) isPair = true;

        require(
            msg.sender == address(rareSwapRouter) || isPair,
            "RARE: NOT_ALLOWED"
        );
        _;
    }

    //Code Deployer Configuration for wallets, these wallets are used to collect taxes.
    constructor(
        address _marketingWallet,
        address _antiquitiesWallet,
        address _gasWallet,
        address _trustedForwarder,
        address _depWallet,
        address _router,
        address[] memory adminRoles
    ) ERC2771Context(_trustedForwarder) {
        _rOwned[_msgSender()] = _rTotal;
        _tOwned[_msgSender()] = _tTotal;

        marketingWallet = _marketingWallet;
        antiquitiesWallet = _antiquitiesWallet;
        gasWallet = _gasWallet;

        // Setup router
        rareSwapRouter = IRARESwapRouter(_router);
        WETH = rareSwapRouter.WETH();
        // Create the pair
        rareSwapPair = IRARESwapFactory(rareSwapRouter.factory()).createPair(
            address(this),
            WETH
        );
        try IRARESwapPair(rareSwapPair).setBaseToken(WETH) {
            IRARESwapPair(rareSwapPair).updateTotalFee(
                _marketingFee + _antiquitiesFee + _gasFee
            );
        } catch {
            // If the pair doesn't support setBaseToken, we can't set the base token
            // and we can't update the total fee
        }
        // Set base token in the pair as WETH, which acts as the tax token

        depWallet = _depWallet;
        //exclude owner and this contract from fee
        //exclude definition to avoid problems with swap,router and owner or marketing wallets from getting fees.

        _isExcludedFromFee[owner()] = true;
        _isExcludedFromFee[address(this)] = true;
        _isExcludedFromFee[depWallet] = true;
        _isExcludedFromFee[gasWallet] = true;
        _isExcludedFromFee[marketingWallet] = true;
        _isExcludedFromFee[antiquitiesWallet] = true;
        //exclude from getting reflections.
        excludeFromReward(address(this));
        excludeFromReward(depWallet);
        excludeFromReward(gasWallet);
        excludeFromReward(marketingWallet);
        excludeFromReward(antiquitiesWallet);
        excludeFromReward(rareSwapPair);
        excludeFromReward(address(rareSwapRouter));
        //define those that Have permissions using access roles.
        require(adminRoles.length == 5, "ERR: INVALID_ADMIN_ROLES");
        _grantRole(MAX_ROLE, adminRoles[0]);
        _grantRole(LOSSLESS_ROLE, adminRoles[1]);
        _grantRole(FEE_ROLE, adminRoles[2]);
        _grantRole(WALLET_ROLE, adminRoles[3]);
        _grantRole(BOT_ROLE, adminRoles[4]);
        //transfer tokens to owner after mint or creation
        emit Transfer(address(0), _msgSender(), _tTotal);
    }

    /// @notice set the Maximum amount of tokens that can be held in a wallet
    /// @param amount the amount of tokens in gwei
    /// @dev only owner can call this function, minimum limit is 0.5% of the total supply
    function setMaxWalletAmount(uint256 amount) external onlyRole(MAX_ROLE) {
        require(
            amount > (totalSupply() * 5) / (1000 * 1 gwei),
            "ERR: max wallet amount should exceed 0.5% of the supply"
        );
        _maxWallet = amount * 10 ** 9;
        emit Log("New max wallet amount:", amount);
    }

    /// @notice ERC20 implementation of total Circulating supply of the token
    /// @return _tTotal total supply of the token
    function totalSupply() public view override returns (uint256) {
        return _tTotal;
    }

    /// @notice ERC20 implementation of user's balance
    /// @param account the address of the user to check
    /// @return balance of the user
    /// @dev if the address is excluded from reward, it returns the balance of the user without any reflections accounted for
    function balanceOf(address account) public view override returns (uint256) {
        if (_isExcluded[account]) return _tOwned[account];
        return tokenFromReflection(_rOwned[account]);
    }

    /// @notice ERC20 implementation of transfer function
    /// @param recipient the address of the recipient
    /// @param amount the amount of tokens to transfer
    /// @return true if the transfer is successful
    function transfer(
        address recipient,
        uint256 amount
    ) public override lssTransfer(recipient, amount) returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /// @notice ERC20 implementation of allowance function
    /// @param _owner the address of the owner
    /// @param spender the address of the spender
    /// @return amount of tokens that the spender is allowed to spend
    function allowance(
        address _owner,
        address spender
    ) public view override returns (uint256) {
        return _allowances[_owner][spender];
    }

    /// @notice ERC20 implementation of approve function
    /// @param spender the address of the spender
    /// @param amount the amount of tokens to approve
    /// @return true if the approval is successful
    function approve(
        address spender,
        uint256 amount
    ) public override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /// @notice ERC20 implementation of transferFrom function
    /// @param sender the address of the sender
    /// @param recipient the address of the recipient
    /// @param amount the amount of tokens to transfer
    /// @return true if the transfer is successful
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    )
        public
        override
        lssTransferFrom(sender, recipient, amount)
        returns (bool)
    {
        _transfer(sender, recipient, amount);
        _approve(
            sender,
            _msgSender(),
            _allowances[sender][_msgSender()] - amount
        );
        return true;
    }

    /// @notice ERC20 implementation of increaseAllowance function
    /// @param spender the address of the spender
    /// @param addedValue the amount of tokens to increase the allowance by
    /// @return true if the increase is successful
    function increaseAllowance(
        address spender,
        uint256 addedValue
    ) public virtual returns (bool) {
        _approve(
            _msgSender(),
            spender,
            _allowances[_msgSender()][spender] + addedValue
        );
        return true;
    }

    /// @notice ERC20 implementation of decreaseAllowance function
    /// @param spender the address of the spender
    /// @param subtractedValue the amount of tokens to decrease the allowance by
    /// @return true if the decrease is successful
    function decreaseAllowance(
        address spender,
        uint256 subtractedValue
    ) public virtual returns (bool) {
        _approve(
            _msgSender(),
            spender,
            _allowances[_msgSender()][spender] - subtractedValue
        );
        return true;
    }

    /// @notice function that determines if an address is excluded from reward
    /// @param account the address to check
    /// @return true if the address is excluded from reward
    function isExcludedFromReward(address account) public view returns (bool) {
        return _isExcluded[account];
    }

    /// @notice function that returns the amount collected in fees
    /// @return the amount collected in fees
    function totalFees() public view returns (uint256) {
        return _tFeeTotal;
    }

    /// @notice this works similar to burn function
    /// @param tAmount the amount of tokens to deliver
    /// @dev although this function does not reduce the total supply, it reduces the reflection of the sender and the total to be distributed
    function deliver(uint256 tAmount) public {
        address sender = _msgSender();
        require(
            !_isExcluded[sender],
            "Excluded addresses cannot call this function"
        );
        (uint256 rAmount, , , , ) = _getValues(tAmount);
        _rOwned[sender] = _rOwned[sender] - rAmount;
        _rTotal = _rTotal - rAmount;
        _tFeeTotal = _tFeeTotal + tAmount;
    }

    /// @notice calcualtes the reflection amount from a given token amount
    /// @param tAmount the amount of tokens to calculate the reflection amount from
    /// @param deductTransferFee true if the transfer fee should be deducted
    /// @return the reflection amount
    function reflectionFromToken(
        uint256 tAmount,
        bool deductTransferFee
    ) public view returns (uint256) {
        require(tAmount <= _tTotal, "Amount must be less than supply");
        (uint256 rAmount, uint256 rTransferAmount, , , ) = _getValues(tAmount);
        return deductTransferFee ? rTransferAmount : rAmount;
    }

    /// @notice calculates the token amount from a given reflection amount
    /// @param rAmount the amount of reflections to calculate the token amount from
    /// @return the token amount
    function tokenFromReflection(
        uint256 rAmount
    ) public view returns (uint256) {
        require(
            rAmount <= _rTotal,
            "Amount must be less than total reflections"
        );
        uint256 currentRate = _getRate();
        if (currentRate > 0) return rAmount / currentRate;
        return rAmount;
    }

    /// @notice excludes an address from reward
    /// @param account the address to exclude from reward
    /// @dev this function can only be called by the owner and the variables for excluded amounts are updated
    function excludeFromReward(address account) public onlyOwner {
        // require(account != 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D, 'We can not exclude Uniswap router.');
        require(!_isExcluded[account], "Account is already excluded");
        if (_rOwned[account] > 0) {
            _tOwned[account] = tokenFromReflection(_rOwned[account]);
        }
        _isExcluded[account] = true;
        excludedT += _tOwned[account];
        excludedR += _rOwned[account];
    }

    /// @notice updates the Fees set up in the DEX pairs
    /// @param fee the new fee amount to update
    function _updatePairsFee(uint256 fee) internal {
        try IRARESwapPair(rareSwapPair).updateTotalFee(fee) {} catch {
            emit Log("Cant update fee", fee);
        }
    }

    /// @notice excludes and address from transfer fees
    /// @param account the address to exclude from transfer fees
    /// @dev this function can only be called by the owner
    function excludeFromFee(address account) public onlyRole(FEE_ROLE) {
        require(account != address(0), "excludeFromFee: ZERO");
        require(!_isExcludedFromFee[account], "Account is already excluded");
        _isExcludedFromFee[account] = true;
        emit AuditLog("We have Updated the excludeFromFee:", account);
    }

    /// @notice includes an address in transfer fees
    /// @param account the address to include in transfer fees
    /// @dev this function can only be called by the owner
    function includeInFee(address account) public onlyRole(FEE_ROLE) {
        require(account != address(0), "includeInFee: ZERO");
        require(_isExcludedFromFee[account], "Account is already included");
        _isExcludedFromFee[account] = false;
        emit AuditLog("We have Updated the includeInFee:", account);
    }

    /// @notice sets the marketing wallet address
    /// @param walletAddress the address of the new marketing wallet
    /// @dev this function can only be called by the owner
    function setMarketingWallet(
        address walletAddress
    ) public onlyRole(WALLET_ROLE) {
        require(walletAddress != address(0), "mkWallet: ZERO");
        marketingWallet = walletAddress;
        emit AuditLog("We have Updated the setMarketingWallet:", walletAddress);
    }

    /// @notice sets the antiquities Wallet address
    /// @param walletAddress the address of the new antiquities wallet
    /// @dev this function can only be called by the owner
    function setAntiquitiesWallet(
        address walletAddress
    ) public onlyRole(WALLET_ROLE) {
        require(walletAddress != address(0), "antiqueWallet: ZERO");
        antiquitiesWallet = walletAddress;
        emit AuditLog(
            "We have Updated the setAntiquitiesWallet:",
            walletAddress
        );
    }

    /// @notice sets the gas Wallet address
    /// @param walletAddress the address of the new gas wallet
    /// @dev this function can only be called by the owner
    function setGasWallet(address walletAddress) public onlyRole(WALLET_ROLE) {
        require(walletAddress != address(0), "gasWallet: ZERO");
        gasWallet = walletAddress;
        emit AuditLog("We have Updated the gasWallet:", walletAddress);
    }

    /// @notice sets the Maximum transaction token transfer limit
    /// @param amount the amount of tokens to set the maximum transaction limit to
    /// @dev this function can only be called by the owner, the amount must be greater than 0.5% of the total supply
    function setMaxTxAmount(uint256 amount) external onlyRole(MAX_ROLE) {
        require(
            amount >= ((totalSupply() * 5) / (1000 * 1 gwei)),
            "ERR: max tx amount should exceed 0.5% of the supply"
        );
        _maxTxAmount = amount * 10 ** 9;
        emit Log("New Max Transfer Amount:", amount);
    }

    /// @notice sends any stuck ETH balance to the marketing wallet
    /// @dev No matter who calls this function, it always is allocated to marketing wallet
    function clearStuckBalance() public {
        uint256 balance = address(this).balance;
        (bool succ, ) = payable(marketingWallet).call{value: balance}("");
        require(succ, "Transfer failed.");
    }

    /// @notice implementation of Context msgSender
    /// @return the sender of the transaction
    /// @dev this is mostly for the lossless and gasless stuff
    function _msgSender()
        internal
        view
        override(Context, ERC2771Context)
        returns (address)
    {
        return ERC2771Context._msgSender();
    }

    /// @notice implementation of Context msgData
    /// @return the data of the transaction
    /// @dev this is mostly for the lossless and gasless stuff
    function _msgData()
        internal
        view
        override(Context, ERC2771Context)
        returns (bytes calldata)
    {
        return ERC2771Context._msgData();
    }

    /// @notice this function is just to add a usecase to the _msgData function that needed to be rewritten here.
    function getMsgData() external view returns (bytes calldata) {
        return _msgData();
    }

    /// @notice claim ERC20 tokens sent to this contract
    /// @param tokenAddress the address of the ERC20 token to claim
    /// @dev no matter who calls this function, funds are always sent to marketing wallet
    function claimERCtokens(IERC20 tokenAddress) external {
        try
            tokenAddress.transfer(
                marketingWallet,
                tokenAddress.balanceOf(address(this))
            )
        {} catch {
            revert("Transfer failed.");
        }
    }

    /// @notice add a bot wallet to stop from trading and selling
    /// @param botwallet the address of the bot wallet to add
    /// @dev this function can only be called by the owner
    function addBotWallet(address botwallet) external onlyRole(BOT_ROLE) {
        require(botwallet != rareSwapPair, "Cannot add pair as a bot");
        require(botwallet != address(this), "Cannot add CA as a bot");
        if (owner() != address(0))
            require(botwallet != owner(), "Owner not bot");
        require(botwallet != depWallet, "Dep not bot");
        require(botwallet != marketingWallet, "Dep not bot");
        require(botwallet != antiquitiesWallet, "Dep not bot");
        require(botwallet != gasWallet, "Dep not bot");
        botWallets[botwallet] = true;
    }

    /// @notice remove a wallet from being a bot
    /// @param botwallet the address of the bot wallet to remove
    /// @dev this function can only be called by the owner
    function removeBotWallet(address botwallet) external onlyRole(BOT_ROLE) {
        botWallets[botwallet] = false;
    }

    /// @notice check if a wallet is a bot
    /// @param botwallet the address of the bot wallet to check
    /// @return true if the wallet is a bot, false otherwise
    function getBotWalletStatus(address botwallet) public view returns (bool) {
        return botWallets[botwallet];
    }

    /// @notice Enables trading for the contract
    /// @dev this function can only be called by the owner and once called, trading cannot be stopped
    function enableTrading() external onlyOwner {
        canTrade = true;
    }

    /// @notice Set the new tax amounts
    /// @param _reflectionTaxBPS the amount of tax to be taken for reflections
    /// @param _marketingTaxBPS the amount of tax to be taken for marketing
    /// @param _antiquitiesTaxBPS the amount of tax to be taken for antiquities
    /// @param _gasTaxBPS the amount of tax to be taken for gas
    /// @dev this function can only be called by the owner, max totalTax is 15%, marketing + antiquities + gas tax must be over 1%
    function setFees(
        uint256 _reflectionTaxBPS,
        uint256 _marketingTaxBPS,
        uint256 _antiquitiesTaxBPS,
        uint256 _gasTaxBPS
    ) public onlyRole(FEE_ROLE) {
        _taxFee = _reflectionTaxBPS;
        _marketingFee = _marketingTaxBPS;
        _antiquitiesFee = _antiquitiesTaxBPS;
        _gasFee = _gasTaxBPS;

        _totalTax = _taxFee + _marketingFee + _antiquitiesFee + _gasFee;
        require(_totalTax <= MAX_TAX, "total tax cannot exceed 15%");
        require(
            (_marketingFee + _antiquitiesFee + _gasFee) >= MIN_TAX,
            "ERR: marketing + antiquities + gas tax must be over 1%"
        );

        _updatePairsFee(_marketingFee + _antiquitiesFee + _gasFee);
    }

    //to recieve ETH from uniswapV2Router when swaping
    receive() external payable {}

    /// @notice distributes reflection fee
    /// @param rFee the fee to be distributed
    /// @param tFee the fee to be added to the counter
    function _reflectFee(uint256 rFee, uint256 tFee) private {
        _rTotal = _rTotal - rFee;
        _tFeeTotal = _tFeeTotal + tFee;
    }

    /// @notice calculates the transfer values
    /// @param tAmount the amount of tokens to be transferred
    /// @return rAmount the total amount of reflections to be transferred
    /// @return rTransferAmount the amount of reflections to be transferred after tax
    /// @return rFee the tax fee to be reflected
    /// @return tTransferAmount the amount of tokens to be transferred after tax
    /// @return tFee the amount of tokens to be taxed
    function _getValues(
        uint256 tAmount
    )
        private
        view
        returns (
            uint256 rAmount,
            uint256 rTransferAmount,
            uint256 rFee,
            uint256 tTransferAmount,
            uint256 tFee
        )
    {
        (tFee, tTransferAmount) = _getTValues(tAmount);
        (rAmount, rTransferAmount, rFee) = _getRValues(
            tAmount,
            tFee,
            _getRate()
        );
        return (rAmount, rTransferAmount, rFee, tTransferAmount, tFee);
    }

    /// @notice calculates the tax fee
    /// @param tAmount the amount of tokens to be taxed
    /// @return tFee the amount of tokens to be taxed
    /// @return tTransferAmount the amount of tokens to be transferred after tax
    function _getTValues(
        uint256 tAmount
    ) private view returns (uint256 tFee, uint256 tTransferAmount) {
        tFee = calculateTaxFee(tAmount);
        tTransferAmount = tAmount - tFee;
    }

    /// @notice calculates the reflection coefficient and fee
    /// @param tAmount the amount of tokens to be taxed
    /// @param tFee the amount of tokens to be taxed in total
    /// @param currentRate the current rate of reflections
    /// @return rAmount the total amount of reflections to be transferred
    /// @return rTransferAmount the amount of reflections to be transferred after tax
    /// @return rFee the tax fee to be reflected
    function _getRValues(
        uint256 tAmount,
        uint256 tFee,
        uint256 currentRate
    )
        private
        pure
        returns (uint256 rAmount, uint256 rTransferAmount, uint256 rFee)
    {
        rAmount = tAmount * currentRate;
        rFee = tFee * currentRate;
        rTransferAmount = rAmount - rFee;
    }

    /// @notice calculates the current reflection rate
    /// @return the current reflection rate based on the supply of reflections and tokens
    function _getRate() private view returns (uint256) {
        (uint256 rSupply, uint256 tSupply) = _getCurrentSupply();
        return rSupply / tSupply;
    }

    /// @notice calculates the current supply of reflections and tokens
    /// @return rSupply the current supply of reflections
    /// @return tSupply the current supply of tokens
    /// @dev this function removes all excluded value amounts from the supply
    function _getCurrentSupply() private view returns (uint256, uint256) {
        return supplyCalc(_rTotal, _tTotal, excludedR, excludedT);
    }

    function supplyCalc(
        uint rSupply,
        uint tSupply,
        uint rExcluded,
        uint tExcluded
    ) public pure returns (uint, uint) {
        if (rExcluded > rSupply || tExcluded > tSupply)
            return (rSupply, tSupply);

        uint rSupplyCalc = rSupply - rExcluded;
        uint tSupplyCalc = tSupply - tExcluded;

        if (rSupplyCalc < rSupply / tSupply) return (rSupply, tSupply);
        return (rSupplyCalc, tSupplyCalc);
    }

    /// @notice calculates the tax fee
    /// @param _amount the amount of tokens to be taxed
    /// @return the amount of tokens to be taxed
    function calculateTaxFee(uint256 _amount) private view returns (uint256) {
        return (_amount * _taxFee) / TAX_DIVISOR;
    }

    /// @notice remove all fees
    function removeAllFee() private {
        if (_taxFee == 0) return;
        _previousTaxFee = _taxFee;
        _taxFee = 0;
    }

    /// @notice restore all fees
    function restoreAllFee() private {
        _taxFee = _previousTaxFee;
    }

    /// @notice checks the exclusion status of an account
    function isExcludedFromFee(address account) public view returns (bool) {
        return _isExcludedFromFee[account];
    }

    /// @notice Sets the allowance to a specific value
    /// @param _owner the owner of the allowance
    /// @param spender the spender of the allowance
    /// @param amount the amount of allowance
    function _approve(address _owner, address spender, uint256 amount) private {
        require(_owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[_owner][spender] = amount;
        emit Approval(_owner, spender, amount);
    }

    /// @notice transfers tokens from one account to another
    /// @param from the account to transfer from
    /// @param to the account to transfer to
    /// @param amount the amount of tokens to transfer
    /// @dev this is the first step where all checks occur before transfer is executed
    function _transfer(address from, address to, uint256 amount) private {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");
        if (from != owner() && to != owner())
            require(
                amount <= _maxTxAmount,
                "Transfer amount exceeds the maxTxAmount."
            );

        if (from == rareSwapPair && to != depWallet) {
            require(balanceOf(to) + amount <= _maxWallet, "check max wallet");
        }

        //indicates if fee should be deducted from transfer
        bool takeFee = true;

        //if any account belongs to _isExcludedFromFee account then remove the fee
        if (_isExcludedFromFee[from] || _isExcludedFromFee[to]) {
            takeFee = false;
        }

        //transfer amount, it will take tax, burn, liquidity fee
        _tokenTransfer(from, to, amount, takeFee);
    }

    /// @notice transfers tokens from one account to another checks for bots and calculates trade amounts and tax fees
    /// @param sender the account to transfer from
    /// @param recipient the account to transfer to
    /// @param amount the amount of tokens to transfer
    /// @param takeFee indicates if fee should be deducted from transfer
    function _tokenTransfer(
        address sender,
        address recipient,
        uint256 amount,
        bool takeFee
    ) private {
        if (!canTrade) {
            require(sender == owner(), "Trade disabled"); // only owner allowed to trade or add liquidity
        }

        if (botWallets[sender] || botWallets[recipient]) {
            revert("bots arent allowed to trade");
        }

        if (!takeFee) removeAllFee();

        bool fromExcluded = _isExcluded[sender];
        bool toExcluded = _isExcluded[recipient];

        {
            (
                uint256 rAmount,
                uint256 rTransferAmount,
                uint256 rFee,
                uint256 tTransferAmount,
                uint256 tFee
            ) = _getValues(amount);

            _rOwned[sender] -= rAmount;
            _rOwned[recipient] += rTransferAmount;

            if (fromExcluded) {
                _tOwned[sender] -= amount;
                if (toExcluded) {
                    _tOwned[recipient] += tTransferAmount;
                } else {
                    excludedR -= rAmount;
                    excludedT -= tTransferAmount;
                }
            } else {
                if (toExcluded) {
                    _tOwned[recipient] += tTransferAmount;
                    excludedR += rAmount;
                    excludedT += tTransferAmount;
                }
            }
            _reflectFee(rFee, tFee);
            emit Transfer(sender, recipient, tTransferAmount);
        }
        if (!takeFee) restoreAllFee();
    }

    /// @notice transfers tokens from the exchange to the tax receiving wallets
    /// @param amount the amount of tokens to transfer
    /// @param token the token to transfer
    /// @dev token is only on ERC20
    function depositLPFee(uint256 amount, address token) public onlyExchange {
        uint256 allowanceT = IERC20(token).allowance(msg.sender, address(this));

        if (allowanceT >= amount) {
            IERC20(token).transferFrom(msg.sender, address(this), amount); // _marketingFee + _antiquitiesFee antiquitiesWallet + _gasFee gasWallet
            // calculate individual tax amount
            uint256 marketingAmount = (amount * _marketingFee) /
                (_marketingFee + _antiquitiesFee + _gasFee);
            uint256 antiquitiesAmount = (amount * _antiquitiesFee) /
                (_marketingFee + _antiquitiesFee + _gasFee);
            uint256 gasAmount = amount - marketingAmount - antiquitiesAmount;
            // send WETH to respective wallet
            IERC20(token).transfer(marketingWallet, marketingAmount);
            IERC20(token).transfer(antiquitiesWallet, antiquitiesAmount);
            IERC20(token).transfer(gasWallet, gasAmount);
        }
    }

    /// Lossless Compliance
    /// @dev due to the nature of the implementation of lossless protocol, we need to add the following modifiers to the functions that transfer tokens
    /// @dev these will not be described as they are not part of the RAT token contract but rather the lossless protoco.
    // more information about lossless in their documentation https://docs.lossless.io/protocol/technical-reference/hack-mitigation-protocol
    modifier lssTransfer(address recipient, uint256 amount) {
        if (isLosslessOn) {
            lossless.beforeTransfer(_msgSender(), recipient, amount);
        }
        _;
    }

    modifier lssTransferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) {
        if (isLosslessOn) {
            lossless.beforeTransferFrom(
                _msgSender(),
                sender,
                recipient,
                amount
            );
        }
        _;
    }

    modifier onlyRecoveryAdmin() {
        require(
            _msgSender() == recoveryAdmin,
            "LERC20: Must be recovery admin"
        );
        _;
    }

    /**
     * @notice  Function to set the lossless controller
     *
     * @param   _controller Lossless controller address
     */
    function setLosslessController(
        address _controller
    ) public onlyRole(LOSSLESS_ROLE) {
        require(
            _controller != address(0),
            "BridgeMintableToken: Controller cannot be zero address."
        );
        require(
            _controller != address(lossless),
            "BridgeMintableToken: Cannot set same address."
        );

        lossless = ILssController(_controller);
        if (!isLosslessOn) isLosslessOn = true;
    }

    /**
     * @notice  Function to set the lossless admin that interacts with controller
     *
     * @param   newAdmin address of the new admin
     */
    function setLosslessAdmin(
        address newAdmin
    ) external onlyRole(LOSSLESS_ROLE) {
        require(newAdmin != admin, "LERC20: Cannot set same address");
        admin = newAdmin;
        emit NewAdmin(newAdmin);
    }

    /**
     * @notice  Function to propose a new recovery admin
     *
     * @param   candidate new admin proposed address
     * @param   keyHash Key to accept
     */
    function transferRecoveryAdminOwnership(
        address candidate,
        bytes32 keyHash
    ) external onlyRole(LOSSLESS_ROLE) {
        recoveryAdminCandidate = candidate;
        recoveryAdminKeyHash = keyHash;
        emit NewRecoveryAdminProposal(candidate);
    }

    /**
     * @notice  Function to accept the admin proposal
     * @param   key Key to accept
     */
    function acceptRecoveryAdminOwnership(bytes memory key) external {
        require(
            _msgSender() == recoveryAdminCandidate,
            "LERC20: Must be candidate"
        );
        require(keccak256(key) == recoveryAdminKeyHash, "LERC20: Invalid key");
        recoveryAdmin = recoveryAdminCandidate;
        recoveryAdminCandidate = address(0);
        emit NewRecoveryAdmin(recoveryAdmin);
    }

    /**
     * @notice  Function to retrieve the funds of a blacklisted address.
     *
     * @param   from Array of addresses corresponding to a report and a second report
     */
    function transferOutBlacklistedFunds(address[] calldata from) external {
        require(
            _msgSender() == address(lossless),
            "LERC20: Only lossless contract"
        );

        uint256 fromLength = from.length;

        for (uint256 i = 0; i < fromLength; i++) {
            address fromAddress = from[i];
            uint256 fromBalance = balanceOf(fromAddress);
            // Use internal transfer function to avoid lossless checks and remove fees on this transfer
            _tokenTransfer(fromAddress, address(lossless), fromBalance, false);
        }
    }

    /**
     * @notice  Function to propose turning off everything related to lossless
     */
    function proposeLosslessTurnOff() external onlyRecoveryAdmin {
        require(
            losslessTurnOffTimestamp == 0,
            "LERC20: TurnOff already proposed"
        );
        require(isLosslessOn, "LERC20: Lossless already off");
        losslessTurnOffTimestamp = block.timestamp + timelockPeriod;
        emit LosslessTurnOffProposal(losslessTurnOffTimestamp);
    }

    /**
     * @notice  Function to execute lossless turn off after a period of time
     */
    function executeLosslessTurnOff() external onlyRecoveryAdmin {
        require(losslessTurnOffTimestamp != 0, "LERC20: TurnOff not proposed");
        require(
            losslessTurnOffTimestamp <= block.timestamp,
            "LERC20: Time lock in progress"
        );
        isLosslessOn = false;
        losslessTurnOffTimestamp = 0;
        emit LosslessOff();
    }

    /**
     * @notice  Function to turn on everything related to lossless
     */
    function executeLosslessTurnOn() external onlyRecoveryAdmin {
        require(!isLosslessOn, "LERC20: Lossless already on");
        losslessTurnOffTimestamp = 0;
        isLosslessOn = true;
        emit LosslessOn();
    }

    function getAdmin() external view returns (address) {
        return admin;
    }
}

interface ILssController {
    function beforeTransfer(
        address _msgSender,
        address _recipient,
        uint256 _amount
    ) external;

    function beforeTransferFrom(
        address _msgSender,
        address _sender,
        address _recipient,
        uint256 _amount
    ) external;

    function beforeMint(address _to, uint256 _amount) external;

    function beforeBurn(address _account, uint256 _amount) external;
}
//Blade/Semi final review and doc.

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_marketingWallet","type":"address"},{"internalType":"address","name":"_antiquitiesWallet","type":"address"},{"internalType":"address","name":"_gasWallet","type":"address"},{"internalType":"address","name":"_trustedForwarder","type":"address"},{"internalType":"address","name":"_depWallet","type":"address"},{"internalType":"address","name":"_router","type":"address"},{"internalType":"address[]","name":"adminRoles","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"string","name":"","type":"string"},{"indexed":false,"internalType":"address","name":"","type":"address"}],"name":"AuditLog","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"","type":"string"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"Log","type":"event"},{"anonymous":false,"inputs":[],"name":"LosslessOff","type":"event"},{"anonymous":false,"inputs":[],"name":"LosslessOn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_turnOffDate","type":"uint256"}],"name":"LosslessTurnOffProposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_newAdmin","type":"address"}],"name":"NewAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_newAdmin","type":"address"}],"name":"NewRecoveryAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_candidate","type":"address"}],"name":"NewRecoveryAdminProposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","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"},{"inputs":[],"name":"BOT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LOSSLESS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TAX","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_TAX","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TAX_DIVISOR","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WALLET_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_maxTxAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_maxWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_totalTax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"key","type":"bytes"}],"name":"acceptRecoveryAdminOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"botwallet","type":"address"}],"name":"addBotWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"antiquitiesWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","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":"canTrade","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"tokenAddress","type":"address"}],"name":"claimERCtokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"clearStuckBalance","outputs":[],"stateMutability":"nonpayable","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":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tAmount","type":"uint256"}],"name":"deliver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"name":"depositLPFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableTrading","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"excludeFromFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"excludeFromReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"executeLosslessTurnOff","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"executeLosslessTurnOn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gasWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"botwallet","type":"address"}],"name":"getBotWalletStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMsgData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"includeInFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromReward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isLosslessOn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"isTrustedForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lossless","outputs":[{"internalType":"contract ILssController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"losslessTurnOffTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketingWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"proposeLosslessTurnOff","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rareSwapPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rareSwapRouter","outputs":[{"internalType":"contract IRARESwapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"recoveryAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tAmount","type":"uint256"},{"internalType":"bool","name":"deductTransferFee","type":"bool"}],"name":"reflectionFromToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"botwallet","type":"address"}],"name":"removeBotWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"walletAddress","type":"address"}],"name":"setAntiquitiesWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_reflectionTaxBPS","type":"uint256"},{"internalType":"uint256","name":"_marketingTaxBPS","type":"uint256"},{"internalType":"uint256","name":"_antiquitiesTaxBPS","type":"uint256"},{"internalType":"uint256","name":"_gasTaxBPS","type":"uint256"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"walletAddress","type":"address"}],"name":"setGasWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"setLosslessAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"name":"setLosslessController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"walletAddress","type":"address"}],"name":"setMarketingWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMaxTxAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMaxWalletAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rSupply","type":"uint256"},{"internalType":"uint256","name":"tSupply","type":"uint256"},{"internalType":"uint256","name":"rExcluded","type":"uint256"},{"internalType":"uint256","name":"tExcluded","type":"uint256"}],"name":"supplyCalc","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timelockPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"rAmount","type":"uint256"}],"name":"tokenFromReflection","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"from","type":"address[]"}],"name":"transferOutBlacklistedFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"candidate","type":"address"},{"internalType":"bytes32","name":"keyHash","type":"bytes32"}],"name":"transferRecoveryAdminOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

610120604052600d805460ff19169055681b1ae4d6e2ef500000600e8190556200002c9060001962000bd0565b6200003a9060001962000bfd565b600f55606460115560115460125560135460145560c860155561012c601655606460175560175460165460155460115462000076919062000c13565b62000082919062000c13565b6200008e919062000c13565b601855681b1ae4d6e2ef500000601955674563918244f40000601a5562278d00601f556021805460ff19169055348015620000c857600080fd5b506040516200526238038062005262833981016040819052620000eb9162000c5c565b6001600160a01b0384166080526200010c6200010662000732565b6200074e565b600f54600260006200011d62000732565b6001600160a01b03166001600160a01b0316815260200190815260200160002081905550600e5460036000620001586200073260201b60201c565b6001600160a01b039081168252602080830193909352604091820160002093909355600880546001600160a01b03199081168c8616179091556009805482168b8616179055600a805490911689851617905591841660e081905282516315ab88c960e31b81529251909263ad5c46489260048083019391928290030181865afa158015620001ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000210919062000da1565b6001600160a01b031660a0816001600160a01b03168152505060e0516001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000290919062000da1565b60a0516040516364e329cb60e11b81523060048201526001600160a01b03918216602482015291169063c9c65396906044016020604051808303816000875af1158015620002e2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000308919062000da1565b6001600160a01b0390811661010081905260a0516040516316bb6c1360e01b815292166004830152906316bb6c1390602401600060405180830381600087803b1580156200035557600080fd5b505af192505050801562000367575060015b156200040757610100516001600160a01b031663d32b960460175460165460155462000394919062000c13565b620003a0919062000c13565b6040518263ffffffff1660e01b8152600401620003bf91815260200190565b6020604051808303816000875af1158015620003df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000405919062000dbf565b505b6001600160a01b03831660c0526001600560006200042d6001546001600160a01b031690565b6001600160a01b03908116825260208083019390935260409182016000908120805495151560ff1996871617905530808252600590945282812080548616600190811790915560c051831682528382208054871682179055600a54831682528382208054871682179055600854831682528382208054871682179055600954909216815291909120805490931617909155620004c990620007a0565b60c051620004d790620007a0565b600a54620004ee906001600160a01b0316620007a0565b60085462000505906001600160a01b0316620007a0565b6009546200051c906001600160a01b0316620007a0565b610100516200052b90620007a0565b60e0516200053990620007a0565b8051600514620005905760405162461bcd60e51b815260206004820152601860248201527f4552523a20494e56414c49445f41444d494e5f524f4c4553000000000000000060448201526064015b60405180910390fd5b620005df7fa42787877dd247913f847bc654d767d1919585674d8f1a26ea00084043233daa82600081518110620005cb57620005cb62000de3565b6020026020010151620008f060201b60201c565b6200061a7f353ade2f164e14105123d6ee399d29e979120b2f7a3852f8d1854ece00e1d07282600181518110620005cb57620005cb62000de3565b620006557f607744c37698f0ad2c7e8b300d57eaef2f987ccbb958ce7cd316a2c3e663f9ec82600281518110620005cb57620005cb62000de3565b620006907f9dffd71004dfaab55bf910c5a0672e6384235f73ad747a585d74609cf1ce97be82600381518110620005cb57620005cb62000de3565b620006cb7f902cbe3a02736af9827fb6a90bada39e955c0941e08f0c63b3a662a7b17a4e2b82600481518110620005cb57620005cb62000de3565b620006d562000732565b6001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600e546040516200071d91815260200190565b60405180910390a35050505050505062000e10565b6000620007496200097b60201b620030c41760201c565b905090565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b620007aa620009b3565b6001600160a01b03811660009081526006602052604090205460ff1615620008155760405162461bcd60e51b815260206004820152601b60248201527f4163636f756e7420697320616c7265616479206578636c756465640000000000604482015260640162000587565b6001600160a01b0381166000908152600260205260409020541562000872576001600160a01b038116600090815260026020526040902054620008589062000a33565b6001600160a01b0382166000908152600360205260409020555b6001600160a01b0381166000908152600660209081526040808320805460ff191660011790556003909152812054600b805491929091620008b590849062000c13565b90915550506001600160a01b038116600090815260026020526040812054600c805491929091620008e890849062000c13565b909155505050565b620008fc828262000acb565b62000977576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556200093662000732565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6080516000906001600160a01b031633036200099e575060131936013560601c90565b6200074962000af660201b620030eb1760201c565b620009bd62000732565b6001600160a01b0316620009d96001546001600160a01b031690565b6001600160a01b03161462000a315760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000587565b565b6000600f5482111562000a9c5760405162461bcd60e51b815260206004820152602a60248201527f416d6f756e74206d757374206265206c657373207468616e20746f74616c207260448201526965666c656374696f6e7360b01b606482015260840162000587565b600062000aa862000afa565b9050801562000ac45762000abd818462000df9565b9392505050565b5090919050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff165b92915050565b3390565b6000808062000b0862000b20565b909250905062000b19818362000df9565b9250505090565b60008062000b3f600f54600e54600c54600b5462000b4760201b60201c565b915091509091565b6000808584118062000b5857508483115b1562000b6957508490508362000bb1565b600062000b77858862000bfd565b9050600062000b87858862000bfd565b905062000b95878962000df9565b82101562000bab57878793509350505062000bb1565b90925090505b94509492505050565b634e487b7160e01b600052601260045260246000fd5b60008262000be25762000be262000bba565b500690565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000af05762000af062000be7565b8082018082111562000af05762000af062000be7565b80516001600160a01b038116811462000c4157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600080600080600080600060e0888a03121562000c7857600080fd5b62000c838862000c29565b9650602062000c94818a0162000c29565b965062000ca460408a0162000c29565b955062000cb460608a0162000c29565b945062000cc460808a0162000c29565b935062000cd460a08a0162000c29565b60c08a01519093506001600160401b038082111562000cf257600080fd5b818b0191508b601f83011262000d0757600080fd5b81518181111562000d1c5762000d1c62000c46565b8060051b604051601f19603f8301168101818110858211171562000d445762000d4462000c46565b60405291825284820192508381018501918e83111562000d6357600080fd5b938501935b8285101562000d8c5762000d7c8562000c29565b8452938501939285019262000d68565b80965050505050505092959891949750929550565b60006020828403121562000db457600080fd5b62000abd8262000c29565b60006020828403121562000dd257600080fd5b8151801515811462000abd57600080fd5b634e487b7160e01b600052603260045260246000fd5b60008262000e0b5762000e0b62000bba565b500490565b60805160a05160c05160e051610100516143dc62000e8660003960008181610a590152818161136e015281816121a90152818161338a015261369f015260008181610f3d01526121de01526000818161054e015281816114be01526133c601526000610c8801526000611df201526143dc6000f3fe6080604052600436106104775760003560e01c8063715018a61161024a578063ad5c464811610139578063dd62ed3e116100b6578063ea2f0b371161007a578063ea2f0b3714610eab578063ec28438a14610ecb578063f2fde38b14610eeb578063f851a44014610f0b578063ff64821e14610f2b57600080fd5b8063dd62ed3e14610dee578063e2d6649a14610e34578063e34420b414610e49578063e45c17e114610e69578063e97e5bae14610e8957600080fd5b8063c8e7ca2e116100fd578063c8e7ca2e14610d48578063ccfa214f14610d6b578063d24f19d514610d85578063d547741f14610db9578063d6e242b814610dd957600080fd5b8063ad5c464814610c76578063b150377414610caa578063b38fe95714610cde578063b414cae914610cf3578063b5c2287714610d2857600080fd5b80638e8ecaff116101c7578063a1ca53471161018b578063a1ca534714610bf5578063a217fddf14610c0b578063a335d4ff14610c20578063a457c2d714610c36578063a9059cbb14610c5657600080fd5b80638e8ecaff14610b4657806391d1485414610b6657806393310ffe14610b86578063936af91114610ba657806395d89b4114610bc657600080fd5b80638283bbf31161020e5780638283bbf314610a9157806386a35f2514610ab157806388f8202014610ada5780638a8c523c14610b135780638da5cb5b14610b2857600080fd5b8063715018a6146109fc57806375f0a87414610a115780637d1db4a514610a315780637d35aa9314610a4757806382247ec014610a7b57600080fd5b8063364333f4116103665780635342acb4116102e357806360d48489116102a757806360d484891461094f57806361086b00146109885780636e9960c31461099e5780636fcba377146109bc57806370a08231146109dc57600080fd5b80635342acb4146108a1578063572b6c05146108da5780635b8a194a146108fa5780635d098b381461090f5780635f6529a31461092f57600080fd5b806342d59d271161032a57806342d59d27146107ff578063437823ec146108215780634549b0391461084157806352390c021461086157806352e199c51461088157600080fd5b8063364333f41461076a57806336568abe1461077f578063395093511461079f5780633951709c146107bf5780633bd5d173146107df57600080fd5b806327a14fc2116103f45780632ecaf675116103b85780632ecaf675146106ce5780632f05205c146106e45780632f2ff15d146106fe578063313ce5671461071e57806334f6ebf51461074557600080fd5b806327a14fc21461062c5780632a0276f81461064c5780632a3606311461066e5780632baa3c9e1461068e5780632d838119146106ae57600080fd5b80631080afd51161043b5780631080afd51461058857806313114a9d146105a857806318160ddd146105c757806323b872dd146105dc578063248a9ca3146105fc57600080fd5b806301ffc9a7146104835780630305caff146104b857806306fdde03146104da578063095ea7b31461051c5780630ffd3dfb1461053c57600080fd5b3661047e57005b600080fd5b34801561048f57600080fd5b506104a361049e366004613dd3565b610f5f565b60405190151581526020015b60405180910390f35b3480156104c457600080fd5b506104d86104d3366004613e12565b610f96565b005b3480156104e657600080fd5b5061050f6040518060400160405280600981526020016814985c9948119a539160ba1b81525081565b6040516104af9190613e53565b34801561052857600080fd5b506104a3610537366004613e86565b610fe2565b34801561054857600080fd5b506105707f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016104af565b34801561059457600080fd5b506104d86105a3366004613e12565b610fff565b3480156105b457600080fd5b506010545b6040519081526020016104af565b3480156105d357600080fd5b50600e546105b9565b3480156105e857600080fd5b506104a36105f7366004613eb2565b6110f6565b34801561060857600080fd5b506105b9610617366004613ef3565b60009081526020819052604090206001015490565b34801561063857600080fd5b506104d8610647366004613ef3565b61120f565b34801561065857600080fd5b506105b960008051602061436783398151915281565b34801561067a57600080fd5b506104d8610689366004613e12565b611342565b34801561069a57600080fd5b506104d86106a9366004613e12565b6115bc565b3480156106ba57600080fd5b506105b96106c9366004613ef3565b61167d565b3480156106da57600080fd5b506105b9601f5481565b3480156106f057600080fd5b50600d546104a39060ff1681565b34801561070a57600080fd5b506104d8610719366004613f0c565b61170e565b34801561072a57600080fd5b50610733600981565b60405160ff90911681526020016104af565b34801561075157600080fd5b506021546105709061010090046001600160a01b031681565b34801561077657600080fd5b506104d8611738565b34801561078b57600080fd5b506104d861079a366004613f0c565b6117d6565b3480156107ab57600080fd5b506104a36107ba366004613e86565b611860565b3480156107cb57600080fd5b506104d86107da366004613e12565b6118af565b3480156107eb57600080fd5b506104d86107fa366004613ef3565b6119cf565b34801561080b57600080fd5b506105b960008051602061432783398151915281565b34801561082d57600080fd5b506104d861083c366004613e12565b611ad0565b34801561084d57600080fd5b506105b961085c366004613f4a565b611c2e565b34801561086d57600080fd5b506104d861087c366004613e12565b611cab565b34801561088d57600080fd5b50600a54610570906001600160a01b031681565b3480156108ad57600080fd5b506104a36108bc366004613e12565b6001600160a01b031660009081526005602052604090205460ff1690565b3480156108e657600080fd5b506104a36108f5366004613e12565b611df0565b34801561090657600080fd5b506104d8611e22565b34801561091b57600080fd5b506104d861092a366004613e12565b611eec565b34801561093b57600080fd5b50601c54610570906001600160a01b031681565b34801561095b57600080fd5b506104a361096a366004613e12565b6001600160a01b031660009081526007602052604090205460ff1690565b34801561099457600080fd5b506105b960205481565b3480156109aa57600080fd5b50601b546001600160a01b0316610570565b3480156109c857600080fd5b506104d86109d7366004613f6f565b611fcf565b3480156109e857600080fd5b506105b96109f7366004613e12565b61212a565b348015610a0857600080fd5b506104d8612189565b348015610a1d57600080fd5b50600854610570906001600160a01b031681565b348015610a3d57600080fd5b506105b960195481565b348015610a5357600080fd5b506105707f000000000000000000000000000000000000000000000000000000000000000081565b348015610a8757600080fd5b506105b9601a5481565b348015610a9d57600080fd5b506104d8610aac366004613f0c565b61219d565b348015610abd57600080fd5b50610ac76105dc81565b60405161ffff90911681526020016104af565b348015610ae657600080fd5b506104a3610af5366004613e12565b6001600160a01b031660009081526006602052604090205460ff1690565b348015610b1f57600080fd5b506104d8612534565b348015610b3457600080fd5b506001546001600160a01b0316610570565b348015610b5257600080fd5b506104d8610b61366004613e12565b61254b565b348015610b7257600080fd5b506104a3610b81366004613f0c565b612698565b348015610b9257600080fd5b506104d8610ba1366004613e86565b6126c1565b348015610bb257600080fd5b506104d8610bc1366004613fa1565b61272a565b348015610bd257600080fd5b5061050f6040518060400160405280600381526020016211939160ea1b81525081565b348015610c0157600080fd5b506105b960185481565b348015610c1757600080fd5b506105b9600081565b348015610c2c57600080fd5b50610ac761271081565b348015610c4257600080fd5b506104a3610c51366004613e86565b612814565b348015610c6257600080fd5b506104a3610c71366004613e86565b612863565b348015610c8257600080fd5b506105707f000000000000000000000000000000000000000000000000000000000000000081565b348015610cb657600080fd5b506105b97f902cbe3a02736af9827fb6a90bada39e955c0941e08f0c63b3a662a7b17a4e2b81565b348015610cea57600080fd5b506104d8612919565b348015610cff57600080fd5b50610d13610d0e366004613f6f565b612a31565b604080519283526020830191909152016104af565b348015610d3457600080fd5b506104d8610d4336600461402c565b612a99565b348015610d5457600080fd5b50610d5d612ba5565b6040516104af9291906140dd565b348015610d7757600080fd5b506021546104a39060ff1681565b348015610d9157600080fd5b506105b97fa42787877dd247913f847bc654d767d1919585674d8f1a26ea00084043233daa81565b348015610dc557600080fd5b506104d8610dd4366004613f0c565b612bb8565b348015610de557600080fd5b506104d8612bdd565b348015610dfa57600080fd5b506105b9610e0936600461410c565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205490565b348015610e4057600080fd5b50610ac7606481565b348015610e5557600080fd5b50600954610570906001600160a01b031681565b348015610e7557600080fd5b506104d8610e84366004613e12565b612cfe565b348015610e9557600080fd5b506105b960008051602061438783398151915281565b348015610eb757600080fd5b506104d8610ec6366004613e12565b612dd2565b348015610ed757600080fd5b506104d8610ee6366004613ef3565b612f1d565b348015610ef757600080fd5b506104d8610f06366004613e12565b61304e565b348015610f1757600080fd5b50601b54610570906001600160a01b031681565b348015610f3757600080fd5b506105707f000000000000000000000000000000000000000000000000000000000000000081565b60006001600160e01b03198216637965db0b60e01b1480610f9057506301ffc9a760e01b6001600160e01b03198316145b92915050565b7f902cbe3a02736af9827fb6a90bada39e955c0941e08f0c63b3a662a7b17a4e2b610fc0816130ef565b506001600160a01b03166000908152600760205260409020805460ff19169055565b6000610ff6610fef613100565b848461310a565b50600192915050565b600080516020614327833981519152611017816130ef565b6001600160a01b0382166110685760405162461bcd60e51b8152602060048201526013602482015272616e746971756557616c6c65743a205a45524f60681b60448201526064015b60405180910390fd5b600980546001600160a01b0319166001600160a01b038416908117909155604080518181526029918101919091527f5765206861766520557064617465642074686520736574416e7469717569746960608201526832b9abb0b63632ba1d60b91b608082015260208101919091526000805160206143478339815191529060a0015b60405180910390a15050565b60215460009084908490849060ff16156111995760215461010090046001600160a01b031663379f5c69611128613100565b6040516001600160e01b031960e084901b1681526001600160a01b0391821660048201528187166024820152908516604482015260648101849052608401600060405180830381600087803b15801561118057600080fd5b505af1158015611194573d6000803e3d6000fd5b505050505b6111a487878761322e565b611202876111b0613100565b6001600160a01b038a16600090815260046020526040812089916111d2613100565b6001600160a01b03166001600160a01b03168152602001908152602001600020546111fd9190614150565b61310a565b5060019695505050505050565b7fa42787877dd247913f847bc654d767d1919585674d8f1a26ea00084043233daa611239816130ef565b64e8d4a51000611248600e5490565b611253906005614163565b61125d919061417a565b82116112d15760405162461bcd60e51b815260206004820152603760248201527f4552523a206d61782077616c6c657420616d6f756e742073686f756c6420657860448201527f6365656420302e3525206f662074686520737570706c79000000000000000000606482015260840161105f565b6112df82633b9aca00614163565b601a5560408051818152601691810191909152752732bb9036b0bc103bb0b63632ba1030b6b7bab73a1d60511b6060820152602081018390527fdd970dd9b5bfe707922155b058a407655cb18288b807e2216442bca8ad83d6b5906080016110ea565b7f902cbe3a02736af9827fb6a90bada39e955c0941e08f0c63b3a662a7b17a4e2b61136c816130ef565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316036113ed5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f74206164642070616972206173206120626f740000000000000000604482015260640161105f565b306001600160a01b0383160361143e5760405162461bcd60e51b815260206004820152601660248201527510d85b9b9bdd081859190810d048185cc81848189bdd60521b604482015260640161105f565b60006114526001546001600160a01b031690565b6001600160a01b0316146114bc576001546001600160a01b03166001600160a01b0316826001600160a01b0316036114bc5760405162461bcd60e51b815260206004820152600d60248201526c13dddb995c881b9bdd08189bdd609a1b604482015260640161105f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03160361150d5760405162461bcd60e51b815260040161105f9061419c565b6008546001600160a01b039081169083160361153b5760405162461bcd60e51b815260040161105f9061419c565b6009546001600160a01b03908116908316036115695760405162461bcd60e51b815260040161105f9061419c565b600a546001600160a01b03908116908316036115975760405162461bcd60e51b815260040161105f9061419c565b506001600160a01b03166000908152600760205260409020805460ff19166001179055565b6000805160206143878339815191526115d4816130ef565b601b546001600160a01b03908116908316036116325760405162461bcd60e51b815260206004820152601f60248201527f4c45524332303a2043616e6e6f74207365742073616d65206164647265737300604482015260640161105f565b601b80546001600160a01b0319166001600160a01b0384169081179091556040517f71614071b88dee5e0b2ae578a9dd7b2ebbe9ae832ba419dc0242cd065a290b6c90600090a25050565b6000600f548211156116e45760405162461bcd60e51b815260206004820152602a60248201527f416d6f756e74206d757374206265206c657373207468616e20746f74616c207260448201526965666c656374696f6e7360b01b606482015260840161105f565b60006116ee6134af565b9050801561170757611700818461417a565b9392505050565b5090919050565b600082815260208190526040902060010154611729816130ef565b61173383836134d2565b505050565b60085460405147916000916001600160a01b039091169083908381818185875af1925050503d8060008114611789576040519150601f19603f3d011682016040523d82523d6000602084013e61178e565b606091505b50509050806117d25760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b604482015260640161105f565b5050565b6117de613100565b6001600160a01b0316816001600160a01b0316146118565760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b606482015260840161105f565b6117d28282613557565b6000610ff661186d613100565b84846004600061187b613100565b6001600160a01b03908116825260208083019390935260409182016000908120918b16815292529020546111fd91906141c1565b6008546040516370a0823160e01b81523060048201526001600160a01b038381169263a9059cbb9291169083906370a0823190602401602060405180830381865afa158015611902573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192691906141d4565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af192505050801561198d575060408051601f3d908101601f1916820190925261198a918101906141ed565b60015b6117d25760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b604482015260640161105f565b50565b60006119d9613100565b6001600160a01b03811660009081526006602052604090205490915060ff1615611a5a5760405162461bcd60e51b815260206004820152602c60248201527f4578636c75646564206164647265737365732063616e6e6f742063616c6c207460448201526b3434b990333ab731ba34b7b760a11b606482015260840161105f565b6000611a65836135da565b5050506001600160a01b038416600090815260026020526040902054919250611a9091839150614150565b6001600160a01b038316600090815260026020526040902055600f54611ab7908290614150565b600f55601054611ac89084906141c1565b601055505050565b600080516020614367833981519152611ae8816130ef565b6001600160a01b038216611b355760405162461bcd60e51b81526020600482015260146024820152736578636c75646546726f6d4665653a205a45524f60601b604482015260640161105f565b6001600160a01b03821660009081526005602052604090205460ff1615611b9e5760405162461bcd60e51b815260206004820152601b60248201527f4163636f756e7420697320616c7265616479206578636c756465640000000000604482015260640161105f565b6001600160a01b03821660009081526005602052604090819020805460ff1916600117905551600080516020614347833981519152906110ea90849060408082526023908201527f57652068617665205570646174656420746865206578636c75646546726f6d4660608201526232b29d60e91b60808201526001600160a01b0391909116602082015260a00190565b6000600e54831115611c825760405162461bcd60e51b815260206004820152601f60248201527f416d6f756e74206d757374206265206c657373207468616e20737570706c7900604482015260640161105f565b600080611c8e856135da565b5050509150915083611ca05781611ca2565b805b95945050505050565b611cb3613610565b6001600160a01b03811660009081526006602052604090205460ff1615611d1c5760405162461bcd60e51b815260206004820152601b60248201527f4163636f756e7420697320616c7265616479206578636c756465640000000000604482015260640161105f565b6001600160a01b03811660009081526002602052604090205415611d76576001600160a01b038116600090815260026020526040902054611d5c9061167d565b6001600160a01b0382166000908152600360205260409020555b6001600160a01b0381166000908152600660209081526040808320805460ff191660011790556003909152812054600b805491929091611db79084906141c1565b90915550506001600160a01b038116600090815260026020526040812054600c805491929091611de89084906141c1565b909155505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0390811691161490565b601c546001600160a01b0316611e36613100565b6001600160a01b031614611e5c5760405162461bcd60e51b815260040161105f9061420a565b60215460ff1615611eaf5760405162461bcd60e51b815260206004820152601b60248201527f4c45524332303a204c6f73736c65737320616c7265616479206f6e0000000000604482015260640161105f565b600060208190556021805460ff191660011790556040517f1ba3b66404043da8297d0b876fa6464f2cb127edfc6626308046d4503028322b9190a1565b600080516020614327833981519152611f04816130ef565b6001600160a01b038216611f4b5760405162461bcd60e51b815260206004820152600e60248201526d6d6b57616c6c65743a205a45524f60901b604482015260640161105f565b600880546001600160a01b0319166001600160a01b038416908117909155604080518181526027918101919091527f57652068617665205570646174656420746865207365744d61726b6574696e676060820152662bb0b63632ba1d60c91b608082015260208101919091526000805160206143478339815191529060a0016110ea565b600080516020614367833981519152611fe7816130ef565b6011859055601584905560168390556017829055818361200786886141c1565b61201191906141c1565b61201b91906141c1565b60188190556105dc10156120715760405162461bcd60e51b815260206004820152601b60248201527f746f74616c207461782063616e6e6f7420657863656564203135250000000000604482015260640161105f565b60175460165460155460649291612087916141c1565b61209191906141c1565b10156120fe5760405162461bcd60e51b815260206004820152603660248201527f4552523a206d61726b6574696e67202b20616e746971756974696573202b2067604482015275617320746178206d757374206265206f76657220312560501b606482015260840161105f565b61212360175460165460155461211491906141c1565b61211e91906141c1565b613689565b5050505050565b6001600160a01b03811660009081526006602052604081205460ff161561216757506001600160a01b031660009081526003602052604090205490565b6001600160a01b038216600090815260026020526040902054610f909061167d565b612191613610565b61219b600061376b565b565b60006001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633036121d3575060015b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614806122075750805b6122475760405162461bcd60e51b8152602060048201526011602482015270149054914e881393d517d0531313d5d151607a1b604482015260640161105f565b604051636eb1769f60e11b81523360048201523060248201526000906001600160a01b0384169063dd62ed3e90604401602060405180830381865afa158015612294573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122b891906141d4565b905083811061252e576040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038416906323b872dd906064016020604051808303816000875af1158015612314573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233891906141ed565b50600060175460165460155461234e91906141c1565b61235891906141c1565b6015546123659087614163565b61236f919061417a565b9050600060175460165460155461238691906141c1565b61239091906141c1565b60165461239d9088614163565b6123a7919061417a565b90506000816123b68489614150565b6123c09190614150565b60085460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810186905291925087169063a9059cbb906044016020604051808303816000875af1158015612415573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243991906141ed565b5060095460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018490529087169063a9059cbb906044016020604051808303816000875af115801561248d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124b191906141ed565b50600a5460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529087169063a9059cbb906044016020604051808303816000875af1158015612505573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061252991906141ed565b505050505b50505050565b61253c613610565b600d805460ff19166001179055565b600080516020614387833981519152612563816130ef565b6001600160a01b0382166125df5760405162461bcd60e51b815260206004820152603760248201527f4272696467654d696e7461626c65546f6b656e3a20436f6e74726f6c6c65722060448201527f63616e6e6f74206265207a65726f20616464726573732e000000000000000000606482015260840161105f565b6021546001600160a01b036101009091048116908316036126585760405162461bcd60e51b815260206004820152602d60248201527f4272696467654d696e7461626c65546f6b656e3a2043616e6e6f74207365742060448201526c39b0b6b29030b2323932b9b99760991b606482015260840161105f565b602180546001600160a01b03841661010002610100600160a81b03198216811790925560ff9182169116176117d2576021805460ff191660011790555050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b6000805160206143878339815191526126d9816130ef565b601d80546001600160a01b0319166001600160a01b038516908117909155601e8390556040517f6c591da8da2f6e69746d7d9ae61c27ee29fbe303798141b4942ae2aef54274b190600090a2505050565b60215461010090046001600160a01b0316612743613100565b6001600160a01b0316146127995760405162461bcd60e51b815260206004820152601e60248201527f4c45524332303a204f6e6c79206c6f73736c65737320636f6e74726163740000604482015260640161105f565b8060005b8181101561252e5760008484838181106127b9576127b9614241565b90506020020160208101906127ce9190613e12565b905060006127db8261212a565b90506127ff82602160019054906101000a90046001600160a01b03168360006137bd565b5050808061280c90614257565b91505061279d565b6000610ff6612821613100565b84846004600061282f613100565b6001600160a01b03908116825260208083019390935260409182016000908120918b16815292529020546111fd9190614150565b6021546000908390839060ff16156128fc5760215461010090046001600160a01b0316631ffb811f612893613100565b6040516001600160e01b031960e084901b1681526001600160a01b039182166004820152908516602482015260448101849052606401600060405180830381600087803b1580156128e357600080fd5b505af11580156128f7573d6000803e3d6000fd5b505050505b61290e612907613100565b868661322e565b506001949350505050565b601c546001600160a01b031661292d613100565b6001600160a01b0316146129535760405162461bcd60e51b815260040161105f9061420a565b6020546000036129a55760405162461bcd60e51b815260206004820152601c60248201527f4c45524332303a205475726e4f6666206e6f742070726f706f73656400000000604482015260640161105f565b4260205411156129f75760405162461bcd60e51b815260206004820152601d60248201527f4c45524332303a2054696d65206c6f636b20696e2070726f6772657373000000604482015260640161105f565b6021805460ff19169055600060208190556040517f3eb72350c9c7928d31e9ab450bfff2c159434aa4b82658a7d8eae7f109cb4e7b9190a1565b60008085841180612a4157508483115b15612a50575084905083612a90565b6000612a5c8588614150565b90506000612a6a8588614150565b9050612a76878961417a565b821015612a8a578787935093505050612a90565b90925090505b94509492505050565b601d546001600160a01b0316612aad613100565b6001600160a01b031614612b035760405162461bcd60e51b815260206004820152601960248201527f4c45524332303a204d7573742062652063616e64696461746500000000000000604482015260640161105f565b601e548151602083012014612b505760405162461bcd60e51b81526020600482015260136024820152724c45524332303a20496e76616c6964206b657960681b604482015260640161105f565b601d8054601c80546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fb94bba6936ec7f75ee931dadf6e1a4d66b43d09b6fa0178fb13df9b77fb5841f90600090a250565b366000612bb0613ac8565b915091509091565b600082815260208190526040902060010154612bd3816130ef565b6117338383613557565b601c546001600160a01b0316612bf1613100565b6001600160a01b031614612c175760405162461bcd60e51b815260040161105f9061420a565b60205415612c675760405162461bcd60e51b815260206004820181905260248201527f4c45524332303a205475726e4f666620616c72656164792070726f706f736564604482015260640161105f565b60215460ff16612cb95760405162461bcd60e51b815260206004820152601c60248201527f4c45524332303a204c6f73736c65737320616c7265616479206f666600000000604482015260640161105f565b601f54612cc690426141c1565b60208181556040519182527f6ca688e6e3ddd707280140b2bf0106afe883689b6c74e68cbd517576dd9c245a910160405180910390a1565b600080516020614327833981519152612d16816130ef565b6001600160a01b038216612d5e5760405162461bcd60e51b815260206004820152600f60248201526e67617357616c6c65743a205a45524f60881b604482015260640161105f565b600a80546001600160a01b0319166001600160a01b03841690811790915560408051818152601e918101919091527f576520686176652055706461746564207468652067617357616c6c65743a000060608201526020810191909152600080516020614347833981519152906080016110ea565b600080516020614367833981519152612dea816130ef565b6001600160a01b038216612e355760405162461bcd60e51b8152602060048201526012602482015271696e636c756465496e4665653a205a45524f60701b604482015260640161105f565b6001600160a01b03821660009081526005602052604090205460ff16612e9d5760405162461bcd60e51b815260206004820152601b60248201527f4163636f756e7420697320616c726561647920696e636c756465640000000000604482015260640161105f565b6001600160a01b038216600081815260056020908152604091829020805460ff1916905581518281526021928101929092527f5765206861766520557064617465642074686520696e636c756465496e4665656060830152601d60f91b60808301528101919091526000805160206143478339815191529060a0016110ea565b7fa42787877dd247913f847bc654d767d1919585674d8f1a26ea00084043233daa612f47816130ef565b64e8d4a51000612f56600e5490565b612f61906005614163565b612f6b919061417a565b821015612fd65760405162461bcd60e51b815260206004820152603360248201527f4552523a206d617820747820616d6f756e742073686f756c642065786365656460448201527220302e3525206f662074686520737570706c7960681b606482015260840161105f565b612fe482633b9aca00614163565b601955604080518181526018918101919091527f4e6577204d6178205472616e7366657220416d6f756e743a00000000000000006060820152602081018390527fdd970dd9b5bfe707922155b058a407655cb18288b807e2216442bca8ad83d6b5906080016110ea565b613056613610565b6001600160a01b0381166130bb5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161105f565b6119cc8161376b565b60006130cf33611df0565b156130e1575060131936013560601c90565b503390565b905090565b3390565b6119cc816130fb613100565b613ad3565b60006130e66130c4565b6001600160a01b03831661316c5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161105f565b6001600160a01b0382166131cd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161105f565b6001600160a01b0383811660008181526004602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166132925760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161105f565b6001600160a01b0382166132f45760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161105f565b6001546001600160a01b0384811691161480159061332057506001546001600160a01b03838116911614155b15613388576019548111156133885760405162461bcd60e51b815260206004820152602860248201527f5472616e7366657220616d6f756e74206578636565647320746865206d6178546044820152673c20b6b7bab73a1760c11b606482015260840161105f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b03161480156133fb57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614155b1561345857601a548161340d8461212a565b61341791906141c1565b11156134585760405162461bcd60e51b815260206004820152601060248201526f18da1958dac81b585e081dd85b1b195d60821b604482015260640161105f565b6001600160a01b03831660009081526005602052604090205460019060ff168061349a57506001600160a01b03831660009081526005602052604090205460ff165b156134a3575060005b61252e848484846137bd565b60008060006134bc613b2c565b90925090506134cb818361417a565b9250505090565b6134dc8282612698565b6117d2576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055613513613100565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6135618282612698565b156117d2576000828152602081815260408083206001600160a01b03851684529091529020805460ff19169055613596613100565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60008060008060006135eb86613b43565b9250905061360186826135fc6134af565b613b62565b91989097509095509193509150565b613618613100565b6001600160a01b03166136336001546001600160a01b031690565b6001600160a01b03161461219b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161105f565b6040516334cae58160e21b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063d32b9604906024016020604051808303816000875af192505050801561370c575060408051601f3d908101601f19168201909252613709918101906141ed565b60015b6117d25760408051818152600f818301526e43616e74207570646174652066656560881b60608201526020810183905290517fdd970dd9b5bfe707922155b058a407655cb18288b807e2216442bca8ad83d6b59181900360800190a150565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600d5460ff16613815576001546001600160a01b038581169116146138155760405162461bcd60e51b815260206004820152600e60248201526d151c98591948191a5cd8589b195960921b604482015260640161105f565b6001600160a01b03841660009081526007602052604090205460ff168061385457506001600160a01b03831660009081526007602052604090205460ff165b156138a15760405162461bcd60e51b815260206004820152601b60248201527f626f7473206172656e7420616c6c6f77656420746f2074726164650000000000604482015260640161105f565b806138ae576138ae613b93565b6001600160a01b0380851660009081526006602052604080822054928616825281205460ff928316921690808080806138e6896135da565b9450945094509450945084600260008d6001600160a01b03166001600160a01b0316815260200190815260200160002060008282546139259190614150565b90915550506001600160a01b038a16600090815260026020526040812080548692906139529084906141c1565b909155505086156139ee576001600160a01b038b16600090815260036020526040812080548b9290613985908490614150565b909155505085156139c3576001600160a01b038a16600090815260036020526040812080548492906139b89084906141c1565b90915550613a549050565b84600c60008282546139d59190614150565b9250508190555081600b60008282546139b89190614150565b8515613a54576001600160a01b038a1660009081526003602052604081208054849290613a1c9084906141c1565b9250508190555084600c6000828254613a3591906141c1565b9250508190555081600b6000828254613a4e91906141c1565b90915550505b613a5e8382613bac565b896001600160a01b03168b6001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613aa391815260200190565b60405180910390a3505050505082613ac057613ac0601254601155565b505050505050565b366000612bb0613bd2565b613add8282612698565b6117d257613aea81613c07565b613af5836020613c19565b604051602001613b06929190614270565b60408051601f198184030181529082905262461bcd60e51b825261105f91600401613e53565b600080612bb0600f54600e54600c54600b54612a31565b600080613b4f83613db5565b9150613b5b8284614150565b9050915091565b60008080613b708487614163565b9250613b7c8486614163565b9050613b888184614150565b915093509350939050565b601154600003613b9f57565b6011805460125560009055565b81600f54613bba9190614150565b600f55601054613bcb9082906141c1565b6010555050565b366000613bde33611df0565b15613bff5760008036613bf2601482614150565b92612bb0939291906142e5565b600036612bb0565b6060610f906001600160a01b03831660145b60606000613c28836002614163565b613c339060026141c1565b67ffffffffffffffff811115613c4b57613c4b614016565b6040519080825280601f01601f191660200182016040528015613c75576020820181803683370190505b509050600360fc1b81600081518110613c9057613c90614241565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613cbf57613cbf614241565b60200101906001600160f81b031916908160001a9053506000613ce3846002614163565b613cee9060016141c1565b90505b6001811115613d66576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613d2257613d22614241565b1a60f81b828281518110613d3857613d38614241565b60200101906001600160f81b031916908160001a90535060049490941c93613d5f8161430f565b9050613cf1565b5083156117005760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161105f565b60115460009061271090613dc99084614163565b610f90919061417a565b600060208284031215613de557600080fd5b81356001600160e01b03198116811461170057600080fd5b6001600160a01b03811681146119cc57600080fd5b600060208284031215613e2457600080fd5b813561170081613dfd565b60005b83811015613e4a578181015183820152602001613e32565b50506000910152565b6020815260008251806020840152613e72816040850160208701613e2f565b601f01601f19169190910160400192915050565b60008060408385031215613e9957600080fd5b8235613ea481613dfd565b946020939093013593505050565b600080600060608486031215613ec757600080fd5b8335613ed281613dfd565b92506020840135613ee281613dfd565b929592945050506040919091013590565b600060208284031215613f0557600080fd5b5035919050565b60008060408385031215613f1f57600080fd5b823591506020830135613f3181613dfd565b809150509250929050565b80151581146119cc57600080fd5b60008060408385031215613f5d57600080fd5b823591506020830135613f3181613f3c565b60008060008060808587031215613f8557600080fd5b5050823594602084013594506040840135936060013592509050565b60008060208385031215613fb457600080fd5b823567ffffffffffffffff80821115613fcc57600080fd5b818501915085601f830112613fe057600080fd5b813581811115613fef57600080fd5b8660208260051b850101111561400457600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561403e57600080fd5b813567ffffffffffffffff8082111561405657600080fd5b818401915084601f83011261406a57600080fd5b81358181111561407c5761407c614016565b604051601f8201601f19908116603f011681019083821181831017156140a4576140a4614016565b816040528281528760208487010111156140bd57600080fd5b826020860160208301376000928101602001929092525095945050505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b6000806040838503121561411f57600080fd5b823561412a81613dfd565b91506020830135613f3181613dfd565b634e487b7160e01b600052601160045260246000fd5b81810381811115610f9057610f9061413a565b8082028115828204841417610f9057610f9061413a565b60008261419757634e487b7160e01b600052601260045260246000fd5b500490565b6020808252600b908201526a11195c081b9bdd08189bdd60aa1b604082015260600190565b80820180821115610f9057610f9061413a565b6000602082840312156141e657600080fd5b5051919050565b6000602082840312156141ff57600080fd5b815161170081613f3c565b6020808252601e908201527f4c45524332303a204d757374206265207265636f766572792061646d696e0000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6000600182016142695761426961413a565b5060010190565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516142a8816017850160208801613e2f565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516142d9816028840160208801613e2f565b01602801949350505050565b600080858511156142f557600080fd5b8386111561430257600080fd5b5050820193919092039150565b60008161431e5761431e61413a565b50600019019056fe9dffd71004dfaab55bf910c5a0672e6384235f73ad747a585d74609cf1ce97be025dbd6ad989fe1a64db7dc049e29723ff9d35a97d84ae9aab96196f00ec1a00607744c37698f0ad2c7e8b300d57eaef2f987ccbb958ce7cd316a2c3e663f9ec353ade2f164e14105123d6ee399d29e979120b2f7a3852f8d1854ece00e1d072a26469706673582212205c93e450317ff83c48891892b6b11e4c57e91c6cf50871173e53f483b181cd7264736f6c63430008110033000000000000000000000000039bd8607fc1656f780ede49250e440c939f913a000000000000000000000000e90b8a4f1c87d5ec6b07bbf96dc850061209981b0000000000000000000000005289cde36fad0e85636863f3e056d5d3bc4bf4f300000000000000000000000084a0856b038eaad1cc7e297cf34a7e72685a86930000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc779000000000000000000000000f8262a34300a3115dfcb9e46897746673ef7b97d00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000050000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc7790000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc7790000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc7790000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc7790000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc779

Deployed Bytecode

0x6080604052600436106104775760003560e01c8063715018a61161024a578063ad5c464811610139578063dd62ed3e116100b6578063ea2f0b371161007a578063ea2f0b3714610eab578063ec28438a14610ecb578063f2fde38b14610eeb578063f851a44014610f0b578063ff64821e14610f2b57600080fd5b8063dd62ed3e14610dee578063e2d6649a14610e34578063e34420b414610e49578063e45c17e114610e69578063e97e5bae14610e8957600080fd5b8063c8e7ca2e116100fd578063c8e7ca2e14610d48578063ccfa214f14610d6b578063d24f19d514610d85578063d547741f14610db9578063d6e242b814610dd957600080fd5b8063ad5c464814610c76578063b150377414610caa578063b38fe95714610cde578063b414cae914610cf3578063b5c2287714610d2857600080fd5b80638e8ecaff116101c7578063a1ca53471161018b578063a1ca534714610bf5578063a217fddf14610c0b578063a335d4ff14610c20578063a457c2d714610c36578063a9059cbb14610c5657600080fd5b80638e8ecaff14610b4657806391d1485414610b6657806393310ffe14610b86578063936af91114610ba657806395d89b4114610bc657600080fd5b80638283bbf31161020e5780638283bbf314610a9157806386a35f2514610ab157806388f8202014610ada5780638a8c523c14610b135780638da5cb5b14610b2857600080fd5b8063715018a6146109fc57806375f0a87414610a115780637d1db4a514610a315780637d35aa9314610a4757806382247ec014610a7b57600080fd5b8063364333f4116103665780635342acb4116102e357806360d48489116102a757806360d484891461094f57806361086b00146109885780636e9960c31461099e5780636fcba377146109bc57806370a08231146109dc57600080fd5b80635342acb4146108a1578063572b6c05146108da5780635b8a194a146108fa5780635d098b381461090f5780635f6529a31461092f57600080fd5b806342d59d271161032a57806342d59d27146107ff578063437823ec146108215780634549b0391461084157806352390c021461086157806352e199c51461088157600080fd5b8063364333f41461076a57806336568abe1461077f578063395093511461079f5780633951709c146107bf5780633bd5d173146107df57600080fd5b806327a14fc2116103f45780632ecaf675116103b85780632ecaf675146106ce5780632f05205c146106e45780632f2ff15d146106fe578063313ce5671461071e57806334f6ebf51461074557600080fd5b806327a14fc21461062c5780632a0276f81461064c5780632a3606311461066e5780632baa3c9e1461068e5780632d838119146106ae57600080fd5b80631080afd51161043b5780631080afd51461058857806313114a9d146105a857806318160ddd146105c757806323b872dd146105dc578063248a9ca3146105fc57600080fd5b806301ffc9a7146104835780630305caff146104b857806306fdde03146104da578063095ea7b31461051c5780630ffd3dfb1461053c57600080fd5b3661047e57005b600080fd5b34801561048f57600080fd5b506104a361049e366004613dd3565b610f5f565b60405190151581526020015b60405180910390f35b3480156104c457600080fd5b506104d86104d3366004613e12565b610f96565b005b3480156104e657600080fd5b5061050f6040518060400160405280600981526020016814985c9948119a539160ba1b81525081565b6040516104af9190613e53565b34801561052857600080fd5b506104a3610537366004613e86565b610fe2565b34801561054857600080fd5b506105707f0000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc77981565b6040516001600160a01b0390911681526020016104af565b34801561059457600080fd5b506104d86105a3366004613e12565b610fff565b3480156105b457600080fd5b506010545b6040519081526020016104af565b3480156105d357600080fd5b50600e546105b9565b3480156105e857600080fd5b506104a36105f7366004613eb2565b6110f6565b34801561060857600080fd5b506105b9610617366004613ef3565b60009081526020819052604090206001015490565b34801561063857600080fd5b506104d8610647366004613ef3565b61120f565b34801561065857600080fd5b506105b960008051602061436783398151915281565b34801561067a57600080fd5b506104d8610689366004613e12565b611342565b34801561069a57600080fd5b506104d86106a9366004613e12565b6115bc565b3480156106ba57600080fd5b506105b96106c9366004613ef3565b61167d565b3480156106da57600080fd5b506105b9601f5481565b3480156106f057600080fd5b50600d546104a39060ff1681565b34801561070a57600080fd5b506104d8610719366004613f0c565b61170e565b34801561072a57600080fd5b50610733600981565b60405160ff90911681526020016104af565b34801561075157600080fd5b506021546105709061010090046001600160a01b031681565b34801561077657600080fd5b506104d8611738565b34801561078b57600080fd5b506104d861079a366004613f0c565b6117d6565b3480156107ab57600080fd5b506104a36107ba366004613e86565b611860565b3480156107cb57600080fd5b506104d86107da366004613e12565b6118af565b3480156107eb57600080fd5b506104d86107fa366004613ef3565b6119cf565b34801561080b57600080fd5b506105b960008051602061432783398151915281565b34801561082d57600080fd5b506104d861083c366004613e12565b611ad0565b34801561084d57600080fd5b506105b961085c366004613f4a565b611c2e565b34801561086d57600080fd5b506104d861087c366004613e12565b611cab565b34801561088d57600080fd5b50600a54610570906001600160a01b031681565b3480156108ad57600080fd5b506104a36108bc366004613e12565b6001600160a01b031660009081526005602052604090205460ff1690565b3480156108e657600080fd5b506104a36108f5366004613e12565b611df0565b34801561090657600080fd5b506104d8611e22565b34801561091b57600080fd5b506104d861092a366004613e12565b611eec565b34801561093b57600080fd5b50601c54610570906001600160a01b031681565b34801561095b57600080fd5b506104a361096a366004613e12565b6001600160a01b031660009081526007602052604090205460ff1690565b34801561099457600080fd5b506105b960205481565b3480156109aa57600080fd5b50601b546001600160a01b0316610570565b3480156109c857600080fd5b506104d86109d7366004613f6f565b611fcf565b3480156109e857600080fd5b506105b96109f7366004613e12565b61212a565b348015610a0857600080fd5b506104d8612189565b348015610a1d57600080fd5b50600854610570906001600160a01b031681565b348015610a3d57600080fd5b506105b960195481565b348015610a5357600080fd5b506105707f0000000000000000000000006ddcf818d4d47a450b483678bfed01c37abb904a81565b348015610a8757600080fd5b506105b9601a5481565b348015610a9d57600080fd5b506104d8610aac366004613f0c565b61219d565b348015610abd57600080fd5b50610ac76105dc81565b60405161ffff90911681526020016104af565b348015610ae657600080fd5b506104a3610af5366004613e12565b6001600160a01b031660009081526006602052604090205460ff1690565b348015610b1f57600080fd5b506104d8612534565b348015610b3457600080fd5b506001546001600160a01b0316610570565b348015610b5257600080fd5b506104d8610b61366004613e12565b61254b565b348015610b7257600080fd5b506104a3610b81366004613f0c565b612698565b348015610b9257600080fd5b506104d8610ba1366004613e86565b6126c1565b348015610bb257600080fd5b506104d8610bc1366004613fa1565b61272a565b348015610bd257600080fd5b5061050f6040518060400160405280600381526020016211939160ea1b81525081565b348015610c0157600080fd5b506105b960185481565b348015610c1757600080fd5b506105b9600081565b348015610c2c57600080fd5b50610ac761271081565b348015610c4257600080fd5b506104a3610c51366004613e86565b612814565b348015610c6257600080fd5b506104a3610c71366004613e86565b612863565b348015610c8257600080fd5b506105707f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b348015610cb657600080fd5b506105b97f902cbe3a02736af9827fb6a90bada39e955c0941e08f0c63b3a662a7b17a4e2b81565b348015610cea57600080fd5b506104d8612919565b348015610cff57600080fd5b50610d13610d0e366004613f6f565b612a31565b604080519283526020830191909152016104af565b348015610d3457600080fd5b506104d8610d4336600461402c565b612a99565b348015610d5457600080fd5b50610d5d612ba5565b6040516104af9291906140dd565b348015610d7757600080fd5b506021546104a39060ff1681565b348015610d9157600080fd5b506105b97fa42787877dd247913f847bc654d767d1919585674d8f1a26ea00084043233daa81565b348015610dc557600080fd5b506104d8610dd4366004613f0c565b612bb8565b348015610de557600080fd5b506104d8612bdd565b348015610dfa57600080fd5b506105b9610e0936600461410c565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205490565b348015610e4057600080fd5b50610ac7606481565b348015610e5557600080fd5b50600954610570906001600160a01b031681565b348015610e7557600080fd5b506104d8610e84366004613e12565b612cfe565b348015610e9557600080fd5b506105b960008051602061438783398151915281565b348015610eb757600080fd5b506104d8610ec6366004613e12565b612dd2565b348015610ed757600080fd5b506104d8610ee6366004613ef3565b612f1d565b348015610ef757600080fd5b506104d8610f06366004613e12565b61304e565b348015610f1757600080fd5b50601b54610570906001600160a01b031681565b348015610f3757600080fd5b506105707f000000000000000000000000f8262a34300a3115dfcb9e46897746673ef7b97d81565b60006001600160e01b03198216637965db0b60e01b1480610f9057506301ffc9a760e01b6001600160e01b03198316145b92915050565b7f902cbe3a02736af9827fb6a90bada39e955c0941e08f0c63b3a662a7b17a4e2b610fc0816130ef565b506001600160a01b03166000908152600760205260409020805460ff19169055565b6000610ff6610fef613100565b848461310a565b50600192915050565b600080516020614327833981519152611017816130ef565b6001600160a01b0382166110685760405162461bcd60e51b8152602060048201526013602482015272616e746971756557616c6c65743a205a45524f60681b60448201526064015b60405180910390fd5b600980546001600160a01b0319166001600160a01b038416908117909155604080518181526029918101919091527f5765206861766520557064617465642074686520736574416e7469717569746960608201526832b9abb0b63632ba1d60b91b608082015260208101919091526000805160206143478339815191529060a0015b60405180910390a15050565b60215460009084908490849060ff16156111995760215461010090046001600160a01b031663379f5c69611128613100565b6040516001600160e01b031960e084901b1681526001600160a01b0391821660048201528187166024820152908516604482015260648101849052608401600060405180830381600087803b15801561118057600080fd5b505af1158015611194573d6000803e3d6000fd5b505050505b6111a487878761322e565b611202876111b0613100565b6001600160a01b038a16600090815260046020526040812089916111d2613100565b6001600160a01b03166001600160a01b03168152602001908152602001600020546111fd9190614150565b61310a565b5060019695505050505050565b7fa42787877dd247913f847bc654d767d1919585674d8f1a26ea00084043233daa611239816130ef565b64e8d4a51000611248600e5490565b611253906005614163565b61125d919061417a565b82116112d15760405162461bcd60e51b815260206004820152603760248201527f4552523a206d61782077616c6c657420616d6f756e742073686f756c6420657860448201527f6365656420302e3525206f662074686520737570706c79000000000000000000606482015260840161105f565b6112df82633b9aca00614163565b601a5560408051818152601691810191909152752732bb9036b0bc103bb0b63632ba1030b6b7bab73a1d60511b6060820152602081018390527fdd970dd9b5bfe707922155b058a407655cb18288b807e2216442bca8ad83d6b5906080016110ea565b7f902cbe3a02736af9827fb6a90bada39e955c0941e08f0c63b3a662a7b17a4e2b61136c816130ef565b7f0000000000000000000000006ddcf818d4d47a450b483678bfed01c37abb904a6001600160a01b0316826001600160a01b0316036113ed5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f74206164642070616972206173206120626f740000000000000000604482015260640161105f565b306001600160a01b0383160361143e5760405162461bcd60e51b815260206004820152601660248201527510d85b9b9bdd081859190810d048185cc81848189bdd60521b604482015260640161105f565b60006114526001546001600160a01b031690565b6001600160a01b0316146114bc576001546001600160a01b03166001600160a01b0316826001600160a01b0316036114bc5760405162461bcd60e51b815260206004820152600d60248201526c13dddb995c881b9bdd08189bdd609a1b604482015260640161105f565b7f0000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc7796001600160a01b0316826001600160a01b03160361150d5760405162461bcd60e51b815260040161105f9061419c565b6008546001600160a01b039081169083160361153b5760405162461bcd60e51b815260040161105f9061419c565b6009546001600160a01b03908116908316036115695760405162461bcd60e51b815260040161105f9061419c565b600a546001600160a01b03908116908316036115975760405162461bcd60e51b815260040161105f9061419c565b506001600160a01b03166000908152600760205260409020805460ff19166001179055565b6000805160206143878339815191526115d4816130ef565b601b546001600160a01b03908116908316036116325760405162461bcd60e51b815260206004820152601f60248201527f4c45524332303a2043616e6e6f74207365742073616d65206164647265737300604482015260640161105f565b601b80546001600160a01b0319166001600160a01b0384169081179091556040517f71614071b88dee5e0b2ae578a9dd7b2ebbe9ae832ba419dc0242cd065a290b6c90600090a25050565b6000600f548211156116e45760405162461bcd60e51b815260206004820152602a60248201527f416d6f756e74206d757374206265206c657373207468616e20746f74616c207260448201526965666c656374696f6e7360b01b606482015260840161105f565b60006116ee6134af565b9050801561170757611700818461417a565b9392505050565b5090919050565b600082815260208190526040902060010154611729816130ef565b61173383836134d2565b505050565b60085460405147916000916001600160a01b039091169083908381818185875af1925050503d8060008114611789576040519150601f19603f3d011682016040523d82523d6000602084013e61178e565b606091505b50509050806117d25760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b604482015260640161105f565b5050565b6117de613100565b6001600160a01b0316816001600160a01b0316146118565760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b606482015260840161105f565b6117d28282613557565b6000610ff661186d613100565b84846004600061187b613100565b6001600160a01b03908116825260208083019390935260409182016000908120918b16815292529020546111fd91906141c1565b6008546040516370a0823160e01b81523060048201526001600160a01b038381169263a9059cbb9291169083906370a0823190602401602060405180830381865afa158015611902573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192691906141d4565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af192505050801561198d575060408051601f3d908101601f1916820190925261198a918101906141ed565b60015b6117d25760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b604482015260640161105f565b50565b60006119d9613100565b6001600160a01b03811660009081526006602052604090205490915060ff1615611a5a5760405162461bcd60e51b815260206004820152602c60248201527f4578636c75646564206164647265737365732063616e6e6f742063616c6c207460448201526b3434b990333ab731ba34b7b760a11b606482015260840161105f565b6000611a65836135da565b5050506001600160a01b038416600090815260026020526040902054919250611a9091839150614150565b6001600160a01b038316600090815260026020526040902055600f54611ab7908290614150565b600f55601054611ac89084906141c1565b601055505050565b600080516020614367833981519152611ae8816130ef565b6001600160a01b038216611b355760405162461bcd60e51b81526020600482015260146024820152736578636c75646546726f6d4665653a205a45524f60601b604482015260640161105f565b6001600160a01b03821660009081526005602052604090205460ff1615611b9e5760405162461bcd60e51b815260206004820152601b60248201527f4163636f756e7420697320616c7265616479206578636c756465640000000000604482015260640161105f565b6001600160a01b03821660009081526005602052604090819020805460ff1916600117905551600080516020614347833981519152906110ea90849060408082526023908201527f57652068617665205570646174656420746865206578636c75646546726f6d4660608201526232b29d60e91b60808201526001600160a01b0391909116602082015260a00190565b6000600e54831115611c825760405162461bcd60e51b815260206004820152601f60248201527f416d6f756e74206d757374206265206c657373207468616e20737570706c7900604482015260640161105f565b600080611c8e856135da565b5050509150915083611ca05781611ca2565b805b95945050505050565b611cb3613610565b6001600160a01b03811660009081526006602052604090205460ff1615611d1c5760405162461bcd60e51b815260206004820152601b60248201527f4163636f756e7420697320616c7265616479206578636c756465640000000000604482015260640161105f565b6001600160a01b03811660009081526002602052604090205415611d76576001600160a01b038116600090815260026020526040902054611d5c9061167d565b6001600160a01b0382166000908152600360205260409020555b6001600160a01b0381166000908152600660209081526040808320805460ff191660011790556003909152812054600b805491929091611db79084906141c1565b90915550506001600160a01b038116600090815260026020526040812054600c805491929091611de89084906141c1565b909155505050565b7f00000000000000000000000084a0856b038eaad1cc7e297cf34a7e72685a86936001600160a01b0390811691161490565b601c546001600160a01b0316611e36613100565b6001600160a01b031614611e5c5760405162461bcd60e51b815260040161105f9061420a565b60215460ff1615611eaf5760405162461bcd60e51b815260206004820152601b60248201527f4c45524332303a204c6f73736c65737320616c7265616479206f6e0000000000604482015260640161105f565b600060208190556021805460ff191660011790556040517f1ba3b66404043da8297d0b876fa6464f2cb127edfc6626308046d4503028322b9190a1565b600080516020614327833981519152611f04816130ef565b6001600160a01b038216611f4b5760405162461bcd60e51b815260206004820152600e60248201526d6d6b57616c6c65743a205a45524f60901b604482015260640161105f565b600880546001600160a01b0319166001600160a01b038416908117909155604080518181526027918101919091527f57652068617665205570646174656420746865207365744d61726b6574696e676060820152662bb0b63632ba1d60c91b608082015260208101919091526000805160206143478339815191529060a0016110ea565b600080516020614367833981519152611fe7816130ef565b6011859055601584905560168390556017829055818361200786886141c1565b61201191906141c1565b61201b91906141c1565b60188190556105dc10156120715760405162461bcd60e51b815260206004820152601b60248201527f746f74616c207461782063616e6e6f7420657863656564203135250000000000604482015260640161105f565b60175460165460155460649291612087916141c1565b61209191906141c1565b10156120fe5760405162461bcd60e51b815260206004820152603660248201527f4552523a206d61726b6574696e67202b20616e746971756974696573202b2067604482015275617320746178206d757374206265206f76657220312560501b606482015260840161105f565b61212360175460165460155461211491906141c1565b61211e91906141c1565b613689565b5050505050565b6001600160a01b03811660009081526006602052604081205460ff161561216757506001600160a01b031660009081526003602052604090205490565b6001600160a01b038216600090815260026020526040902054610f909061167d565b612191613610565b61219b600061376b565b565b60006001600160a01b037f0000000000000000000000006ddcf818d4d47a450b483678bfed01c37abb904a1633036121d3575060015b336001600160a01b037f000000000000000000000000f8262a34300a3115dfcb9e46897746673ef7b97d1614806122075750805b6122475760405162461bcd60e51b8152602060048201526011602482015270149054914e881393d517d0531313d5d151607a1b604482015260640161105f565b604051636eb1769f60e11b81523360048201523060248201526000906001600160a01b0384169063dd62ed3e90604401602060405180830381865afa158015612294573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122b891906141d4565b905083811061252e576040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038416906323b872dd906064016020604051808303816000875af1158015612314573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233891906141ed565b50600060175460165460155461234e91906141c1565b61235891906141c1565b6015546123659087614163565b61236f919061417a565b9050600060175460165460155461238691906141c1565b61239091906141c1565b60165461239d9088614163565b6123a7919061417a565b90506000816123b68489614150565b6123c09190614150565b60085460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810186905291925087169063a9059cbb906044016020604051808303816000875af1158015612415573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243991906141ed565b5060095460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018490529087169063a9059cbb906044016020604051808303816000875af115801561248d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124b191906141ed565b50600a5460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529087169063a9059cbb906044016020604051808303816000875af1158015612505573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061252991906141ed565b505050505b50505050565b61253c613610565b600d805460ff19166001179055565b600080516020614387833981519152612563816130ef565b6001600160a01b0382166125df5760405162461bcd60e51b815260206004820152603760248201527f4272696467654d696e7461626c65546f6b656e3a20436f6e74726f6c6c65722060448201527f63616e6e6f74206265207a65726f20616464726573732e000000000000000000606482015260840161105f565b6021546001600160a01b036101009091048116908316036126585760405162461bcd60e51b815260206004820152602d60248201527f4272696467654d696e7461626c65546f6b656e3a2043616e6e6f74207365742060448201526c39b0b6b29030b2323932b9b99760991b606482015260840161105f565b602180546001600160a01b03841661010002610100600160a81b03198216811790925560ff9182169116176117d2576021805460ff191660011790555050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b6000805160206143878339815191526126d9816130ef565b601d80546001600160a01b0319166001600160a01b038516908117909155601e8390556040517f6c591da8da2f6e69746d7d9ae61c27ee29fbe303798141b4942ae2aef54274b190600090a2505050565b60215461010090046001600160a01b0316612743613100565b6001600160a01b0316146127995760405162461bcd60e51b815260206004820152601e60248201527f4c45524332303a204f6e6c79206c6f73736c65737320636f6e74726163740000604482015260640161105f565b8060005b8181101561252e5760008484838181106127b9576127b9614241565b90506020020160208101906127ce9190613e12565b905060006127db8261212a565b90506127ff82602160019054906101000a90046001600160a01b03168360006137bd565b5050808061280c90614257565b91505061279d565b6000610ff6612821613100565b84846004600061282f613100565b6001600160a01b03908116825260208083019390935260409182016000908120918b16815292529020546111fd9190614150565b6021546000908390839060ff16156128fc5760215461010090046001600160a01b0316631ffb811f612893613100565b6040516001600160e01b031960e084901b1681526001600160a01b039182166004820152908516602482015260448101849052606401600060405180830381600087803b1580156128e357600080fd5b505af11580156128f7573d6000803e3d6000fd5b505050505b61290e612907613100565b868661322e565b506001949350505050565b601c546001600160a01b031661292d613100565b6001600160a01b0316146129535760405162461bcd60e51b815260040161105f9061420a565b6020546000036129a55760405162461bcd60e51b815260206004820152601c60248201527f4c45524332303a205475726e4f6666206e6f742070726f706f73656400000000604482015260640161105f565b4260205411156129f75760405162461bcd60e51b815260206004820152601d60248201527f4c45524332303a2054696d65206c6f636b20696e2070726f6772657373000000604482015260640161105f565b6021805460ff19169055600060208190556040517f3eb72350c9c7928d31e9ab450bfff2c159434aa4b82658a7d8eae7f109cb4e7b9190a1565b60008085841180612a4157508483115b15612a50575084905083612a90565b6000612a5c8588614150565b90506000612a6a8588614150565b9050612a76878961417a565b821015612a8a578787935093505050612a90565b90925090505b94509492505050565b601d546001600160a01b0316612aad613100565b6001600160a01b031614612b035760405162461bcd60e51b815260206004820152601960248201527f4c45524332303a204d7573742062652063616e64696461746500000000000000604482015260640161105f565b601e548151602083012014612b505760405162461bcd60e51b81526020600482015260136024820152724c45524332303a20496e76616c6964206b657960681b604482015260640161105f565b601d8054601c80546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fb94bba6936ec7f75ee931dadf6e1a4d66b43d09b6fa0178fb13df9b77fb5841f90600090a250565b366000612bb0613ac8565b915091509091565b600082815260208190526040902060010154612bd3816130ef565b6117338383613557565b601c546001600160a01b0316612bf1613100565b6001600160a01b031614612c175760405162461bcd60e51b815260040161105f9061420a565b60205415612c675760405162461bcd60e51b815260206004820181905260248201527f4c45524332303a205475726e4f666620616c72656164792070726f706f736564604482015260640161105f565b60215460ff16612cb95760405162461bcd60e51b815260206004820152601c60248201527f4c45524332303a204c6f73736c65737320616c7265616479206f666600000000604482015260640161105f565b601f54612cc690426141c1565b60208181556040519182527f6ca688e6e3ddd707280140b2bf0106afe883689b6c74e68cbd517576dd9c245a910160405180910390a1565b600080516020614327833981519152612d16816130ef565b6001600160a01b038216612d5e5760405162461bcd60e51b815260206004820152600f60248201526e67617357616c6c65743a205a45524f60881b604482015260640161105f565b600a80546001600160a01b0319166001600160a01b03841690811790915560408051818152601e918101919091527f576520686176652055706461746564207468652067617357616c6c65743a000060608201526020810191909152600080516020614347833981519152906080016110ea565b600080516020614367833981519152612dea816130ef565b6001600160a01b038216612e355760405162461bcd60e51b8152602060048201526012602482015271696e636c756465496e4665653a205a45524f60701b604482015260640161105f565b6001600160a01b03821660009081526005602052604090205460ff16612e9d5760405162461bcd60e51b815260206004820152601b60248201527f4163636f756e7420697320616c726561647920696e636c756465640000000000604482015260640161105f565b6001600160a01b038216600081815260056020908152604091829020805460ff1916905581518281526021928101929092527f5765206861766520557064617465642074686520696e636c756465496e4665656060830152601d60f91b60808301528101919091526000805160206143478339815191529060a0016110ea565b7fa42787877dd247913f847bc654d767d1919585674d8f1a26ea00084043233daa612f47816130ef565b64e8d4a51000612f56600e5490565b612f61906005614163565b612f6b919061417a565b821015612fd65760405162461bcd60e51b815260206004820152603360248201527f4552523a206d617820747820616d6f756e742073686f756c642065786365656460448201527220302e3525206f662074686520737570706c7960681b606482015260840161105f565b612fe482633b9aca00614163565b601955604080518181526018918101919091527f4e6577204d6178205472616e7366657220416d6f756e743a00000000000000006060820152602081018390527fdd970dd9b5bfe707922155b058a407655cb18288b807e2216442bca8ad83d6b5906080016110ea565b613056613610565b6001600160a01b0381166130bb5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161105f565b6119cc8161376b565b60006130cf33611df0565b156130e1575060131936013560601c90565b503390565b905090565b3390565b6119cc816130fb613100565b613ad3565b60006130e66130c4565b6001600160a01b03831661316c5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161105f565b6001600160a01b0382166131cd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161105f565b6001600160a01b0383811660008181526004602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166132925760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161105f565b6001600160a01b0382166132f45760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161105f565b6001546001600160a01b0384811691161480159061332057506001546001600160a01b03838116911614155b15613388576019548111156133885760405162461bcd60e51b815260206004820152602860248201527f5472616e7366657220616d6f756e74206578636565647320746865206d6178546044820152673c20b6b7bab73a1760c11b606482015260840161105f565b7f0000000000000000000000006ddcf818d4d47a450b483678bfed01c37abb904a6001600160a01b0316836001600160a01b03161480156133fb57507f0000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc7796001600160a01b0316826001600160a01b031614155b1561345857601a548161340d8461212a565b61341791906141c1565b11156134585760405162461bcd60e51b815260206004820152601060248201526f18da1958dac81b585e081dd85b1b195d60821b604482015260640161105f565b6001600160a01b03831660009081526005602052604090205460019060ff168061349a57506001600160a01b03831660009081526005602052604090205460ff165b156134a3575060005b61252e848484846137bd565b60008060006134bc613b2c565b90925090506134cb818361417a565b9250505090565b6134dc8282612698565b6117d2576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055613513613100565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6135618282612698565b156117d2576000828152602081815260408083206001600160a01b03851684529091529020805460ff19169055613596613100565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60008060008060006135eb86613b43565b9250905061360186826135fc6134af565b613b62565b91989097509095509193509150565b613618613100565b6001600160a01b03166136336001546001600160a01b031690565b6001600160a01b03161461219b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161105f565b6040516334cae58160e21b8152600481018290527f0000000000000000000000006ddcf818d4d47a450b483678bfed01c37abb904a6001600160a01b03169063d32b9604906024016020604051808303816000875af192505050801561370c575060408051601f3d908101601f19168201909252613709918101906141ed565b60015b6117d25760408051818152600f818301526e43616e74207570646174652066656560881b60608201526020810183905290517fdd970dd9b5bfe707922155b058a407655cb18288b807e2216442bca8ad83d6b59181900360800190a150565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600d5460ff16613815576001546001600160a01b038581169116146138155760405162461bcd60e51b815260206004820152600e60248201526d151c98591948191a5cd8589b195960921b604482015260640161105f565b6001600160a01b03841660009081526007602052604090205460ff168061385457506001600160a01b03831660009081526007602052604090205460ff165b156138a15760405162461bcd60e51b815260206004820152601b60248201527f626f7473206172656e7420616c6c6f77656420746f2074726164650000000000604482015260640161105f565b806138ae576138ae613b93565b6001600160a01b0380851660009081526006602052604080822054928616825281205460ff928316921690808080806138e6896135da565b9450945094509450945084600260008d6001600160a01b03166001600160a01b0316815260200190815260200160002060008282546139259190614150565b90915550506001600160a01b038a16600090815260026020526040812080548692906139529084906141c1565b909155505086156139ee576001600160a01b038b16600090815260036020526040812080548b9290613985908490614150565b909155505085156139c3576001600160a01b038a16600090815260036020526040812080548492906139b89084906141c1565b90915550613a549050565b84600c60008282546139d59190614150565b9250508190555081600b60008282546139b89190614150565b8515613a54576001600160a01b038a1660009081526003602052604081208054849290613a1c9084906141c1565b9250508190555084600c6000828254613a3591906141c1565b9250508190555081600b6000828254613a4e91906141c1565b90915550505b613a5e8382613bac565b896001600160a01b03168b6001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613aa391815260200190565b60405180910390a3505050505082613ac057613ac0601254601155565b505050505050565b366000612bb0613bd2565b613add8282612698565b6117d257613aea81613c07565b613af5836020613c19565b604051602001613b06929190614270565b60408051601f198184030181529082905262461bcd60e51b825261105f91600401613e53565b600080612bb0600f54600e54600c54600b54612a31565b600080613b4f83613db5565b9150613b5b8284614150565b9050915091565b60008080613b708487614163565b9250613b7c8486614163565b9050613b888184614150565b915093509350939050565b601154600003613b9f57565b6011805460125560009055565b81600f54613bba9190614150565b600f55601054613bcb9082906141c1565b6010555050565b366000613bde33611df0565b15613bff5760008036613bf2601482614150565b92612bb0939291906142e5565b600036612bb0565b6060610f906001600160a01b03831660145b60606000613c28836002614163565b613c339060026141c1565b67ffffffffffffffff811115613c4b57613c4b614016565b6040519080825280601f01601f191660200182016040528015613c75576020820181803683370190505b509050600360fc1b81600081518110613c9057613c90614241565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613cbf57613cbf614241565b60200101906001600160f81b031916908160001a9053506000613ce3846002614163565b613cee9060016141c1565b90505b6001811115613d66576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613d2257613d22614241565b1a60f81b828281518110613d3857613d38614241565b60200101906001600160f81b031916908160001a90535060049490941c93613d5f8161430f565b9050613cf1565b5083156117005760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161105f565b60115460009061271090613dc99084614163565b610f90919061417a565b600060208284031215613de557600080fd5b81356001600160e01b03198116811461170057600080fd5b6001600160a01b03811681146119cc57600080fd5b600060208284031215613e2457600080fd5b813561170081613dfd565b60005b83811015613e4a578181015183820152602001613e32565b50506000910152565b6020815260008251806020840152613e72816040850160208701613e2f565b601f01601f19169190910160400192915050565b60008060408385031215613e9957600080fd5b8235613ea481613dfd565b946020939093013593505050565b600080600060608486031215613ec757600080fd5b8335613ed281613dfd565b92506020840135613ee281613dfd565b929592945050506040919091013590565b600060208284031215613f0557600080fd5b5035919050565b60008060408385031215613f1f57600080fd5b823591506020830135613f3181613dfd565b809150509250929050565b80151581146119cc57600080fd5b60008060408385031215613f5d57600080fd5b823591506020830135613f3181613f3c565b60008060008060808587031215613f8557600080fd5b5050823594602084013594506040840135936060013592509050565b60008060208385031215613fb457600080fd5b823567ffffffffffffffff80821115613fcc57600080fd5b818501915085601f830112613fe057600080fd5b813581811115613fef57600080fd5b8660208260051b850101111561400457600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561403e57600080fd5b813567ffffffffffffffff8082111561405657600080fd5b818401915084601f83011261406a57600080fd5b81358181111561407c5761407c614016565b604051601f8201601f19908116603f011681019083821181831017156140a4576140a4614016565b816040528281528760208487010111156140bd57600080fd5b826020860160208301376000928101602001929092525095945050505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b6000806040838503121561411f57600080fd5b823561412a81613dfd565b91506020830135613f3181613dfd565b634e487b7160e01b600052601160045260246000fd5b81810381811115610f9057610f9061413a565b8082028115828204841417610f9057610f9061413a565b60008261419757634e487b7160e01b600052601260045260246000fd5b500490565b6020808252600b908201526a11195c081b9bdd08189bdd60aa1b604082015260600190565b80820180821115610f9057610f9061413a565b6000602082840312156141e657600080fd5b5051919050565b6000602082840312156141ff57600080fd5b815161170081613f3c565b6020808252601e908201527f4c45524332303a204d757374206265207265636f766572792061646d696e0000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6000600182016142695761426961413a565b5060010190565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516142a8816017850160208801613e2f565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516142d9816028840160208801613e2f565b01602801949350505050565b600080858511156142f557600080fd5b8386111561430257600080fd5b5050820193919092039150565b60008161431e5761431e61413a565b50600019019056fe9dffd71004dfaab55bf910c5a0672e6384235f73ad747a585d74609cf1ce97be025dbd6ad989fe1a64db7dc049e29723ff9d35a97d84ae9aab96196f00ec1a00607744c37698f0ad2c7e8b300d57eaef2f987ccbb958ce7cd316a2c3e663f9ec353ade2f164e14105123d6ee399d29e979120b2f7a3852f8d1854ece00e1d072a26469706673582212205c93e450317ff83c48891892b6b11e4c57e91c6cf50871173e53f483b181cd7264736f6c63430008110033

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

000000000000000000000000039bd8607fc1656f780ede49250e440c939f913a000000000000000000000000e90b8a4f1c87d5ec6b07bbf96dc850061209981b0000000000000000000000005289cde36fad0e85636863f3e056d5d3bc4bf4f300000000000000000000000084a0856b038eaad1cc7e297cf34a7e72685a86930000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc779000000000000000000000000f8262a34300a3115dfcb9e46897746673ef7b97d00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000050000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc7790000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc7790000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc7790000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc7790000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc779

-----Decoded View---------------
Arg [0] : _marketingWallet (address): 0x039BD8607fC1656F780eDE49250e440C939f913A
Arg [1] : _antiquitiesWallet (address): 0xe90b8a4F1C87D5eC6b07bBF96DC850061209981b
Arg [2] : _gasWallet (address): 0x5289CDE36FaD0e85636863f3E056D5d3BC4bF4F3
Arg [3] : _trustedForwarder (address): 0x84a0856b038eaAd1cC7E297cF34A7e72685A8693
Arg [4] : _depWallet (address): 0x2662a653DaE828297ccCBAe9aB04f23FaC8Fc779
Arg [5] : _router (address): 0xf8262a34300a3115DfCb9E46897746673Ef7b97d
Arg [6] : adminRoles (address[]): 0x2662a653DaE828297ccCBAe9aB04f23FaC8Fc779,0x2662a653DaE828297ccCBAe9aB04f23FaC8Fc779,0x2662a653DaE828297ccCBAe9aB04f23FaC8Fc779,0x2662a653DaE828297ccCBAe9aB04f23FaC8Fc779,0x2662a653DaE828297ccCBAe9aB04f23FaC8Fc779

-----Encoded View---------------
13 Constructor Arguments found :
Arg [0] : 000000000000000000000000039bd8607fc1656f780ede49250e440c939f913a
Arg [1] : 000000000000000000000000e90b8a4f1c87d5ec6b07bbf96dc850061209981b
Arg [2] : 0000000000000000000000005289cde36fad0e85636863f3e056d5d3bc4bf4f3
Arg [3] : 00000000000000000000000084a0856b038eaad1cc7e297cf34a7e72685a8693
Arg [4] : 0000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc779
Arg [5] : 000000000000000000000000f8262a34300a3115dfcb9e46897746673ef7b97d
Arg [6] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [8] : 0000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc779
Arg [9] : 0000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc779
Arg [10] : 0000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc779
Arg [11] : 0000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc779
Arg [12] : 0000000000000000000000002662a653dae828297cccbae9ab04f23fac8fc779


Deployed Bytecode Sourcemap

72714:37347:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66456:204;;;;;;;;;;-1:-1:-1;66456:204:0;;;;;:::i;:::-;;:::i;:::-;;;470:14:1;;463:22;445:41;;433:2;418:18;66456:204:0;;;;;;;;93085:120;;;;;;;;;;-1:-1:-1;93085:120:0;;;;;:::i;:::-;;:::i;:::-;;74667:41;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;74667:41:0;;;;;;;;;;;;:::i;81768:186::-;;;;;;;;;;-1:-1:-1;81768:186:0;;;;;:::i;:::-;;:::i;74208:34::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2025:32:1;;;2007:51;;1995:2;1980:18;74208:34:0;1861:203:1;88894:341:0;;;;;;;;;;-1:-1:-1;88894:341:0;;;;;:::i;:::-;;:::i;84214:87::-;;;;;;;;;;-1:-1:-1;84283:10:0;;84214:87;;;2215:25:1;;;2203:2;2188:18;84214:87:0;2069:177:1;80105:95:0;;;;;;;;;;-1:-1:-1;80185:7:0;;80105:95;;82237:434;;;;;;;;;;-1:-1:-1;82237:434:0;;;;;:::i;:::-;;:::i;68279:131::-;;;;;;;;;;-1:-1:-1;68279:131:0;;;;;:::i;:::-;68353:7;68380:12;;;;;;;;;;:22;;;;68279:131;79632:335;;;;;;;;;;-1:-1:-1;79632:335:0;;;;;:::i;:::-;;:::i;72949:51::-;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;72949:51:0;;92301:600;;;;;;;;;;-1:-1:-1;92301:600:0;;;;;:::i;:::-;;:::i;106631:234::-;;;;;;;;;;-1:-1:-1;106631:234:0;;;;;:::i;:::-;;:::i;85808:349::-;;;;;;;;;;-1:-1:-1;85808:349:0;;;;;:::i;:::-;;:::i;76249:39::-;;;;;;;;;;;;;;;;74381:28;;;;;;;;;;-1:-1:-1;74381:28:0;;;;;;;;68720:147;;;;;;;;;;-1:-1:-1;68720:147:0;;;;;:::i;:::-;;:::i;74759:34::-;;;;;;;;;;;;74792:1;74759:34;;;;;3756:4:1;3744:17;;;3726:36;;3714:2;3699:18;74759:34:0;3584:184:1;76380:30:0;;;;;;;;;;-1:-1:-1;76380:30:0;;;;;;;-1:-1:-1;;;;;76380:30:0;;;90449:214;;;;;;;;;;;;;:::i;69864:218::-;;;;;;;;;;-1:-1:-1;69864:218:0;;;;;:::i;:::-;;:::i;82927:290::-;;;;;;;;;;-1:-1:-1;82927:290:0;;;;;:::i;:::-;;:::i;91816:287::-;;;;;;;;;;-1:-1:-1;91816:287:0;;;;;:::i;:::-;;:::i;84561:408::-;;;;;;;;;;-1:-1:-1;84561:408:0;;;;;:::i;:::-;;:::i;73007:57::-;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;73007:57:0;;87367:336;;;;;;;;;;-1:-1:-1;87367:336:0;;;;;:::i;:::-;;:::i;85255:350::-;;;;;;;;;;-1:-1:-1;85255:350:0;;;;;:::i;:::-;;:::i;86384:492::-;;;;;;;;;;-1:-1:-1;86384:492:0;;;;;:::i;:::-;;:::i;74155:24::-;;;;;;;;;;-1:-1:-1;74155:24:0;;;;-1:-1:-1;;;;;74155:24:0;;;99504:124;;;;;;;;;;-1:-1:-1;99504:124:0;;;;;:::i;:::-;-1:-1:-1;;;;;99593:27:0;99569:4;99593:27;;;:18;:27;;;;;;;;;99504:124;43912:138;;;;;;;;;;-1:-1:-1;43912:138:0;;;;;:::i;:::-;;:::i;109738:229::-;;;;;;;;;;;;;:::i;88408:293::-;;;;;;;;;;-1:-1:-1;88408:293:0;;;;;:::i;:::-;;:::i;76126:28::-;;;;;;;;;;-1:-1:-1;76126:28:0;;;;-1:-1:-1;;;;;76126:28:0;;;93384:121;;;;;;;;;;-1:-1:-1;93384:121:0;;;;;:::i;:::-;-1:-1:-1;;;;;93476:21:0;93452:4;93476:21;;;:10;:21;;;;;;;;;93384:121;76295:39;;;;;;;;;;;;;;;;109975:83;;;;;;;;;;-1:-1:-1;110045:5:0;;-1:-1:-1;;;;;110045:5:0;109975:83;;94228:741;;;;;;;;;;-1:-1:-1;94228:741:0;;;;;:::i;:::-;;:::i;80485:198::-;;;;;;;;;;-1:-1:-1;80485:198:0;;;;;:::i;:::-;;:::i;60009:103::-;;;;;;;;;;;;;:::i;74021:30::-;;;;;;;;;;-1:-1:-1;74021:30:0;;;;-1:-1:-1;;;;;74021:30:0;;;75748:50;;;;;;;;;;;;;;;;75675:37;;;;;;;;;;;;;;;75856:46;;;;;;;;;;;;;;;;103666:1001;;;;;;;;;;-1:-1:-1;103666:1001:0;;;;;:::i;:::-;;:::i;74843:37::-;;;;;;;;;;;;74876:4;74843:37;;;;;5592:6:1;5580:19;;;5562:38;;5550:2;5535:18;74843:37:0;5418:188:1;83972:120:0;;;;;;;;;;-1:-1:-1;83972:120:0;;;;;:::i;:::-;-1:-1:-1;;;;;84064:20:0;84040:4;84064:20;;;:11;:20;;;;;;;;;83972:120;93666:78;;;;;;;;;;;;;:::i;59361:87::-;;;;;;;;;;-1:-1:-1;59434:6:0;;-1:-1:-1;;;;;59434:6:0;59361:87;;105977:486;;;;;;;;;;-1:-1:-1;105977:486:0;;;;;:::i;:::-;;:::i;66752:147::-;;;;;;;;;;-1:-1:-1;66752:147:0;;;;;:::i;:::-;;:::i;107050:279::-;;;;;;;;;;-1:-1:-1;107050:279:0;;;;;:::i;:::-;;:::i;108060:602::-;;;;;;;;;;-1:-1:-1;108060:602:0;;;;;:::i;:::-;;:::i;74715:37::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;74715:37:0;;;;;75426:87;;;;;;;;;;;;;;;;65857:49;;;;;;;;;;-1:-1:-1;65857:49:0;65902:4;65857:49;;74887:43;;;;;;;;;;;;74924:6;74887:43;;83478:300;;;;;;;;;;-1:-1:-1;83478:300:0;;;;;:::i;:::-;;:::i;80913:223::-;;;;;;;;;;-1:-1:-1;80913:223:0;;;;;:::i;:::-;;:::i;73985:29::-;;;;;;;;;;;;;;;73197:51;;;;;;;;;;;;73232:16;73197:51;;109262:382;;;;;;;;;;;;;:::i;98377:480::-;;;;;;;;;;-1:-1:-1;98377:480:0;;;;;:::i;:::-;;:::i;:::-;;;;6725:25:1;;;6781:2;6766:18;;6759:34;;;;6698:18;98377:480:0;6551:248:1;107445:420:0;;;;;;;;;;-1:-1:-1;107445:420:0;;;;;:::i;:::-;;:::i;91493:97::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;76341:32::-;;;;;;;;;;-1:-1:-1;76341:32:0;;;;;;;;73139:51;;;;;;;;;;;;73174:16;73139:51;;69160:149;;;;;;;;;;-1:-1:-1;69160:149:0;;;;;:::i;:::-;;:::i;108768:390::-;;;;;;;;;;;;;:::i;81374:170::-;;;;;;;;;;-1:-1:-1;81374:170:0;;;;;:::i;:::-;-1:-1:-1;;;;;81508:19:0;;;81481:7;81508:19;;;:11;:19;;;;;;;;:28;;;;;;;;;;;;;81374:170;74800:36;;;;;;;;;;;;74833:3;74800:36;;74086:32;;;;;;;;;;-1:-1:-1;74086:32:0;;;;-1:-1:-1;;;;;74086:32:0;;;89412:257;;;;;;;;;;-1:-1:-1;89412:257:0;;;;;:::i;:::-;;:::i;73071:61::-;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;73071:61:0;;87889:330;;;;;;;;;;-1:-1:-1;87889:330:0;;;;;:::i;:::-;;:::i;89946:334::-;;;;;;;;;;-1:-1:-1;89946:334:0;;;;;:::i;:::-;;:::i;60267:201::-;;;;;;;;;;-1:-1:-1;60267:201:0;;;;;:::i;:::-;;:::i;76099:20::-;;;;;;;;;;-1:-1:-1;76099:20:0;;;;-1:-1:-1;;;;;76099:20:0;;;75621:47;;;;;;;;;;;;;;;66456:204;66541:4;-1:-1:-1;;;;;;66565:47:0;;-1:-1:-1;;;66565:47:0;;:87;;-1:-1:-1;;;;;;;;;;27187:40:0;;;66616:36;66558:94;66456:204;-1:-1:-1;;66456:204:0:o;93085:120::-;73232:16;66348;66359:4;66348:10;:16::i;:::-;-1:-1:-1;;;;;;93168:21:0::1;93192:5;93168:21:::0;;;:10:::1;:21;::::0;;;;:29;;-1:-1:-1;;93168:29:0::1;::::0;;93085:120::o;81768:186::-;81868:4;81885:39;81894:12;:10;:12::i;:::-;81908:7;81917:6;81885:8;:39::i;:::-;-1:-1:-1;81942:4:0;81768:186;;;;:::o;88894:341::-;-1:-1:-1;;;;;;;;;;;66348:16:0;66359:4;66348:10;:16::i;:::-;-1:-1:-1;;;;;89011:27:0;::::1;89003:59;;;::::0;-1:-1:-1;;;89003:59:0;;9081:2:1;89003:59:0::1;::::0;::::1;9063:21:1::0;9120:2;9100:18;;;9093:30;-1:-1:-1;;;9139:18:1;;;9132:49;9198:18;;89003:59:0::1;;;;;;;;;89073:17;:33:::0;;-1:-1:-1;;;;;;89073:33:0::1;-1:-1:-1::0;;;;;89073:33:0;::::1;::::0;;::::1;::::0;;;89122:105:::1;::::0;;9439:21:1;;;9496:2;9476:18;;;9469:30;;;;9535:34;9530:2;9515:18;;9508:62;-1:-1:-1;;;9601:3:1;9586:19;;9579:40;9686:4;9671:20;;9664:62;;;;-1:-1:-1;;;;;;;;;;;89122:105:0;9651:3:1;9636:19;89122:105:0::1;;;;;;;;88894:341:::0;;:::o;82237:434::-;105441:12;;82448:4;;82403:6;;82411:9;;82422:6;;105441:12;;105437:196;;;105470:8;;;;;-1:-1:-1;;;;;105470:8:0;:27;105516:12;:10;:12::i;:::-;105470:151;;-1:-1:-1;;;;;;105470:151:0;;;;;;;-1:-1:-1;;;;;10024:15:1;;;105470:151:0;;;10006:34:1;10076:15;;;10056:18;;;10049:43;10128:15;;;10108:18;;;10101:43;10160:18;;;10153:34;;;9940:19;;105470:151:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105437:196;82470:36:::1;82480:6;82488:9;82499:6;82470:9;:36::i;:::-;82517:124;82540:6;82561:12;:10;:12::i;:::-;-1:-1:-1::0;;;;;82588:19:0;::::1;;::::0;;;:11:::1;:19;::::0;;;;82624:6;;82608:12:::1;:10;:12::i;:::-;-1:-1:-1::0;;;;;82588:33:0::1;-1:-1:-1::0;;;;;82588:33:0::1;;;;;;;;;;;;;:42;;;;:::i;:::-;82517:8;:124::i;:::-;-1:-1:-1::0;82659:4:0::1;::::0;82237:434;-1:-1:-1;;;;;;82237:434:0:o;79632:335::-;73174:16;66348;66359:4;66348:10;:16::i;:::-;79769:13:::1;79747;80185:7:::0;;;80105:95;79747:13:::1;:17;::::0;79763:1:::1;79747:17;:::i;:::-;79746:37;;;;:::i;:::-;79737:6;:46;79715:151;;;::::0;-1:-1:-1;;;79715:151:0;;11060:2:1;79715:151:0::1;::::0;::::1;11042:21:1::0;11099:2;11079:18;;;11072:30;11138:34;11118:18;;;11111:62;11209:25;11189:18;;;11182:53;11252:19;;79715:151:0::1;10858:419:1::0;79715:151:0::1;79890:16;:6:::0;79899:7:::1;79890:16;:::i;:::-;79877:10;:29:::0;79922:37:::1;::::0;;11494:21:1;;;11551:2;11531:18;;;11524:30;;;;-1:-1:-1;;;11585:2:1;11570:18;;11563:52;11682:4;11667:20;;11660:36;;;79922:37:0::1;::::0;11647:3:1;11632:19;79922:37:0::1;11282:420:1::0;92301:600:0;73232:16;66348;66359:4;66348:10;:16::i;:::-;92402:12:::1;-1:-1:-1::0;;;;;92389:25:0::1;:9;-1:-1:-1::0;;;;;92389:25:0::1;::::0;92381:62:::1;;;::::0;-1:-1:-1;;;92381:62:0;;11909:2:1;92381:62:0::1;::::0;::::1;11891:21:1::0;11948:2;11928:18;;;11921:30;11987:26;11967:18;;;11960:54;12031:18;;92381:62:0::1;11707:348:1::0;92381:62:0::1;92483:4;-1:-1:-1::0;;;;;92462:26:0;::::1;::::0;92454:61:::1;;;::::0;-1:-1:-1;;;92454:61:0;;12262:2:1;92454:61:0::1;::::0;::::1;12244:21:1::0;12301:2;12281:18;;;12274:30;-1:-1:-1;;;12320:18:1;;;12313:52;12382:18;;92454:61:0::1;12060:346:1::0;92454:61:0::1;92549:1;92530:7;59434:6:::0;;-1:-1:-1;;;;;59434:6:0;;59361:87;92530:7:::1;-1:-1:-1::0;;;;;92530:21:0::1;;92526:86;;59434:6:::0;;-1:-1:-1;;;;;59434:6:0;-1:-1:-1;;;;;92574:20:0::1;:9;-1:-1:-1::0;;;;;92574:20:0::1;::::0;92566:46:::1;;;::::0;-1:-1:-1;;;92566:46:0;;12613:2:1;92566:46:0::1;::::0;::::1;12595:21:1::0;12652:2;12632:18;;;12625:30;-1:-1:-1;;;12671:18:1;;;12664:43;12724:18;;92566:46:0::1;12411:337:1::0;92566:46:0::1;92644:9;-1:-1:-1::0;;;;;92631:22:0::1;:9;-1:-1:-1::0;;;;;92631:22:0::1;::::0;92623:46:::1;;;;-1:-1:-1::0;;;92623:46:0::1;;;;;;;:::i;:::-;92701:15;::::0;-1:-1:-1;;;;;92701:15:0;;::::1;92688:28:::0;;::::1;::::0;92680:52:::1;;;;-1:-1:-1::0;;;92680:52:0::1;;;;;;;:::i;:::-;92764:17;::::0;-1:-1:-1;;;;;92764:17:0;;::::1;92751:30:::0;;::::1;::::0;92743:54:::1;;;;-1:-1:-1::0;;;92743:54:0::1;;;;;;;:::i;:::-;92829:9;::::0;-1:-1:-1;;;;;92829:9:0;;::::1;92816:22:::0;;::::1;::::0;92808:46:::1;;;;-1:-1:-1::0;;;92808:46:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;92865:21:0::1;;::::0;;;:10:::1;:21;::::0;;;;:28;;-1:-1:-1;;92865:28:0::1;92889:4;92865:28;::::0;;92301:600::o;106631:234::-;-1:-1:-1;;;;;;;;;;;66348:16:0;66359:4;66348:10;:16::i;:::-;106755:5:::1;::::0;-1:-1:-1;;;;;106755:5:0;;::::1;106743:17:::0;;::::1;::::0;106735:61:::1;;;::::0;-1:-1:-1;;;106735:61:0;;13295:2:1;106735:61:0::1;::::0;::::1;13277:21:1::0;13334:2;13314:18;;;13307:30;13373:33;13353:18;;;13346:61;13424:18;;106735:61:0::1;13093:355:1::0;106735:61:0::1;106807:5;:16:::0;;-1:-1:-1;;;;;;106807:16:0::1;-1:-1:-1::0;;;;;106807:16:0;::::1;::::0;;::::1;::::0;;;106839:18:::1;::::0;::::1;::::0;-1:-1:-1;;106839:18:0::1;106631:234:::0;;:::o;85808:349::-;85891:7;85944;;85933;:18;;85911:110;;;;-1:-1:-1;;;85911:110:0;;13655:2:1;85911:110:0;;;13637:21:1;13694:2;13674:18;;;13667:30;13733:34;13713:18;;;13706:62;-1:-1:-1;;;13784:18:1;;;13777:40;13834:19;;85911:110:0;13453:406:1;85911:110:0;86032:19;86054:10;:8;:10::i;:::-;86032:32;-1:-1:-1;86079:15:0;;86075:49;;86103:21;86113:11;86103:7;:21;:::i;:::-;86096:28;85808:349;-1:-1:-1;;;85808:349:0:o;86075:49::-;-1:-1:-1;86142:7:0;;85808:349;-1:-1:-1;85808:349:0:o;68720:147::-;68353:7;68380:12;;;;;;;;;;:22;;;66348:16;66359:4;66348:10;:16::i;:::-;68834:25:::1;68845:4;68851:7;68834:10;:25::i;:::-;68720:147:::0;;;:::o;90449:214::-;90570:15;;90562:49;;90514:21;;90496:15;;-1:-1:-1;;;;;90570:15:0;;;;90514:21;;90496:15;90562:49;90496:15;90562:49;90514:21;90570:15;90562:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90546:65;;;90630:4;90622:33;;;;-1:-1:-1;;;90622:33:0;;14276:2:1;90622:33:0;;;14258:21:1;14315:2;14295:18;;;14288:30;-1:-1:-1;;;14334:18:1;;;14327:46;14390:18;;90622:33:0;14074:340:1;90622:33:0;90485:178;;90449:214::o;69864:218::-;69971:12;:10;:12::i;:::-;-1:-1:-1;;;;;69960:23:0;:7;-1:-1:-1;;;;;69960:23:0;;69952:83;;;;-1:-1:-1;;;69952:83:0;;14621:2:1;69952:83:0;;;14603:21:1;14660:2;14640:18;;;14633:30;14699:34;14679:18;;;14672:62;-1:-1:-1;;;14750:18:1;;;14743:45;14805:19;;69952:83:0;14419:411:1;69952:83:0;70048:26;70060:4;70066:7;70048:11;:26::i;82927:290::-;83040:4;83057:130;83080:12;:10;:12::i;:::-;83107:7;83166:10;83129:11;:25;83141:12;:10;:12::i;:::-;-1:-1:-1;;;;;83129:25:0;;;;;;;;;;;;;;;;;-1:-1:-1;83129:25:0;;;:34;;;;;;;;;;:47;;;;:::i;91816:287::-;91938:15;;91972:37;;-1:-1:-1;;;91972:37:0;;92003:4;91972:37;;;2007:51:1;-1:-1:-1;;;;;91898:21:0;;;;;;91938:15;;;91898:21;;91972:22;;1980:18:1;;91972:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91898:126;;-1:-1:-1;;;;;;91898:126:0;;;;;;;-1:-1:-1;;;;;15346:32:1;;;91898:126:0;;;15328:51:1;15395:18;;;15388:34;15301:18;;91898:126:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;91898:126:0;;;;;;;;-1:-1:-1;;91898:126:0;;;;;;;;;;;;:::i;:::-;;;91881:215;;92058:26;;-1:-1:-1;;;92058:26:0;;14276:2:1;92058:26:0;;;14258:21:1;14315:2;14295:18;;;14288:30;-1:-1:-1;;;14334:18:1;;;14327:46;14390:18;;92058:26:0;14074:340:1;91881:215:0;91816:287;:::o;84561:408::-;84613:14;84630:12;:10;:12::i;:::-;-1:-1:-1;;;;;84676:19:0;;;;;;:11;:19;;;;;;84613:29;;-1:-1:-1;84676:19:0;;84675:20;84653:114;;;;-1:-1:-1;;;84653:114:0;;15885:2:1;84653:114:0;;;15867:21:1;15924:2;15904:18;;;15897:30;15963:34;15943:18;;;15936:62;-1:-1:-1;;;16014:18:1;;;16007:42;16066:19;;84653:114:0;15683:408:1;84653:114:0;84779:15;84806:19;84817:7;84806:10;:19::i;:::-;-1:-1:-1;;;;;;;;84854:15:0;;;;;;:7;:15;;;;;;84778:47;;-1:-1:-1;84854:25:0;;84778:47;;-1:-1:-1;84854:25:0;:::i;:::-;-1:-1:-1;;;;;84836:15:0;;;;;;:7;:15;;;;;:43;84900:7;;:17;;84910:7;;84900:17;:::i;:::-;84890:7;:27;84941:10;;:20;;84954:7;;84941:20;:::i;:::-;84928:10;:33;-1:-1:-1;;;84561:408:0:o;87367:336::-;-1:-1:-1;;;;;;;;;;;66348:16:0;66359:4;66348:10;:16::i;:::-;-1:-1:-1;;;;;87453:21:0;::::1;87445:54;;;::::0;-1:-1:-1;;;87445:54:0;;16298:2:1;87445:54:0::1;::::0;::::1;16280:21:1::0;16337:2;16317:18;;;16310:30;-1:-1:-1;;;16356:18:1;;;16349:50;16416:18;;87445:54:0::1;16096:344:1::0;87445:54:0::1;-1:-1:-1::0;;;;;87519:27:0;::::1;;::::0;;;:18:::1;:27;::::0;;;;;::::1;;87518:28;87510:68;;;::::0;-1:-1:-1;;;87510:68:0;;16647:2:1;87510:68:0::1;::::0;::::1;16629:21:1::0;16686:2;16666:18;;;16659:30;16725:29;16705:18;;;16698:57;16772:18;;87510:68:0::1;16445:351:1::0;87510:68:0::1;-1:-1:-1::0;;;;;87589:27:0;::::1;;::::0;;;:18:::1;:27;::::0;;;;;;:34;;-1:-1:-1;;87589:34:0::1;87619:4;87589:34;::::0;;87639:56;-1:-1:-1;;;;;;;;;;;87639:56:0;::::1;::::0;87608:7;;17031:2:1;17013:21;;;17070:2;17050:18;;;17043:30;17109:34;17104:2;17089:18;;17082:62;-1:-1:-1;;;17175:3:1;17160:19;;17153:34;-1:-1:-1;;;;;17261:32:1;;;;17254:4;17239:20;;17232:62;17219:3;17204:19;;16801:499;85255:350:0;85371:7;85410;;85399;:18;;85391:62;;;;-1:-1:-1;;;85391:62:0;;17507:2:1;85391:62:0;;;17489:21:1;17546:2;17526:18;;;17519:30;17585:33;17565:18;;;17558:61;17636:18;;85391:62:0;17305:355:1;85391:62:0;85465:15;85482:23;85515:19;85526:7;85515:10;:19::i;:::-;85464:70;;;;;;;85552:17;:45;;85590:7;85552:45;;;85572:15;85552:45;85545:52;85255:350;-1:-1:-1;;;;;85255:350:0:o;86384:492::-;59247:13;:11;:13::i;:::-;-1:-1:-1;;;;;86579:20:0;::::1;;::::0;;;:11:::1;:20;::::0;;;;;::::1;;86578:21;86570:61;;;::::0;-1:-1:-1;;;86570:61:0;;16647:2:1;86570:61:0::1;::::0;::::1;16629:21:1::0;16686:2;16666:18;;;16659:30;16725:29;16705:18;;;16698:57;16772:18;;86570:61:0::1;16445:351:1::0;86570:61:0::1;-1:-1:-1::0;;;;;86646:16:0;::::1;86665:1;86646:16:::0;;;:7:::1;:16;::::0;;;;;:20;86642:109:::1;;-1:-1:-1::0;;;;;86722:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;;86702:37:::1;::::0;:19:::1;:37::i;:::-;-1:-1:-1::0;;;;;86683:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;:56;86642:109:::1;-1:-1:-1::0;;;;;86761:20:0;::::1;;::::0;;;:11:::1;:20;::::0;;;;;;;:27;;-1:-1:-1;;86761:27:0::1;86784:4;86761:27;::::0;;86812:7:::1;:16:::0;;;;;;86799:9:::1;:29:::0;;86812:16;;86799:9;;:29:::1;::::0;86812:16;;86799:29:::1;:::i;:::-;::::0;;;-1:-1:-1;;;;;;;86852:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;;86839:9:::1;:29:::0;;86852:16;;86839:9;;:29:::1;::::0;86852:16;;86839:29:::1;:::i;:::-;::::0;;;-1:-1:-1;;;86384:492:0:o;43912:138::-;44025:17;-1:-1:-1;;;;;44012:30:0;;;;;;;43912:138::o;109738:229::-;105738:13;;-1:-1:-1;;;;;105738:13:0;105722:12;:10;:12::i;:::-;-1:-1:-1;;;;;105722:29:0;;105700:109;;;;-1:-1:-1;;;105700:109:0;;;;;;;:::i;:::-;109818:12:::1;::::0;::::1;;109817:13;109809:53;;;::::0;-1:-1:-1;;;109809:53:0;;18226:2:1;109809:53:0::1;::::0;::::1;18208:21:1::0;18265:2;18245:18;;;18238:30;18304:29;18284:18;;;18277:57;18351:18;;109809:53:0::1;18024:351:1::0;109809:53:0::1;109900:1;109873:24;:28:::0;;;109912:12:::1;:19:::0;;-1:-1:-1;;109912:19:0::1;109927:4;109912:19;::::0;;109947:12:::1;::::0;::::1;::::0;109900:1;109947:12:::1;109738:229::o:0;88408:293::-;-1:-1:-1;;;;;;;;;;;66348:16:0;66359:4;66348:10;:16::i;:::-;-1:-1:-1;;;;;88523:27:0;::::1;88515:54;;;::::0;-1:-1:-1;;;88515:54:0;;18582:2:1;88515:54:0::1;::::0;::::1;18564:21:1::0;18621:2;18601:18;;;18594:30;-1:-1:-1;;;18640:18:1;;;18633:44;18694:18;;88515:54:0::1;18380:338:1::0;88515:54:0::1;88580:15;:31:::0;;-1:-1:-1;;;;;;88580:31:0::1;-1:-1:-1::0;;;;;88580:31:0;::::1;::::0;;::::1;::::0;;;88627:66:::1;::::0;;18935:21:1;;;18992:2;18972:18;;;18965:30;;;;19031:34;19026:2;19011:18;;19004:62;-1:-1:-1;;;19097:3:1;19082:19;;19075:38;19180:4;19165:20;;19158:62;;;;-1:-1:-1;;;;;;;;;;;88627:66:0;19145:3:1;19130:19;88627:66:0::1;18723:503:1::0;94228:741:0;-1:-1:-1;;;;;;;;;;;66348:16:0;66359:4;66348:10;:16::i;:::-;94426:7:::1;:27:::0;;;94464:13:::1;:32:::0;;;94507:15:::1;:36:::0;;;94554:7:::1;:20:::0;;;94564:10;94525:18;94599:23:::1;94480:16:::0;94436:17;94599:23:::1;:::i;:::-;:41;;;;:::i;:::-;:51;;;;:::i;:::-;94587:9;:63:::0;;;74876:4:::1;-1:-1:-1::0;94669:20:0::1;94661:60;;;::::0;-1:-1:-1;;;94661:60:0;;19433:2:1;94661:60:0::1;::::0;::::1;19415:21:1::0;19472:2;19452:18;;;19445:30;19511:29;19491:18;;;19484:57;19558:18;;94661:60:0::1;19231:351:1::0;94661:60:0::1;94789:7;::::0;94771:15:::1;::::0;94755:13:::1;::::0;74833:3:::1;::::0;94789:7;94755:31:::1;::::0;::::1;:::i;:::-;:41;;;;:::i;:::-;94754:54;;94732:158;;;::::0;-1:-1:-1;;;94732:158:0;;19789:2:1;94732:158:0::1;::::0;::::1;19771:21:1::0;19828:2;19808:18;;;19801:30;19867:34;19847:18;;;19840:62;-1:-1:-1;;;19918:18:1;;;19911:52;19980:19;;94732:158:0::1;19587:418:1::0;94732:158:0::1;94903:58;94953:7;;94935:15;;94919:13;;:31;;;;:::i;:::-;:41;;;;:::i;:::-;94903:15;:58::i;:::-;94228:741:::0;;;;;:::o;80485:198::-;-1:-1:-1;;;;;80575:20:0;;80551:7;80575:20;;;:11;:20;;;;;;;;80571:49;;;-1:-1:-1;;;;;;80604:16:0;;;;;:7;:16;;;;;;;80485:198::o;80571:49::-;-1:-1:-1;;;;;80658:16:0;;;;;;:7;:16;;;;;;80638:37;;:19;:37::i;60009:103::-;59247:13;:11;:13::i;:::-;60074:30:::1;60101:1;60074:18;:30::i;:::-;60009:103::o:0;103666:1001::-;76513:11;-1:-1:-1;;;;;76561:12:0;76547:26;:10;:26;76543:45;;-1:-1:-1;76584:4:0;76543:45;76623:10;-1:-1:-1;;;;;76645:14:0;76623:37;;;:47;;;76664:6;76623:47;76601:114;;;;-1:-1:-1;;;76601:114:0;;20212:2:1;76601:114:0;;;20194:21:1;20251:2;20231:18;;;20224:30;-1:-1:-1;;;20270:18:1;;;20263:47;20327:18;;76601:114:0;20010:341:1;76601:114:0;103771:50:::1;::::0;-1:-1:-1;;;103771:50:0;;103795:10:::1;103771:50;::::0;::::1;20568:34:1::0;103815:4:0::1;20618:18:1::0;;;20611:43;103750:18:0::1;::::0;-1:-1:-1;;;;;103771:23:0;::::1;::::0;::::1;::::0;20503:18:1;;103771:50:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;103750:71;;103852:6;103838:10;:20;103834:826;;103875:61;::::0;-1:-1:-1;;;103875:61:0;;103902:10:::1;103875:61;::::0;::::1;20905:34:1::0;103922:4:0::1;20955:18:1::0;;;20948:43;21007:18;;;21000:34;;;-1:-1:-1;;;;;103875:26:0;::::1;::::0;::::1;::::0;20840:18:1;;103875:61:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;104072:23;104177:7;;104159:15;;104143:13;;:31;;;;:::i;:::-;:41;;;;:::i;:::-;104108:13;::::0;104099:22:::1;::::0;:6;:22:::1;:::i;:::-;104098:87;;;;:::i;:::-;104072:113;;104200:25;104309:7;;104291:15;;104275:13;;:31;;;;:::i;:::-;:41;;;;:::i;:::-;104238:15;::::0;104229:24:::1;::::0;:6;:24:::1;:::i;:::-;104228:89;;;;:::i;:::-;104200:117:::0;-1:-1:-1;104332:17:0::1;104200:117:::0;104352:24:::1;104361:15:::0;104352:6;:24:::1;:::i;:::-;:44;;;;:::i;:::-;104481:15;::::0;104458:56:::1;::::0;-1:-1:-1;;;104458:56:0;;-1:-1:-1;;;;;104481:15:0;;::::1;104458:56;::::0;::::1;15328:51:1::0;15395:18;;;15388:34;;;104332:64:0;;-1:-1:-1;104458:22:0;::::1;::::0;::::1;::::0;15301:18:1;;104458:56:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;104552:17:0::1;::::0;104529:60:::1;::::0;-1:-1:-1;;;104529:60:0;;-1:-1:-1;;;;;104552:17:0;;::::1;104529:60;::::0;::::1;15328:51:1::0;15395:18;;;15388:34;;;104529:22:0;;::::1;::::0;::::1;::::0;15301:18:1;;104529:60:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;104627:9:0::1;::::0;104604:44:::1;::::0;-1:-1:-1;;;104604:44:0;;-1:-1:-1;;;;;104627:9:0;;::::1;104604:44;::::0;::::1;15328:51:1::0;15395:18;;;15388:34;;;104604:22:0;;::::1;::::0;::::1;::::0;15301:18:1;;104604:44:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;103860:800;;;103834:826;103739:928;76502:233:::0;103666:1001;;:::o;93666:78::-;59247:13;:11;:13::i;:::-;93721:8:::1;:15:::0;;-1:-1:-1;;93721:15:0::1;93732:4;93721:15;::::0;;93666:78::o;105977:486::-;-1:-1:-1;;;;;;;;;;;66348:16:0;66359:4;66348:10;:16::i;:::-;-1:-1:-1;;;;;106109:25:0;::::1;106087:130;;;::::0;-1:-1:-1;;;106087:130:0;;21247:2:1;106087:130:0::1;::::0;::::1;21229:21:1::0;21286:2;21266:18;;;21259:30;21325:34;21305:18;;;21298:62;21396:25;21376:18;;;21369:53;21439:19;;106087:130:0::1;21045:419:1::0;106087:130:0::1;106273:8;::::0;-1:-1:-1;;;;;106273:8:0::1;::::0;;::::1;::::0;::::1;106250:32:::0;;::::1;::::0;106228:127:::1;;;::::0;-1:-1:-1;;;106228:127:0;;21671:2:1;106228:127:0::1;::::0;::::1;21653:21:1::0;21710:2;21690:18;;;21683:30;21749:34;21729:18;;;21722:62;-1:-1:-1;;;21800:18:1;;;21793:43;21853:19;;106228:127:0::1;21469:409:1::0;106228:127:0::1;106368:8;:38:::0;;-1:-1:-1;;;;;106368:38:0;::::1;;;-1:-1:-1::0;;;;;;106368:38:0;::::1;::::0;::::1;::::0;;;106422:12:::1;::::0;;;;;;106417:38:::1;;106436:12;:19:::0;;-1:-1:-1;;106436:19:0::1;106451:4;106436:19;::::0;;105977:486;;:::o;66752:147::-;66838:4;66862:12;;;;;;;;;;;-1:-1:-1;;;;;66862:29:0;;;;;;;;;;;;;;;66752:147::o;107050:279::-;-1:-1:-1;;;;;;;;;;;66348:16:0;66359:4;66348:10;:16::i;:::-;107195:22:::1;:34:::0;;-1:-1:-1;;;;;;107195:34:0::1;-1:-1:-1::0;;;;;107195:34:0;::::1;::::0;;::::1;::::0;;;107240:20:::1;:30:::0;;;107286:35:::1;::::0;::::1;::::0;-1:-1:-1;;107286:35:0::1;107050:279:::0;;;:::o;108060:602::-;108188:8;;;;;-1:-1:-1;;;;;108188:8:0;108164:12;:10;:12::i;:::-;-1:-1:-1;;;;;108164:33:0;;108142:113;;;;-1:-1:-1;;;108142:113:0;;22085:2:1;108142:113:0;;;22067:21:1;22124:2;22104:18;;;22097:30;22163:32;22143:18;;;22136:60;22213:18;;108142:113:0;21883:354:1;108142:113:0;108289:4;108268:18;108313:342;108337:10;108333:1;:14;108313:342;;;108369:19;108391:4;;108396:1;108391:7;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;108369:29;;108413:19;108435:22;108445:11;108435:9;:22::i;:::-;108413:44;;108577:66;108592:11;108613:8;;;;;;;;;-1:-1:-1;;;;;108613:8:0;108624:11;108637:5;108577:14;:66::i;:::-;108354:301;;108349:3;;;;;:::i;:::-;;;;108313:342;;83478:300;83596:4;83613:135;83636:12;:10;:12::i;:::-;83663:7;83722:15;83685:11;:25;83697:12;:10;:12::i;:::-;-1:-1:-1;;;;;83685:25:0;;;;;;;;;;;;;;;;;-1:-1:-1;83685:25:0;;;:34;;;;;;;;;;:52;;;;:::i;80913:223::-;105192:12;;81047:4;;81019:9;;81030:6;;105192:12;;105188:101;;;105221:8;;;;;-1:-1:-1;;;;;105221:8:0;:23;105245:12;:10;:12::i;:::-;105221:56;;-1:-1:-1;;;;;;105221:56:0;;;;;;;-1:-1:-1;;;;;20923:15:1;;;105221:56:0;;;20905:34:1;20975:15;;;20955:18;;;20948:43;21007:18;;;21000:34;;;20840:18;;105221:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105188:101;81064:42:::1;81074:12;:10;:12::i;:::-;81088:9;81099:6;81064:9;:42::i;:::-;-1:-1:-1::0;81124:4:0::1;::::0;80913:223;-1:-1:-1;;;;80913:223:0:o;109262:382::-;105738:13;;-1:-1:-1;;;;;105738:13:0;105722:12;:10;:12::i;:::-;-1:-1:-1;;;;;105722:29:0;;105700:109;;;;-1:-1:-1;;;105700:109:0;;;;;;;:::i;:::-;109342:24:::1;;109370:1;109342:29:::0;109334:70:::1;;;::::0;-1:-1:-1;;;109334:70:0;;22716:2:1;109334:70:0::1;::::0;::::1;22698:21:1::0;22755:2;22735:18;;;22728:30;22794;22774:18;;;22767:58;22842:18;;109334:70:0::1;22514:352:1::0;109334:70:0::1;109465:15;109437:24;;:43;;109415:122;;;::::0;-1:-1:-1;;;109415:122:0;;23073:2:1;109415:122:0::1;::::0;::::1;23055:21:1::0;23112:2;23092:18;;;23085:30;23151:31;23131:18;;;23124:59;23200:18;;109415:122:0::1;22871:353:1::0;109415:122:0::1;109548:12;:20:::0;;-1:-1:-1;;109548:20:0::1;::::0;;109563:5:::1;109579:24;:28:::0;;;109623:13:::1;::::0;::::1;::::0;109563:5;109623:13:::1;109262:382::o:0;98377:480::-;98521:4;98527;98560:7;98548:9;:19;:42;;;;98583:7;98571:9;:19;98548:42;98544:86;;;-1:-1:-1;98613:7:0;;-1:-1:-1;98622:7:0;98605:25;;98544:86;98643:16;98662:19;98672:9;98662:7;:19;:::i;:::-;98643:38;-1:-1:-1;98692:16:0;98711:19;98721:9;98711:7;:19;:::i;:::-;98692:38;-1:-1:-1;98761:17:0;98771:7;98761;:17;:::i;:::-;98747:11;:31;98743:62;;;98788:7;98797;98780:25;;;;;;;;98743:62;98824:11;;-1:-1:-1;98837:11:0;-1:-1:-1;98377:480:0;;;;;;;;:::o;107445:420::-;107559:22;;-1:-1:-1;;;;;107559:22:0;107543:12;:10;:12::i;:::-;-1:-1:-1;;;;;107543:38:0;;107521:113;;;;-1:-1:-1;;;107521:113:0;;23431:2:1;107521:113:0;;;23413:21:1;23470:2;23450:18;;;23443:30;23509:27;23489:18;;;23482:55;23554:18;;107521:113:0;23229:349:1;107521:113:0;107671:20;;107653:14;;;;;;:38;107645:70;;;;-1:-1:-1;;;107645:70:0;;23785:2:1;107645:70:0;;;23767:21:1;23824:2;23804:18;;;23797:30;-1:-1:-1;;;23843:18:1;;;23836:49;23902:18;;107645:70:0;23583:343:1;107645:70:0;107742:22;;;107726:13;:38;;-1:-1:-1;;;;;107742:22:0;;-1:-1:-1;;;;;;107726:38:0;;;;;;;;107775:35;;;;;;107826:31;;;;-1:-1:-1;;107826:31:0;107445:420;:::o;91493:97::-;91538:14;;91572:10;:8;:10::i;:::-;91565:17;;;;91493:97;;:::o;69160:149::-;68353:7;68380:12;;;;;;;;;;:22;;;66348:16;66359:4;66348:10;:16::i;:::-;69275:26:::1;69287:4;69293:7;69275:11;:26::i;108768:390::-:0;105738:13;;-1:-1:-1;;;;;105738:13:0;105722:12;:10;:12::i;:::-;-1:-1:-1;;;;;105722:29:0;;105700:109;;;;-1:-1:-1;;;105700:109:0;;;;;;;:::i;:::-;108862:24:::1;::::0;:29;108840:111:::1;;;::::0;-1:-1:-1;;;108840:111:0;;24133:2:1;108840:111:0::1;::::0;::::1;24115:21:1::0;;;24152:18;;;24145:30;24211:34;24191:18;;;24184:62;24263:18;;108840:111:0::1;23931:356:1::0;108840:111:0::1;108970:12;::::0;::::1;;108962:53;;;::::0;-1:-1:-1;;;108962:53:0;;24494:2:1;108962:53:0::1;::::0;::::1;24476:21:1::0;24533:2;24513:18;;;24506:30;24572;24552:18;;;24545:58;24620:18;;108962:53:0::1;24292:352:1::0;108962:53:0::1;109071:14;::::0;109053:32:::1;::::0;:15:::1;:32;:::i;:::-;109026:24;:59:::0;;;109101:49:::1;::::0;2215:25:1;;;109101:49:0::1;::::0;2188:18:1;109101:49:0::1;;;;;;;108768:390::o:0;89412:257::-;-1:-1:-1;;;;;;;;;;;66348:16:0;66359:4;66348:10;:16::i;:::-;-1:-1:-1;;;;;89505:27:0;::::1;89497:55;;;::::0;-1:-1:-1;;;89497:55:0;;24851:2:1;89497:55:0::1;::::0;::::1;24833:21:1::0;24890:2;24870:18;;;24863:30;-1:-1:-1;;;24909:18:1;;;24902:45;24964:18;;89497:55:0::1;24649:339:1::0;89497:55:0::1;89563:9;:25:::0;;-1:-1:-1;;;;;;89563:25:0::1;-1:-1:-1::0;;;;;89563:25:0;::::1;::::0;;::::1;::::0;;;89604:57:::1;::::0;;25205:21:1;;;25262:2;25242:18;;;25235:30;;;;25301:32;25296:2;25281:18;;25274:60;25401:4;25386:20;;25379:62;;;;-1:-1:-1;;;;;;;;;;;89604:57:0;25366:3:1;25351:19;89604:57:0::1;24993:454:1::0;87889:330:0;-1:-1:-1;;;;;;;;;;;66348:16:0;66359:4;66348:10;:16::i;:::-;-1:-1:-1;;;;;87973:21:0;::::1;87965:52;;;::::0;-1:-1:-1;;;87965:52:0;;25654:2:1;87965:52:0::1;::::0;::::1;25636:21:1::0;25693:2;25673:18;;;25666:30;-1:-1:-1;;;25712:18:1;;;25705:48;25770:18;;87965:52:0::1;25452:342:1::0;87965:52:0::1;-1:-1:-1::0;;;;;88036:27:0;::::1;;::::0;;;:18:::1;:27;::::0;;;;;::::1;;88028:67;;;::::0;-1:-1:-1;;;88028:67:0;;26001:2:1;88028:67:0::1;::::0;::::1;25983:21:1::0;26040:2;26020:18;;;26013:30;26079:29;26059:18;;;26052:57;26126:18;;88028:67:0::1;25799:351:1::0;88028:67:0::1;-1:-1:-1::0;;;;;88106:27:0;::::1;88136:5;88106:27:::0;;;:18:::1;:27;::::0;;;;;;;;:35;;-1:-1:-1;;88106:35:0::1;::::0;;88157:54;;26367:21:1;;;26424:2;26404:18;;;26397:30;;;;26463:34;26458:2;26443:18;;26436:62;-1:-1:-1;;;26529:3:1;26514:19;;26507:32;26591:20;;26584:62;;;;-1:-1:-1;;;;;;;;;;;88157:54:0;26571:3:1;26556:19;88157:54:0::1;26155:497:1::0;89946:334:0;73174:16;66348;66359:4;66348:10;:16::i;:::-;90081:13:::1;90059;80185:7:::0;;;80105:95;90059:13:::1;:17;::::0;90075:1:::1;90059:17;:::i;:::-;90058:37;;;;:::i;:::-;90047:6;:49;;90025:150;;;::::0;-1:-1:-1;;;90025:150:0;;26859:2:1;90025:150:0::1;::::0;::::1;26841:21:1::0;26898:2;26878:18;;;26871:30;26937:34;26917:18;;;26910:62;-1:-1:-1;;;26988:18:1;;;26981:49;27047:19;;90025:150:0::1;26657:415:1::0;90025:150:0::1;90201:16;:6:::0;90210:7:::1;90201:16;:::i;:::-;90186:12;:31:::0;90233:39:::1;::::0;;27289:21:1;;;27346:2;27326:18;;;27319:30;;;;27385:26;27380:2;27365:18;;27358:54;27479:4;27464:20;;27457:36;;;90233:39:0::1;::::0;27444:3:1;27429:19;90233:39:0::1;27077:422:1::0;60267:201:0;59247:13;:11;:13::i;:::-;-1:-1:-1;;;;;60356:22:0;::::1;60348:73;;;::::0;-1:-1:-1;;;60348:73:0;;27706:2:1;60348:73:0::1;::::0;::::1;27688:21:1::0;27745:2;27725:18;;;27718:30;27784:34;27764:18;;;27757:62;-1:-1:-1;;;27835:18:1;;;27828:36;27881:19;;60348:73:0::1;27504:402:1::0;60348:73:0::1;60432:28;60451:8;60432:18;:28::i;44058:458::-:0;44120:14;44151:30;44170:10;44151:18;:30::i;:::-;44147:362;;;-1:-1:-1;;;44404:14:0;44400:23;44387:37;44383:2;44379:46;44058:458;:::o;44147:362::-;-1:-1:-1;43218:10:0;;44058:458::o;44479:18::-;44472:25;;44058:458;:::o;43138:98::-;43218:10;;43138:98::o;67203:105::-;67270:30;67281:4;67287:12;:10;:12::i;:::-;67270:10;:30::i;90835:182::-;90950:7;90982:27;:25;:27::i;99842:341::-;-1:-1:-1;;;;;99936:20:0;;99928:69;;;;-1:-1:-1;;;99928:69:0;;28113:2:1;99928:69:0;;;28095:21:1;28152:2;28132:18;;;28125:30;28191:34;28171:18;;;28164:62;-1:-1:-1;;;28242:18:1;;;28235:34;28286:19;;99928:69:0;27911:400:1;99928:69:0;-1:-1:-1;;;;;100016:21:0;;100008:68;;;;-1:-1:-1;;;100008:68:0;;28518:2:1;100008:68:0;;;28500:21:1;28557:2;28537:18;;;28530:30;28596:34;28576:18;;;28569:62;-1:-1:-1;;;28647:18:1;;;28640:32;28689:19;;100008:68:0;28316:398:1;100008:68:0;-1:-1:-1;;;;;100089:19:0;;;;;;;:11;:19;;;;;;;;:28;;;;;;;;;;;;;:37;;;100142:33;;2215:25:1;;;100142:33:0;;2188:18:1;100142:33:0;;;;;;;99842:341;;;:::o;100493:973::-;-1:-1:-1;;;;;100581:18:0;;100573:68;;;;-1:-1:-1;;;100573:68:0;;28921:2:1;100573:68:0;;;28903:21:1;28960:2;28940:18;;;28933:30;28999:34;28979:18;;;28972:62;-1:-1:-1;;;29050:18:1;;;29043:35;29095:19;;100573:68:0;28719:401:1;100573:68:0;-1:-1:-1;;;;;100660:16:0;;100652:64;;;;-1:-1:-1;;;100652:64:0;;29327:2:1;100652:64:0;;;29309:21:1;29366:2;29346:18;;;29339:30;29405:34;29385:18;;;29378:62;-1:-1:-1;;;29456:18:1;;;29449:33;29499:19;;100652:64:0;29125:399:1;100652:64:0;59434:6;;-1:-1:-1;;;;;100731:15:0;;;59434:6;;100731:15;;;;:32;;-1:-1:-1;59434:6:0;;-1:-1:-1;;;;;100750:13:0;;;59434:6;;100750:13;;100731:32;100727:175;;;100814:12;;100804:6;:22;;100778:124;;;;-1:-1:-1;;;100778:124:0;;29731:2:1;100778:124:0;;;29713:21:1;29770:2;29750:18;;;29743:30;29809:34;29789:18;;;29782:62;-1:-1:-1;;;29860:18:1;;;29853:38;29908:19;;100778:124:0;29529:404:1;100778:124:0;100927:12;-1:-1:-1;;;;;100919:20:0;:4;-1:-1:-1;;;;;100919:20:0;;:39;;;;;100949:9;-1:-1:-1;;;;;100943:15:0;:2;-1:-1:-1;;;;;100943:15:0;;;100919:39;100915:137;;;101009:10;;100999:6;100983:13;100993:2;100983:9;:13::i;:::-;:22;;;;:::i;:::-;:36;;100975:65;;;;-1:-1:-1;;;100975:65:0;;30140:2:1;100975:65:0;;;30122:21:1;30179:2;30159:18;;;30152:30;-1:-1:-1;;;30198:18:1;;;30191:46;30254:18;;100975:65:0;29938:340:1;100975:65:0;-1:-1:-1;;;;;101245:24:0;;101125:12;101245:24;;;:18;:24;;;;;;101140:4;;101245:24;;;:50;;-1:-1:-1;;;;;;101273:22:0;;;;;;:18;:22;;;;;;;;101245:50;101241:98;;;-1:-1:-1;101322:5:0;101241:98;101417:41;101432:4;101438:2;101442:6;101450:7;101417:14;:41::i;97790:161::-;97832:7;97853:15;97870;97889:19;:17;:19::i;:::-;97852:56;;-1:-1:-1;97852:56:0;-1:-1:-1;97926:17:0;97852:56;;97926:17;:::i;:::-;97919:24;;;;97790:161;:::o;71461:238::-;71545:22;71553:4;71559:7;71545;:22::i;:::-;71540:152;;71584:6;:12;;;;;;;;;;;-1:-1:-1;;;;;71584:29:0;;;;;;;;;:36;;-1:-1:-1;;71584:36:0;71616:4;71584:36;;;71667:12;:10;:12::i;:::-;-1:-1:-1;;;;;71640:40:0;71658:7;-1:-1:-1;;;;;71640:40:0;71652:4;71640:40;;;;;;;;;;71461:238;;:::o;71879:239::-;71963:22;71971:4;71977:7;71963;:22::i;:::-;71959:152;;;72034:5;72002:12;;;;;;;;;;;-1:-1:-1;;;;;72002:29:0;;;;;;;;;:37;;-1:-1:-1;;72002:37:0;;;72086:12;:10;:12::i;:::-;-1:-1:-1;;;;;72059:40:0;72077:7;-1:-1:-1;;;;;72059:40:0;72071:4;72059:40;;;;;;;;;;71879:239;;:::o;95826:550::-;95942:15;95972:23;96010:12;96037:23;96075:12;96141:20;96153:7;96141:11;:20::i;:::-;96115:46;-1:-1:-1;96115:46:0;-1:-1:-1;96207:88:0;96233:7;96115:46;96274:10;:8;:10::i;:::-;96207:11;:88::i;:::-;96172:123;;;;-1:-1:-1;96172:123:0;;-1:-1:-1;95826:550:0;;-1:-1:-1;95826:550:0;-1:-1:-1;95826:550:0:o;59526:132::-;59601:12;:10;:12::i;:::-;-1:-1:-1;;;;;59590:23:0;:7;59434:6;;-1:-1:-1;;;;;59434:6:0;;59361:87;59590:7;-1:-1:-1;;;;;59590:23:0;;59582:68;;;;-1:-1:-1;;;59582:68:0;;30485:2:1;59582:68:0;;;30467:21:1;;;30504:18;;;30497:30;30563:34;30543:18;;;30536:62;30615:18;;59582:68:0;30283:356:1;86991:185:0;87053:47;;-1:-1:-1;;;87053:47:0;;;;;2215:25:1;;;87067:12:0;-1:-1:-1;;;;;87053:42:0;;;;2188:18:1;;87053:47:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;87053:47:0;;;;;;;;-1:-1:-1;;87053:47:0;;;;;;;;;;;;:::i;:::-;;;87049:120;;87130:27;;;30856:21:1;;;30913:2;30893:18;;;30886:30;-1:-1:-1;;;30947:2:1;30932:18;;30925:45;31037:4;31022:20;;31015:36;;;87130:27:0;;;;;;;31002:3:1;87130:27:0;;;91816:287;:::o;60628:191::-;60721:6;;;-1:-1:-1;;;;;60738:17:0;;;-1:-1:-1;;;;;;60738:17:0;;;;;;;60771:40;;60721:6;;;60738:17;60721:6;;60771:40;;60702:16;;60771:40;60691:128;60628:191;:::o;101829:1611::-;101985:8;;;;101980:134;;59434:6;;-1:-1:-1;;;;;102018:17:0;;;59434:6;;102018:17;102010:44;;;;-1:-1:-1;;;102010:44:0;;31264:2:1;102010:44:0;;;31246:21:1;31303:2;31283:18;;;31276:30;-1:-1:-1;;;31322:18:1;;;31315:44;31376:18;;102010:44:0;31062:338:1;102010:44:0;-1:-1:-1;;;;;102130:18:0;;;;;;:10;:18;;;;;;;;;:43;;-1:-1:-1;;;;;;102152:21:0;;;;;;:10;:21;;;;;;;;102130:43;102126:113;;;102190:37;;-1:-1:-1;;;102190:37:0;;31607:2:1;102190:37:0;;;31589:21:1;31646:2;31626:18;;;31619:30;31685:29;31665:18;;;31658:57;31732:18;;102190:37:0;31405:351:1;102126:113:0;102256:7;102251:28;;102265:14;:12;:14::i;:::-;-1:-1:-1;;;;;102312:19:0;;;102292:17;102312:19;;;:11;:19;;;;;;;102360:22;;;;;;;;102312:19;;;;;102360:22;;102292:17;;;;102608:18;102619:6;102608:10;:18::i;:::-;102410:216;;;;;;;;;;102662:7;102643;:15;102651:6;-1:-1:-1;;;;;102643:15:0;-1:-1:-1;;;;;102643:15:0;;;;;;;;;;;;;:26;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;102684:18:0;;;;;;:7;:18;;;;;:37;;102706:15;;102684:18;:37;;102706:15;;102684:37;:::i;:::-;;;;-1:-1:-1;;102738:542:0;;;;-1:-1:-1;;;;;102775:15:0;;;;;;:7;:15;;;;;:25;;102794:6;;102775:15;:25;;102794:6;;102775:25;:::i;:::-;;;;-1:-1:-1;;102819:216:0;;;;-1:-1:-1;;;;;102858:18:0;;;;;;:7;:18;;;;;:37;;102880:15;;102858:18;:37;;102880:15;;102858:37;:::i;:::-;;;;-1:-1:-1;102738:542:0;;-1:-1:-1;102738:542:0;102819:216;102957:7;102944:9;;:20;;;;;;;:::i;:::-;;;;;;;;103000:15;102987:9;;:28;;;;;;;:::i;102738:542::-;103079:10;103075:190;;;-1:-1:-1;;;;;103114:18:0;;;;;;:7;:18;;;;;:37;;103136:15;;103114:18;:37;;103136:15;;103114:37;:::i;:::-;;;;;;;;103187:7;103174:9;;:20;;;;;;;:::i;:::-;;;;;;;;103230:15;103217:9;;:28;;;;;;;:::i;:::-;;;;-1:-1:-1;;103075:190:0;103294:23;103306:4;103312;103294:11;:23::i;:::-;103354:9;-1:-1:-1;;;;;103337:44:0;103346:6;-1:-1:-1;;;;;103337:44:0;;103365:15;103337:44;;;;2215:25:1;;2203:2;2188:18;;2069:177;103337:44:0;;;;;;;;102395:998;;;;;103408:7;103403:29;;103417:15;99414;;99404:7;:25;99360:77;103417:15;101969:1471;;101829:1611;;;;:::o;91185:185::-;91298:14;;91337:25;:23;:25::i;67598:492::-;67687:22;67695:4;67701:7;67687;:22::i;:::-;67682:401;;67875:28;67895:7;67875:19;:28::i;:::-;67976:38;68004:4;68011:2;67976:19;:38::i;:::-;67780:257;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;67780:257:0;;;;;;;;;;-1:-1:-1;;;67726:345:0;;;;;;;:::i;98224:145::-;98275:7;98284;98311:50;98322:7;;98331;;98340:9;;98351;;98311:10;:50::i;96618:208::-;96694:12;96708:23;96751:24;96767:7;96751:15;:24::i;:::-;96744:31;-1:-1:-1;96804:14:0;96744:31;96804:7;:14;:::i;:::-;96786:32;;96618:208;;;:::o;97289:346::-;97445:15;;;97527:21;97537:11;97527:7;:21;:::i;:::-;97517:31;-1:-1:-1;97566:18:0;97573:11;97566:4;:18;:::i;:::-;97559:25;-1:-1:-1;97613:14:0;97559:25;97613:7;:14;:::i;:::-;97595:32;;97289:346;;;;;;;:::o;99185:133::-;99232:7;;99243:1;99232:12;99228:25;;99185:133::o;99228:25::-;99281:7;;;99263:15;:25;-1:-1:-1;99299:11:0;;99185:133::o;95217:141::-;95305:4;95295:7;;:14;;;;:::i;:::-;95285:7;:24;95333:10;;:17;;95346:4;;95333:17;:::i;:::-;95320:10;:30;-1:-1:-1;;95217:141:0:o;44524:251::-;44584:14;;44615:30;44634:10;44615:18;:30::i;:::-;44611:157;;;44669:8;;;44679:20;44697:2;44669:8;44679:20;:::i;:::-;44669:31;;;;;;;:::i;44611:157::-;43295:14;;44740:16;43244:101;42295:151;42353:13;42386:52;-1:-1:-1;;;;;42398:22:0;;40450:2;41691:447;41766:13;41792:19;41824:10;41828:6;41824:1;:10;:::i;:::-;:14;;41837:1;41824:14;:::i;:::-;41814:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41814:25:0;;41792:47;;-1:-1:-1;;;41850:6:0;41857:1;41850:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;41850:15:0;;;;;;;;;-1:-1:-1;;;41876:6:0;41883:1;41876:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;41876:15:0;;;;;;;;-1:-1:-1;41907:9:0;41919:10;41923:6;41919:1;:10;:::i;:::-;:14;;41932:1;41919:14;:::i;:::-;41907:26;;41902:131;41939:1;41935;:5;41902:131;;;-1:-1:-1;;;41983:5:0;41991:3;41983:11;41974:21;;;;;;;:::i;:::-;;;;41962:6;41969:1;41962:9;;;;;;;;:::i;:::-;;;;:33;-1:-1:-1;;;;;41962:33:0;;;;;;;;-1:-1:-1;42020:1:0;42010:11;;;;;41942:3;;;:::i;:::-;;;41902:131;;;-1:-1:-1;42051:10:0;;42043:55;;;;-1:-1:-1;;;42043:55:0;;33257:2:1;42043:55:0;;;33239:21:1;;;33276:18;;;33269:30;33335:34;33315:18;;;33308:62;33387:18;;42043:55:0;33055:356:1;99012:132:0;99114:7;;99076;;74924:6;;99104:17;;:7;:17;:::i;:::-;99103:33;;;;:::i;14:286:1:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:1;;209:43;;199:71;;266:1;263;256:12;497:131;-1:-1:-1;;;;;572:31:1;;562:42;;552:70;;618:1;615;608:12;633:247;692:6;745:2;733:9;724:7;720:23;716:32;713:52;;;761:1;758;751:12;713:52;800:9;787:23;819:31;844:5;819:31;:::i;885:250::-;970:1;980:113;994:6;991:1;988:13;980:113;;;1070:11;;;1064:18;1051:11;;;1044:39;1016:2;1009:10;980:113;;;-1:-1:-1;;1127:1:1;1109:16;;1102:27;885:250::o;1140:396::-;1289:2;1278:9;1271:21;1252:4;1321:6;1315:13;1364:6;1359:2;1348:9;1344:18;1337:34;1380:79;1452:6;1447:2;1436:9;1432:18;1427:2;1419:6;1415:15;1380:79;:::i;:::-;1520:2;1499:15;-1:-1:-1;;1495:29:1;1480:45;;;;1527:2;1476:54;;1140:396;-1:-1:-1;;1140:396:1:o;1541:315::-;1609:6;1617;1670:2;1658:9;1649:7;1645:23;1641:32;1638:52;;;1686:1;1683;1676:12;1638:52;1725:9;1712:23;1744:31;1769:5;1744:31;:::i;:::-;1794:5;1846:2;1831:18;;;;1818:32;;-1:-1:-1;;;1541:315:1:o;2251:456::-;2328:6;2336;2344;2397:2;2385:9;2376:7;2372:23;2368:32;2365:52;;;2413:1;2410;2403:12;2365:52;2452:9;2439:23;2471:31;2496:5;2471:31;:::i;:::-;2521:5;-1:-1:-1;2578:2:1;2563:18;;2550:32;2591:33;2550:32;2591:33;:::i;:::-;2251:456;;2643:7;;-1:-1:-1;;;2697:2:1;2682:18;;;;2669:32;;2251:456::o;2712:180::-;2771:6;2824:2;2812:9;2803:7;2799:23;2795:32;2792:52;;;2840:1;2837;2830:12;2792:52;-1:-1:-1;2863:23:1;;2712:180;-1:-1:-1;2712:180:1:o;3264:315::-;3332:6;3340;3393:2;3381:9;3372:7;3368:23;3364:32;3361:52;;;3409:1;3406;3399:12;3361:52;3445:9;3432:23;3422:33;;3505:2;3494:9;3490:18;3477:32;3518:31;3543:5;3518:31;:::i;:::-;3568:5;3558:15;;;3264:315;;;;;:::o;4271:118::-;4357:5;4350:13;4343:21;4336:5;4333:32;4323:60;;4379:1;4376;4369:12;4394:309;4459:6;4467;4520:2;4508:9;4499:7;4495:23;4491:32;4488:52;;;4536:1;4533;4526:12;4488:52;4572:9;4559:23;4549:33;;4632:2;4621:9;4617:18;4604:32;4645:28;4667:5;4645:28;:::i;4708:385::-;4794:6;4802;4810;4818;4871:3;4859:9;4850:7;4846:23;4842:33;4839:53;;;4888:1;4885;4878:12;4839:53;-1:-1:-1;;4911:23:1;;;4981:2;4966:18;;4953:32;;-1:-1:-1;5032:2:1;5017:18;;5004:32;;5083:2;5068:18;5055:32;;-1:-1:-1;4708:385:1;-1:-1:-1;4708:385:1:o;5931:615::-;6017:6;6025;6078:2;6066:9;6057:7;6053:23;6049:32;6046:52;;;6094:1;6091;6084:12;6046:52;6134:9;6121:23;6163:18;6204:2;6196:6;6193:14;6190:34;;;6220:1;6217;6210:12;6190:34;6258:6;6247:9;6243:22;6233:32;;6303:7;6296:4;6292:2;6288:13;6284:27;6274:55;;6325:1;6322;6315:12;6274:55;6365:2;6352:16;6391:2;6383:6;6380:14;6377:34;;;6407:1;6404;6397:12;6377:34;6460:7;6455:2;6445:6;6442:1;6438:14;6434:2;6430:23;6426:32;6423:45;6420:65;;;6481:1;6478;6471:12;6420:65;6512:2;6504:11;;;;;6534:6;;-1:-1:-1;5931:615:1;;-1:-1:-1;;;;5931:615:1:o;6804:127::-;6865:10;6860:3;6856:20;6853:1;6846:31;6896:4;6893:1;6886:15;6920:4;6917:1;6910:15;6936:921;7004:6;7057:2;7045:9;7036:7;7032:23;7028:32;7025:52;;;7073:1;7070;7063:12;7025:52;7113:9;7100:23;7142:18;7183:2;7175:6;7172:14;7169:34;;;7199:1;7196;7189:12;7169:34;7237:6;7226:9;7222:22;7212:32;;7282:7;7275:4;7271:2;7267:13;7263:27;7253:55;;7304:1;7301;7294:12;7253:55;7340:2;7327:16;7362:2;7358;7355:10;7352:36;;;7368:18;;:::i;:::-;7443:2;7437:9;7411:2;7497:13;;-1:-1:-1;;7493:22:1;;;7517:2;7489:31;7485:40;7473:53;;;7541:18;;;7561:22;;;7538:46;7535:72;;;7587:18;;:::i;:::-;7627:10;7623:2;7616:22;7662:2;7654:6;7647:18;7702:7;7697:2;7692;7688;7684:11;7680:20;7677:33;7674:53;;;7723:1;7720;7713:12;7674:53;7779:2;7774;7770;7766:11;7761:2;7753:6;7749:15;7736:46;7824:1;7802:15;;;7819:2;7798:24;7791:35;;;;-1:-1:-1;7806:6:1;6936:921;-1:-1:-1;;;;;6936:921:1:o;7862:388::-;8019:2;8008:9;8001:21;8058:6;8053:2;8042:9;8038:18;8031:34;8115:6;8107;8102:2;8091:9;8087:18;8074:48;8171:1;8142:22;;;8166:2;8138:31;;;8131:42;;;;8234:2;8213:15;;;-1:-1:-1;;8209:29:1;8194:45;8190:54;;7862:388;-1:-1:-1;7862:388:1:o;8255:::-;8323:6;8331;8384:2;8372:9;8363:7;8359:23;8355:32;8352:52;;;8400:1;8397;8390:12;8352:52;8439:9;8426:23;8458:31;8483:5;8458:31;:::i;:::-;8508:5;-1:-1:-1;8565:2:1;8550:18;;8537:32;8578:33;8537:32;8578:33;:::i;10198:127::-;10259:10;10254:3;10250:20;10247:1;10240:31;10290:4;10287:1;10280:15;10314:4;10311:1;10304:15;10330:128;10397:9;;;10418:11;;;10415:37;;;10432:18;;:::i;10463:168::-;10536:9;;;10567;;10584:15;;;10578:22;;10564:37;10554:71;;10605:18;;:::i;10636:217::-;10676:1;10702;10692:132;;10746:10;10741:3;10737:20;10734:1;10727:31;10781:4;10778:1;10771:15;10809:4;10806:1;10799:15;10692:132;-1:-1:-1;10838:9:1;;10636:217::o;12753:335::-;12955:2;12937:21;;;12994:2;12974:18;;;12967:30;-1:-1:-1;;;13028:2:1;13013:18;;13006:41;13079:2;13064:18;;12753:335::o;14835:125::-;14900:9;;;14921:10;;;14918:36;;;14934:18;;:::i;14965:184::-;15035:6;15088:2;15076:9;15067:7;15063:23;15059:32;15056:52;;;15104:1;15101;15094:12;15056:52;-1:-1:-1;15127:16:1;;14965:184;-1:-1:-1;14965:184:1:o;15433:245::-;15500:6;15553:2;15541:9;15532:7;15528:23;15524:32;15521:52;;;15569:1;15566;15559:12;15521:52;15601:9;15595:16;15620:28;15642:5;15620:28;:::i;17665:354::-;17867:2;17849:21;;;17906:2;17886:18;;;17879:30;17945:32;17940:2;17925:18;;17918:60;18010:2;17995:18;;17665:354::o;22242:127::-;22303:10;22298:3;22294:20;22291:1;22284:31;22334:4;22331:1;22324:15;22358:4;22355:1;22348:15;22374:135;22413:3;22434:17;;;22431:43;;22454:18;;:::i;:::-;-1:-1:-1;22501:1:1;22490:13;;22374:135::o;31761:812::-;32172:25;32167:3;32160:38;32142:3;32227:6;32221:13;32243:75;32311:6;32306:2;32301:3;32297:12;32290:4;32282:6;32278:17;32243:75;:::i;:::-;-1:-1:-1;;;32377:2:1;32337:16;;;32369:11;;;32362:40;32427:13;;32449:76;32427:13;32511:2;32503:11;;32496:4;32484:17;;32449:76;:::i;:::-;32545:17;32564:2;32541:26;;31761:812;-1:-1:-1;;;;31761:812:1:o;32578:331::-;32683:9;32694;32736:8;32724:10;32721:24;32718:44;;;32758:1;32755;32748:12;32718:44;32787:6;32777:8;32774:20;32771:40;;;32807:1;32804;32797:12;32771:40;-1:-1:-1;;32833:23:1;;;32878:25;;;;;-1:-1:-1;32578:331:1:o;32914:136::-;32953:3;32981:5;32971:39;;32990:18;;:::i;:::-;-1:-1:-1;;;33026:18:1;;32914:136::o

Swarm Source

ipfs://5c93e450317ff83c48891892b6b11e4c57e91c6cf50871173e53f483b181cd72
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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