ERC-20
Artificial Intelligence
Overview
Max Total Supply
1,000,000 SOUTH
Holders
3,697 ( -0.054%)
Market
Price
$3.70 @ 0.001041 ETH (+4.24%)
Onchain Market Cap
$3,699,007.68
Circulating Supply Market Cap
$0.00
Other Info
Token Contract (WITH 18 Decimals)
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
DeepSouthAI
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2024-01-05 */ /** * @dev This smart contract was developed based on the general * OpenZeppelin Contracts guidelines where functions revert instead of * returning `false` on failure. */ // SPDX-License-Identifier: MIT pragma solidity 0.8.18; /******************************************************************************************** LIBRARY ********************************************************************************************/ /** * @title Address Library * * @notice Collection of functions providing utility for interacting with addresses. */ library Address { // ERROR /** * @notice Error indicating insufficient balance while performing an operation. * * @param account Address where the balance is insufficient. */ error AddressInsufficientBalance(address account); /** * @notice Error indicating an attempt to interact with a contract having empty code. * * @param target Address of the contract with empty code. */ error AddressEmptyCode(address target); /** * @notice Error indicating a failed internal call. */ error FailedInnerCall(); // FUNCTION /** * @notice Calls a function on a specified address without transferring value. * * @param target Address on which the function will be called. * @param data Encoded data of the function call. * * @return returndata Result of the function call. * * @dev The `target` must be a contract address and this function must be calling * `target` with `data` not reverting. */ function functionCall( address target, bytes memory data ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @notice Calls a function on a specified address with a specified value. * * @param target Address on which the function will be called. * @param data Encoded data of the function call. * @param value Value to be sent in the call. * * @return returndata Result of the function call. * * @dev This function ensure that the calling contract actually have Ether balance * of at least `value` and that the called Solidity function is a `payable`. Should * throw if caller does have insufficient balance. */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}( data ); return verifyCallResultFromTarget(target, success, returndata); } /** * @notice Verifies the result of a function call and handles errors if any. * * @param target Address on which the function was called. * @param success Boolean indicating the success of the function call. * @param returndata Result data of the function call. * * @return Result of the function call or reverts with an appropriate error. * * @dev This help to verify that a low level call to smart-contract was successful * and will reverts if the target was not a contract. For unsuccessful call, this * will bubble up the revert reason (falling back to {FailedInnerCall}). Should * throw if both the returndata and target.code length are 0 when `success` is true. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @notice Reverts with decoded revert data or FailedInnerCall if no revert * data is available. * * @param returndata Result data of a failed function call. * * @dev Should throw if returndata length is 0. */ function _revert(bytes memory returndata) private pure { if (returndata.length > 0) { assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } } /** * @title SafeERC20 Library * * @notice Collection of functions providing utility for safe operations with * ERC20 tokens. * * @dev This is mainly for the usage of token that throw on failure (when the * token contract returns false). Tokens that return no value (and instead revert * or throw on failure) are also supported where non-reverting calls are assumed * to be a successful transaction. */ library SafeERC20 { // LIBRARY using Address for address; // ERROR /** * @notice Error indicating a failed operation during an ERC-20 token transfer. * * @param token Address of the token contract. */ error SafeERC20FailedOperation(address token); // FUNCTION /** * @notice Safely transfers tokens. * * @param token ERC20 token interface. * @param to Address to which the tokens will be transferred. * @param value Amount of tokens to be transferred. * * @dev Transfer `value` amount of `token` from the calling contract to `to` where * non-reverting calls are assumed to be successful if `token` returns no value. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @notice Calls a function on a token contract and reverts if the operation fails. * * @param token ERC20 token interface. * @param data Encoded data of the function call. * * @dev This imitates a Solidity high-level call such as a regular function call to * a contract while relaxing the requirement on the return value. */ function _callOptionalReturn(IERC20 token, bytes memory data) private { bytes memory returndata = address(token).functionCall(data); if (returndata.length != 0 && !abi.decode(returndata, (bool))) { revert SafeERC20FailedOperation(address(token)); } } } /******************************************************************************************** INTERFACE ********************************************************************************************/ /** * @title Router Interface * * @notice Interface of the Router contract, providing functions to interact with * Router contract that is derived from Uniswap V2 Router. * * @dev See https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02 */ interface IRouter { // FUNCTION /** * @notice Get the address of the Wrapped Ether (WETH) token. * * @return The address of the WETH token. */ function WETH() external pure returns (address); /** * @notice Get the address of the linked Factory contract. * * @return The address of the Factory contract. */ function factory() external pure returns (address); /** * @notice Swaps an exact amount of tokens for ETH, supporting * tokens that implement fee-on-transfer mechanisms. * * @param amountIn The exact amount of input tokens for the swap. * @param amountOutMin The minimum acceptable amount of ETH to receive in the swap. * @param path An array of token addresses representing the token swap path. * @param to The recipient address that will receive the swapped ETH. * @param deadline The timestamp by which the transaction must be executed to be * considered valid. * * @dev This function swaps a specific amount of tokens for ETH on a specified path, * ensuring a minimum amount of output ETH. */ function swapExactTokensForETHSupportingFeeOnTransferTokens(uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline) external; /** * @notice Swaps a precise amount of ETH for tokens, supporting tokens with fee-on-transfer mechanisms. * * @param amountOutMin The minimum acceptable amount of output tokens expected from the swap. * @param path An array of token addresses representing the token swap path. * @param to The recipient address that will receive the swapped tokens. * @param deadline The timestamp by which the transaction must be executed to be considered valid. * * @dev This function performs a direct swap of a specified amount of ETH for tokens based on the provided * path and minimum acceptable output token amount. */ function swapExactETHForTokensSupportingFeeOnTransferTokens(uint256 amountOutMin, address[] calldata path, address to, uint256 deadline) external payable; } /** * @title Factory Interface * * @notice Interface of the Factory contract, providing functions to interact with * Factory contract that is derived from Uniswap V2 Factory. * * @dev See https://docs.uniswap.org/contracts/v2/reference/smart-contracts/factory */ interface IFactory { // FUNCTION /** * @notice Create a new token pair for two given tokens on Uniswap V2-based factory. * * @param tokenA The address of the first token. * @param tokenB The address of the second token. * * @return pair The address of the created pair for the given tokens. */ function createPair(address tokenA, address tokenB) external returns (address pair); /** * @notice Get the address of the pair for two tokens on the decentralized exchange. * * @param tokenA The address of the first token. * @param tokenB The address of the second token. * * @return pair The address of the pair corresponding to the provided tokens. */ function getPair(address tokenA, address tokenB) external view returns (address pair); } /** * @title Pair Interface * * @notice Interface of the Pair contract in a decentralized exchange based on the * Pair contract that is derived from Uniswap V2 Pair. * * @dev See https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair */ interface IPair { // FUNCTION /** * @notice Get the address of the first token in the pair. * * @return The address of the first token. */ function token0() external view returns (address); /** * @notice Get the address of the second token in the pair. * * @return The address of the second token. */ function token1() external view returns (address); } /** * @title ERC20 Token Standard Interface * * @notice Interface of the ERC-20 standard token as defined in the ERC. * * @dev See https://eips.ethereum.org/EIPS/eip-20 */ interface IERC20 { // EVENT /** * @notice Emitted when `value` tokens are transferred from * one account (`from`) to another (`to`). * * @param from The address tokens are transferred from. * @param to The address tokens are transferred to. * @param value The amount of tokens transferred. * * @dev The `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @notice Emitted when the allowance of a `spender` for an `owner` * is set by a call to {approve}. * * @param owner The address allowing `spender` to spend on their behalf. * @param spender The address allowed to spend tokens on behalf of `owner`. * @param value The allowance amount set for `spender`. * * @dev The `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); // FUNCTION /** * @notice Returns the value of tokens in existence. * * @return The value of the total supply of tokens. * * @dev This should get the total token supply. */ function totalSupply() external view returns (uint256); /** * @notice Returns the value of tokens owned by `account`. * * @param account The address to query the balance for. * * @return The token balance of `account`. * * @dev This should get the token balance of a specific account. */ function balanceOf(address account) external view returns (uint256); /** * @notice Moves a `value` amount of tokens from the caller's account to `to`. * * @param to The address to transfer tokens to. * @param value The amount of tokens to be transferred. * * @return A boolean indicating whether the transfer was successful or not. * * @dev This should transfer tokens to a specified address and emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @notice Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. * * @param owner The address allowing `spender` to spend on their behalf. * @param spender The address allowed to spend tokens on behalf of `owner`. * * @return The allowance amount for `spender`. * * @dev The return value should be zero by default and * changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @notice Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * @param spender The address allowed to spend tokens on behalf of the sender. * @param value The allowance amount for `spender`. * * @return A boolean indicating whether the approval was successful or not. * * @dev This should approve `spender` to spend a specified amount of tokens * on behalf of the sender and emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @notice Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's allowance. * * @param from The address to transfer tokens from. * @param to The address to transfer tokens to. * @param value The amount of tokens to be transferred. * * @return A boolean indicating whether the transfer was successful or not. * * @dev This should transfer tokens from one address to another after * spending caller's allowance and emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); } /** * @title ERC20 Token Metadata Interface * * @notice Interface for the optional metadata functions of the ERC-20 standard as defined in the ERC. * * @dev It extends the IERC20 interface. See https://eips.ethereum.org/EIPS/eip-20 */ interface IERC20Metadata is IERC20 { // FUNCTION /** * @notice Returns the name of the token. * * @return The name of the token as a string. */ function name() external view returns (string memory); /** * @notice Returns the symbol of the token. * * @return The symbol of the token as a string. */ function symbol() external view returns (string memory); /** * @notice Returns the number of decimals used to display the token. * * @return The number of decimals as a uint8. */ function decimals() external view returns (uint8); } /** * @title ERC20 Token Standard Error Interface * * @notice Interface of the ERC-6093 custom errors that defined common errors * related to the ERC-20 standard token functionalities. * * @dev See https://eips.ethereum.org/EIPS/eip-6093 */ interface IERC20Errors { // ERROR /** * @notice Error indicating that the `sender` has inssufficient `balance` for the operation. * * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * * @dev The `needed` value is required to inform user on the needed amount. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @notice Error indicating that the `sender` is invalid for the operation. * * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @notice Error indicating that the `receiver` is invalid for the operation. * * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @notice Error indicating that the `spender` does not have enough `allowance` for the operation. * * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. * * @dev The `needed` value is required to inform user on the needed amount. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @notice Error indicating that the `approver` is invalid for the approval operation. * * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @notice Error indicating that the `spender` is invalid for the allowance operation. * * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @title Common Error Interface * * @notice Interface of the common errors not specific to ERC-20 functionalities. */ interface ICommonError { // ERROR /** * @notice Error indicating that the `current` address cannot be used in this context. * * @param current Address used in the context. */ error CannotUseCurrentAddress(address current); /** * @notice Error indicating that the `current` value cannot be used in this context. * * @param current Value used in the context. */ error CannotUseCurrentValue(uint256 current); /** * @notice Error indicating that the `current` state cannot be used in this context. * * @param current Boolean state used in the context. */ error CannotUseCurrentState(bool current); /** * @notice Error indicating that the `invalid` address provided is not a valid address for this context. * * @param invalid Address used in the context. */ error InvalidAddress(address invalid); /** * @notice Error indicating that the `invalid` value provided is not a valid value for this context. * * @param invalid Value used in the context. */ error InvalidValue(uint256 invalid); } /******************************************************************************************** ACCESS ********************************************************************************************/ /** * @title Ownable Contract * * @notice Abstract contract module implementing ownership functionality through * inheritance as a basic access control mechanism, where there is an owner account * that can be granted exclusive access to specific functions. * * @dev The initial owner is set to the address provided by the deployer and can * later be changed with {transferOwnership}. */ abstract contract Ownable { // DATA address private _owner; // MODIFIER /** * @notice Modifier that allows access only to the contract owner. * * @dev Should throw if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } // ERROR /** * @notice Error indicating that the `account` is not authorized to perform an operation. * * @param account Address used to perform the operation. */ error OwnableUnauthorizedAccount(address account); /** * @notice Error indicating that the provided `owner` address is invalid. * * @param owner Address used to perform the operation. * * @dev Should throw if called by an invalid owner account such as address(0) as an example. */ error OwnableInvalidOwner(address owner); // CONSTRUCTOR /** * @notice Initializes the contract setting the `initialOwner` address provided by * the deployer as the initial owner. * * @param initialOwner The address to set as the initial owner. * * @dev Should throw an error if called with address(0) as the `initialOwner`. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } // EVENT /** * @notice Emitted when ownership of the contract is transferred. * * @param previousOwner The address of the previous owner. * @param newOwner The address of the new owner. */ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); // FUNCTION /** * @notice Get the address of the smart contract owner. * * @return The address of the current owner. * * @dev Should return the address of the current smart contract owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @notice Checks if the caller is the owner and reverts if not. * * @dev Should throw if the sender is not the current owner of the smart contract. */ function _checkOwner() internal view virtual { if (owner() != msg.sender) { revert OwnableUnauthorizedAccount(msg.sender); } } /** * @notice Allows the current owner to renounce ownership and make the * smart contract ownerless. * * @dev This function can only be called by the current owner and will * render all `onlyOwner` functions inoperable. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @notice Allows the current owner to transfer ownership of the smart contract * to `newOwner` address. * * @param newOwner The address to transfer ownership to. * * @dev This function can only be called by the current owner and will render * all `onlyOwner` functions inoperable to him/her. Should throw if called with * address(0) as the `newOwner`. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @notice Internal function to transfer ownership of the smart contract * to `newOwner` address. * * @param newOwner The address to transfer ownership to. * * @dev This function replace current owner address stored as _owner with * the address of the `newOwner`. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } /******************************************************************************************** TOKEN ********************************************************************************************/ /** * @title DeepSouth AI Token Contract * * @notice DeepSouth AI is an extended version of ERC-20 standard token that * includes additional functionalities for ownership control, trading enabling, * and token management. * * @dev Implements ERC20Metadata, ERC20Errors, and CommonError interfaces, and * extends Ownable contract. */ contract DeepSouthAI is Ownable, IERC20Metadata, IERC20Errors, ICommonError { // LIBRARY using SafeERC20 for IERC20; using Address for address; // DATA struct Fee { uint256 marketing; uint256 total; } Fee public buyFee = Fee(1000, 1000); Fee public sellFee = Fee(1000, 1000); Fee public transferFee = Fee(0, 0); Fee public collectedFee = Fee(0, 0); Fee public redeemedFee = Fee(0, 0); IRouter public router = IRouter(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); string private constant NAME = "DeepSouth AI"; string private constant SYMBOL = "SOUTH"; uint8 private constant DECIMALS = 18; uint256 public constant FEEDENOMINATOR = 10_000; uint256 public immutable deployTime; uint256 private _totalSupply; uint256 public tradeStartTime = 0; uint256 public tradeStartBlock = 0; uint256 public minSwap = 1_000 ether; uint256 public maxWalletLimit = 200; address public projectOwner = 0x8683b156e02a61924f36E1a88dD1D30964FeB7c5; address public marketingReceiver = 0xFFb44e038Cd5bfAD4807FF6ace10793ec9d6330e; address public pair; bool public tradeEnabled = false; bool public isFeeActive = false; bool public isFeeLocked = false; bool public isReceiverLocked = false; bool public isFailsafeLocked = false; bool public isWalletLimitLocked = false; bool public isWalletLimitActive = false; bool public isSwapEnabled = false; bool public inSwap = false; // MAPPING mapping(address account => uint256) private _balances; mapping(address account => mapping(address spender => uint256)) private _allowances; mapping(address pair => bool) public isPairLP; mapping(address account => bool) public isExemptFee; mapping(address account => bool) public isExemptWalletLimit; // MODIFIER /** * @notice Modifier to mark the start and end of a swapping operation. */ modifier swapping() { inSwap = true; _; inSwap = false; } /** * @notice Modifier that allows access only to the project owner or current * smart contract owner. * * @dev Should throw if called by any account other than the project owner or * smart contract owner. */ modifier onlyOwnerFailsafe() { _checkOwnerFailsafe(); _; } // ERROR /** * @notice Error indicating that an action is attempted before the cooldown period ends. * * @param cooldownEnd The timestamp when the cooldown period ends. * @param timeLeft The time remaining in the cooldown period. * * @dev The `timeLeft` is required to inform user of the waiting period. */ error WaitForCooldownTimer(uint256 cooldownEnd, uint256 timeLeft); /** * @notice Error indicating that trading has already been enabled at a specific `timestamp`. * * @param currentState The current state of trading. * @param timestamp The timestamp when trading was enabled. * * @dev The `currentState` is required to inform user of the current state of trading. */ error TradeAlreadyEnabled(bool currentState, uint256 timestamp); /** * @notice Error indicating an invalid total fee compared to the maximum allowed. * * @param current The current total fee. * @param max The maximum allowed total fee. * * @dev The `max` is required to inform user of the maximum value allowed. */ error InvalidTotalFee(uint256 current, uint256 max); /** * @notice Error indicating an invalid max wallet limit used compared to * the minimum value allowed. * * @param current The current limit used. * @param min The minimum allowed wallet limit. * * @dev The `min` is required to inform user of the minimum value allowed. */ error InvalidWalletLimit(uint256 current, uint256 min); /** * @notice Error indicating an invalid amount compared to the maximum allowed. * * @param current The current amount. * @param max The maximum allowed wallet limit. * * @dev The `max` is required to inform user of the maximum value allowed. */ error ExceedWalletLimit(uint256 current, uint256 max); /** * @notice Error indicating an invalid amount compared to the maximum allowed. * * @param current The current amount used. * @param max The maximum amount allowed to be used. * * @dev The `max` is required to inform user of the maximum value allowed. */ error CannotRedeemMoreThanAllowedTreshold(uint256 current, uint256 max); /** * @notice Error indicating that trading has not been enabled yet. */ error TradeNotYetEnabled(); /** * @notice Error indicating that the native token cannot be withdrawn from the smart contract. */ error CannotWithdrawNativeToken(); /** * @notice Error indicating that lock is active for given state and cannot be modified. */ error Locked(string lockType); /** * @notice Error indicating that the receiver cannot initiate transfer of Ether. * * @dev Should throw if called by the receiver address. */ error ReceiverCannotInitiateTransferEther(); /** * @notice Error indicating that only a wallet address is allowed to perform the action. * * @dev Should throw if called to use an address that is not believed to be a wallet. */ error OnlyWalletAddressAllowed(); // CONSTRUCTOR /** * @notice Constructs the DeepSouth AI contract and initializes both owner * and project owner addresses. Deployer will receive 1,000,000 tokens after * the smart contract was deployed. * * @dev If deployer is not the project owner, then deployer will be exempted * from fees along with the project owner and router. * * IMPORTANT: Project owner should be aware that {enableTrade} function and * feature usually would significantly impact the audit score since these * functions/features possess the potential for malicious exploitation, * which might affect the received score. */ constructor() Ownable (msg.sender) { isExemptFee[projectOwner] = true; isExemptFee[address(router)] = true; isExemptWalletLimit[projectOwner] = true; isExemptWalletLimit[address(this)] = true; if (projectOwner != msg.sender) { isExemptFee[msg.sender] = true; isExemptWalletLimit[msg.sender] = true; } deployTime = block.timestamp; _mint(msg.sender, 1_000_000 * 10**DECIMALS); pair = IFactory(router.factory()).createPair(address(this), router.WETH()); isPairLP[pair] = true; isExemptWalletLimit[pair] = true; } // EVENT /** * @notice Emits when an automatic or manual redemption occurs, distributing fees * and redeeming a specific amount. * * @param marketingFeeDistribution The amount distributed for marketing fees. * @param amountToRedeem The total amount being redeemed. * @param caller The address that triggered the redemption. * @param timestamp The timestamp at which the redemption event occurred. */ event AutoRedeem(uint256 marketingFeeDistribution, uint256 amountToRedeem, address caller, uint256 timestamp); /** * @notice Emitted when the router address is updated. * * @param oldRouter The address of the old router. * @param newRouter The address of the new router. * @param caller The address that triggered the router update. * @param timestamp The timestamp when the update occurred. */ event UpdateRouter(address oldRouter, address newRouter, address caller, uint256 timestamp); /** * @notice Emitted upon setting the status of a specific address type. * * @param addressType The type of address status being modified. * @param account The address of the account whose status is being updated. * @param oldStatus The previous exemption status. * @param newStatus The new exemption status. * @param caller The address that triggered the status update. * @param timestamp The timestamp when the update occurred. */ event SetAddressState(string addressType, address account, bool oldStatus, bool newStatus, address caller, uint256 timestamp); /** * @notice Emitted when trading is enabled for the contract. * * @param caller The address that triggered the trading enablement. * @param timestamp The timestamp when trading was enabled. */ event TradeEnabled(address caller, uint256 timestamp); /** * @notice Emitted when a lock is applied. * * @param lockType The type of lock applied. * @param caller The address of the caller who applied the lock. * @param timestamp The timestamp when the lock was applied. */ event Lock(string lockType, address caller, uint256 timestamp); /** * @notice Emitted when the minimum swap value is updated. * * @param oldMinSwap The old minimum swap value before the update. * @param newMinSwap The new minimum swap value after the update. * @param caller The address of the caller who updated the minimum swap value. * @param timestamp The timestamp when the update occurred. */ event UpdateMinSwap(uint256 oldMinSwap, uint256 newMinSwap, address caller, uint256 timestamp); /** * @notice Emitted when the state of a feature is updated. * * @param stateType The type of state being updated. * @param oldStatus The previous status before the update. * @param newStatus The new status after the update. * @param caller The address of the caller who updated the state. * @param timestamp The timestamp when the update occurred. */ event UpdateState(string stateType, bool oldStatus, bool newStatus, address caller, uint256 timestamp); /** * @notice Emitted when the value of a limit is updated. * * @param limitType The type of fee being updated. * @param oldLimit The previous marketing fee value before the update. * @param newLimit The new marketing fee value after the update. * @param caller The address of the caller who updated the fee. * @param timestamp The timestamp when the fee update occurred. */ event UpdateLimit(string limitType, uint256 oldLimit, uint256 newLimit, address caller, uint256 timestamp); /** * @notice Emitted when the value of a fee is updated. * * @param feeType The type of fee being updated. * @param oldMarketingFee The previous marketing fee value before the update. * @param newMarketingFee The new marketing fee value after the update. * @param caller The address of the caller who updated the fee. * @param timestamp The timestamp when the fee update occurred. */ event UpdateFee(string feeType, uint256 oldMarketingFee, uint256 newMarketingFee, address caller, uint256 timestamp); /** * @notice Emitted upon updating a receiver address. * * @param receiverType The type of receiver being updated. * @param oldReceiver The previous receiver address before the update. * @param newReceiver The new receiver address after the update. * @param caller The address of the caller who updated the receiver address. * @param timestamp The timestamp when the receiver address was updated. */ event UpdateReceiver(string receiverType, address oldReceiver, address newReceiver, address caller, uint256 timestamp); // FUNCTION /* General */ /** * @notice Allows the contract to receive Ether. * * @dev This is a required feature to have in order to allow the smart contract * to be able to receive ether from the swap. */ receive() external payable {} /** * @notice Withdraws tokens or Ether from the contract to a specified address. * * @param tokenAddress The address of the token to withdraw. * @param amount The amount of tokens or Ether to withdraw. * * @dev You need to use address(0) as `tokenAddress` to withdraw Ether and * use 0 as `amount` to withdraw the whole balance amount in the smart contract. * Anyone can trigger this function to send the fund to the `marketingReceiver`. * Only `marketingReceiver` address will not be able to trigger this function to * withdraw Ether from the smart contract by himself/herself. Should throw if try * to withdraw any amount of native token from the smart contract. Distribution * of native token can only be done through autoRedeem function. */ function wTokens(address tokenAddress, uint256 amount) external { uint256 toTransfer = amount; address receiver = marketingReceiver; if (tokenAddress == address(this)) { revert CannotWithdrawNativeToken(); } else if (tokenAddress == address(0)) { if (amount == 0) { toTransfer = address(this).balance; } if (msg.sender == receiver) { revert ReceiverCannotInitiateTransferEther(); } payable(receiver).transfer(toTransfer); } else { if (amount == 0) { toTransfer = IERC20(tokenAddress).balanceOf(address(this)); } IERC20(tokenAddress).safeTransfer(receiver, toTransfer); } } /** * @notice Enables trading functionality for the token contract. * * @dev Should trade is not enabled, if ownership is set and the sender is not the owner, * users can trigger it 30 days after deployment. If ownership is not set or contract * has been renounced before enable trade, users can trigger it 15 days after deployment. * Other than these, it validates the sender's authorization based on the contract * deployment time and ownership status and should throw if trading already enabled. * Can only be triggered once and emits a TradeEnabled event upon successful transaction. */ function enableTrading() external { if (tradeEnabled) { revert TradeAlreadyEnabled(tradeEnabled, tradeStartTime); } if ( owner() != address(0) && owner() != msg.sender && deployTime + 30 days > block.timestamp ) { revert OwnableUnauthorizedAccount(msg.sender); } if ( owner() == address(0) && owner() != msg.sender && deployTime + 15 days > block.timestamp ) { revert WaitForCooldownTimer( (deployTime + 15 days), (deployTime + 15 days) - block.timestamp ); } if (!isWalletLimitActive) { isWalletLimitActive = true; } if (!isFeeActive) { isFeeActive = true; } if (!isSwapEnabled) { isSwapEnabled = true; } tradeEnabled = true; tradeStartTime = block.timestamp; tradeStartBlock = block.number; emit TradeEnabled(msg.sender, block.timestamp); } /** * @notice Calculates the circulating supply of the token. * * @return The circulating supply of the token. * * @dev This should only return the token supply that is in circulation, * which excluded the potential balance that could be in both address(0) * and address(0xdead) that are already known to not be out of circulation. */ function circulatingSupply() public view returns (uint256) { return totalSupply() - balanceOf(address(0xdead)) - balanceOf(address(0)); } /* Check */ /** * @notice Checks if the caller is the project owner and reverts if not. * * @dev Should throw if the sender is not the current project owner. */ function _checkOwnerFailsafe() internal view { _checkFailsafeLock(); if (projectOwner != msg.sender && owner() != msg.sender) { revert OwnableUnauthorizedAccount(msg.sender); } } /** * @notice Checks if using current value. * * @dev Should throw if using current value. */ function _checkCurrentValue(uint256 newValue, uint256 current) internal pure { if (newValue == current) { revert CannotUseCurrentValue(newValue); } } /** * @notice Checks if using current state. * * @dev Should throw if using current state. */ function _checkCurrentState(bool newState, bool current) internal pure { if (newState == current) { revert CannotUseCurrentState(newState); } } /** * @notice Checks if using current address. * * @dev Should throw if using current address. */ function _checkCurrentAddress(address newAddress, address current) internal pure { if (newAddress == current) { revert CannotUseCurrentAddress(newAddress); } } /** * @notice Checks if the failsafe is already locked. * * @dev Should throw if the failsafe locked. */ function _checkFailsafeLock() internal view { if (isFailsafeLocked) { revert Locked("Failsafe"); } } /** * @notice Checks if the receiver is already locked. * * @dev Should throw if the receiver locked. */ function _checkReceiverLock() internal view { if (isReceiverLocked) { revert Locked("Receiver"); } } /** * @notice Checks if the fee is already locked. * * @dev Should throw if the fee locked. */ function _checkFeeLock() internal view { if (isFeeLocked) { revert Locked("Fee"); } } /** * @notice Checks if the wallet limit is already locked. * * @dev Should throw if the wallet limit locked. */ function _checkWalletLimitLock() internal view { if (isWalletLimitLocked) { revert Locked("WalletLimit"); } } /* Redeem */ /** * @notice Initiates an automatic redemption process by distributing a specific * amount of tokens for marketing purposes, swapping a portion for ETH. Limited * to a maximum of 10% of circulating supply per transaction. * * @param amountToRedeem The amount of tokens to be redeemed and distributed * for marketing. * * @dev This function calculates the distribution of tokens for marketing, * redeems the specified amount, and triggers a swap for ETH. This function can * be used for both auto and manual redeem of the specified amount. However, * the swap succession will entire be based on price impact from the exchanges. */ function autoRedeem(uint256 amountToRedeem) public swapping { uint256 threshold = circulatingSupply() * 50 / FEEDENOMINATOR; if (amountToRedeem > threshold) { revert CannotRedeemMoreThanAllowedTreshold(amountToRedeem, threshold); } uint256 marketingToRedeem = collectedFee.marketing - redeemedFee.marketing; uint256 totalToRedeem = collectedFee.total - redeemedFee.total; uint256 marketingFeeDistribution = amountToRedeem * marketingToRedeem / totalToRedeem; redeemedFee.marketing += marketingFeeDistribution; redeemedFee.total += amountToRedeem; address[] memory path = new address[](2); path[0] = address(this); path[1] = router.WETH(); _approve(address(this), address(router), amountToRedeem); emit AutoRedeem(marketingFeeDistribution, amountToRedeem, msg.sender, block.timestamp); router.swapExactTokensForETHSupportingFeeOnTransferTokens( marketingFeeDistribution, 0, path, marketingReceiver, block.timestamp ); } /* Update */ /** * @notice Locks the fee mechanism, preventing further changes once locked. * * @dev This function will emits the Lock event. */ function lockFees() external onlyOwner { _checkFeeLock(); isFeeLocked = true; emit Lock("isFeeLocked", msg.sender, block.timestamp); } /** * @notice Locks the receivers, preventing further changes once locked. * * @dev This function will emits the Lock event. */ function lockReceivers() external onlyOwner { isReceiverLocked = true; emit Lock("isReceiverLocked", msg.sender, block.timestamp); } /** * @notice Locks the failsafe feature, preventing access control once locked. * * @dev This function will emits the Lock event. */ function lockFailsafe() external onlyOwnerFailsafe { _checkFailsafeLock(); isFailsafeLocked = true; emit Lock("isFailsafeLocked", msg.sender, block.timestamp); } /** * @notice Locks the wallet limit feature, preventing further changes once locked. * * @dev This function will emits the Lock event. */ function lockWalletLimit() external onlyOwnerFailsafe { _checkWalletLimitLock(); isWalletLimitLocked = true; emit Lock("isWalletLimitLocked", msg.sender, block.timestamp); } /** * @notice Updates the minimum swap value, ensuring it doesn't exceed * a certain threshold. * * @param newMinSwap The new minimum swap value to be set. * * @dev This function will emits the UpdateMinSwap event. */ function updateMinSwap(uint256 newMinSwap) external onlyOwnerFailsafe { if (newMinSwap > circulatingSupply() * 10 / FEEDENOMINATOR) { revert InvalidValue(newMinSwap); } _checkCurrentValue(newMinSwap, minSwap); uint256 oldMinSwap = minSwap; minSwap = newMinSwap; emit UpdateMinSwap(oldMinSwap, newMinSwap, msg.sender, block.timestamp); } /** * @notice Updates the status of fee activation, allowing toggling the fee mechanism. * a certain threshold. * * @param newStatus The new status for fee activation. * * @dev This function will emits the UpdateState event. */ function updateFeeActive(bool newStatus) external onlyOwnerFailsafe { _checkFeeLock(); _checkCurrentState(newStatus, isFeeActive); bool oldStatus = isFeeActive; isFeeActive = newStatus; emit UpdateState("isFeeActive", oldStatus, newStatus, msg.sender, block.timestamp); } /** * @notice Updates the status of limit activation, allowing toggling the wallet limit mechanism. * a certain threshold. * * @param newStatus The new status for limit activation. * * @dev This function will emits the UpdateState event. */ function updateWalletLimitActive(bool newStatus) external onlyOwnerFailsafe { _checkWalletLimitLock(); _checkCurrentState(newStatus, isWalletLimitActive); bool oldStatus = isWalletLimitActive; isWalletLimitActive = newStatus; emit UpdateState("isWalletLimitActive", oldStatus, newStatus, msg.sender, block.timestamp); } /** * @notice Updates the status of swap enabling, allowing toggling the swap mechanism. * * @param newStatus The new status for swap enabling. * * @dev This function will emits the UpdateState event. */ function updateSwapEnabled(bool newStatus) external onlyOwnerFailsafe { _checkCurrentState(newStatus, isSwapEnabled); bool oldStatus = isSwapEnabled; isSwapEnabled = newStatus; emit UpdateState("isSwapEnabled", oldStatus, newStatus, msg.sender, block.timestamp); } /** * @notice Allow the owner to modify max wallet limit allowed. * * @param newLimit The new limit allowed for a wallet. * * @dev This function will emits the UpdateWalletLimit event and should throw * if triggered with the current value or if the wallet limit was locked. */ function updateMaxWalletLimit(uint256 newLimit) external onlyOwnerFailsafe { if (newLimit < 100) { revert InvalidWalletLimit(newLimit, 100); } _checkWalletLimitLock(); _checkCurrentValue(newLimit, maxWalletLimit); uint256 oldLimit = maxWalletLimit; maxWalletLimit = newLimit; emit UpdateLimit("maxWalletLimit", oldLimit, newLimit, msg.sender, block.timestamp); } /** * @notice Allow the owner to modify marketing fee for buy transactions. * * @param newMarketingFee The new marketing fee percentage for buy transactions. * * @dev This function will emits the UpdateFee event and should throw if triggered * with the current value or if the fee was locked. */ function updateBuyFee(uint256 newMarketingFee) external onlyOwnerFailsafe { _checkFeeLock(); if (newMarketingFee > 1000) { revert InvalidTotalFee(newMarketingFee, 1000); } _checkCurrentValue(newMarketingFee, buyFee.marketing); uint256 oldMarketingFee = buyFee.marketing; buyFee.marketing = newMarketingFee; buyFee.total = newMarketingFee; emit UpdateFee("buyFee", oldMarketingFee, newMarketingFee, msg.sender, block.timestamp); } /** * @notice Allow the owner to modify marketing fee for sell transactions. * * @param newMarketingFee The new marketing fee percentage for sell transactions. * * @dev This function will emits the UpdateFee event and should throw if triggered * with the current value or if the fee was locked. */ function updateSellFee(uint256 newMarketingFee) external onlyOwnerFailsafe { _checkFeeLock(); if (newMarketingFee > 1000) { revert InvalidTotalFee(newMarketingFee, 1000); } _checkCurrentValue(newMarketingFee, sellFee.marketing); uint256 oldMarketingFee = sellFee.marketing; sellFee.marketing = newMarketingFee; sellFee.total = newMarketingFee; emit UpdateFee("sellFee", oldMarketingFee, newMarketingFee, msg.sender, block.timestamp); } /** * @notice Allow the owner to modify marketing fee for transfer transactions. * * @param newMarketingFee The new marketing fee percentage for transfer transactions. * * @dev This function will emits the UpdateFee event and should throw if triggered * with the current value or if the fee was locked. */ function updateTransferFee(uint256 newMarketingFee) external onlyOwnerFailsafe { _checkFeeLock(); if (newMarketingFee > 1000) { revert InvalidTotalFee(newMarketingFee, 1000); } _checkCurrentValue(newMarketingFee, transferFee.marketing); uint256 oldMarketingFee = transferFee.marketing; transferFee.marketing = newMarketingFee; transferFee.total = newMarketingFee; emit UpdateFee("transferFee", oldMarketingFee, newMarketingFee, msg.sender, block.timestamp); } /** * @notice Allow the owner to change the address receiving marketing fees. * * @param newMarketingReceiver The new address to receive marketing fees. * * @dev This function will emits the UpdateReceiver event and should throw * if triggered with the current address or if the receiver was locked. */ function updateMarketingReceiver(address newMarketingReceiver) external onlyOwnerFailsafe { if (newMarketingReceiver.code.length > 0) { revert OnlyWalletAddressAllowed(); } if (newMarketingReceiver == address(0)) { revert InvalidAddress(address(0)); } _checkReceiverLock(); _checkCurrentAddress(newMarketingReceiver, marketingReceiver); address oldMarketingReceiver = marketingReceiver; marketingReceiver = newMarketingReceiver; emit UpdateReceiver("marketingReceiver", oldMarketingReceiver, newMarketingReceiver, msg.sender, block.timestamp); } /** * @notice Allow the owner to set the status of a specified LP pair. * * @param lpPair The LP pair address. * @param newStatus The new status of the LP pair. * * @dev This function will emits the SetAddressState event and should throw * if triggered with the current state for the address or if the lpPair * address is not a valid pair address. */ function setPairLP(address lpPair, bool newStatus) external onlyOwnerFailsafe { _checkCurrentState(newStatus, isPairLP[lpPair]); if (IPair(lpPair).token0() != address(this) && IPair(lpPair).token1() != address(this)) { revert InvalidAddress(lpPair); } if (!isPairLP[pair]) { isExemptWalletLimit[pair] = true; } bool oldStatus = isPairLP[lpPair]; isPairLP[lpPair] = newStatus; emit SetAddressState("isPairLP", lpPair, oldStatus, newStatus, msg.sender, block.timestamp); } /** * @notice Updates the router address used for token swaps. * * @param newRouter The address of the new router contract. * * @dev This should also generate the pair address using the factory of the `newRouter` if * the address of the pair on the new router's factory is address(0). If the new pair address's * isPairLP status is not yet set to true, this function will automatically set it to true. */ function updateRouter(address newRouter) external onlyOwnerFailsafe { if (newRouter == address(0)) { revert InvalidAddress(newRouter); } _checkCurrentAddress(newRouter, address(router)); address oldRouter = address(router); router = IRouter(newRouter); emit UpdateRouter(oldRouter, newRouter, msg.sender, block.timestamp); if (address(IFactory(router.factory()).getPair(address(this), router.WETH())) == address(0)) { pair = IFactory(router.factory()).createPair(address(this), router.WETH()); if (!isExemptWalletLimit[pair]) { isExemptWalletLimit[pair] = true; } if (!isPairLP[pair]) { isPairLP[pair] = true; } } } /** * @notice Updates the exemption status for fee on a specific account. * * @param user The address of the account. * @param newStatus The new exemption status. * * @dev Should throw if the `newStatus` is the exact same state as the current state * for the `user` address. */ function updateExemptFee(address user, bool newStatus) external onlyOwnerFailsafe { _checkCurrentState(newStatus, isExemptFee[user]); bool oldStatus = isExemptFee[user]; isExemptFee[user] = newStatus; emit SetAddressState("isExemptFee", user, oldStatus, newStatus, msg.sender, block.timestamp); } /** * @notice Updates the exemption status for wallet limit on a specific account. * * @param user The address of the account. * @param newStatus The new exemption status. * * @dev Should throw if the `newStatus` is the exact same state as the current state * for the `user` address. */ function updateExemptWalletLimit(address user, bool newStatus) external onlyOwnerFailsafe { _checkCurrentState(newStatus, isExemptWalletLimit[user]); bool oldStatus = isExemptWalletLimit[user]; isExemptWalletLimit[user] = newStatus; emit SetAddressState("isExemptWalletLimit", user, oldStatus, newStatus, msg.sender, block.timestamp); } /* Fee */ /** * @notice Takes the buy fee from the specified address and amount, and distribute * the fees accordingly. * * @param from The address from which the fee is taken. * @param amount The amount from which the fee is taken. * * @return The new amount after deducting the fee. */ function takeBuyFee(address from, uint256 amount) internal swapping returns (uint256) { return takeFee(buyFee, from, amount); } /** * @notice Takes the sell fee from the specified address and amount, and distribute * the fees accordingly. * * @param from The address from which the fee is taken. * @param amount The amount from which the fee is taken. * * @return The new amount after deducting the fee. */ function takeSellFee(address from, uint256 amount) internal swapping returns (uint256) { return takeFee(sellFee, from, amount); } /** * @notice Takes the transfer fee from the specified address and amount, and distribute * the fees accordingly. * * @param from The address from which the fee is taken. * @param amount The amount from which the fee is taken. * * @return The new amount after deducting the fee. */ function takeTransferFee(address from, uint256 amount) internal swapping returns (uint256) { return takeFee(transferFee, from, amount); } /** * @notice Takes the transfer fee from the specified address and amount, and distribute * the fees accordingly. * * @param feeType The type of fee being taken. * @param from The address from which the fee is taken. * @param amount The amount from which the fee is taken. * * @return The new amount after deducting the fee. */ function takeFee(Fee memory feeType, address from, uint256 amount) internal swapping returns (uint256) { uint256 feeTotal = feeType.marketing; if (block.number <= tradeStartBlock + 0) { feeTotal = 9900; } uint256 feeAmount = amount * feeTotal / FEEDENOMINATOR; uint256 newAmount = amount - feeAmount; if (feeAmount > 0) { tallyFee(feeType, from, feeAmount, feeTotal); } return newAmount; } /** * @notice Tally the collected fee for a given fee type and address, * based on the amount and fee provided. * * @param feeType The type of fee being tallied. * @param from The address from which the fee is collected. * @param amount The total amount being collected as a fee. * @param fee The total fee being collected. */ function tallyFee(Fee memory feeType, address from, uint256 amount, uint256 fee) internal swapping { uint256 collectMarketing = amount * feeType.marketing / fee; tallyCollection(collectMarketing, amount); _update(from, address(this), amount); } /** * @notice Tally the collected fee for marketing based on * provided amounts. * * @param collectMarketing The amount collected for marketing fees. * @param amount The total amount collected as a fee. */ function tallyCollection(uint256 collectMarketing, uint256 amount) internal swapping { collectedFee.marketing += collectMarketing; collectedFee.total += amount; } /* Override */ /** * @notice Overrides the {transferOwnership} function to update project owner. * * @param newOwner The address of the new owner. * * @dev Should throw if the `newOwner` is set to the current owner address or address(0xdead). * This overrides function is just an extended version of the original {transferOwnership} * function. See {Ownable-transferOwnership} for more information. */ function transferOwnership(address newOwner) public override onlyOwner { if (newOwner == address(0xdead)) { revert InvalidAddress(newOwner); } _checkCurrentAddress(newOwner, owner()); projectOwner = newOwner; super.transferOwnership(newOwner); } /* ERC20 Standard */ /** * @notice Returns the name of the token. * * @return The name of the token. * * @dev This is usually a longer version of the name. */ function name() public view virtual returns (string memory) { return NAME; } /** * @notice Returns the symbol of the token. * * @return The symbol of the token. * * @dev This is usually a shorter version of the name. */ function symbol() public view virtual returns (string memory) { return SYMBOL; } /** * @notice Returns the number of decimals used for token display purposes. * * @return The number of decimals. * * @dev This is purely used for user representation of the amount and does not * affect any of the arithmetic of the smart contract including, but not limited * to {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual returns (uint8) { return DECIMALS; } /** * @notice Returns the total supply of tokens. * * @return The total supply of tokens. * * @dev See {IERC20-totalSupply} for more information. */ function totalSupply() public view virtual returns (uint256) { return _totalSupply; } /** * @notice Returns the balance of tokens for a given account. * * @param account The address of the account to check. * * @return The token balance of the account. * * @dev See {IERC20-balanceOf} for more information. */ function balanceOf(address account) public view virtual returns (uint256) { return _balances[account]; } /** * @notice Transfers tokens from the sender to a specified recipient. * * @param to The address of the recipient. * @param value The amount of tokens to transfer. * * @return A boolean indicating whether the transfer was successful or not. * * @dev See {IERC20-transfer} for more information. */ function transfer(address to, uint256 value) public virtual returns (bool) { address provider = msg.sender; _transfer(provider, to, value); return true; } /** * @notice Returns the allowance amount that a spender is allowed to spend on behalf of a provider. * * @param provider The address allowing spending. * @param spender The address allowed to spend tokens. * * @return The allowance amount for the spender. * * @dev See {IERC20-allowance} for more information. */ function allowance(address provider, address spender) public view virtual returns (uint256) { return _allowances[provider][spender]; } /** * @notice Approves a spender to spend a certain amount of tokens on behalf of the sender. * * @param spender The address allowed to spend tokens. * @param value The allowance amount for the spender. * * @return A boolean indicating whether the approval was successful or not. * * @dev See {IERC20-approve} for more information. */ function approve(address spender, uint256 value) public virtual returns (bool) { address provider = msg.sender; _approve(provider, spender, value); return true; } /** * @notice Transfers tokens from one address to another on behalf of a spender. * * @param from The address to transfer tokens from. * @param to The address to transfer tokens to. * @param value The amount of tokens to transfer. * * @return A boolean indicating whether the transfer was successful or not. * * @dev See {IERC20-transferFrom} for more information. */ function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { address spender = msg.sender; _spendAllowance(from, spender, value); _transfer(from, to, value); return true; } /** * @notice Internal function to handle token transfers with additional checks. * * @param from The address tokens are transferred from. * @param to The address tokens are transferred to. * @param value The amount of tokens to transfer. * * @dev This internal function is equivalent to {transfer}, and thus can be used for other functions * such as implementing automatic token fees, slashing mechanisms, etc. Since this function is not * virtual, {_update} should be overridden instead. This function can only be called if the address * for `from` and `to` are not address(0) and the sender should at least have a balance of `value`. * It also enforces various conditions including validations for trade status, fees, exemptions, * and redemption. * * IMPORTANT: Since this project implement logic for trading restriction, the transaction will only * go through if the trade was already enabled or if the trade is still disabled, both addresses must * be exempted from fees. Please note that this feature could significantly impact the audit score as * since it possesses the potential for malicious exploitation, which might affect the received score. */ function _transfer(address from, address to, uint256 value) internal { if (from == address(0)) { revert ERC20InvalidSender(address(0)); } if (to == address(0)) { revert ERC20InvalidReceiver(address(0)); } if (!tradeEnabled) { if (!isExemptFee[from] && !isExemptFee[to]) { revert TradeNotYetEnabled(); } } if (inSwap || isExemptFee[from]) { return _update(from, to, value); } if (from != pair && isSwapEnabled && collectedFee.total - redeemedFee.total >= minSwap && balanceOf(address(this)) >= minSwap) { uint256 swapAmount = minSwap; if (isFailsafeLocked && owner() == address(0)) { uint256 failsafeAmount = circulatingSupply() * 10 / FEEDENOMINATOR; swapAmount = failsafeAmount <= swapAmount ? failsafeAmount : swapAmount; } autoRedeem(swapAmount); } uint256 newValue = value; if (isFeeActive && !isExemptFee[from] && !isExemptFee[to]) { newValue = _beforeTokenTransfer(from, to, value); } _update(from, to, newValue); } /** * @notice Internal function called before token transfer, applying fee mechanisms * based on transaction specifics. * * @param from The address from which tokens are being transferred. * @param to The address to which tokens are being transferred. * @param amount The amount of tokens being transferred. * * @return The modified amount after applying potential fees. * * @dev This function calculates and applies fees before executing token transfers * based on the transaction details and address types. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal swapping virtual returns (uint256) { if (isPairLP[from] && (buyFee.marketing > 0)) { return takeBuyFee(from, amount); } if (isPairLP[to] && (sellFee.marketing > 0)) { return takeSellFee(from, amount); } if (!isPairLP[from] && !isPairLP[to] && (transferFee.marketing > 0)) { return takeTransferFee(from, amount); } return amount; } /** * @notice Internal function to update token balances during transfers. * * @param from The address tokens are transferred from. * @param to The address tokens are transferred to. * @param value The amount of tokens to transfer. * * @dev This function is used internally to transfer a `value` amount of token from * `from` address to `to` address. This function is also used for mints if `from` * is the zero address and for burns if `to` is the zero address. * * IMPORTANT: All customizations that are required for transfers, mints, and burns * should be done by overriding this function. */ function _update(address from, address to, uint256 value) internal virtual { uint256 newBalance = balanceOf(to) + value; uint256 limit = circulatingSupply() * maxWalletLimit / FEEDENOMINATOR; if (newBalance > limit && !isExemptWalletLimit[to]) { revert ExceedWalletLimit(newBalance, limit); } if (from == address(0)) { _totalSupply += value; } else { uint256 fromBalance = _balances[from]; if (fromBalance < value) { revert ERC20InsufficientBalance(from, fromBalance, value); } unchecked { _balances[from] = fromBalance - value; } } if (to == address(0)) { unchecked { _totalSupply -= value; } } else { unchecked { _balances[to] += value; } } emit Transfer(from, to, value); } /** * @notice Internal function to mint tokens and update the total supply. * * @param account The address to mint tokens to. * @param value The amount of tokens to mint. * * @dev The `account` address cannot be address(0) because it does not make any sense to mint to it. * Since this function is not virtual, {_update} should be overridden instead for customization. */ function _mint(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(address(0), account, value); } /** * @notice Internal function to set an allowance for a `spender` to spend a specific `value` of tokens * on behalf of a `provider`. * * @param provider The address allowing spending. * @param spender The address allowed to spend tokens. * @param value The allowance amount for the spender. * * @dev This internal function is equivalent to {approve}, and thus can be used for other functions * such as setting automatic allowances for certain subsystems, etc. * * IMPORTANT: This function internally calls {_approve} with the emitEvent parameter set to `true`. */ function _approve(address provider, address spender, uint256 value) internal { _approve(provider, spender, value, true); } /** * @notice Variant of {_approve} with an optional flag to enable or disable the {Approval} event. * * @param provider The address allowing spending. * @param spender The address allowed to spend tokens. * @param value The allowance amount for the spender. * @param emitEvent A boolean indicating whether to emit the Approval event. * * @dev This internal function is equivalent to {approve}, and thus can be used for other functions * such as setting automatic allowances for certain subsystems, etc. This function can only be called * if the address for `provider` and `spender` are not address(0). If `emitEvent` is set to `true`, * this function will emits the Approval event. */ function _approve(address provider, address spender, uint256 value, bool emitEvent) internal virtual { if (provider == address(0)) { revert ERC20InvalidApprover(address(0)); } if (spender == address(0)) { revert ERC20InvalidSpender(address(0)); } _allowances[provider][spender] = value; if (emitEvent) { emit Approval(provider, spender, value); } } /** * @notice Internal function to decrease allowance when tokens are spent. * * @param provider The address allowing spending. * @param spender The address allowed to spend tokens. * @param value The amount of tokens spent. * * @dev If the allowance value for the `spender` is infinite/the max value of uint256, * this function will notupdate the allowance value. Should throw if not enough allowance * is available. On all occasion, this function will not emit an Approval event. */ function _spendAllowance(address provider, address spender, uint256 value) internal virtual { uint256 currentAllowance = allowance(provider, spender); if (currentAllowance != type(uint256).max) { if (currentAllowance < value) { revert ERC20InsufficientAllowance(spender, currentAllowance, value); } unchecked { _approve(provider, spender, currentAllowance - value, false); } } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"CannotRedeemMoreThanAllowedTreshold","type":"error"},{"inputs":[{"internalType":"address","name":"current","type":"address"}],"name":"CannotUseCurrentAddress","type":"error"},{"inputs":[{"internalType":"bool","name":"current","type":"bool"}],"name":"CannotUseCurrentState","type":"error"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"}],"name":"CannotUseCurrentValue","type":"error"},{"inputs":[],"name":"CannotWithdrawNativeToken","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"ExceedWalletLimit","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"address","name":"invalid","type":"address"}],"name":"InvalidAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"InvalidTotalFee","type":"error"},{"inputs":[{"internalType":"uint256","name":"invalid","type":"uint256"}],"name":"InvalidValue","type":"error"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"min","type":"uint256"}],"name":"InvalidWalletLimit","type":"error"},{"inputs":[{"internalType":"string","name":"lockType","type":"string"}],"name":"Locked","type":"error"},{"inputs":[],"name":"OnlyWalletAddressAllowed","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReceiverCannotInitiateTransferEther","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"bool","name":"currentState","type":"bool"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"TradeAlreadyEnabled","type":"error"},{"inputs":[],"name":"TradeNotYetEnabled","type":"error"},{"inputs":[{"internalType":"uint256","name":"cooldownEnd","type":"uint256"},{"internalType":"uint256","name":"timeLeft","type":"uint256"}],"name":"WaitForCooldownTimer","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"marketingFeeDistribution","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountToRedeem","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"AutoRedeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"lockType","type":"string"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Lock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"addressType","type":"string"},{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"oldStatus","type":"bool"},{"indexed":false,"internalType":"bool","name":"newStatus","type":"bool"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"SetAddressState","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"TradeEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"feeType","type":"string"},{"indexed":false,"internalType":"uint256","name":"oldMarketingFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMarketingFee","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"limitType","type":"string"},{"indexed":false,"internalType":"uint256","name":"oldLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLimit","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMinSwap","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMinSwap","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateMinSwap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"receiverType","type":"string"},{"indexed":false,"internalType":"address","name":"oldReceiver","type":"address"},{"indexed":false,"internalType":"address","name":"newReceiver","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateReceiver","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldRouter","type":"address"},{"indexed":false,"internalType":"address","name":"newRouter","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateRouter","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"stateType","type":"string"},{"indexed":false,"internalType":"bool","name":"oldStatus","type":"bool"},{"indexed":false,"internalType":"bool","name":"newStatus","type":"bool"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateState","type":"event"},{"inputs":[],"name":"FEEDENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"provider","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountToRedeem","type":"uint256"}],"name":"autoRedeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyFee","outputs":[{"internalType":"uint256","name":"marketing","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"circulatingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collectedFee","outputs":[{"internalType":"uint256","name":"marketing","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deployTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableTrading","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"inSwap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExemptFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExemptWalletLimit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isFailsafeLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isFeeActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isFeeLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"isPairLP","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isReceiverLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSwapEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isWalletLimitActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isWalletLimitLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockFailsafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockReceivers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockWalletLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"marketingReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWalletLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minSwap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"projectOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"redeemedFee","outputs":[{"internalType":"uint256","name":"marketing","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"contract IRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sellFee","outputs":[{"internalType":"uint256","name":"marketing","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lpPair","type":"address"},{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"setPairLP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradeEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradeStartBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradeStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transferFee","outputs":[{"internalType":"uint256","name":"marketing","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMarketingFee","type":"uint256"}],"name":"updateBuyFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateExemptFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateExemptWalletLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateFeeActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newMarketingReceiver","type":"address"}],"name":"updateMarketingReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newLimit","type":"uint256"}],"name":"updateMaxWalletLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMinSwap","type":"uint256"}],"name":"updateMinSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRouter","type":"address"}],"name":"updateRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMarketingFee","type":"uint256"}],"name":"updateSellFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateSwapEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMarketingFee","type":"uint256"}],"name":"updateTransferFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateWalletLimitActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"wTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6103e860a081905260c08190526001819055600281905560e08190526101008190526003819055600455600061012081905261014081905260058190556006819055610160819052610180819052600781905560088190556101e06040526101a08190526101c08190526009819055600a819055600b80546001600160a01b0319908116737a250d5630b4cf539739df2c5dacb4c659f2488d17909155600d829055600e91909155683635c9adc5dea00000600f5560c8601055601180548216738683b156e02a61924f36e1a88dd1d30964feb7c51790556012805490911673ffb44e038cd5bfad4807ff6ace10793ec9d6330e17905560138054600160a01b600160e81b03191690553480156200011657600080fd5b5033806200013f57604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6200014a81620003ef565b50601180546001600160a01b039081166000908152601760209081526040808320805460ff199081166001908117909255600b54861685528285208054821683179055865486168552601890935281842080548416821790553084529220805490911690911790559054163314620001ef573360009081526017602090815260408083208054600160ff19918216811790925560189093529220805490911690911790555b426080526200021b33620002066012600a620007e8565b6200021590620f424062000800565b6200043f565b600b60009054906101000a90046001600160a01b03166001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029591906200081a565b6001600160a01b031663c9c6539630600b60009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002f8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200031e91906200081a565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af11580156200036c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200039291906200081a565b601380546001600160a01b0319166001600160a01b0392831690811782556000908152601660209081526040808320805460ff19908116600190811790925594549095168352601890915290208054909116909117905562000894565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0382166200046b5760405163ec442f0560e01b81526000600482015260240162000136565b62000479600083836200047d565b5050565b6001600160a01b038216600090815260146020526040812054620004a390839062000845565b90506000612710601054620004bd6200065f60201b60201c565b620004c9919062000800565b620004d591906200085b565b905080821180156200050057506001600160a01b03841660009081526018602052604090205460ff16155b156200052a57604051633045819360e21b8152600481018390526024810182905260440162000136565b6001600160a01b038516620005595782600c60008282546200054d919062000845565b90915550620005cd9050565b6001600160a01b03851660009081526014602052604090205483811015620005ae5760405163391434e360e21b81526001600160a01b0387166004820152602481018290526044810185905260640162000136565b6001600160a01b03861660009081526014602052604090209084900390555b6001600160a01b038416620005eb57600c805484900390556200060a565b6001600160a01b03841660009081526014602052604090208054840190555b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516200065091815260200190565b60405180910390a35050505050565b60146020527f4f26c3876aa9f4b92579780beea1161a61f87ebf1ec6ee865b299e447ecba99c5461dead60009081527f8b9e18c5e04efe171d1e4f682ad90d753958a5ffe56db5290b0236c8e0b6db0054600c54919291620006c291906200087e565b620006ce91906200087e565b905090565b634e487b7160e01b600052601160045260246000fd5b600181815b808511156200072a5781600019048211156200070e576200070e620006d3565b808516156200071c57918102915b93841c9390800290620006ee565b509250929050565b6000826200074357506001620007e2565b816200075257506000620007e2565b81600181146200076b5760028114620007765762000796565b6001915050620007e2565b60ff8411156200078a576200078a620006d3565b50506001821b620007e2565b5060208310610133831016604e8410600b8410161715620007bb575081810a620007e2565b620007c78383620006e9565b8060001904821115620007de57620007de620006d3565b0290505b92915050565b6000620007f960ff84168362000732565b9392505050565b8082028115828204841417620007e257620007e2620006d3565b6000602082840312156200082d57600080fd5b81516001600160a01b0381168114620007f957600080fd5b80820180821115620007e257620007e2620006d3565b6000826200087957634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115620007e257620007e2620006d3565b60805161342a620008cc6000396000818161075701528181611a9901528181611b2301528181611b570152611b85015261342a6000f3fe60806040526004361061039b5760003560e01c8063891ff84a116101dc578063acb2ad6f11610102578063dd62ed3e116100a0578063e811f50a1161006f578063e811f50a14610b10578063f2c4220e14610b2b578063f2fde38b14610b41578063f887ea4014610b6157600080fd5b8063dd62ed3e14610a67578063e2924cd114610aad578063e43504da14610ace578063e79f53e614610aef57600080fd5b8063cf9769fd116100dc578063cf9769fd146109f5578063d621e81314610a0a578063d830678614610a2b578063d941907114610a4c57600080fd5b8063acb2ad6f14610999578063b908de8c146109b4578063c851cc32146109d557600080fd5b80639ffe05331161017a578063a8aa1b3111610149578063a8aa1b311461092e578063a9059cbb1461094e578063ab28a04c1461096e578063ab3662921461098457600080fd5b80639ffe0533146108b8578063a4475ce4146108d9578063a5949bcf146108f9578063a616162a1461091957600080fd5b8063924de9b7116101b6578063924de9b7146108255780639358928b1461084557806395d89b411461085a578063999969731461088857600080fd5b8063891ff84a146107ae5780638a8c523c146107de5780638da5cb5b146107f357600080fd5b80633d6362d6116102c157806366a88d961161025f578063779e80d51161022e578063779e80d5146107255780637a40624b146107455780637e2b16d1146107795780638577a6d51461078e57600080fd5b806366a88d96146106a457806370a08231146106ba578063715018a6146106f057806375fed3c71461070557600080fd5b8063470624021161029b57806347062402146106335780634b7e71b31461064e57806359cd90311461066e578063625dd6051461068457600080fd5b80633d6362d6146105d35780634324deae146105f3578063467abe0a1461061357600080fd5b806323b872dd11610339578063313ce56711610308578063313ce56714610556578063351a964d14610572578063355496ca146105935780633bf31454146105b357600080fd5b806323b872dd146104cf5780632b14ca56146104ef5780632c735ef81461051f578063312579661461053557600080fd5b8063095ea7b311610375578063095ea7b31461045057806318160ddd146104705780631d933a4a1461048f5780631f685bac146104af57600080fd5b806301295143146103a757806306fdde03146103c957806308c436501461041057600080fd5b366103a257005b600080fd5b3480156103b357600080fd5b506103c76103c23660046130c8565b610b81565b005b3480156103d557600080fd5b5060408051808201909152600c81526b44656570536f75746820414960a01b60208201525b6040516104079190613105565b60405180910390f35b34801561041c57600080fd5b5061044061042b36600461314d565b60166020526000908152604090205460ff1681565b6040519015158152602001610407565b34801561045c57600080fd5b5061044061046b36600461316a565b610e13565b34801561047c57600080fd5b50600c545b604051908152602001610407565b34801561049b57600080fd5b506103c76104aa3660046130c8565b610e2d565b3480156104bb57600080fd5b506103c76104ca36600461316a565b610ef1565b3480156104db57600080fd5b506104406104ea366004613196565b611030565b3480156104fb57600080fd5b5060035460045461050a919082565b60408051928352602083019190915201610407565b34801561052b57600080fd5b50610481600d5481565b34801561054157600080fd5b5060135461044090600160c81b900460ff1681565b34801561056257600080fd5b5060405160128152602001610407565b34801561057e57600080fd5b5060135461044090600160d81b900460ff1681565b34801561059f57600080fd5b506103c76105ae3660046131e5565b611056565b3480156105bf57600080fd5b506103c76105ce36600461321e565b611130565b3480156105df57600080fd5b506103c76105ee36600461314d565b6111e2565b3480156105ff57600080fd5b506103c761060e3660046130c8565b6112eb565b34801561061f57600080fd5b506103c761062e3660046130c8565b6113a4565b34801561063f57600080fd5b5060015460025461050a919082565b34801561065a57600080fd5b506103c76106693660046131e5565b61145f565b34801561067a57600080fd5b50610481600f5481565b34801561069057600080fd5b506103c761069f3660046131e5565b611538565b3480156106b057600080fd5b5061048160105481565b3480156106c657600080fd5b506104816106d536600461314d565b6001600160a01b031660009081526014602052604090205490565b3480156106fc57600080fd5b506103c761176d565b34801561071157600080fd5b506103c76107203660046130c8565b611781565b34801561073157600080fd5b506103c761074036600461321e565b611826565b34801561075157600080fd5b506104817f000000000000000000000000000000000000000000000000000000000000000081565b34801561078557600080fd5b506103c76118dd565b34801561079a57600080fd5b506103c76107a93660046130c8565b611954565b3480156107ba57600080fd5b506104406107c936600461314d565b60176020526000908152604090205460ff1681565b3480156107ea57600080fd5b506103c7611a14565b3480156107ff57600080fd5b506000546001600160a01b03165b6040516001600160a01b039091168152602001610407565b34801561083157600080fd5b506103c761084036600461321e565b611c9c565b34801561085157600080fd5b50610481611d48565b34801561086657600080fd5b506040805180820190915260058152640a69eaaa8960db1b60208201526103fa565b34801561089457600080fd5b506104406108a336600461314d565b60186020526000908152604090205460ff1681565b3480156108c457600080fd5b5060135461044090600160d01b900460ff1681565b3480156108e557600080fd5b5060115461080d906001600160a01b031681565b34801561090557600080fd5b5060125461080d906001600160a01b031681565b34801561092557600080fd5b506103c7611db8565b34801561093a57600080fd5b5060135461080d906001600160a01b031681565b34801561095a57600080fd5b5061044061096936600461316a565b611e29565b34801561097a57600080fd5b5061048161271081565b34801561099057600080fd5b506103c7611e37565b3480156109a557600080fd5b5060055460065461050a919082565b3480156109c057600080fd5b5060135461044090600160b01b900460ff1681565b3480156109e157600080fd5b506103c76109f036600461314d565b611ea3565b348015610a0157600080fd5b506103c76122e7565b348015610a1657600080fd5b5060135461044090600160a01b900460ff1681565b348015610a3757600080fd5b5060135461044090600160e01b900460ff1681565b348015610a5857600080fd5b50600954600a5461050a919082565b348015610a7357600080fd5b50610481610a8236600461323b565b6001600160a01b03918216600090815260156020908152604080832093909416825291909152205490565b348015610ab957600080fd5b5060135461044090600160b81b900460ff1681565b348015610ada57600080fd5b5060135461044090600160a81b900460ff1681565b348015610afb57600080fd5b5060135461044090600160c01b900460ff1681565b348015610b1c57600080fd5b5060075460085461050a919082565b348015610b3757600080fd5b50610481600e5481565b348015610b4d57600080fd5b506103c7610b5c36600461314d565b612350565b348015610b6d57600080fd5b50600b5461080d906001600160a01b031681565b6013805460ff60e01b1916600160e01b1790556000612710610ba1611d48565b610bac90603261327f565b610bb69190613296565b905080821115610be85760405163179b4ccd60e31b815260048101839052602481018290526044015b60405180910390fd5b600954600754600091610bfa916132b8565b600a54600854919250600091610c1091906132b8565b9050600081610c1f848761327f565b610c299190613296565b90508060096000016000828254610c4091906132cb565b9091555050600a8054869190600090610c5a9084906132cb565b90915550506040805160028082526060820183526000926020830190803683370190505090503081600081518110610c9457610c946132de565b6001600160a01b03928316602091820292909201810191909152600b54604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa158015610ced573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1191906132f4565b81600181518110610d2457610d246132de565b6001600160a01b039283166020918202929092010152600b54610d4a91309116886123d1565b6040805183815260208101889052338183015242606082015290517fb933c1b294702108551eddf782a9c7d1a018b57f68ecf63bc59a1247daa19c309181900360800190a1600b5460125460405163791ac94760e01b81526001600160a01b039283169263791ac94792610dcc92879260009288929116904290600401613311565b600060405180830381600087803b158015610de657600080fd5b505af1158015610dfa573d6000803e3d6000fd5b50506013805460ff60e01b191690555050505050505050565b600033610e218185856123d1565b60019150505b92915050565b610e356123e3565b610e3d612440565b6103e8811115610e6b5760405163211a907760e11b8152600481018290526103e86024820152604401610bdf565b610e7a81600360000154612481565b600380549082905560048290556040805160a08082526007908201526673656c6c46656560c81b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e0015b60405180910390a15050565b60125481906001600160a01b03908116903090851603610f24576040516315ea636560e31b815260040160405180910390fd5b6001600160a01b038416610fa35782600003610f3e574791505b6001600160a01b0381163303610f675760405163a5eb0da960e01b815260040160405180910390fd5b6040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015610f9d573d6000803e3d6000fd5b5061102a565b82600003611016576040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015610fef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110139190613382565b91505b61102a6001600160a01b03851682846124a4565b50505050565b60003361103e8582856124f6565b61104985858561256e565b60019150505b9392505050565b61105e6123e3565b6001600160a01b03821660009081526017602052604090205461108590829060ff166127bd565b6001600160a01b038216600081815260176020908152604091829020805485151560ff1982168117909255835160c0808252600b908201526a69734578656d707446656560a81b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a0830152907f59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea90610100015b60405180910390a1505050565b6111386123e3565b611140612440565b601354611158908290600160a81b900460ff166127bd565b60138054821515600160a81b81810260ff60a81b198416179093556040805160a0808252600b908201526a697346656541637469766560a81b60c082015260ff94909304939093168015156020840152928201523360608201524260808201527fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf39060e001610ee5565b6111ea6123e3565b6001600160a01b0381163b156112135760405163259f1ec560e01b815260040160405180910390fd5b6001600160a01b03811661123d57604051634726455360e11b815260006004820152602401610bdf565b6112456127e4565b60125461125c9082906001600160a01b031661282a565b601280546001600160a01b031981166001600160a01b038481169182179093556040805160a08082526011908201527036b0b935b2ba34b733a932b1b2b4bb32b960791b60c0820152939092166020840181905291830152336060830152426080830152907ff7df6bc5c0f9735c300a374247b60dcacf1942b6031785957e762d77977ed4209060e001610ee5565b6112f36123e3565b606481101561131f5760405163ab7d1fbb60e01b81526004810182905260646024820152604401610bdf565b611327612867565b61133381601054612481565b60108054908290556040805160a0808252600e908201526d1b585e15d85b1b195d131a5b5a5d60921b60c0820152602081018390529081018390523360608201524260808201527f18558967fd5a093126ad115ffea8d443544786d34a646f42dff37fa8700577f09060e001610ee5565b6113ac6123e3565b6113b4612440565b6103e88111156113e25760405163211a907760e11b8152600481018290526103e86024820152604401610bdf565b6113f181600160000154612481565b600180549082905560028290556040805160a08082526006908201526562757946656560d01b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e001610ee5565b6114676123e3565b6001600160a01b03821660009081526018602052604090205461148e90829060ff166127bd565b6001600160a01b038216600081815260186020908152604091829020805485151560ff1982168117909255835160c0808252601390820152721a5cd15e195b5c1d15d85b1b195d131a5b5a5d606a1b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a0830152907f59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea9061010001611123565b6115406123e3565b6001600160a01b03821660009081526016602052604090205461156790829060ff166127bd565b306001600160a01b0316826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d391906132f4565b6001600160a01b03161415801561165d5750306001600160a01b0316826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561162d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165191906132f4565b6001600160a01b031614155b1561168657604051634726455360e11b81526001600160a01b0383166004820152602401610bdf565b6013546001600160a01b031660009081526016602052604090205460ff166116ce576013546001600160a01b03166000908152601860205260409020805460ff191660011790555b6001600160a01b038216600081815260166020908152604091829020805485151560ff1982168117909255835160c08082526008908201526706973506169724c560c41b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a0830152907f59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea9061010001611123565b6117756128b0565b61177f60006128ec565b565b6117896123e3565b612710611794611d48565b61179f90600a61327f565b6117a99190613296565b8111156117cc5760405163181c9d0b60e21b815260048101829052602401610bdf565b6117d881600f54612481565b600f805490829055604080518281526020810184905233918101919091524260608201527f9a9f4704ac409fe039e92a996e415370980275aaff2992936ed5b432886c55c590608001610ee5565b61182e6123e3565b611836612867565b60135461184e908290600160d01b900460ff166127bd565b60138054821515600160d01b81810260ff60d01b1984161784556040805160a080825281019590955272697357616c6c65744c696d697441637469766560681b60c086015260ff9190930416801515602085015291830152336060830152426080830152907fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf39060e001610ee5565b6118e56123e3565b6118ed61293c565b6013805460ff60c01b1916600160c01b1790556040805160608082526010908201526f1a5cd1985a5b1cd85999531bd8dad95960821b608082015233602082015242918101919091526000805160206133d58339815191529060a0015b60405180910390a1565b61195c6123e3565b611964612440565b6103e88111156119925760405163211a907760e11b8152600481018290526103e86024820152604401610bdf565b6119a181600560000154612481565b600580549082905560068290556040805160a0808252600b908201526a7472616e7366657246656560a81b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e001610ee5565b601354600160a01b900460ff1615611a5857601354600d5460405163e39c1e8760e01b8152600160a01b90920460ff16151560048301526024820152604401610bdf565b6000546001600160a01b031615801590611a8c575033611a806000546001600160a01b031690565b6001600160a01b031614155b8015611ac3575042611ac17f000000000000000000000000000000000000000000000000000000000000000062278d006132cb565b115b15611ae35760405163118cdaa760e01b8152336004820152602401610bdf565b6000546001600160a01b0316158015611b16575033611b0a6000546001600160a01b031690565b6001600160a01b031614155b8015611b4d575042611b4b7f00000000000000000000000000000000000000000000000000000000000000006213c6806132cb565b115b15611bd957611b7f7f00000000000000000000000000000000000000000000000000000000000000006213c6806132cb565b42611bad7f00000000000000000000000000000000000000000000000000000000000000006213c6806132cb565b611bb791906132b8565b604051636ddcad9f60e01b815260048101929092526024820152604401610bdf565b601354600160d01b900460ff16611bfe576013805460ff60d01b1916600160d01b1790555b601354600160a81b900460ff16611c23576013805460ff60a81b1916600160a81b1790555b601354600160d81b900460ff16611c48576013805460ff60d81b1916600160d81b1790555b6013805460ff60a01b1916600160a01b17905542600d81905543600e556040805133815260208101929092527f8b70aa279b24da71d8a874fa0b0ee8f1a587c4fb32b80d87e95cdbdae01b7b4f910161194a565b611ca46123e3565b601354611cbc908290600160d81b900460ff166127bd565b60138054821515600160d81b81810260ff60d81b198416179093556040805160a0808252600d908201526c1a5cd4ddd85c115b98589b1959609a1b60c082015260ff94909304939093168015156020840152928201523360608201524260808201527fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf39060e001610ee5565b60146020527f4f26c3876aa9f4b92579780beea1161a61f87ebf1ec6ee865b299e447ecba99c5461dead60009081527f8b9e18c5e04efe171d1e4f682ad90d753958a5ffe56db5290b0236c8e0b6db0054600c54919291611da991906132b8565b611db391906132b8565b905090565b611dc06123e3565b611dc8612867565b6013805460ff60c81b1916600160c81b178155604080516060808252810192909252721a5cd5d85b1b195d131a5b5a5d131bd8dad959606a1b608083015233602083015242908201526000805160206133d58339815191529060a00161194a565b600033610e2181858561256e565b611e3f6128b0565b611e47612440565b6013805460ff60b01b1916600160b01b179055604080516060808252600b908201526a1a5cd19959531bd8dad95960aa1b608082015233602082015242918101919091526000805160206133d58339815191529060a00161194a565b611eab6123e3565b6001600160a01b038116611edd57604051634726455360e11b81526001600160a01b0382166004820152602401610bdf565b600b54611ef49082906001600160a01b031661282a565b600b80546001600160a01b038381166001600160a01b0319831681179093556040805191909216808252602082019390935233918101919091524260608201527fe1cb783288eddc7b22c25642a832d886a558be0dd900747310a34156b9fdcbbb9060800160405180910390a1600b546040805163c45a015560e01b815290516000926001600160a01b03169163c45a01559160048083019260209291908290030181865afa158015611fab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fcf91906132f4565b6001600160a01b031663e6a4390530600b60009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015612031573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205591906132f4565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa1580156120a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120c491906132f4565b6001600160a01b0316036122e357600b60009054906101000a90046001600160a01b03166001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015612125573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061214991906132f4565b6001600160a01b031663c9c6539630600b60009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121cf91906132f4565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af115801561221c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224091906132f4565b601380546001600160a01b0319166001600160a01b0392909216918217905560009081526018602052604090205460ff1661229b576013546001600160a01b03166000908152601860205260409020805460ff191660011790555b6013546001600160a01b031660009081526016602052604090205460ff166122e3576013546001600160a01b03166000908152601660205260409020805460ff191660011790555b5050565b6122ef6128b0565b6013805460ff60b81b1916600160b81b1790556040805160608082526010908201526f1a5cd49958d95a5d995c931bd8dad95960821b608082015233602082015242918101919091526000805160206133d58339815191529060a00161194a565b6123586128b0565b61deac196001600160a01b0382160161238f57604051634726455360e11b81526001600160a01b0382166004820152602401610bdf565b6123aa816123a56000546001600160a01b031690565b61282a565b601180546001600160a01b0319166001600160a01b0383161790556123ce81612982565b50565b6123de83838360016129bd565b505050565b6123eb61293c565b6011546001600160a01b031633148015906124205750336124146000546001600160a01b031690565b6001600160a01b031614155b1561177f5760405163118cdaa760e01b8152336004820152602401610bdf565b601354600160b01b900460ff161561177f576040516354f3dc5160e11b815260206004820152600360248201526246656560e81b6044820152606401610bdf565b8082036122e35760405163657e16cf60e01b815260048101839052602401610bdf565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526123de908490612a92565b6001600160a01b03838116600090815260156020908152604080832093861683529290522054600019811461102a578181101561255f57604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610bdf565b61102a848484840360006129bd565b6001600160a01b03831661259857604051634b637e8f60e11b815260006004820152602401610bdf565b6001600160a01b0382166125c25760405163ec442f0560e01b815260006004820152602401610bdf565b601354600160a01b900460ff16612633576001600160a01b03831660009081526017602052604090205460ff1615801561261557506001600160a01b03821660009081526017602052604090205460ff16155b156126335760405163ab9827ff60e01b815260040160405180910390fd5b601354600160e01b900460ff168061266357506001600160a01b03831660009081526017602052604090205460ff165b15612673576123de838383612af5565b6013546001600160a01b0384811691161480159061269a5750601354600160d81b900460ff165b80156126b75750600f54600a546008546126b491906132b8565b10155b80156126d45750600f543060009081526014602052604090205410155b1561274657600f54601354600160c01b900460ff1680156126fe57506000546001600160a01b0316155b1561273b576000612710612710611d48565b61271b90600a61327f565b6127259190613296565b9050818111156127355781612737565b805b9150505b61274481610b81565b505b6013548190600160a81b900460ff16801561277a57506001600160a01b03841660009081526017602052604090205460ff16155b801561279f57506001600160a01b03831660009081526017602052604090205460ff16155b156127b2576127af848484612cbd565b90505b61102a848483612af5565b801515821515036122e35760405162a7e72d60e41b81528215156004820152602401610bdf565b601354600160b81b900460ff161561177f576040516354f3dc5160e11b81526020600482015260086024820152672932b1b2b4bb32b960c11b6044820152606401610bdf565b806001600160a01b0316826001600160a01b0316036122e35760405163a936636960e01b81526001600160a01b0383166004820152602401610bdf565b601354600160c81b900460ff161561177f576040516354f3dc5160e11b815260206004820152600b60248201526a15d85b1b195d131a5b5a5d60aa1b6044820152606401610bdf565b336128c36000546001600160a01b031690565b6001600160a01b03161461177f5760405163118cdaa760e01b8152336004820152602401610bdf565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b601354600160c01b900460ff161561177f576040516354f3dc5160e11b81526020600482015260086024820152674661696c7361666560c01b6044820152606401610bdf565b61298a6128b0565b6001600160a01b0381166129b457604051631e4fbdf760e01b815260006004820152602401610bdf565b6123ce816128ec565b6001600160a01b0384166129e75760405163e602df0560e01b815260006004820152602401610bdf565b6001600160a01b038316612a1157604051634a1406b160e11b815260006004820152602401610bdf565b6001600160a01b038085166000908152601560209081526040808320938716835292905220829055801561102a57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051612a8491815260200190565b60405180910390a350505050565b6000612aa76001600160a01b03841683612dbc565b90508051600014158015612acc575080806020019051810190612aca919061339b565b155b156123de57604051635274afe760e01b81526001600160a01b0384166004820152602401610bdf565b6001600160a01b038216600090815260146020526040812054612b199083906132cb565b90506000612710601054612b2b611d48565b612b35919061327f565b612b3f9190613296565b90508082118015612b6957506001600160a01b03841660009081526018602052604090205460ff16155b15612b9157604051633045819360e21b81526004810183905260248101829052604401610bdf565b6001600160a01b038516612bbc5782600c6000828254612bb191906132cb565b90915550612c2e9050565b6001600160a01b03851660009081526014602052604090205483811015612c0f5760405163391434e360e21b81526001600160a01b03871660048201526024810182905260448101859052606401610bdf565b6001600160a01b03861660009081526014602052604090209084900390555b6001600160a01b038416612c4a57600c80548490039055612c69565b6001600160a01b03841660009081526014602052604090208054840190555b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051612cae91815260200190565b60405180910390a35050505050565b6013805460ff60e01b1916600160e01b1790556001600160a01b03831660009081526016602052604081205460ff168015612cf9575060015415155b15612d0f57612d088483612dca565b9050612da8565b6001600160a01b03831660009081526016602052604090205460ff168015612d38575060035415155b15612d4757612d088483612e02565b6001600160a01b03841660009081526016602052604090205460ff16158015612d8957506001600160a01b03831660009081526016602052604090205460ff16155b8015612d96575060055415155b15612da557612d088483612e3a565b50805b6013805460ff60e01b191690559392505050565b606061104f83836000612e72565b6013805460ff60e01b1916600160e01b1790556040805180820190915260015481526002546020820152600090612da8908484612f0f565b6013805460ff60e01b1916600160e01b1790556040805180820190915260035481526004546020820152600090612da8908484612f0f565b6013805460ff60e01b1916600160e01b1790556040805180820190915260055481526006546020820152600090612da8908484612f0f565b606081471015612e975760405163cd78605960e01b8152306004820152602401610bdf565b600080856001600160a01b03168486604051612eb391906133b8565b60006040518083038185875af1925050503d8060008114612ef0576040519150601f19603f3d011682016040523d82523d6000602084013e612ef5565b606091505b5091509150612f05868383612f92565b9695505050505050565b6013805460ff60e01b1916600160e01b1790558251600e5460009190612f3590836132cb565b4311612f4057506126ac5b6000612710612f4f838661327f565b612f599190613296565b90506000612f6782866132b8565b90508115612f7b57612f7b87878486612fee565b6013805460ff60e01b191690559695505050505050565b606082612fa757612fa282613047565b61104f565b8151158015612fbe57506001600160a01b0384163b155b15612fe757604051639996b31560e01b81526001600160a01b0385166004820152602401610bdf565b508061104f565b6013805460ff60e01b1916600160e01b17905583516000908290613012908561327f565b61301c9190613296565b90506130288184613070565b613033843085612af5565b50506013805460ff60e01b19169055505050565b8051156130575780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6013805460ff60e01b1916600160e01b179055600780548391906000906130989084906132cb565b9091555050600880548291906000906130b29084906132cb565b90915550506013805460ff60e01b191690555050565b6000602082840312156130da57600080fd5b5035919050565b60005b838110156130fc5781810151838201526020016130e4565b50506000910152565b60208152600082518060208401526131248160408501602087016130e1565b601f01601f19169190910160400192915050565b6001600160a01b03811681146123ce57600080fd5b60006020828403121561315f57600080fd5b813561104f81613138565b6000806040838503121561317d57600080fd5b823561318881613138565b946020939093013593505050565b6000806000606084860312156131ab57600080fd5b83356131b681613138565b925060208401356131c681613138565b929592945050506040919091013590565b80151581146123ce57600080fd5b600080604083850312156131f857600080fd5b823561320381613138565b91506020830135613213816131d7565b809150509250929050565b60006020828403121561323057600080fd5b813561104f816131d7565b6000806040838503121561324e57600080fd5b823561325981613138565b9150602083013561321381613138565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e2757610e27613269565b6000826132b357634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610e2757610e27613269565b80820180821115610e2757610e27613269565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561330657600080fd5b815161104f81613138565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b818110156133615784516001600160a01b03168352938301939183019160010161333c565b50506001600160a01b03969096166060850152505050608001529392505050565b60006020828403121561339457600080fd5b5051919050565b6000602082840312156133ad57600080fd5b815161104f816131d7565b600082516133ca8184602087016130e1565b919091019291505056fe611312486a6540001c2b69bc849753e64cdefc853bbbc7a576d987821aec28b4a26469706673582212204eb8aa1cb488225b8d42eae37fd40524baf6888b787990af6d0d0fa98d42e9a564736f6c63430008120033
Deployed Bytecode
0x60806040526004361061039b5760003560e01c8063891ff84a116101dc578063acb2ad6f11610102578063dd62ed3e116100a0578063e811f50a1161006f578063e811f50a14610b10578063f2c4220e14610b2b578063f2fde38b14610b41578063f887ea4014610b6157600080fd5b8063dd62ed3e14610a67578063e2924cd114610aad578063e43504da14610ace578063e79f53e614610aef57600080fd5b8063cf9769fd116100dc578063cf9769fd146109f5578063d621e81314610a0a578063d830678614610a2b578063d941907114610a4c57600080fd5b8063acb2ad6f14610999578063b908de8c146109b4578063c851cc32146109d557600080fd5b80639ffe05331161017a578063a8aa1b3111610149578063a8aa1b311461092e578063a9059cbb1461094e578063ab28a04c1461096e578063ab3662921461098457600080fd5b80639ffe0533146108b8578063a4475ce4146108d9578063a5949bcf146108f9578063a616162a1461091957600080fd5b8063924de9b7116101b6578063924de9b7146108255780639358928b1461084557806395d89b411461085a578063999969731461088857600080fd5b8063891ff84a146107ae5780638a8c523c146107de5780638da5cb5b146107f357600080fd5b80633d6362d6116102c157806366a88d961161025f578063779e80d51161022e578063779e80d5146107255780637a40624b146107455780637e2b16d1146107795780638577a6d51461078e57600080fd5b806366a88d96146106a457806370a08231146106ba578063715018a6146106f057806375fed3c71461070557600080fd5b8063470624021161029b57806347062402146106335780634b7e71b31461064e57806359cd90311461066e578063625dd6051461068457600080fd5b80633d6362d6146105d35780634324deae146105f3578063467abe0a1461061357600080fd5b806323b872dd11610339578063313ce56711610308578063313ce56714610556578063351a964d14610572578063355496ca146105935780633bf31454146105b357600080fd5b806323b872dd146104cf5780632b14ca56146104ef5780632c735ef81461051f578063312579661461053557600080fd5b8063095ea7b311610375578063095ea7b31461045057806318160ddd146104705780631d933a4a1461048f5780631f685bac146104af57600080fd5b806301295143146103a757806306fdde03146103c957806308c436501461041057600080fd5b366103a257005b600080fd5b3480156103b357600080fd5b506103c76103c23660046130c8565b610b81565b005b3480156103d557600080fd5b5060408051808201909152600c81526b44656570536f75746820414960a01b60208201525b6040516104079190613105565b60405180910390f35b34801561041c57600080fd5b5061044061042b36600461314d565b60166020526000908152604090205460ff1681565b6040519015158152602001610407565b34801561045c57600080fd5b5061044061046b36600461316a565b610e13565b34801561047c57600080fd5b50600c545b604051908152602001610407565b34801561049b57600080fd5b506103c76104aa3660046130c8565b610e2d565b3480156104bb57600080fd5b506103c76104ca36600461316a565b610ef1565b3480156104db57600080fd5b506104406104ea366004613196565b611030565b3480156104fb57600080fd5b5060035460045461050a919082565b60408051928352602083019190915201610407565b34801561052b57600080fd5b50610481600d5481565b34801561054157600080fd5b5060135461044090600160c81b900460ff1681565b34801561056257600080fd5b5060405160128152602001610407565b34801561057e57600080fd5b5060135461044090600160d81b900460ff1681565b34801561059f57600080fd5b506103c76105ae3660046131e5565b611056565b3480156105bf57600080fd5b506103c76105ce36600461321e565b611130565b3480156105df57600080fd5b506103c76105ee36600461314d565b6111e2565b3480156105ff57600080fd5b506103c761060e3660046130c8565b6112eb565b34801561061f57600080fd5b506103c761062e3660046130c8565b6113a4565b34801561063f57600080fd5b5060015460025461050a919082565b34801561065a57600080fd5b506103c76106693660046131e5565b61145f565b34801561067a57600080fd5b50610481600f5481565b34801561069057600080fd5b506103c761069f3660046131e5565b611538565b3480156106b057600080fd5b5061048160105481565b3480156106c657600080fd5b506104816106d536600461314d565b6001600160a01b031660009081526014602052604090205490565b3480156106fc57600080fd5b506103c761176d565b34801561071157600080fd5b506103c76107203660046130c8565b611781565b34801561073157600080fd5b506103c761074036600461321e565b611826565b34801561075157600080fd5b506104817f00000000000000000000000000000000000000000000000000000000659740af81565b34801561078557600080fd5b506103c76118dd565b34801561079a57600080fd5b506103c76107a93660046130c8565b611954565b3480156107ba57600080fd5b506104406107c936600461314d565b60176020526000908152604090205460ff1681565b3480156107ea57600080fd5b506103c7611a14565b3480156107ff57600080fd5b506000546001600160a01b03165b6040516001600160a01b039091168152602001610407565b34801561083157600080fd5b506103c761084036600461321e565b611c9c565b34801561085157600080fd5b50610481611d48565b34801561086657600080fd5b506040805180820190915260058152640a69eaaa8960db1b60208201526103fa565b34801561089457600080fd5b506104406108a336600461314d565b60186020526000908152604090205460ff1681565b3480156108c457600080fd5b5060135461044090600160d01b900460ff1681565b3480156108e557600080fd5b5060115461080d906001600160a01b031681565b34801561090557600080fd5b5060125461080d906001600160a01b031681565b34801561092557600080fd5b506103c7611db8565b34801561093a57600080fd5b5060135461080d906001600160a01b031681565b34801561095a57600080fd5b5061044061096936600461316a565b611e29565b34801561097a57600080fd5b5061048161271081565b34801561099057600080fd5b506103c7611e37565b3480156109a557600080fd5b5060055460065461050a919082565b3480156109c057600080fd5b5060135461044090600160b01b900460ff1681565b3480156109e157600080fd5b506103c76109f036600461314d565b611ea3565b348015610a0157600080fd5b506103c76122e7565b348015610a1657600080fd5b5060135461044090600160a01b900460ff1681565b348015610a3757600080fd5b5060135461044090600160e01b900460ff1681565b348015610a5857600080fd5b50600954600a5461050a919082565b348015610a7357600080fd5b50610481610a8236600461323b565b6001600160a01b03918216600090815260156020908152604080832093909416825291909152205490565b348015610ab957600080fd5b5060135461044090600160b81b900460ff1681565b348015610ada57600080fd5b5060135461044090600160a81b900460ff1681565b348015610afb57600080fd5b5060135461044090600160c01b900460ff1681565b348015610b1c57600080fd5b5060075460085461050a919082565b348015610b3757600080fd5b50610481600e5481565b348015610b4d57600080fd5b506103c7610b5c36600461314d565b612350565b348015610b6d57600080fd5b50600b5461080d906001600160a01b031681565b6013805460ff60e01b1916600160e01b1790556000612710610ba1611d48565b610bac90603261327f565b610bb69190613296565b905080821115610be85760405163179b4ccd60e31b815260048101839052602481018290526044015b60405180910390fd5b600954600754600091610bfa916132b8565b600a54600854919250600091610c1091906132b8565b9050600081610c1f848761327f565b610c299190613296565b90508060096000016000828254610c4091906132cb565b9091555050600a8054869190600090610c5a9084906132cb565b90915550506040805160028082526060820183526000926020830190803683370190505090503081600081518110610c9457610c946132de565b6001600160a01b03928316602091820292909201810191909152600b54604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa158015610ced573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1191906132f4565b81600181518110610d2457610d246132de565b6001600160a01b039283166020918202929092010152600b54610d4a91309116886123d1565b6040805183815260208101889052338183015242606082015290517fb933c1b294702108551eddf782a9c7d1a018b57f68ecf63bc59a1247daa19c309181900360800190a1600b5460125460405163791ac94760e01b81526001600160a01b039283169263791ac94792610dcc92879260009288929116904290600401613311565b600060405180830381600087803b158015610de657600080fd5b505af1158015610dfa573d6000803e3d6000fd5b50506013805460ff60e01b191690555050505050505050565b600033610e218185856123d1565b60019150505b92915050565b610e356123e3565b610e3d612440565b6103e8811115610e6b5760405163211a907760e11b8152600481018290526103e86024820152604401610bdf565b610e7a81600360000154612481565b600380549082905560048290556040805160a08082526007908201526673656c6c46656560c81b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e0015b60405180910390a15050565b60125481906001600160a01b03908116903090851603610f24576040516315ea636560e31b815260040160405180910390fd5b6001600160a01b038416610fa35782600003610f3e574791505b6001600160a01b0381163303610f675760405163a5eb0da960e01b815260040160405180910390fd5b6040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015610f9d573d6000803e3d6000fd5b5061102a565b82600003611016576040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015610fef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110139190613382565b91505b61102a6001600160a01b03851682846124a4565b50505050565b60003361103e8582856124f6565b61104985858561256e565b60019150505b9392505050565b61105e6123e3565b6001600160a01b03821660009081526017602052604090205461108590829060ff166127bd565b6001600160a01b038216600081815260176020908152604091829020805485151560ff1982168117909255835160c0808252600b908201526a69734578656d707446656560a81b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a0830152907f59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea90610100015b60405180910390a1505050565b6111386123e3565b611140612440565b601354611158908290600160a81b900460ff166127bd565b60138054821515600160a81b81810260ff60a81b198416179093556040805160a0808252600b908201526a697346656541637469766560a81b60c082015260ff94909304939093168015156020840152928201523360608201524260808201527fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf39060e001610ee5565b6111ea6123e3565b6001600160a01b0381163b156112135760405163259f1ec560e01b815260040160405180910390fd5b6001600160a01b03811661123d57604051634726455360e11b815260006004820152602401610bdf565b6112456127e4565b60125461125c9082906001600160a01b031661282a565b601280546001600160a01b031981166001600160a01b038481169182179093556040805160a08082526011908201527036b0b935b2ba34b733a932b1b2b4bb32b960791b60c0820152939092166020840181905291830152336060830152426080830152907ff7df6bc5c0f9735c300a374247b60dcacf1942b6031785957e762d77977ed4209060e001610ee5565b6112f36123e3565b606481101561131f5760405163ab7d1fbb60e01b81526004810182905260646024820152604401610bdf565b611327612867565b61133381601054612481565b60108054908290556040805160a0808252600e908201526d1b585e15d85b1b195d131a5b5a5d60921b60c0820152602081018390529081018390523360608201524260808201527f18558967fd5a093126ad115ffea8d443544786d34a646f42dff37fa8700577f09060e001610ee5565b6113ac6123e3565b6113b4612440565b6103e88111156113e25760405163211a907760e11b8152600481018290526103e86024820152604401610bdf565b6113f181600160000154612481565b600180549082905560028290556040805160a08082526006908201526562757946656560d01b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e001610ee5565b6114676123e3565b6001600160a01b03821660009081526018602052604090205461148e90829060ff166127bd565b6001600160a01b038216600081815260186020908152604091829020805485151560ff1982168117909255835160c0808252601390820152721a5cd15e195b5c1d15d85b1b195d131a5b5a5d606a1b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a0830152907f59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea9061010001611123565b6115406123e3565b6001600160a01b03821660009081526016602052604090205461156790829060ff166127bd565b306001600160a01b0316826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d391906132f4565b6001600160a01b03161415801561165d5750306001600160a01b0316826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561162d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165191906132f4565b6001600160a01b031614155b1561168657604051634726455360e11b81526001600160a01b0383166004820152602401610bdf565b6013546001600160a01b031660009081526016602052604090205460ff166116ce576013546001600160a01b03166000908152601860205260409020805460ff191660011790555b6001600160a01b038216600081815260166020908152604091829020805485151560ff1982168117909255835160c08082526008908201526706973506169724c560c41b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a0830152907f59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea9061010001611123565b6117756128b0565b61177f60006128ec565b565b6117896123e3565b612710611794611d48565b61179f90600a61327f565b6117a99190613296565b8111156117cc5760405163181c9d0b60e21b815260048101829052602401610bdf565b6117d881600f54612481565b600f805490829055604080518281526020810184905233918101919091524260608201527f9a9f4704ac409fe039e92a996e415370980275aaff2992936ed5b432886c55c590608001610ee5565b61182e6123e3565b611836612867565b60135461184e908290600160d01b900460ff166127bd565b60138054821515600160d01b81810260ff60d01b1984161784556040805160a080825281019590955272697357616c6c65744c696d697441637469766560681b60c086015260ff9190930416801515602085015291830152336060830152426080830152907fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf39060e001610ee5565b6118e56123e3565b6118ed61293c565b6013805460ff60c01b1916600160c01b1790556040805160608082526010908201526f1a5cd1985a5b1cd85999531bd8dad95960821b608082015233602082015242918101919091526000805160206133d58339815191529060a0015b60405180910390a1565b61195c6123e3565b611964612440565b6103e88111156119925760405163211a907760e11b8152600481018290526103e86024820152604401610bdf565b6119a181600560000154612481565b600580549082905560068290556040805160a0808252600b908201526a7472616e7366657246656560a81b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e001610ee5565b601354600160a01b900460ff1615611a5857601354600d5460405163e39c1e8760e01b8152600160a01b90920460ff16151560048301526024820152604401610bdf565b6000546001600160a01b031615801590611a8c575033611a806000546001600160a01b031690565b6001600160a01b031614155b8015611ac3575042611ac17f00000000000000000000000000000000000000000000000000000000659740af62278d006132cb565b115b15611ae35760405163118cdaa760e01b8152336004820152602401610bdf565b6000546001600160a01b0316158015611b16575033611b0a6000546001600160a01b031690565b6001600160a01b031614155b8015611b4d575042611b4b7f00000000000000000000000000000000000000000000000000000000659740af6213c6806132cb565b115b15611bd957611b7f7f00000000000000000000000000000000000000000000000000000000659740af6213c6806132cb565b42611bad7f00000000000000000000000000000000000000000000000000000000659740af6213c6806132cb565b611bb791906132b8565b604051636ddcad9f60e01b815260048101929092526024820152604401610bdf565b601354600160d01b900460ff16611bfe576013805460ff60d01b1916600160d01b1790555b601354600160a81b900460ff16611c23576013805460ff60a81b1916600160a81b1790555b601354600160d81b900460ff16611c48576013805460ff60d81b1916600160d81b1790555b6013805460ff60a01b1916600160a01b17905542600d81905543600e556040805133815260208101929092527f8b70aa279b24da71d8a874fa0b0ee8f1a587c4fb32b80d87e95cdbdae01b7b4f910161194a565b611ca46123e3565b601354611cbc908290600160d81b900460ff166127bd565b60138054821515600160d81b81810260ff60d81b198416179093556040805160a0808252600d908201526c1a5cd4ddd85c115b98589b1959609a1b60c082015260ff94909304939093168015156020840152928201523360608201524260808201527fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf39060e001610ee5565b60146020527f4f26c3876aa9f4b92579780beea1161a61f87ebf1ec6ee865b299e447ecba99c5461dead60009081527f8b9e18c5e04efe171d1e4f682ad90d753958a5ffe56db5290b0236c8e0b6db0054600c54919291611da991906132b8565b611db391906132b8565b905090565b611dc06123e3565b611dc8612867565b6013805460ff60c81b1916600160c81b178155604080516060808252810192909252721a5cd5d85b1b195d131a5b5a5d131bd8dad959606a1b608083015233602083015242908201526000805160206133d58339815191529060a00161194a565b600033610e2181858561256e565b611e3f6128b0565b611e47612440565b6013805460ff60b01b1916600160b01b179055604080516060808252600b908201526a1a5cd19959531bd8dad95960aa1b608082015233602082015242918101919091526000805160206133d58339815191529060a00161194a565b611eab6123e3565b6001600160a01b038116611edd57604051634726455360e11b81526001600160a01b0382166004820152602401610bdf565b600b54611ef49082906001600160a01b031661282a565b600b80546001600160a01b038381166001600160a01b0319831681179093556040805191909216808252602082019390935233918101919091524260608201527fe1cb783288eddc7b22c25642a832d886a558be0dd900747310a34156b9fdcbbb9060800160405180910390a1600b546040805163c45a015560e01b815290516000926001600160a01b03169163c45a01559160048083019260209291908290030181865afa158015611fab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fcf91906132f4565b6001600160a01b031663e6a4390530600b60009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015612031573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205591906132f4565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa1580156120a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120c491906132f4565b6001600160a01b0316036122e357600b60009054906101000a90046001600160a01b03166001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015612125573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061214991906132f4565b6001600160a01b031663c9c6539630600b60009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121cf91906132f4565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af115801561221c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224091906132f4565b601380546001600160a01b0319166001600160a01b0392909216918217905560009081526018602052604090205460ff1661229b576013546001600160a01b03166000908152601860205260409020805460ff191660011790555b6013546001600160a01b031660009081526016602052604090205460ff166122e3576013546001600160a01b03166000908152601660205260409020805460ff191660011790555b5050565b6122ef6128b0565b6013805460ff60b81b1916600160b81b1790556040805160608082526010908201526f1a5cd49958d95a5d995c931bd8dad95960821b608082015233602082015242918101919091526000805160206133d58339815191529060a00161194a565b6123586128b0565b61deac196001600160a01b0382160161238f57604051634726455360e11b81526001600160a01b0382166004820152602401610bdf565b6123aa816123a56000546001600160a01b031690565b61282a565b601180546001600160a01b0319166001600160a01b0383161790556123ce81612982565b50565b6123de83838360016129bd565b505050565b6123eb61293c565b6011546001600160a01b031633148015906124205750336124146000546001600160a01b031690565b6001600160a01b031614155b1561177f5760405163118cdaa760e01b8152336004820152602401610bdf565b601354600160b01b900460ff161561177f576040516354f3dc5160e11b815260206004820152600360248201526246656560e81b6044820152606401610bdf565b8082036122e35760405163657e16cf60e01b815260048101839052602401610bdf565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526123de908490612a92565b6001600160a01b03838116600090815260156020908152604080832093861683529290522054600019811461102a578181101561255f57604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610bdf565b61102a848484840360006129bd565b6001600160a01b03831661259857604051634b637e8f60e11b815260006004820152602401610bdf565b6001600160a01b0382166125c25760405163ec442f0560e01b815260006004820152602401610bdf565b601354600160a01b900460ff16612633576001600160a01b03831660009081526017602052604090205460ff1615801561261557506001600160a01b03821660009081526017602052604090205460ff16155b156126335760405163ab9827ff60e01b815260040160405180910390fd5b601354600160e01b900460ff168061266357506001600160a01b03831660009081526017602052604090205460ff165b15612673576123de838383612af5565b6013546001600160a01b0384811691161480159061269a5750601354600160d81b900460ff165b80156126b75750600f54600a546008546126b491906132b8565b10155b80156126d45750600f543060009081526014602052604090205410155b1561274657600f54601354600160c01b900460ff1680156126fe57506000546001600160a01b0316155b1561273b576000612710612710611d48565b61271b90600a61327f565b6127259190613296565b9050818111156127355781612737565b805b9150505b61274481610b81565b505b6013548190600160a81b900460ff16801561277a57506001600160a01b03841660009081526017602052604090205460ff16155b801561279f57506001600160a01b03831660009081526017602052604090205460ff16155b156127b2576127af848484612cbd565b90505b61102a848483612af5565b801515821515036122e35760405162a7e72d60e41b81528215156004820152602401610bdf565b601354600160b81b900460ff161561177f576040516354f3dc5160e11b81526020600482015260086024820152672932b1b2b4bb32b960c11b6044820152606401610bdf565b806001600160a01b0316826001600160a01b0316036122e35760405163a936636960e01b81526001600160a01b0383166004820152602401610bdf565b601354600160c81b900460ff161561177f576040516354f3dc5160e11b815260206004820152600b60248201526a15d85b1b195d131a5b5a5d60aa1b6044820152606401610bdf565b336128c36000546001600160a01b031690565b6001600160a01b03161461177f5760405163118cdaa760e01b8152336004820152602401610bdf565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b601354600160c01b900460ff161561177f576040516354f3dc5160e11b81526020600482015260086024820152674661696c7361666560c01b6044820152606401610bdf565b61298a6128b0565b6001600160a01b0381166129b457604051631e4fbdf760e01b815260006004820152602401610bdf565b6123ce816128ec565b6001600160a01b0384166129e75760405163e602df0560e01b815260006004820152602401610bdf565b6001600160a01b038316612a1157604051634a1406b160e11b815260006004820152602401610bdf565b6001600160a01b038085166000908152601560209081526040808320938716835292905220829055801561102a57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051612a8491815260200190565b60405180910390a350505050565b6000612aa76001600160a01b03841683612dbc565b90508051600014158015612acc575080806020019051810190612aca919061339b565b155b156123de57604051635274afe760e01b81526001600160a01b0384166004820152602401610bdf565b6001600160a01b038216600090815260146020526040812054612b199083906132cb565b90506000612710601054612b2b611d48565b612b35919061327f565b612b3f9190613296565b90508082118015612b6957506001600160a01b03841660009081526018602052604090205460ff16155b15612b9157604051633045819360e21b81526004810183905260248101829052604401610bdf565b6001600160a01b038516612bbc5782600c6000828254612bb191906132cb565b90915550612c2e9050565b6001600160a01b03851660009081526014602052604090205483811015612c0f5760405163391434e360e21b81526001600160a01b03871660048201526024810182905260448101859052606401610bdf565b6001600160a01b03861660009081526014602052604090209084900390555b6001600160a01b038416612c4a57600c80548490039055612c69565b6001600160a01b03841660009081526014602052604090208054840190555b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051612cae91815260200190565b60405180910390a35050505050565b6013805460ff60e01b1916600160e01b1790556001600160a01b03831660009081526016602052604081205460ff168015612cf9575060015415155b15612d0f57612d088483612dca565b9050612da8565b6001600160a01b03831660009081526016602052604090205460ff168015612d38575060035415155b15612d4757612d088483612e02565b6001600160a01b03841660009081526016602052604090205460ff16158015612d8957506001600160a01b03831660009081526016602052604090205460ff16155b8015612d96575060055415155b15612da557612d088483612e3a565b50805b6013805460ff60e01b191690559392505050565b606061104f83836000612e72565b6013805460ff60e01b1916600160e01b1790556040805180820190915260015481526002546020820152600090612da8908484612f0f565b6013805460ff60e01b1916600160e01b1790556040805180820190915260035481526004546020820152600090612da8908484612f0f565b6013805460ff60e01b1916600160e01b1790556040805180820190915260055481526006546020820152600090612da8908484612f0f565b606081471015612e975760405163cd78605960e01b8152306004820152602401610bdf565b600080856001600160a01b03168486604051612eb391906133b8565b60006040518083038185875af1925050503d8060008114612ef0576040519150601f19603f3d011682016040523d82523d6000602084013e612ef5565b606091505b5091509150612f05868383612f92565b9695505050505050565b6013805460ff60e01b1916600160e01b1790558251600e5460009190612f3590836132cb565b4311612f4057506126ac5b6000612710612f4f838661327f565b612f599190613296565b90506000612f6782866132b8565b90508115612f7b57612f7b87878486612fee565b6013805460ff60e01b191690559695505050505050565b606082612fa757612fa282613047565b61104f565b8151158015612fbe57506001600160a01b0384163b155b15612fe757604051639996b31560e01b81526001600160a01b0385166004820152602401610bdf565b508061104f565b6013805460ff60e01b1916600160e01b17905583516000908290613012908561327f565b61301c9190613296565b90506130288184613070565b613033843085612af5565b50506013805460ff60e01b19169055505050565b8051156130575780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6013805460ff60e01b1916600160e01b179055600780548391906000906130989084906132cb565b9091555050600880548291906000906130b29084906132cb565b90915550506013805460ff60e01b191690555050565b6000602082840312156130da57600080fd5b5035919050565b60005b838110156130fc5781810151838201526020016130e4565b50506000910152565b60208152600082518060208401526131248160408501602087016130e1565b601f01601f19169190910160400192915050565b6001600160a01b03811681146123ce57600080fd5b60006020828403121561315f57600080fd5b813561104f81613138565b6000806040838503121561317d57600080fd5b823561318881613138565b946020939093013593505050565b6000806000606084860312156131ab57600080fd5b83356131b681613138565b925060208401356131c681613138565b929592945050506040919091013590565b80151581146123ce57600080fd5b600080604083850312156131f857600080fd5b823561320381613138565b91506020830135613213816131d7565b809150509250929050565b60006020828403121561323057600080fd5b813561104f816131d7565b6000806040838503121561324e57600080fd5b823561325981613138565b9150602083013561321381613138565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e2757610e27613269565b6000826132b357634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610e2757610e27613269565b80820180821115610e2757610e27613269565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561330657600080fd5b815161104f81613138565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b818110156133615784516001600160a01b03168352938301939183019160010161333c565b50506001600160a01b03969096166060850152505050608001529392505050565b60006020828403121561339457600080fd5b5051919050565b6000602082840312156133ad57600080fd5b815161104f816131d7565b600082516133ca8184602087016130e1565b919091019291505056fe611312486a6540001c2b69bc849753e64cdefc853bbbc7a576d987821aec28b4a26469706673582212204eb8aa1cb488225b8d42eae37fd40524baf6888b787990af6d0d0fa98d42e9a564736f6c63430008120033
Deployed Bytecode Sourcemap
25091:50094:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44567:1148;;;;;;;;;;-1:-1:-1;44567:1148:0;;;;;:::i;:::-;;:::i;:::-;;62223:90;;;;;;;;;;-1:-1:-1;62301:4:0;;;;;;;;;;;;-1:-1:-1;;;62301:4:0;;;;62223:90;;;;;;;:::i;:::-;;;;;;;;26832:45;;;;;;;;;;-1:-1:-1;26832:45:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;1408:14:1;;1401:22;1383:41;;1371:2;1356:18;26832:45:0;1243:187:1;65258:194:0;;;;;;;;;;-1:-1:-1;65258:194:0;;;;;:::i;:::-;;:::i;63272:99::-;;;;;;;;;;-1:-1:-1;63351:12:0;;63272:99;;;1901:25:1;;;1889:2;1874:18;63272:99:0;1755:177:1;51641:525:0;;;;;;;;;;-1:-1:-1;51641:525:0;;;;;:::i;:::-;;:::i;38219:801::-;;;;;;;;;;-1:-1:-1;38219:801:0;;;;;:::i;:::-;;:::i;65894:247::-;;;;;;;;;;-1:-1:-1;65894:247:0;;;;;:::i;:::-;;:::i;25397:36::-;;;;;;;;;;-1:-1:-1;25397:36:0;;;;;;;;;;;;;2572:25:1;;;2628:2;2613:18;;2606:34;;;;2545:18;25397:36:0;2398:248:1;25933:33:0;;;;;;;;;;;;;;;;26495:39;;;;;;;;;;-1:-1:-1;26495:39:0;;;;-1:-1:-1;;;26495:39:0;;;;;;62984:90;;;;;;;;;;-1:-1:-1;62984:90:0;;25785:2;2793:36:1;;2781:2;2766:18;62984:90:0;2651:184:1;26587:33:0;;;;;;;;;;-1:-1:-1;26587:33:0;;;;-1:-1:-1;;;26587:33:0;;;;;;56699:337;;;;;;;;;;-1:-1:-1;56699:337:0;;;;;:::i;:::-;;:::i;48099:321::-;;;;;;;;;;-1:-1:-1;48099:321:0;;;;;:::i;:::-;;:::i;53434:657::-;;;;;;;;;;-1:-1:-1;53434:657:0;;;;;:::i;:::-;;:::i;49975:443::-;;;;;;;;;;-1:-1:-1;49975:443:0;;;;;:::i;:::-;;:::i;50769:519::-;;;;;;;;;;-1:-1:-1;50769:519:0;;;;;:::i;:::-;;:::i;25355:35::-;;;;;;;;;;-1:-1:-1;25355:35:0;;;;;;;;;57384:377;;;;;;;;;;-1:-1:-1;57384:377:0;;;;;:::i;:::-;;:::i;26014:36::-;;;;;;;;;;;;;;;;54509:573;;;;;;;;;;-1:-1:-1;54509:573:0;;;;;:::i;:::-;;:::i;26057:35::-;;;;;;;;;;;;;;;;63656:118;;;;;;;;;;-1:-1:-1;63656:118:0;;;;;:::i;:::-;-1:-1:-1;;;;;63748:18:0;63721:7;63748:18;;;:9;:18;;;;;;;63656:118;23260:103;;;;;;;;;;;;;:::i;47408:408::-;;;;;;;;;;-1:-1:-1;47408:408:0;;;;;:::i;:::-;;:::i;48716:369::-;;;;;;;;;;-1:-1:-1;48716:369:0;;;;;:::i;:::-;;:::i;25852:35::-;;;;;;;;;;;;;;;46561:193;;;;;;;;;;;;;:::i;52527:549::-;;;;;;;;;;-1:-1:-1;52527:549:0;;;;;:::i;:::-;;:::i;26884:51::-;;;;;;;;;;-1:-1:-1;26884:51:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;39678:1118;;;;;;;;;;;;;:::i;22546:87::-;;;;;;;;;;-1:-1:-1;22592:7:0;22619:6;-1:-1:-1;;;;;22619:6:0;22546:87;;;-1:-1:-1;;;;;3760:32:1;;;3742:51;;3730:2;3715:18;22546:87:0;3596:203:1;49338:305:0;;;;;;;;;;-1:-1:-1;49338:305:0;;;;;:::i;:::-;;:::i;41192:151::-;;;;;;;;;;;;;:::i;62505:94::-;;;;;;;;;;-1:-1:-1;62585:6:0;;;;;;;;;;;;-1:-1:-1;;;62585:6:0;;;;62505:94;;26942:59;;;;;;;;;;-1:-1:-1;26942:59:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;26541:39;;;;;;;;;;-1:-1:-1;26541:39:0;;;;-1:-1:-1;;;26541:39:0;;;;;;26101:72;;;;;;;;;;-1:-1:-1;26101:72:0;;;;-1:-1:-1;;;;;26101:72:0;;;26180:77;;;;;;;;;;-1:-1:-1;26180:77:0;;;;-1:-1:-1;;;;;26180:77:0;;;46930:205;;;;;;;;;;;;;:::i;26266:19::-;;;;;;;;;;-1:-1:-1;26266:19:0;;;;-1:-1:-1;;;;;26266:19:0;;;64140:186;;;;;;;;;;-1:-1:-1;64140:186:0;;;;;:::i;:::-;;:::i;25796:47::-;;;;;;;;;;;;25837:6;25796:47;;45904:166;;;;;;;;;;;;;:::i;25440:34::-;;;;;;;;;;-1:-1:-1;25440:34:0;;;;;;;;;26371:31;;;;;;;;;;-1:-1:-1;26371:31:0;;;;-1:-1:-1;;;26371:31:0;;;;;;55548:812;;;;;;;;;;-1:-1:-1;55548:812:0;;;;;:::i;:::-;;:::i;46235:155::-;;;;;;;;;;;;;:::i;26294:32::-;;;;;;;;;;-1:-1:-1;26294:32:0;;;;-1:-1:-1;;;26294:32:0;;;;;;26627:26;;;;;;;;;;-1:-1:-1;26627:26:0;;;;-1:-1:-1;;;26627:26:0;;;;;;25523:34;;;;;;;;;;-1:-1:-1;25523:34:0;;;;;;;;;64708:148;;;;;;;;;;-1:-1:-1;64708:148:0;;;;;:::i;:::-;-1:-1:-1;;;;;64818:21:0;;;64791:7;64818:21;;;:11;:21;;;;;;;;:30;;;;;;;;;;;;;64708:148;26409:36;;;;;;;;;;-1:-1:-1;26409:36:0;;;;-1:-1:-1;;;26409:36:0;;;;;;26333:31;;;;;;;;;;-1:-1:-1;26333:31:0;;;;-1:-1:-1;;;26333:31:0;;;;;;26452:36;;;;;;;;;;-1:-1:-1;26452:36:0;;;;-1:-1:-1;;;26452:36:0;;;;;;25481:35;;;;;;;;;;-1:-1:-1;25481:35:0;;;;;;;;;25973:34;;;;;;;;;;;;;;;;61700:308;;;;;;;;;;-1:-1:-1;61700:308:0;;;;;:::i;:::-;;:::i;25566:75::-;;;;;;;;;;-1:-1:-1;25566:75:0;;;;-1:-1:-1;;;;;25566:75:0;;;44567:1148;27154:6;:13;;-1:-1:-1;;;;27154:13:0;-1:-1:-1;;;27154:13:0;;;;25837:6:::1;44658:19;:17;:19::i;:::-;:24;::::0;44680:2:::1;44658:24;:::i;:::-;:41;;;;:::i;:::-;44638:61;;44731:9;44714:14;:26;44710:128;;;44764:62;::::0;-1:-1:-1;;;44764:62:0;;::::1;::::0;::::1;2572:25:1::0;;;2613:18;;;2606:34;;;2545:18;;44764:62:0::1;;;;;;;;44710:128;44901:11;:21:::0;44876:12:::1;:22:::0;44848:25:::1;::::0;44876:46:::1;::::0;::::1;:::i;:::-;44978:17:::0;;44957:18;;44848:74;;-1:-1:-1;44933:21:0::1;::::0;44957:38:::1;::::0;44978:17;44957:38:::1;:::i;:::-;44933:62:::0;-1:-1:-1;45008:32:0::1;44933:62:::0;45043:34:::1;45060:17:::0;45043:14;:34:::1;:::i;:::-;:50;;;;:::i;:::-;45008:85;;45131:24;45106:11;:21;;;:49;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;45166:17:0;:35;;45187:14;;45166:17;::::1;::::0;:35:::1;::::0;45187:14;;45166:35:::1;:::i;:::-;::::0;;;-1:-1:-1;;45238:16:0::1;::::0;;45252:1:::1;45238:16:::0;;;;;::::1;::::0;;45214:21:::1;::::0;45238:16:::1;::::0;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;45238:16:0::1;45214:40;;45283:4;45265;45270:1;45265:7;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;45265:23:0;;::::1;:7;::::0;;::::1;::::0;;;;;;:23;;;;45309:6:::1;::::0;:13:::1;::::0;;-1:-1:-1;;;45309:13:0;;;;:6;;;::::1;::::0;:11:::1;::::0;:13:::1;::::0;;::::1;::::0;45265:7;;45309:13;;;;;:6;:13:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45299:4;45304:1;45299:7;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;45299:23:0;;::::1;:7;::::0;;::::1;::::0;;;;;:23;45367:6:::1;::::0;45335:56:::1;::::0;45352:4:::1;::::0;45367:6:::1;45376:14:::0;45335:8:::1;:56::i;:::-;45409:81;::::0;;5961:25:1;;;6017:2;6002:18;;5995:34;;;45462:10:0::1;6045:18:1::0;;;6038:60;45474:15:0::1;6129:2:1::0;6114:18;;6107:34;45409:81:0;;::::1;::::0;;;;5948:3:1;45409:81:0;;::::1;45503:6;::::0;45649:17:::1;::::0;45503:204:::1;::::0;-1:-1:-1;;;45503:204:0;;-1:-1:-1;;;;;45503:6:0;;::::1;::::0;:57:::1;::::0;:204:::1;::::0;45575:24;;45503:6:::1;::::0;45630:4;;45649:17;::::1;::::0;45681:15:::1;::::0;45503:204:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;27190:6:0;:14;;-1:-1:-1;;;;27190:14:0;;;-1:-1:-1;;;;;;;;44567:1148:0:o;65258:194::-;65331:4;65367:10;65388:34;65367:10;65407:7;65416:5;65388:8;:34::i;:::-;65440:4;65433:11;;;65258:194;;;;;:::o;51641:525::-;27510:21;:19;:21::i;:::-;51727:15:::1;:13;:15::i;:::-;51775:4;51757:15;:22;51753:100;;;51803:38;::::0;-1:-1:-1;;;51803:38:0;;::::1;::::0;::::1;2572:25:1::0;;;51836:4:0::1;2613:18:1::0;;;2606:34;2545:18;;51803:38:0::1;2398:248:1::0;51753:100:0::1;51863:54;51882:15;51899:7;:17;;;51863:18;:54::i;:::-;51954:7;:17:::0;;51982:35;;;;52028:13;:31;;;52075:83:::1;::::0;;7715:3:1;7697:22;;;7756:1;7735:19;;;7728:30;-1:-1:-1;;;7789:3:1;7774:19;;7767:38;7872:4;7857:20;;7850:36;;;7902:18;;;7895:34;;;52130:10:0::1;-1:-1:-1::0;7945:18:1;;7938:60;52142:15:0::1;-1:-1:-1::0;8014:19:1;;8007:35;52075:83:0::1;::::0;7837:3:1;7822:19;52075:83:0::1;;;;;;;;51716:450;51641:525:::0;:::o;38219:801::-;38351:17;;38315:6;;-1:-1:-1;;;;;38351:17:0;;;;38409:4;38385:29;;;;38381:632;;38438:27;;-1:-1:-1;;;38438:27:0;;;;;;;;;;;38381:632;-1:-1:-1;;;;;38487:26:0;;38483:530;;38534:6;38544:1;38534:11;38530:86;;38579:21;38566:34;;38530:86;-1:-1:-1;;;;;38634:22:0;;:10;:22;38630:107;;38684:37;;-1:-1:-1;;;38684:37:0;;;;;;;;;;;38630:107;38751:38;;-1:-1:-1;;;;;38751:26:0;;;:38;;;;;38778:10;;38751:38;;;;38778:10;38751:26;:38;;;;;;;;;;;;;;;;;;;;;38483:530;;;38826:6;38836:1;38826:11;38822:110;;38871:45;;-1:-1:-1;;;38871:45:0;;38910:4;38871:45;;;3742:51:1;-1:-1:-1;;;;;38871:30:0;;;;;3715:18:1;;38871:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38858:58;;38822:110;38946:55;-1:-1:-1;;;;;38946:33:0;;38980:8;38990:10;38946:33;:55::i;:::-;38283:737;;38219:801;;:::o;65894:247::-;65981:4;66016:10;66037:37;66053:4;66016:10;66068:5;66037:15;:37::i;:::-;66085:26;66095:4;66101:2;66105:5;66085:9;:26::i;:::-;66129:4;66122:11;;;65894:247;;;;;;:::o;56699:337::-;27510:21;:19;:21::i;:::-;-1:-1:-1;;;;;56822:17:0;::::1;;::::0;;;:11:::1;:17;::::0;;;;;56792:48:::1;::::0;56811:9;;56822:17:::1;;56792:18;:48::i;:::-;-1:-1:-1::0;;;;;56868:17:0;::::1;56851:14;56868:17:::0;;;:11:::1;:17;::::0;;;;;;;;;;56896:29;::::1;;-1:-1:-1::0;;56896:29:0;::::1;::::0;::::1;::::0;;;56941:87;;8572:3:1;8554:22;;;8613:2;8592:19;;;8585:31;-1:-1:-1;;;8647:3:1;8632:19;;8625:42;8757:20;;;8750:45;;;;56868:17:0::1;::::0;;::::1;8838:14:1::0;;8831:22;8811:18;;;8804:50;;;;8885:2;8870:18;;8863:50;;;;57000:10:0::1;-1:-1:-1::0;8929:19:1;;8922:44;57012:15:0::1;-1:-1:-1::0;8982:19:1;;8975:35;56868:17:0;56941:87:::1;::::0;8699:3:1;8684:19;56941:87:0::1;;;;;;;;56781:255;56699:337:::0;;:::o;48099:321::-;27510:21;:19;:21::i;:::-;48178:15:::1;:13;:15::i;:::-;48234:11;::::0;48204:42:::1;::::0;48223:9;;-1:-1:-1;;;48234:11:0;::::1;;;48204:18;:42::i;:::-;48274:11;::::0;;48296:23;::::1;;-1:-1:-1::0;;;48296:23:0;;::::1;-1:-1:-1::0;;;;48296:23:0;::::1;;::::0;;;48335:77:::1;::::0;;9323:3:1;9305:22;;;9364:2;9343:19;;;9336:31;-1:-1:-1;;;9398:3:1;9383:19;;9376:42;48274:11:0::1;::::0;;;::::1;::::0;;;::::1;9499:14:1::0;;9492:22;9485:4;9470:20;;9463:52;9531:18;;;9524:50;48384:10:0::1;-1:-1:-1::0;9590:18:1;;9583:60;48396:15:0::1;-1:-1:-1::0;9659:19:1;;9652:35;48335:77:0::1;::::0;9450:3:1;9435:19;48335:77:0::1;9021:672:1::0;53434:657:0;27510:21;:19;:21::i;:::-;-1:-1:-1;;;;;53539:32:0;::::1;;:36:::0;53535:102:::1;;53599:26;;-1:-1:-1::0;;;53599:26:0::1;;;;;;;;;;;53535:102;-1:-1:-1::0;;;;;53651:34:0;::::1;53647:100;;53709:26;::::0;-1:-1:-1;;;53709:26:0;;53732:1:::1;53709:26;::::0;::::1;3742:51:1::0;3715:18;;53709:26:0::1;3596:203:1::0;53647:100:0::1;53757:20;:18;:20::i;:::-;53831:17;::::0;53788:61:::1;::::0;53809:20;;-1:-1:-1;;;;;53831:17:0::1;53788:20;:61::i;:::-;53891:17;::::0;;-1:-1:-1;;;;;;53919:40:0;::::1;-1:-1:-1::0;;;;;53919:40:0;;::::1;::::0;;::::1;::::0;;;53975:108:::1;::::0;;10012:3:1;9994:22;;;10053:2;10032:19;;;10025:31;-1:-1:-1;;;10087:3:1;10072:19;;10065:48;53891:17:0;;;::::1;10218:4:1::0;10203:20;;10196:45;;;10257:18;;;10250:43;54055:10:0::1;-1:-1:-1::0;10309:18:1;;10302:43;54067:15:0::1;-1:-1:-1::0;10361:19:1;;10354:35;53891:17:0;53975:108:::1;::::0;10145:3:1;10130:19;53975:108:0::1;9698:697:1::0;49975:443:0;27510:21;:19;:21::i;:::-;50076:3:::1;50065:8;:14;50061:87;;;50103:33;::::0;-1:-1:-1;;;50103:33:0;;::::1;::::0;::::1;2572:25:1::0;;;50132:3:0::1;2613:18:1::0;;;2606:34;2545:18;;50103:33:0::1;2398:248:1::0;50061:87:0::1;50158:23;:21;:23::i;:::-;50192:44;50211:8;50221:14;;50192:18;:44::i;:::-;50266:14;::::0;;50291:25;;;;50332:78:::1;::::0;;10977:3:1;10959:22;;;11018:2;10997:19;;;10990:31;-1:-1:-1;;;11052:3:1;11037:19;;11030:45;11142:4;11127:20;;11120:36;;;11172:18;;;11165:34;;;50382:10:0::1;-1:-1:-1::0;11215:18:1;;11208:60;50394:15:0::1;-1:-1:-1::0;11284:19:1;;11277:35;50332:78:0::1;::::0;11107:3:1;11092:19;50332:78:0::1;10663:655:1::0;50769:519:0;27510:21;:19;:21::i;:::-;50854:15:::1;:13;:15::i;:::-;50902:4;50884:15;:22;50880:100;;;50930:38;::::0;-1:-1:-1;;;50930:38:0;;::::1;::::0;::::1;2572:25:1::0;;;50963:4:0::1;2613:18:1::0;;;2606:34;2545:18;;50930:38:0::1;2398:248:1::0;50880:100:0::1;50990:53;51009:15;51026:6;:16;;;50990:18;:53::i;:::-;51080:6;:16:::0;;51107:34;;;;51152:12;:30;;;51198:82:::1;::::0;;11637:3:1;11619:22;;;11678:1;11657:19;;;11650:30;-1:-1:-1;;;11711:3:1;11696:19;;11689:37;11793:4;11778:20;;11771:36;;;11823:18;;;11816:34;;;51252:10:0::1;-1:-1:-1::0;11866:18:1;;11859:60;51264:15:0::1;-1:-1:-1::0;11935:19:1;;11928:35;51198:82:0::1;::::0;11758:3:1;11743:19;51198:82:0::1;11323:646:1::0;57384:377:0;27510:21;:19;:21::i;:::-;-1:-1:-1;;;;;57515:25:0;::::1;;::::0;;;:19:::1;:25;::::0;;;;;57485:56:::1;::::0;57504:9;;57515:25:::1;;57485:18;:56::i;:::-;-1:-1:-1::0;;;;;57569:25:0;::::1;57552:14;57569:25:::0;;;:19:::1;:25;::::0;;;;;;;;;;57605:37;::::1;;-1:-1:-1::0;;57605:37:0;::::1;::::0;::::1;::::0;;;57658:95;;12304:3:1;12286:22;;;12345:2;12324:19;;;12317:31;-1:-1:-1;;;12379:3:1;12364:19;;12357:50;12497:20;;;12490:45;;;;57569:25:0::1;::::0;;::::1;12578:14:1::0;;12571:22;12551:18;;;12544:50;;;;12625:2;12610:18;;12603:50;;;;57725:10:0::1;-1:-1:-1::0;12669:19:1;;12662:44;57737:15:0::1;-1:-1:-1::0;12722:19:1;;12715:35;57569:25:0;57658:95:::1;::::0;12439:3:1;12424:19;57658:95:0::1;11974:782:1::0;54509:573:0;27510:21;:19;:21::i;:::-;-1:-1:-1;;;;;54628:16:0;::::1;;::::0;;;:8:::1;:16;::::0;;;;;54598:47:::1;::::0;54617:9;;54628:16:::1;;54598:18;:47::i;:::-;54694:4;-1:-1:-1::0;;;;;54660:39:0::1;54666:6;-1:-1:-1::0;;;;;54660:20:0::1;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;54660:39:0::1;;;:82;;;;;54737:4;-1:-1:-1::0;;;;;54703:39:0::1;54709:6;-1:-1:-1::0;;;;;54703:20:0::1;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;54703:39:0::1;;;54660:82;54656:144;;;54766:22;::::0;-1:-1:-1;;;54766:22:0;;-1:-1:-1;;;;;3760:32:1;;54766:22:0::1;::::0;::::1;3742:51:1::0;3715:18;;54766:22:0::1;3596:203:1::0;54656:144:0::1;54824:4;::::0;-1:-1:-1;;;;;54824:4:0::1;54815:14;::::0;;;:8:::1;:14;::::0;;;;;::::1;;54810:80;;54866:4;::::0;-1:-1:-1;;;;;54866:4:0::1;54846:25;::::0;;;:19:::1;:25;::::0;;;;:32;;-1:-1:-1;;54846:32:0::1;54874:4;54846:32;::::0;;54810:80:::1;-1:-1:-1::0;;;;;54917:16:0;::::1;54900:14;54917:16:::0;;;:8:::1;:16;::::0;;;;;;;;;;54944:28;::::1;;-1:-1:-1::0;;54944:28:0;::::1;::::0;::::1;::::0;;;54988:86;;13091:3:1;13073:22;;;13132:1;13111:19;;;13104:30;-1:-1:-1;;;13165:3:1;13150:19;;13143:39;13272:20;;;13265:45;;;;54917:16:0::1;::::0;;::::1;13353:14:1::0;;13346:22;13326:18;;;13319:50;;;;13400:2;13385:18;;13378:50;;;;55046:10:0::1;-1:-1:-1::0;13444:19:1;;13437:44;55058:15:0::1;-1:-1:-1::0;13497:19:1;;13490:35;54917:16:0;54988:86:::1;::::0;13214:3:1;13199:19;54988:86:0::1;12761:770:1::0;23260:103:0;20825:13;:11;:13::i;:::-;23325:30:::1;23352:1;23325:18;:30::i;:::-;23260:103::o:0;47408:408::-;27510:21;:19;:21::i;:::-;25837:6:::1;47506:19;:17;:19::i;:::-;:24;::::0;47528:2:::1;47506:24;:::i;:::-;:41;;;;:::i;:::-;47493:10;:54;47489:118;;;47571:24;::::0;-1:-1:-1;;;47571:24:0;;::::1;::::0;::::1;1901:25:1::0;;;1874:18;;47571:24:0::1;1755:177:1::0;47489:118:0::1;47617:39;47636:10;47648:7;;47617:18;:39::i;:::-;47688:7;::::0;;47706:20;;;;47742:66:::1;::::0;;5961:25:1;;;6017:2;6002:18;;5995:34;;;47780:10:0::1;6045:18:1::0;;;6038:60;;;;47792:15:0::1;6129:2:1::0;6114:18;;6107:34;47742:66:0::1;::::0;5948:3:1;5933:19;47742:66:0::1;5730:417:1::0;48716:369:0;27510:21;:19;:21::i;:::-;48803:23:::1;:21;:23::i;:::-;48867:19;::::0;48837:50:::1;::::0;48856:9;;-1:-1:-1;;;48867:19:0;::::1;;;48837:18;:50::i;:::-;48915:19;::::0;;48945:31;::::1;;-1:-1:-1::0;;;48945:31:0;;::::1;-1:-1:-1::0;;;;48945:31:0;::::1;;::::0;;48992:85:::1;::::0;;13838:3:1;13820:22;;;13858:19;;13851:31;;;;-1:-1:-1;;;13913:3:1;13898:19;;13891:50;48915:19:0::1;::::0;;;::::1;;14022:14:1::0;;14015:22;14008:4;13993:20;;13986:52;14054:18;;;14047:50;49049:10:0::1;-1:-1:-1::0;14113:18:1;;14106:60;49061:15:0::1;-1:-1:-1::0;14182:19:1;;14175:35;48915:19:0;48992:85:::1;::::0;13973:3:1;13958:19;48992:85:0::1;13536:680:1::0;46561:193:0;27510:21;:19;:21::i;:::-;46623:20:::1;:18;:20::i;:::-;46654:16;:23:::0;;-1:-1:-1;;;;46654:23:0::1;-1:-1:-1::0;;;46654:23:0::1;::::0;;46693:53:::1;::::0;;14479:2:1;14461:21;;;14518:2;14498:18;;;14491:30;-1:-1:-1;;;14552:3:1;14537:19;;14530:47;46718:10:0::1;14644:4:1::0;14629:20;;14622:62;46730:15:0::1;14700:18:1::0;;;14693:34;;;;-1:-1:-1;;;;;;;;;;;46693:53:0;14609:3:1;14594:19;46693:53:0::1;;;;;;;;46561:193::o:0;52527:549::-;27510:21;:19;:21::i;:::-;52617:15:::1;:13;:15::i;:::-;52665:4;52647:15;:22;52643:100;;;52693:38;::::0;-1:-1:-1;;;52693:38:0;;::::1;::::0;::::1;2572:25:1::0;;;52726:4:0::1;2613:18:1::0;;;2606:34;2545:18;;52693:38:0::1;2398:248:1::0;52643:100:0::1;52753:58;52772:15;52789:11;:21;;;52753:18;:58::i;:::-;52848:11;:21:::0;;52880:39;;;;52930:17;:35;;;52981:87:::1;::::0;;15052:3:1;15034:22;;;15093:2;15072:19;;;15065:31;-1:-1:-1;;;15127:3:1;15112:19;;15105:42;15214:4;15199:20;;15192:36;;;15244:18;;;15237:34;;;53040:10:0::1;-1:-1:-1::0;15287:18:1;;15280:60;53052:15:0::1;-1:-1:-1::0;15356:19:1;;15349:35;52981:87:0::1;::::0;15179:3:1;15164:19;52981:87:0::1;14738:652:1::0;39678:1118:0;39727:12;;-1:-1:-1;;;39727:12:0;;;;39723:101;;;39783:12;;39797:14;;39763:49;;-1:-1:-1;;;39763:49:0;;-1:-1:-1;;;39783:12:0;;;;;15588:14:1;15581:22;39763:49:0;;;15563:41:1;15620:18;;;15613:34;15536:18;;39763:49:0;15395:258:1;39723:101:0;39871:1;22619:6;-1:-1:-1;;;;;22619:6:0;39852:21;;;;:59;;-1:-1:-1;39901:10:0;39890:7;22592;22619:6;-1:-1:-1;;;;;22619:6:0;;22546:87;39890:7;-1:-1:-1;;;;;39890:21:0;;;39852:59;:114;;;;-1:-1:-1;39951:15:0;39928:20;:10;39941:7;39928:20;:::i;:::-;:38;39852:114;39834:216;;;40000:38;;-1:-1:-1;;;40000:38:0;;40027:10;40000:38;;;3742:51:1;3715:18;;40000:38:0;3596:203:1;39834:216:0;40097:1;22619:6;-1:-1:-1;;;;;22619:6:0;40078:21;:59;;;;-1:-1:-1;40127:10:0;40116:7;22592;22619:6;-1:-1:-1;;;;;22619:6:0;;22546:87;40116:7;-1:-1:-1;;;;;40116:21:0;;;40078:59;:114;;;;-1:-1:-1;40177:15:0;40154:20;:10;40167:7;40154:20;:::i;:::-;:38;40078:114;40060:313;;;40266:20;:10;40279:7;40266:20;:::i;:::-;40331:15;40307:20;:10;40320:7;40307:20;:::i;:::-;40306:40;;;;:::i;:::-;40226:135;;-1:-1:-1;;;40226:135:0;;;;;2572:25:1;;;;2613:18;;;2606:34;2545:18;;40226:135:0;2398:248:1;40060:313:0;40390:19;;-1:-1:-1;;;40390:19:0;;;;40385:79;;40426:19;:26;;-1:-1:-1;;;;40426:26:0;-1:-1:-1;;;40426:26:0;;;40385:79;40479:11;;-1:-1:-1;;;40479:11:0;;;;40474:63;;40507:11;:18;;-1:-1:-1;;;;40507:18:0;-1:-1:-1;;;40507:18:0;;;40474:63;40552:13;;-1:-1:-1;;;40552:13:0;;;;40547:67;;40582:13;:20;;-1:-1:-1;;;;40582:20:0;-1:-1:-1;;;40582:20:0;;;40547:67;40626:12;:19;;-1:-1:-1;;;;40626:19:0;-1:-1:-1;;;40626:19:0;;;40673:15;40656:14;:32;;;40717:12;40699:15;:30;40747:41;;;40760:10;15832:51:1;;15914:2;15899:18;;15892:34;;;;40747:41:0;;15805:18:1;40747:41:0;15658:274:1;49338:305:0;27510:21;:19;:21::i;:::-;49449:13:::1;::::0;49419:44:::1;::::0;49438:9;;-1:-1:-1;;;49449:13:0;::::1;;;49419:18;:44::i;:::-;49491:13;::::0;;49515:25;::::1;;-1:-1:-1::0;;;49515:25:0;;::::1;-1:-1:-1::0;;;;49515:25:0;::::1;;::::0;;;49556:79:::1;::::0;;16239:3:1;16221:22;;;16280:2;16259:19;;;16252:31;-1:-1:-1;;;16314:3:1;16299:19;;16292:44;49491:13:0::1;::::0;;;::::1;::::0;;;::::1;16417:14:1::0;;16410:22;16403:4;16388:20;;16381:52;16449:18;;;16442:50;49607:10:0::1;-1:-1:-1::0;16508:18:1;;16501:60;49619:15:0::1;-1:-1:-1::0;16577:19:1;;16570:35;49556:79:0::1;::::0;16368:3:1;16353:19;49556:79:0::1;15937:674:1::0;41192:151:0;63748:9;:18;;;;41303:6;41242:7;63748:18;;;;;63351:12;;41242:7;;63748:18;41269:42;;63748:18;41269:42;:::i;:::-;:66;;;;:::i;:::-;41262:73;;41192:151;:::o;46930:205::-;27510:21;:19;:21::i;:::-;46995:23:::1;:21;:23::i;:::-;47029:19;:26:::0;;-1:-1:-1;;;;47029:26:0::1;-1:-1:-1::0;;;47029:26:0::1;::::0;;47071:56:::1;::::0;;16874:2:1;16856:21;;;16893:18;;16886:30;;;;-1:-1:-1;;;16947:3:1;16932:19;;16925:50;47099:10:0::1;17042:4:1::0;17027:20;;17020:62;47111:15:0::1;17098:18:1::0;;;17091:34;-1:-1:-1;;;;;;;;;;;47071:56:0;17007:3:1;16992:19;47071:56:0::1;16616:515:1::0;64140:186:0;64209:4;64245:10;64266:30;64245:10;64286:2;64290:5;64266:9;:30::i;45904:166::-;20825:13;:11;:13::i;:::-;45954:15:::1;:13;:15::i;:::-;45980:11;:18:::0;;-1:-1:-1;;;;45980:18:0::1;-1:-1:-1::0;;;45980:18:0::1;::::0;;46014:48:::1;::::0;;17394:2:1;17376:21;;;17433:2;17413:18;;;17406:30;-1:-1:-1;;;17467:3:1;17452:19;;17445:42;46034:10:0::1;17554:4:1::0;17539:20;;17532:62;46046:15:0::1;17610:18:1::0;;;17603:34;;;;-1:-1:-1;;;;;;;;;;;46014:48:0;17519:3:1;17504:19;46014:48:0::1;17136:507:1::0;55548:812:0;27510:21;:19;:21::i;:::-;-1:-1:-1;;;;;55631:23:0;::::1;55627:88;;55678:25;::::0;-1:-1:-1;;;55678:25:0;;-1:-1:-1;;;;;3760:32:1;;55678:25:0::1;::::0;::::1;3742:51:1::0;3715:18;;55678:25:0::1;3596:203:1::0;55627:88:0::1;55765:6;::::0;55725:48:::1;::::0;55746:9;;-1:-1:-1;;;;;55765:6:0::1;55725:20;:48::i;:::-;55814:6;::::0;;-1:-1:-1;;;;;55832:27:0;;::::1;-1:-1:-1::0;;;;;;55832:27:0;::::1;::::0;::::1;::::0;;;55877:63:::1;::::0;;55814:6;;;::::1;17917:34:1::0;;;17982:2;17967:18;;17960:43;;;;55912:10:0::1;18019:18:1::0;;;18012:43;;;;55924:15:0::1;18086:2:1::0;18071:18;;18064:34;55877:63:0::1;::::0;17866:3:1;17851:19;55877:63:0::1;;;;;;;55974:6;::::0;:16:::1;::::0;;-1:-1:-1;;;55974:16:0;;;;56042:1:::1;::::0;-1:-1:-1;;;;;55974:6:0::1;::::0;:14:::1;::::0;:16:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:6;:16:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;55965:34:0::1;;56008:4;56015:6;;;;;;;;;-1:-1:-1::0;;;;;56015:6:0::1;-1:-1:-1::0;;;;;56015:11:0::1;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55965:64;::::0;-1:-1:-1;;;;;;55965:64:0::1;::::0;;;;;;-1:-1:-1;;;;;18339:15:1;;;55965:64:0::1;::::0;::::1;18321:34:1::0;18391:15;;18371:18;;;18364:43;18256:18;;55965:64:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;55957:87:0::1;::::0;55953:400:::1;;56077:6;;;;;;;;;-1:-1:-1::0;;;;;56077:6:0::1;-1:-1:-1::0;;;;;56077:14:0::1;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;56068:37:0::1;;56114:4;56121:6;;;;;;;;;-1:-1:-1::0;;;;;56121:6:0::1;-1:-1:-1::0;;;;;56121:11:0::1;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56068:67;::::0;-1:-1:-1;;;;;;56068:67:0::1;::::0;;;;;;-1:-1:-1;;;;;18339:15:1;;;56068:67:0::1;::::0;::::1;18321:34:1::0;18391:15;;18371:18;;;18364:43;18256:18;;56068:67:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56061:4;:74:::0;;-1:-1:-1;;;;;;56061:74:0::1;-1:-1:-1::0;;;;;56061:74:0;;;::::1;::::0;;::::1;::::0;;-1:-1:-1;56157:25:0;;;:19:::1;:25;::::0;;;;;::::1;;56152:99;;56223:4;::::0;-1:-1:-1;;;;;56223:4:0::1;56203:25;::::0;;;:19:::1;:25;::::0;;;;:32;;-1:-1:-1;;56203:32:0::1;56231:4;56203:32;::::0;;56152:99:::1;56279:4;::::0;-1:-1:-1;;;;;56279:4:0::1;56270:14;::::0;;;:8:::1;:14;::::0;;;;;::::1;;56265:77;;56314:4;::::0;-1:-1:-1;;;;;56314:4:0::1;56305:14;::::0;;;:8:::1;:14;::::0;;;;:21;;-1:-1:-1;;56305:21:0::1;56322:4;56305:21;::::0;;56265:77:::1;55616:744;55548:812:::0;:::o;46235:155::-;20825:13;:11;:13::i;:::-;46290:16:::1;:23:::0;;-1:-1:-1;;;;46290:23:0::1;-1:-1:-1::0;;;46290:23:0::1;::::0;;46329:53:::1;::::0;;18676:2:1;18658:21;;;18715:2;18695:18;;;18688:30;-1:-1:-1;;;18749:3:1;18734:19;;18727:47;46354:10:0::1;18841:4:1::0;18826:20;;18819:62;46366:15:0::1;18897:18:1::0;;;18890:34;;;;-1:-1:-1;;;;;;;;;;;46329:53:0;18806:3:1;18791:19;46329:53:0::1;18418:512:1::0;61700:308:0;20825:13;:11;:13::i;:::-;-1:-1:-1;;;;;;;61786:27:0;::::1;::::0;61782:91:::1;;61837:24;::::0;-1:-1:-1;;;61837:24:0;;-1:-1:-1;;;;;3760:32:1;;61837:24:0::1;::::0;::::1;3742:51:1::0;3715:18;;61837:24:0::1;3596:203:1::0;61782:91:0::1;61883:39;61904:8;61914:7;22592::::0;22619:6;-1:-1:-1;;;;;22619:6:0;;22546:87;61914:7:::1;61883:20;:39::i;:::-;61933:12;:23:::0;;-1:-1:-1;;;;;;61933:23:0::1;-1:-1:-1::0;;;;;61933:23:0;::::1;;::::0;;61967:33:::1;61933:23:::0;61967::::1;:33::i;:::-;61700:308:::0;:::o;72766:136::-;72854:40;72863:8;72873:7;72882:5;72889:4;72854:8;:40::i;:::-;72766:136;;;:::o;41548:223::-;41604:20;:18;:20::i;:::-;41639:12;;-1:-1:-1;;;;;41639:12:0;41655:10;41639:26;;;;:51;;-1:-1:-1;41680:10:0;41669:7;22592;22619:6;-1:-1:-1;;;;;22619:6:0;;22546:87;41669:7;-1:-1:-1;;;;;41669:21:0;;;41639:51;41635:129;;;41714:38;;-1:-1:-1;;;41714:38:0;;41741:10;41714:38;;;3742:51:1;3715:18;;41714:38:0;3596:203:1;43415:121:0;43469:11;;-1:-1:-1;;;43469:11:0;;;;43465:64;;;43504:13;;-1:-1:-1;;;43504:13:0;;19137:2:1;43504:13:0;;;19119:21:1;19176:1;19156:18;;;19149:29;-1:-1:-1;;;19194:18:1;;;19187:33;19237:18;;43504:13:0;18935:326:1;41902:185:0;42006:7;41994:8;:19;41990:90;;42037:31;;-1:-1:-1;;;42037:31:0;;;;;1901:25:1;;;1874:18;;42037:31:0;1755:177:1;5824:162:0;5934:43;;;-1:-1:-1;;;;;15850:32:1;;5934:43:0;;;15832:51:1;15899:18;;;;15892:34;;;5934:43:0;;;;;;;;;;15805:18:1;;;;5934:43:0;;;;;;;;-1:-1:-1;;;;;5934:43:0;-1:-1:-1;;;5934:43:0;;;5907:71;;5927:5;;5907:19;:71::i;74686:496::-;-1:-1:-1;;;;;64818:21:0;;;74789:24;64818:21;;;:11;:21;;;;;;;;:30;;;;;;;;;;-1:-1:-1;;74859:37:0;;74855:320;;74936:5;74917:16;:24;74913:132;;;74969:60;;-1:-1:-1;;;74969:60:0;;-1:-1:-1;;;;;19486:32:1;;74969:60:0;;;19468:51:1;19535:18;;;19528:34;;;19578:18;;;19571:34;;;19441:18;;74969:60:0;19266:345:1;74913:132:0;75088:60;75097:8;75107:7;75135:5;75116:16;:24;75142:5;75088:8;:60::i;67421:1245::-;-1:-1:-1;;;;;67505:18:0;;67501:88;;67547:30;;-1:-1:-1;;;67547:30:0;;67574:1;67547:30;;;3742:51:1;3715:18;;67547:30:0;3596:203:1;67501:88:0;-1:-1:-1;;;;;67603:16:0;;67599:88;;67643:32;;-1:-1:-1;;;67643:32:0;;67672:1;67643:32;;;3742:51:1;3715:18;;67643:32:0;3596:203:1;67599:88:0;67702:12;;-1:-1:-1;;;67702:12:0;;;;67697:151;;-1:-1:-1;;;;;67736:17:0;;;;;;:11;:17;;;;;;;;67735:18;:38;;;;-1:-1:-1;;;;;;67758:15:0;;;;;;:11;:15;;;;;;;;67757:16;67735:38;67731:106;;;67801:20;;-1:-1:-1;;;67801:20:0;;;;;;;;;;;67731:106;67864:6;;-1:-1:-1;;;67864:6:0;;;;;:27;;-1:-1:-1;;;;;;67874:17:0;;;;;;:11;:17;;;;;;;;67864:27;67860:91;;;67915:24;67923:4;67929:2;67933:5;67915:7;:24::i;67860:91::-;67973:4;;-1:-1:-1;;;;;67965:12:0;;;67973:4;;67965:12;;;;:29;;-1:-1:-1;67981:13:0;;-1:-1:-1;;;67981:13:0;;;;67965:29;:82;;;;-1:-1:-1;68040:7:0;;68019:17;;67998:18;;:38;;68019:17;67998:38;:::i;:::-;:49;;67965:82;:121;;;;-1:-1:-1;68079:7:0;;68069:4;63721:7;63748:18;;;:9;:18;;;;;;68051:35;;67965:121;67961:475;;;68124:7;;68152:16;;-1:-1:-1;;;68152:16:0;;;;:41;;;;-1:-1:-1;68191:1:0;22619:6;-1:-1:-1;;;;;22619:6:0;68172:21;68152:41;68148:238;;;68214:22;25837:6;68239:19;:17;:19::i;:::-;:24;;68261:2;68239:24;:::i;:::-;:41;;;;:::i;:::-;68214:66;;68330:10;68312:14;:28;;:58;;68360:10;68312:58;;;68343:14;68312:58;68299:71;;68195:191;68148:238;68402:22;68413:10;68402;:22::i;:::-;68088:348;67961:475;68489:11;;68467:5;;-1:-1:-1;;;68489:11:0;;;;:33;;;;-1:-1:-1;;;;;;68505:17:0;;;;;;:11;:17;;;;;;;;68504:18;68489:33;:53;;;;-1:-1:-1;;;;;;68527:15:0;;;;;;:11;:15;;;;;;;;68526:16;68489:53;68485:134;;;68570:37;68591:4;68597:2;68601:5;68570:20;:37::i;:::-;68559:48;;68485:134;68631:27;68639:4;68645:2;68649:8;68631:7;:27::i;42218:179::-;42316:7;42304:19;;:8;:19;;;42300:90;;42347:31;;-1:-1:-1;;;42347:31:0;;1408:14:1;;1401:22;42347:31:0;;;1383:41:1;1356:18;;42347:31:0;1243:187:1;43147:136:0;43206:16;;-1:-1:-1;;;43206:16:0;;;;43202:74;;;43246:18;;-1:-1:-1;;;43246:18:0;;19818:2:1;43246:18:0;;;19800:21:1;19857:1;19837:18;;;19830:29;-1:-1:-1;;;19875:18:1;;;19868:38;19923:18;;43246::0;19616:331:1;42532:195:0;42642:7;-1:-1:-1;;;;;42628:21:0;:10;-1:-1:-1;;;;;42628:21:0;;42624:96;;42673:35;;-1:-1:-1;;;42673:35:0;;-1:-1:-1;;;;;3760:32:1;;42673:35:0;;;3742:51:1;3715:18;;42673:35:0;3596:203:1;43686:145:0;43748:19;;-1:-1:-1;;;43748:19:0;;;;43744:80;;;43791:21;;-1:-1:-1;;;43791:21:0;;20154:2:1;43791:21:0;;;20136::1;20193:2;20173:18;;;20166:30;-1:-1:-1;;;20212:18:1;;;20205:41;20263:18;;43791:21:0;19952:335:1;22825:162:0;22896:10;22885:7;22592;22619:6;-1:-1:-1;;;;;22619:6:0;;22546:87;22885:7;-1:-1:-1;;;;;22885:21:0;;22881:99;;22930:38;;-1:-1:-1;;;22930:38:0;;22957:10;22930:38;;;3742:51:1;3715:18;;22930:38:0;3596:203:1;24340:191:0;24414:16;24433:6;;-1:-1:-1;;;;;24450:17:0;;;-1:-1:-1;;;;;;24450:17:0;;;;;;24483:40;;24433:6;;;;;;;24483:40;;24414:16;24483:40;24403:128;24340:191;:::o;42869:136::-;42928:16;;-1:-1:-1;;;42928:16:0;;;;42924:74;;;42968:18;;-1:-1:-1;;;42968:18:0;;20494:2:1;42968:18:0;;;20476:21:1;20533:1;20513:18;;;20506:29;-1:-1:-1;;;20551:18:1;;;20544:38;20599:18;;42968::0;20292:331:1;23789:220:0;20825:13;:11;:13::i;:::-;-1:-1:-1;;;;;23874:22:0;::::1;23870:93;;23920:31;::::0;-1:-1:-1;;;23920:31:0;;23948:1:::1;23920:31;::::0;::::1;3742:51:1::0;3715:18;;23920:31:0::1;3596:203:1::0;23870:93:0::1;23973:28;23992:8;23973:18;:28::i;73673:455::-:0;-1:-1:-1;;;;;73789:22:0;;73785:94;;73835:32;;-1:-1:-1;;;73835:32:0;;73864:1;73835:32;;;3742:51:1;3715:18;;73835:32:0;3596:203:1;73785:94:0;-1:-1:-1;;;;;73893:21:0;;73889:92;;73938:31;;-1:-1:-1;;;73938:31:0;;73966:1;73938:31;;;3742:51:1;3715:18;;73938:31:0;3596:203:1;73889:92:0;-1:-1:-1;;;;;73991:21:0;;;;;;;:11;:21;;;;;;;;:30;;;;;;;;;:38;;;74040:81;;;;74094:7;-1:-1:-1;;;;;74075:34:0;74084:8;-1:-1:-1;;;;;74075:34:0;;74103:5;74075:34;;;;1901:25:1;;1889:2;1874:18;;1755:177;74075:34:0;;;;;;;;73673:455;;;;:::o;6376:295::-;6457:23;6483:33;-1:-1:-1;;;;;6483:27:0;;6511:4;6483:27;:33::i;:::-;6457:59;;6531:10;:17;6552:1;6531:22;;:57;;;;;6569:10;6558:30;;;;;;;;;;;;:::i;:::-;6557:31;6531:57;6527:137;;;6612:40;;-1:-1:-1;;;6612:40:0;;-1:-1:-1;;;;;3760:32:1;;6612:40:0;;;3742:51:1;3715:18;;6612:40:0;3596:203:1;70470:999:0;-1:-1:-1;;;;;63748:18:0;;70556;63748;;;:9;:18;;;;;;70577:21;;70593:5;;70577:21;:::i;:::-;70556:42;;70609:13;25837:6;70647:14;;70625:19;:17;:19::i;:::-;:36;;;;:::i;:::-;:53;;;;:::i;:::-;70609:69;;70708:5;70695:10;:18;:46;;;;-1:-1:-1;;;;;;70718:23:0;;;;;;:19;:23;;;;;;;;70717:24;70695:46;70691:122;;;70765:36;;-1:-1:-1;;;70765:36:0;;;;;2572:25:1;;;2613:18;;;2606:34;;;2545:18;;70765:36:0;2398:248:1;70691:122:0;-1:-1:-1;;;;;70829:18:0;;70825:369;;70880:5;70864:12;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;70825:369:0;;-1:-1:-1;70825:369:0;;-1:-1:-1;;;;;70940:15:0;;70918:19;70940:15;;;:9;:15;;;;;;70974:19;;;70970:117;;;71021:50;;-1:-1:-1;;;71021:50:0;;-1:-1:-1;;;;;19486:32:1;;71021:50:0;;;19468:51:1;19535:18;;;19528:34;;;19578:18;;;19571:34;;;19441:18;;71021:50:0;19266:345:1;70970:117:0;-1:-1:-1;;;;;71130:15:0;;;;;;:9;:15;;;;;71148:19;;;;71130:37;;70825:369;-1:-1:-1;;;;;71210:16:0;;71206:213;;71272:12;:21;;;;;;;71206:213;;;-1:-1:-1;;;;;71370:13:0;;;;;;:9;:13;;;;;:22;;;;;;71206:213;71451:2;-1:-1:-1;;;;;71436:25:0;71445:4;-1:-1:-1;;;;;71436:25:0;;71455:5;71436:25;;;;1901::1;;1889:2;1874:18;;1755:177;71436:25:0;;;;;;;;70545:924;;70470:999;;;:::o;69263:518::-;27154:6;:13;;-1:-1:-1;;;;27154:13:0;-1:-1:-1;;;27154:13:0;;;-1:-1:-1;;;;;69394:14:0;::::1;69370:7:::0;69394:14;;;:8:::1;:14;::::0;;;;;27154:13;69394:14:::1;:40:::0;::::1;;;-1:-1:-1::0;69413:6:0::1;:16:::0;:20;;69394:40:::1;69390:104;;;69458:24;69469:4;69475:6;69458:10;:24::i;:::-;69451:31;;;;69390:104;-1:-1:-1::0;;;;;69508:12:0;::::1;;::::0;;;:8:::1;:12;::::0;;;;;::::1;;:39:::0;::::1;;;-1:-1:-1::0;69525:7:0::1;:17:::0;:21;;69508:39:::1;69504:104;;;69571:25;69583:4;69589:6;69571:11;:25::i;69504:104::-;-1:-1:-1::0;;;;;69623:14:0;::::1;;::::0;;;:8:::1;:14;::::0;;;;;::::1;;69622:15;:32:::0;::::1;;;-1:-1:-1::0;;;;;;69642:12:0;::::1;;::::0;;;:8:::1;:12;::::0;;;;;::::1;;69641:13;69622:32;:63;;;;-1:-1:-1::0;69659:11:0::1;:21:::0;:25;;69622:63:::1;69618:132;;;69709:29;69725:4;69731:6;69709:15;:29::i;69618:132::-;-1:-1:-1::0;69767:6:0;27178:1:::1;27190:6:::0;:14;;-1:-1:-1;;;;27190:14:0;;;69263:518;;-1:-1:-1;;;69263:518:0:o;1635:178::-;1735:12;1767:38;1789:6;1797:4;1803:1;1767:21;:38::i;58117:141::-;27154:6;:13;;-1:-1:-1;;;;27154:13:0;-1:-1:-1;;;27154:13:0;;;58221:29:::1;::::0;;;;::::1;::::0;;;27163:4;58221:29;;;;;::::1;::::0;::::1;::::0;58194:7;;58221:29:::1;::::0;58237:4;58243:6;58221:7:::1;:29::i;58598:143::-:0;27154:6;:13;;-1:-1:-1;;;;27154:13:0;-1:-1:-1;;;27154:13:0;;;58703:30:::1;::::0;;;;::::1;::::0;;;58711:7:::1;58703:30:::0;;;;;::::1;::::0;::::1;::::0;58676:7;;58703:30:::1;::::0;58720:4;58726:6;58703:7:::1;:30::i;59085:151::-:0;27154:6;:13;;-1:-1:-1;;;;27154:13:0;-1:-1:-1;;;27154:13:0;;;59194:34:::1;::::0;;;;::::1;::::0;;;59202:11:::1;59194:34:::0;;;;;::::1;::::0;::::1;::::0;59167:7;;59194:34:::1;::::0;59215:4;59221:6;59194:7:::1;:34::i;2406:456::-:0;2539:12;2592:5;2568:21;:29;2564:110;;;2621:41;;-1:-1:-1;;;2621:41:0;;2656:4;2621:41;;;3742:51:1;3715:18;;2621:41:0;3596:203:1;2564:110:0;2685:12;2699:23;2726:6;-1:-1:-1;;;;;2726:11:0;2745:5;2766:4;2726:55;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2684:97;;;;2799:55;2826:6;2834:7;2843:10;2799:26;:55::i;:::-;2792:62;2406:456;-1:-1:-1;;;;;;2406:456:0:o;59632:492::-;27154:6;:13;;-1:-1:-1;;;;27154:13:0;-1:-1:-1;;;27154:13:0;;;59765:17;;59813:15:::1;::::0;59726:7;;59765:17;59813:19:::1;::::0;59726:7;59813:19:::1;:::i;:::-;59797:12;:35;59793:83;;-1:-1:-1::0;59860:4:0::1;59793:83;59886:17;25837:6;59906:17;59915:8:::0;59906:6;:17:::1;:::i;:::-;:34;;;;:::i;:::-;59886:54:::0;-1:-1:-1;59951:17:0::1;59971:18;59886:54:::0;59971:6;:18:::1;:::i;:::-;59951:38:::0;-1:-1:-1;60004:13:0;;60000:90:::1;;60034:44;60043:7;60052:4;60058:9;60069:8;60034;:44::i;:::-;27190:6:::0;:14;;-1:-1:-1;;;;27190:14:0;;;60107:9;59632:492;-1:-1:-1;;;;;;59632:492:0:o;3626:425::-;3774:12;3804:7;3799:245;;3828:19;3836:10;3828:7;:19::i;:::-;3799:245;;;3884:17;;:22;:49;;;;-1:-1:-1;;;;;;3910:18:0;;;:23;3884:49;3880:121;;;3961:24;;-1:-1:-1;;;3961:24:0;;-1:-1:-1;;;;;3760:32:1;;3961:24:0;;;3742:51:1;3715:18;;3961:24:0;3596:203:1;3880:121:0;-1:-1:-1;4022:10:0;4015:17;;60512:278;27154:6;:13;;-1:-1:-1;;;;27154:13:0;-1:-1:-1;;;27154:13:0;;;60658:17;;27154:13;;60678:3;;60649:26:::1;::::0;:6;:26:::1;:::i;:::-;:32;;;;:::i;:::-;60622:59;;60692:41;60708:16;60726:6;60692:15;:41::i;:::-;60746:36;60754:4;60768;60775:6;60746:7;:36::i;:::-;-1:-1:-1::0;;27190:6:0;:14;;-1:-1:-1;;;;27190:14:0;;;-1:-1:-1;;;60512:278:0:o;4319:328::-;4389:17;;:21;4385:255;;4484:10;4478:17;4541:15;4528:10;4524:2;4520:19;4513:44;4385:255;4611:17;;-1:-1:-1;;;4611:17:0;;;;;;;;;;;61045:185;27154:6;:13;;-1:-1:-1;;;;27154:13:0;-1:-1:-1;;;27154:13:0;;;61141:12:::1;:42:::0;;61167:16;;61141:12;27154:13;;61141:42:::1;::::0;61167:16;;61141:42:::1;:::i;:::-;::::0;;;-1:-1:-1;;61194:18:0;:28;;61216:6;;61194:18;::::1;::::0;:28:::1;::::0;61216:6;;61194:28:::1;:::i;:::-;::::0;;;-1:-1:-1;;27190:6:0;:14;;-1:-1:-1;;;;27190:14:0;;;-1:-1:-1;;61045:185:0:o;14:180:1:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:1;;14:180;-1:-1:-1;14:180:1:o;199:250::-;284:1;294:113;308:6;305:1;302:13;294:113;;;384:11;;;378:18;365:11;;;358:39;330:2;323:10;294:113;;;-1:-1:-1;;441:1:1;423:16;;416:27;199:250::o;454:396::-;603:2;592:9;585:21;566:4;635:6;629:13;678:6;673:2;662:9;658:18;651:34;694:79;766:6;761:2;750:9;746:18;741:2;733:6;729:15;694:79;:::i;:::-;834:2;813:15;-1:-1:-1;;809:29:1;794:45;;;;841:2;790:54;;454:396;-1:-1:-1;;454:396:1:o;855:131::-;-1:-1:-1;;;;;930:31:1;;920:42;;910:70;;976:1;973;966:12;991:247;1050:6;1103:2;1091:9;1082:7;1078:23;1074:32;1071:52;;;1119:1;1116;1109:12;1071:52;1158:9;1145:23;1177:31;1202:5;1177:31;:::i;1435:315::-;1503:6;1511;1564:2;1552:9;1543:7;1539:23;1535:32;1532:52;;;1580:1;1577;1570:12;1532:52;1619:9;1606:23;1638:31;1663:5;1638:31;:::i;:::-;1688:5;1740:2;1725:18;;;;1712:32;;-1:-1:-1;;;1435:315:1:o;1937:456::-;2014:6;2022;2030;2083:2;2071:9;2062:7;2058:23;2054:32;2051:52;;;2099:1;2096;2089:12;2051:52;2138:9;2125:23;2157:31;2182:5;2157:31;:::i;:::-;2207:5;-1:-1:-1;2264:2:1;2249:18;;2236:32;2277:33;2236:32;2277:33;:::i;:::-;1937:456;;2329:7;;-1:-1:-1;;;2383:2:1;2368:18;;;;2355:32;;1937:456::o;2840:118::-;2926:5;2919:13;2912:21;2905:5;2902:32;2892:60;;2948:1;2945;2938:12;2963:382;3028:6;3036;3089:2;3077:9;3068:7;3064:23;3060:32;3057:52;;;3105:1;3102;3095:12;3057:52;3144:9;3131:23;3163:31;3188:5;3163:31;:::i;:::-;3213:5;-1:-1:-1;3270:2:1;3255:18;;3242:32;3283:30;3242:32;3283:30;:::i;:::-;3332:7;3322:17;;;2963:382;;;;;:::o;3350:241::-;3406:6;3459:2;3447:9;3438:7;3434:23;3430:32;3427:52;;;3475:1;3472;3465:12;3427:52;3514:9;3501:23;3533:28;3555:5;3533:28;:::i;3804:388::-;3872:6;3880;3933:2;3921:9;3912:7;3908:23;3904:32;3901:52;;;3949:1;3946;3939:12;3901:52;3988:9;3975:23;4007:31;4032:5;4007:31;:::i;:::-;4057:5;-1:-1:-1;4114:2:1;4099:18;;4086:32;4127:33;4086:32;4127:33;:::i;4420:127::-;4481:10;4476:3;4472:20;4469:1;4462:31;4512:4;4509:1;4502:15;4536:4;4533:1;4526:15;4552:168;4625:9;;;4656;;4673:15;;;4667:22;;4653:37;4643:71;;4694:18;;:::i;4725:217::-;4765:1;4791;4781:132;;4835:10;4830:3;4826:20;4823:1;4816:31;4870:4;4867:1;4860:15;4898:4;4895:1;4888:15;4781:132;-1:-1:-1;4927:9:1;;4725:217::o;4947:128::-;5014:9;;;5035:11;;;5032:37;;;5049:18;;:::i;5080:125::-;5145:9;;;5166:10;;;5163:36;;;5179:18;;:::i;5342:127::-;5403:10;5398:3;5394:20;5391:1;5384:31;5434:4;5431:1;5424:15;5458:4;5455:1;5448:15;5474:251;5544:6;5597:2;5585:9;5576:7;5572:23;5568:32;5565:52;;;5613:1;5610;5603:12;5565:52;5645:9;5639:16;5664:31;5689:5;5664:31;:::i;6152:980::-;6414:4;6462:3;6451:9;6447:19;6493:6;6482:9;6475:25;6519:2;6557:6;6552:2;6541:9;6537:18;6530:34;6600:3;6595:2;6584:9;6580:18;6573:31;6624:6;6659;6653:13;6690:6;6682;6675:22;6728:3;6717:9;6713:19;6706:26;;6767:2;6759:6;6755:15;6741:29;;6788:1;6798:195;6812:6;6809:1;6806:13;6798:195;;;6877:13;;-1:-1:-1;;;;;6873:39:1;6861:52;;6968:15;;;;6933:12;;;;6909:1;6827:9;6798:195;;;-1:-1:-1;;;;;;;7049:32:1;;;;7044:2;7029:18;;7022:60;-1:-1:-1;;;7113:3:1;7098:19;7091:35;7010:3;6152:980;-1:-1:-1;;;6152:980:1:o;8053:184::-;8123:6;8176:2;8164:9;8155:7;8151:23;8147:32;8144:52;;;8192:1;8189;8182:12;8144:52;-1:-1:-1;8215:16:1;;8053:184;-1:-1:-1;8053:184:1:o;20628:245::-;20695:6;20748:2;20736:9;20727:7;20723:23;20719:32;20716:52;;;20764:1;20761;20754:12;20716:52;20796:9;20790:16;20815:28;20837:5;20815:28;:::i;20878:287::-;21007:3;21045:6;21039:13;21061:66;21120:6;21115:3;21108:4;21100:6;21096:17;21061:66;:::i;:::-;21143:16;;;;;20878:287;-1:-1:-1;;20878:287:1:o
Swarm Source
ipfs://4eb8aa1cb488225b8d42eae37fd40524baf6888b787990af6d0d0fa98d42e9a5
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.