ETH Price: $3,441.28 (+4.02%)

Contract

0x570dB9a388B641C92722c0f35574c33063a972D7
 

Overview

ETH Balance

0.100353804710840465 ETH

Eth Value

$345.35 (@ $3,441.28/ETH)

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Transfer207667962024-09-17 0:35:5998 days ago1726533359IN
Scratch Engine: SCRATCH Token
0 ETH0.00010472.07831388
Transfer207652032024-09-16 19:16:3598 days ago1726514195IN
Scratch Engine: SCRATCH Token
0 ETH0.000178043.53426425
Transfer205437132024-08-16 20:55:23129 days ago1723841723IN
Scratch Engine: SCRATCH Token
0 ETH0.000046410.92123973
Transfer191502052024-02-03 20:28:11324 days ago1706992091IN
Scratch Engine: SCRATCH Token
0 ETH0.0006084816
Transfer184449312023-10-27 23:49:47423 days ago1698450587IN
Scratch Engine: SCRATCH Token
0 ETH0.0006121112.15050678
Transfer183434632023-10-13 19:09:11437 days ago1697224151IN
Scratch Engine: SCRATCH Token
0 ETH0.0005113710.15082655
Transfer183433672023-10-13 18:49:47437 days ago1697222987IN
Scratch Engine: SCRATCH Token
0 ETH0.000635812.62065616
Transfer181493012023-09-16 14:29:59464 days ago1694874599IN
Scratch Engine: SCRATCH Token
0 ETH0.0003587310.78395183
Transfer179774282023-08-23 12:32:23489 days ago1692793943IN
Scratch Engine: SCRATCH Token
0 ETH0.0010132220.11253611
Transfer178641072023-08-07 16:00:59504 days ago1691424059IN
Scratch Engine: SCRATCH Token
0 ETH0.0036259771.97532097
Transfer178568472023-08-06 15:35:23505 days ago1691336123IN
Scratch Engine: SCRATCH Token
0 ETH0.00086626.0513927
Transfer175318712023-06-22 1:22:35551 days ago1687396955IN
Scratch Engine: SCRATCH Token
0 ETH0.0008480416.8375739
Transfer174606662023-06-12 1:17:59561 days ago1686532679IN
Scratch Engine: SCRATCH Token
0 ETH0.0008547916.96765304
Transfer173896582023-06-02 0:59:11571 days ago1685667551IN
Scratch Engine: SCRATCH Token
0 ETH0.0013210126.22198268
Approve172809252023-05-17 17:50:47586 days ago1684345847IN
Scratch Engine: SCRATCH Token
0 ETH0.0034325172.72133276
Transfer172155312023-05-08 11:38:59596 days ago1683545939IN
Scratch Engine: SCRATCH Token
0 ETH0.0048675496.62039131
Approve171614402023-04-30 21:08:59603 days ago1682888939IN
Scratch Engine: SCRATCH Token
0 ETH0.0013347449.47710914
Approve171614222023-04-30 21:05:23603 days ago1682888723IN
Scratch Engine: SCRATCH Token
0 ETH0.0011573846.33789825
Approve169508922023-04-01 0:58:11633 days ago1680310691IN
Scratch Engine: SCRATCH Token
0 ETH0.0009680220.50854139
Transfer169268912023-03-28 16:02:35636 days ago1680019355IN
Scratch Engine: SCRATCH Token
0 ETH0.0016280832.32503659
Transfer169184502023-03-27 11:34:23638 days ago1679916863IN
Scratch Engine: SCRATCH Token
0 ETH0.0007922120.82477586
Transfer168020472023-03-11 3:02:35654 days ago1678503755IN
Scratch Engine: SCRATCH Token
0 ETH0.0022907768.86241454
Transfer166487212023-02-17 13:26:47676 days ago1676640407IN
Scratch Engine: SCRATCH Token
0 ETH0.0013238626.28487407
Transfer166131202023-02-12 13:56:23681 days ago1676210183IN
Scratch Engine: SCRATCH Token
0 ETH0.0005879417.68041139
Transfer164817412023-01-25 5:26:59699 days ago1674624419IN
Scratch Engine: SCRATCH Token
0 ETH0.0005224615.70014166
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block
From
To
157919042022-10-20 21:09:59795 days ago1666300199
Scratch Engine: SCRATCH Token
0.03471859 ETH
157919042022-10-20 21:09:59795 days ago1666300199
Scratch Engine: SCRATCH Token
0.03471859 ETH
157854562022-10-19 23:33:23796 days ago1666222403
Scratch Engine: SCRATCH Token
0.03293994 ETH
157854562022-10-19 23:33:23796 days ago1666222403
Scratch Engine: SCRATCH Token
0.03293994 ETH
157762502022-10-18 16:41:23797 days ago1666111283
Scratch Engine: SCRATCH Token
0.00068839 ETH
157762502022-10-18 16:41:23797 days ago1666111283
Scratch Engine: SCRATCH Token
0.00068839 ETH
157761782022-10-18 16:26:59797 days ago1666110419
Scratch Engine: SCRATCH Token
0.01960789 ETH
157761782022-10-18 16:26:59797 days ago1666110419
Scratch Engine: SCRATCH Token
0.01960789 ETH
157621132022-10-16 17:17:23799 days ago1665940643
Scratch Engine: SCRATCH Token
0.02241604 ETH
157621132022-10-16 17:17:23799 days ago1665940643
Scratch Engine: SCRATCH Token
0.02241604 ETH
157540172022-10-15 14:08:47801 days ago1665842927
Scratch Engine: SCRATCH Token
0.03542622 ETH
157540172022-10-15 14:08:47801 days ago1665842927
Scratch Engine: SCRATCH Token
0.03542622 ETH
157466512022-10-14 13:29:11802 days ago1665754151
Scratch Engine: SCRATCH Token
0.00229403 ETH
157466512022-10-14 13:29:11802 days ago1665754151
Scratch Engine: SCRATCH Token
0.00229403 ETH
157443802022-10-14 5:52:23802 days ago1665726743
Scratch Engine: SCRATCH Token
0.00108939 ETH
157443802022-10-14 5:52:23802 days ago1665726743
Scratch Engine: SCRATCH Token
0.00108939 ETH
157434782022-10-14 2:50:59802 days ago1665715859
Scratch Engine: SCRATCH Token
0.000615 ETH
157434782022-10-14 2:50:59802 days ago1665715859
Scratch Engine: SCRATCH Token
0.000615 ETH
157326032022-10-12 14:23:47803 days ago1665584627
Scratch Engine: SCRATCH Token
0.00267562 ETH
157326032022-10-12 14:23:47803 days ago1665584627
Scratch Engine: SCRATCH Token
0.00267562 ETH
157320332022-10-12 12:28:35804 days ago1665577715
Scratch Engine: SCRATCH Token
0.02408214 ETH
157320332022-10-12 12:28:35804 days ago1665577715
Scratch Engine: SCRATCH Token
0.02408214 ETH
156980452022-10-07 18:38:35808 days ago1665167915
Scratch Engine: SCRATCH Token
0.02526853 ETH
156980452022-10-07 18:38:35808 days ago1665167915
Scratch Engine: SCRATCH Token
0.02526853 ETH
156973802022-10-07 16:23:11808 days ago1665159791
Scratch Engine: SCRATCH Token
0.0595006 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ScratchToken

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, Audited
File 1 of 15 : ScratchToken.sol
// SPDX-License-Identifier: UNLICENSED
/** 
 *   Copyright © 2022 Scratch Engine LLC. All rights reserved.
 *   Limited license is afforded to Etherscan, in accordance with its Terms of Use, 
 *   in order to publish this material.
 *   In connection with the foregoing, redistribution and use on the part of Etherscan,
 *   in source and binary forms, without modification, are permitted, 
 *   provided that such redistributions of source code retain the foregoing copyright notice
 *   and this disclaimer.
 */

pragma solidity 0.8.4;

// import "hardhat/console.sol";

// Openzeppelin
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Address.sol";

// Uniswap
import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol";
import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol";
import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";

import "./FoundersTimelock.sol";

/**
 * @title ScratchToken
 * @dev An ERC20 token featuring fees-on-transfer for buy/sell transactions
 * and increased fees on larger sell transactions.
 */
contract ScratchToken is Context, IERC20, Ownable {

    using Address for address;

    // ERC20
    string private constant _NAME = "ScratchToken";
    string private constant _SYMBOL = "SCRATCH";
    uint8 private constant _DECIMALS = 9;
    uint256 private constant _MAX_SUPPLY = 100 * 10**15 * 10 ** _DECIMALS;
    uint256 private _totalSupply;
    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => uint256)) private _allowances;

    // All percentages are relative to this value (1/10,000)
    uint256 private constant _PERCENTAGE_RELATIVE_TO = 10000;

    /// Distribution
    uint256 private constant _DIST_BURN_PERCENTAGE = 1850;
    uint256 private constant _DIST_FOUNDER1_PERCENTAGE = 250;
    uint256 private constant _DIST_FOUNDER2_PERCENTAGE = 250;
    uint256 private constant _DIST_FOUNDER3_PERCENTAGE = 250;
    uint256 private constant _DIST_FOUNDER4_PERCENTAGE = 250;
    uint256 private constant _DIST_FOUNDER5_PERCENTAGE = 250;
    uint256 private constant _DIST_EXCHANGE_PERCENTAGE = 750;
    uint256 private constant _DIST_DEV_PERCENTAGE = 500;
    uint256 private constant _DIST_OPS_PERCENTAGE = 150;

    // Founders TimeLock
    uint256 private constant _FOUNDERS_CLIFF_DURATION = 30 days * 6; // 6 months
    uint256 private constant _FOUNDERS_VESTING_PERIOD = 30 days; // Release every 30 days
    uint8 private constant _FOUNDERS_VESTING_DURATION = 10; // Linear release 10 times every 30 days
    mapping(address => FoundersTimelock) public foundersTimelocks;
    event FounderLiquidityLocked (
        address wallet,
        address timelockContract,
        uint256 tokensAmount
    );

    // Fees
    uint256 private constant _TAX_NORMAL_DEV_PERCENTAGE = 200;
    uint256 private constant _TAX_NORMAL_LIQUIDITY_PERCENTAGE = 200;
    uint256 private constant _TAX_NORMAL_OPS_PERCENTAGE = 100;
    uint256 private constant _TAX_NORMAL_ARCHA_PERCENTAGE = 100;
    uint256 private constant _TAX_EXTRA_LIQUIDITY_PERCENTAGE = 1000;
    uint256 private constant _TAX_EXTRA_BURN_PERCENTAGE = 500;
    uint256 private constant _TAX_EXTRA_DEV_PERCENTAGE = 500;
    uint256 private constant _TOKEN_STABILITY_PROTECTION_THRESHOLD_PERCENTAGE = 200;

    bool private _devFeeEnabled = true;
    bool private _opsFeeEnabled = true;
    bool private _liquidityFeeEnabled = true;
    bool private _archaFeeEnabled = true;
    bool private _burnFeeEnabled = true;
    bool private _tokenStabilityProtectionEnabled = true;

    mapping (address => bool) private _isExcludedFromFee;
    address private immutable _developmentWallet;
    address private _operationsWallet;
    address private _archaWallet;
    // Accumulated unswaped tokens from fee
    uint256 private _devFeePendingSwap = 0;
    uint256 private _opsFeePendingSwap = 0;
    uint256 private _liquidityFeePendingSwap = 0;

    // Uniswap
    uint256 private constant _UNISWAP_DEADLINE_DELAY = 60; // in seconds
    IUniswapV2Router02 private _uniswapV2Router;
    IUniswapV2Pair private _uniswapV2Pair;
    address private immutable _lpTokensWallet;
    bool private _inSwap = false; // Whether a previous call of swap process is still in process.
    bool private _swapAndLiquifyEnabled = true;
    uint256 private _minTokensBeforeSwapAndLiquify = 1 * 10 ** _DECIMALS;
    address private _liquidityWallet = 0x0000000000000000000000000000000000000000;

    // Events
    event SwapAndLiquify(
        uint256 tokensSwapped,
        uint256 ethReceived,
        uint256 tokensAddedToLiquidity
    );
    event SwapAndLiquifyEnabledUpdated(bool enabled);
    event MinTokensBeforeSwapUpdated(uint256 minTokensBeforeSwap);
    event DevFeeEnabledUpdated(bool enabled);
    event OpsFeeEnabledUpdated(bool enabled);
    event LiquidityFeeEnabledUpdated(bool enabled);
    event ArchaFeeEnabledUpdated(bool enabled);
    event BurnFeeEnabledUpdated(bool enabled);
    event TokenStabilityProtectionEnabledUpdated(bool enabled);

    event ExclusionFromFeesUpdated(address account, bool isExcluded);
    event ArchaWalletUpdated(address newWallet);
    event LiquidityWalletUpdated(address newWallet);


    // Modifiers
    modifier lockTheSwap {
        require(!_inSwap, "Currently in swap.");
        _inSwap = true;
        _;
        _inSwap = false;
    }

    // Fallback function to recieve ETH from uniswapV2Router when swaping
    receive() external payable {}
    
    constructor (
        address owner,
        address founder1Wallet_,
        address founder2Wallet_,
        address founder3Wallet_,
        address founder4Wallet_,
        address founder5Wallet_,
        address developmentWallet_,
        address exchangeWallet_,
        address operationsWallet_,
        address archaWallet_,
        address uniswapV2RouterAddress_
    ) {

        require(developmentWallet_ != address(0), "ScratchToken: set wallet to the zero address");
        require(exchangeWallet_ != address(0), "ScratchToken: set wallet to the zero address");
        require(operationsWallet_ != address(0), "ScratchToken: set wallet to the zero address");
        require(archaWallet_ != address(0), "ScratchToken: set wallet to the zero address");

        // Exclude addresses from fee
        _isExcludedFromFee[owner] = true;
        _isExcludedFromFee[address(this)] = true;
        _isExcludedFromFee[founder1Wallet_] = true;
        _isExcludedFromFee[founder2Wallet_] = true;
        _isExcludedFromFee[founder3Wallet_] = true;
        _isExcludedFromFee[founder4Wallet_] = true;
        _isExcludedFromFee[founder5Wallet_] = true;
        _isExcludedFromFee[developmentWallet_] = true;
        _isExcludedFromFee[exchangeWallet_] = true;
        _isExcludedFromFee[operationsWallet_] = true;
        _isExcludedFromFee[archaWallet_] = true;

        /// Perform initial distribution 
        // Founders
        _lockFounderLiquidity(founder1Wallet_, _DIST_FOUNDER1_PERCENTAGE);
        _lockFounderLiquidity(founder2Wallet_, _DIST_FOUNDER2_PERCENTAGE);
        _lockFounderLiquidity(founder3Wallet_, _DIST_FOUNDER3_PERCENTAGE);
        _lockFounderLiquidity(founder4Wallet_, _DIST_FOUNDER4_PERCENTAGE);
        _lockFounderLiquidity(founder5Wallet_, _DIST_FOUNDER5_PERCENTAGE);
        // Exchange
        _mint(exchangeWallet_, _getAmountToDistribute(_DIST_EXCHANGE_PERCENTAGE));
        _lpTokensWallet = exchangeWallet_;
        // Dev
        _mint(developmentWallet_, _getAmountToDistribute(_DIST_DEV_PERCENTAGE));
        _developmentWallet = developmentWallet_;
        // Operations
        _mint(operationsWallet_, _getAmountToDistribute(_DIST_OPS_PERCENTAGE));
        _operationsWallet = operationsWallet_;
        // Archa (used later for taxes)
        _archaWallet = archaWallet_;
        // Burn
        uint256 burnAmount = _getAmountToDistribute(_DIST_BURN_PERCENTAGE);
        emit Transfer(address(0), address(0), burnAmount);
        // Send the rest of supply minus burn to owner
        _mint(owner, _MAX_SUPPLY - totalSupply() - burnAmount);

        // Initialize uniswap
        _initSwap(uniswapV2RouterAddress_);

        // Transfer ownership to owner
        transferOwnership(owner);
    }

    // Constructor Internal Methods
    function _getAmountToDistribute(uint256 distributionPercentage) private pure returns (uint256) {
        return (_MAX_SUPPLY * distributionPercentage) / _PERCENTAGE_RELATIVE_TO;
    }

    function _lockFounderLiquidity(address wallet, uint256 distributionPercentage) internal {
        FoundersTimelock timelockContract = new FoundersTimelock(this, wallet, _FOUNDERS_CLIFF_DURATION, _FOUNDERS_VESTING_PERIOD, _FOUNDERS_VESTING_DURATION);
        foundersTimelocks[wallet] = timelockContract;
        _isExcludedFromFee[address(timelockContract)] = true;
        _mint(address(timelockContract), _getAmountToDistribute(distributionPercentage));
        emit FounderLiquidityLocked(wallet, address(timelockContract), _getAmountToDistribute(distributionPercentage));
    }

    // Public owner methods
    function isExcludedFromFees(address account) external view returns (bool) {
        return _isExcludedFromFee[account];
    }

    function excludeFromFees(address account, bool isExcluded) external onlyOwner {
        _isExcludedFromFee[account] = isExcluded;
        emit ExclusionFromFeesUpdated(account, isExcluded);
    }
    /**
     * @dev Returns the address of the archa wallet.
     */
    function archaWallet() external view returns (address) {
        return _archaWallet;
    }
    /**
     * @dev Sets the address of the archa wallet.
     */
    function setArchaWallet(address newWallet) external onlyOwner {
        require(newWallet != address(0), "ScratchToken: set wallet to the zero address");
        _archaWallet = newWallet;
        emit ArchaWalletUpdated(newWallet);
    }

    /**
     * @dev Returns true if swap and liquify feature is enabled.
     */
    function swapAndLiquifyEnabled() external view returns (bool) {
        return _swapAndLiquifyEnabled;
    }

    /**
      * @dev Disables or enables the swap and liquify feature.
      */
    function enableSwapAndLiquify(bool isEnabled) external onlyOwner {
        _swapAndLiquifyEnabled = isEnabled;
        emit SwapAndLiquifyEnabledUpdated(isEnabled);
    }

     /**
      * @dev Updates the minimum amount of tokens before triggering Swap and Liquify
      */
    function minTokensBeforeSwapAndLiquify() external view returns (uint256) {
        return _minTokensBeforeSwapAndLiquify;
    }

     /**
      * @dev Updates the minimum amount of tokens before triggering Swap and Liquify
      */
    function setMinTokensBeforeSwapAndLiquify(uint256 minTokens) external onlyOwner {
        require(minTokens < _totalSupply, "New value must be lower than total supply.");
        _minTokensBeforeSwapAndLiquify = minTokens;
        emit MinTokensBeforeSwapUpdated(minTokens);
    }
    /**
     * @dev Returns the address of the liquidity wallet, or 0 if not using it.
     */
    function liquidityWallet() external view returns (address) {
        return _liquidityWallet;
    }
    /**
     * @dev Sets the address of the liquidity wallet.
     */
    function setLiquidityWallet(address newWallet) external onlyOwner {
        _isExcludedFromFee[newWallet] = true;
        _liquidityWallet = newWallet;
        emit LiquidityWalletUpdated(newWallet);
    }

    /**
     * @dev Returns true if dev fee is enabled.
     */
    function devFeeEnabled() external view returns (bool) {
        return _devFeeEnabled;
    }

    /**
      * @dev Sets whether to collect or not the dev fee.
      */
    function enableDevFee(bool isEnabled) external onlyOwner {
        _devFeeEnabled = isEnabled;
        emit DevFeeEnabledUpdated(isEnabled);
    }

    /**
     * @dev Returns true if ops fee is enabled.
     */
    function opsFeeEnabled() external view returns (bool) {
        return _opsFeeEnabled;
    }

    /**
      * @dev Sets whether to collect or not the ops fee.
      */
    function enableOpsFee(bool isEnabled) external onlyOwner {
        _opsFeeEnabled = isEnabled;
        emit OpsFeeEnabledUpdated(isEnabled);
    }

    /**
     * @dev Returns true if liquidity fee is enabled.
     */
    function liquidityFeeEnabled() external view returns (bool) {
        return _liquidityFeeEnabled;
    }

    /**
      * @dev Sets whether to collect or not the liquidity fee.
      */
    function enableLiquidityFee(bool isEnabled) external onlyOwner {
        _liquidityFeeEnabled = isEnabled;
        emit LiquidityFeeEnabledUpdated(isEnabled);
    }

    /**
     * @dev Returns true if archa fee is enabled.
     */
    function archaFeeEnabled() external view returns (bool) {
        return _archaFeeEnabled;
    }

    /**
      * @dev Sets whether to collect or not the archa fee.
      */
    function enableArchaFee(bool isEnabled) external onlyOwner {
        _archaFeeEnabled = isEnabled;
        emit ArchaFeeEnabledUpdated(isEnabled);
    }

    /**
     * @dev Returns true if the burn fee is enabled.
     */
    function burnFeeEnabled() external view returns (bool) {
        return _burnFeeEnabled;
    }

    /**
      * @dev Sets whether to enable or not the burn fee.
      */
    function enableBurnFee(bool isEnabled) external onlyOwner {
        _burnFeeEnabled = isEnabled;
        emit BurnFeeEnabledUpdated(isEnabled);
    }

    /**
     * @dev Returns true if token stability protection is enabled.
     */
    function tokenStabilityProtectionEnabled() external view returns (bool) {
        return _tokenStabilityProtectionEnabled;
    }

    /**
      * @dev Sets whether to enable the token stability protection.
      */
    function enableTokenStabilityProtection(bool isEnabled) external onlyOwner {
        _tokenStabilityProtectionEnabled = isEnabled;
        emit TokenStabilityProtectionEnabledUpdated(isEnabled);
    }

    // Fees
    /**
     * @dev Returns the amount of the dev fee tokens pending swap
     */
    function devFeePendingSwap() external onlyOwner view returns (uint256) {
        return _devFeePendingSwap;
    }
    /**
     * @dev Returns the amount of the ops fee tokens pending swap
     */
    function opsFeePendingSwap() external onlyOwner view returns (uint256) {
        return _opsFeePendingSwap;
    }
    /**
     * @dev Returns the amount of the liquidity fee tokens pending swap
     */
    function liquidityFeePendingSwap() external onlyOwner view returns (uint256) {
        return _liquidityFeePendingSwap;
    }

    // Uniswap
    function _initSwap(address routerAddress) private {
        // Setup Uniswap router
        _uniswapV2Router = IUniswapV2Router02(routerAddress);
         // Get uniswap pair for this token or create if needed
        address uniswapV2Pair_ = IUniswapV2Factory(_uniswapV2Router.factory())
            .getPair(address(this), _uniswapV2Router.WETH());

        if (uniswapV2Pair_ == address(0)) {
            uniswapV2Pair_ = IUniswapV2Factory(_uniswapV2Router.factory())
                .createPair(address(this), _uniswapV2Router.WETH());
        }
        _uniswapV2Pair = IUniswapV2Pair(uniswapV2Pair_);

        // Exclude from fee
        _isExcludedFromFee[address(_uniswapV2Router)] = true;
    }

    /**
     * @dev Returns the address of the Token<>WETH pair.
     */
    function uniswapV2Pair() external view returns (address) {
        return address(_uniswapV2Pair);
    }

    /**
     * @dev Swap `amount` tokens for ETH and send to `recipient`
     *
     * Emits {Transfer} event. From this contract to the token and WETH Pair.
     */
    function _swapTokensForEth(uint256 amount, address recipient) private lockTheSwap {
        // Generate the uniswap pair path of Token <> WETH
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = _uniswapV2Router.WETH();

        // Approve token transfer
        _approve(address(this), address(_uniswapV2Router), amount);

        // Make the swap
        _uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            amount,
            0, // accept any amount of ETH
            path,
            recipient,
            block.timestamp + _UNISWAP_DEADLINE_DELAY
        );
    }
    
    /**
     * @dev Add `ethAmount` of ETH and `tokenAmount` of tokens to the LP.
     * Depends on the current rate for the pair between this token and WETH,
     * `ethAmount` and `tokenAmount` might not match perfectly. 
     * Dust(leftover) ETH or token will be refunded to this contract
     * (usually very small quantity).
     *
     */
    function _addLiquidity(uint256 ethAmount, uint256 tokenAmount) private {
        // Approve token transfer
        _approve(address(this), address(_uniswapV2Router), tokenAmount);

        // Add the ETH<>Token pair to the pool.
        _uniswapV2Router.addLiquidityETH {value: ethAmount} (
            address(this), 
            tokenAmount, 
            0, // amountTokenMin
            0, // amountETHMin
            _lpTokensWallet, // the receiver of the lp tokens
            block.timestamp + _UNISWAP_DEADLINE_DELAY
        );
    }
    // Swap and liquify
    /**
     * @dev Swap half of the amount token balance for ETH,
     * and pair it up with the other half to add to the
     * liquidity pool.
     *
     * Emits {SwapAndLiquify} event indicating the amount of tokens swapped to eth,
     * the amount of ETH added to the LP, and the amount of tokens added to the LP.
     */
    function _swapAndLiquify(uint256 amount) private {
        require(_swapAndLiquifyEnabled, "Swap And Liquify is disabled");
        // Split the contract balance into two halves.
        uint256 tokensToSwap = amount / 2;
        uint256 tokensAddToLiquidity = amount - tokensToSwap;

        // Contract's current ETH balance.
        uint256 initialBalance = address(this).balance;

        // Swap half of the tokens to ETH.
        _swapTokensForEth(tokensToSwap, address(this));

        // Figure out the exact amount of tokens received from swapping.
        uint256 ethAddToLiquify = address(this).balance - initialBalance;

        // Add to the LP of this token and WETH pair (half ETH and half this token).
        _addLiquidity(ethAddToLiquify, tokensAddToLiquidity);
        emit SwapAndLiquify(tokensToSwap, ethAddToLiquify, tokensAddToLiquidity);
    }

    function getTokenReserves() public view returns (uint256) {
        uint112 reserve;
        if (_uniswapV2Pair.token0() == address(this))
            (reserve,,) = _uniswapV2Pair.getReserves();
        else
            (,reserve,) = _uniswapV2Pair.getReserves();

        return uint256(reserve);
    }

    // Transfer

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

        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");
        require(amount > 0, "ScratchToken: Transfer amount must be greater than zero");

        require(_balances[sender] >= amount, "ERC20: transfer amount exceeds balance");
        
        // Indicates if fee should be deducted from transfer
        bool selling = recipient == address(_uniswapV2Pair);
        bool buying = sender == address(_uniswapV2Pair) && recipient != address(_uniswapV2Router);
        // Take fees when selling or buying, and the sender and recipient are not excluded
        bool takeFee = (selling || buying) && (!_isExcludedFromFee[sender] && !_isExcludedFromFee[recipient]);
        // Transfer amount, it will take fees if takeFee is true
        _tokenTransfer(sender, recipient, amount, takeFee, buying);
    }

    function _tokenTransfer(address sender, address recipient, uint256 amount, bool takeFee, bool buying) private {
        uint256 amountMinusFees = amount;
        if (takeFee) {
            // Maybe trigger token stability protection
            uint256 extraLiquidityFee = 0;
            uint256 extraDevFee = 0;
            uint256 extraBurnFee = 0;
            if (!buying && _tokenStabilityProtectionEnabled && amount >= (getTokenReserves() * _TOKEN_STABILITY_PROTECTION_THRESHOLD_PERCENTAGE / _PERCENTAGE_RELATIVE_TO)) {
                // Liquidity fee
                extraLiquidityFee = amount * _TAX_EXTRA_LIQUIDITY_PERCENTAGE / _PERCENTAGE_RELATIVE_TO;
                // Dev fee
                extraDevFee = amount * _TAX_EXTRA_DEV_PERCENTAGE / _PERCENTAGE_RELATIVE_TO;
                // Burn
                extraBurnFee = amount * _TAX_EXTRA_BURN_PERCENTAGE / _PERCENTAGE_RELATIVE_TO;
            }
            // Archa
            uint256 archaFee = 0;
            if (_archaFeeEnabled) {
                archaFee = amount * _TAX_NORMAL_ARCHA_PERCENTAGE / _PERCENTAGE_RELATIVE_TO;
                if (archaFee > 0) {
                    _balances[_archaWallet] += archaFee;
                    emit Transfer(sender, _archaWallet, archaFee);
                }
            }
            // Dev fee
            uint256 devFee = 0;
            if (_devFeeEnabled) {
                devFee = (amount * _TAX_NORMAL_DEV_PERCENTAGE / _PERCENTAGE_RELATIVE_TO) + extraDevFee;
                if (devFee > 0) {
                    _balances[address(this)] += devFee;
                    if (buying || _inSwap) {
                        // Store for a later swap
                        _devFeePendingSwap += devFee;
                    }
                    else {
                        // Swap for eth
                        _swapTokensForEth(devFee + _devFeePendingSwap, _developmentWallet);
                        emit Transfer(sender, _developmentWallet, devFee + _devFeePendingSwap);
                        _devFeePendingSwap = 0;
                    }
                }
            }
            // Ops
            uint256 opsFee = 0;
            if (_opsFeeEnabled) {
                opsFee = amount * _TAX_NORMAL_OPS_PERCENTAGE / _PERCENTAGE_RELATIVE_TO;
                if (opsFee > 0) {
                    _balances[address(this)] += opsFee;
                    if (buying || _inSwap) {
                        // Store for a later swap
                        _opsFeePendingSwap += opsFee;
                    }
                    else {
                        // Swap for eth
                        _swapTokensForEth(opsFee + _opsFeePendingSwap, _operationsWallet);
                        emit Transfer(sender, _operationsWallet, opsFee + _opsFeePendingSwap);
                        _opsFeePendingSwap = 0;
                    }
                }
            }
            // Liquity pool
            uint256 liquidityFee = 0;
            if (_liquidityFeeEnabled) {
                liquidityFee = (amount * _TAX_NORMAL_LIQUIDITY_PERCENTAGE / _PERCENTAGE_RELATIVE_TO) + extraLiquidityFee;
                if (liquidityFee > 0) {
                    _balances[address(this)] += liquidityFee;
                    if (buying || _inSwap) {
                        // Store for a later swap
                        _liquidityFeePendingSwap += liquidityFee;
                    }
                    else {
                        uint256 swapAndLiquifyAmount = liquidityFee + _liquidityFeePendingSwap;
                        if(_swapAndLiquifyEnabled) {
                            // Swap and liquify
                            if(swapAndLiquifyAmount > _minTokensBeforeSwapAndLiquify) {
                                _swapAndLiquify(swapAndLiquifyAmount);
                                _liquidityFeePendingSwap = 0;
                            } else {
                                // Accumulate until minimum amount is reached
                                _liquidityFeePendingSwap += liquidityFee;
                            }
                        } else if (_liquidityWallet != address(0)) {
                            // Send to liquidity wallet
                            _swapTokensForEth(swapAndLiquifyAmount, _liquidityWallet);
                            emit Transfer(sender, _liquidityWallet, swapAndLiquifyAmount);
                            _liquidityFeePendingSwap = 0;
                        } else {
                            // Keep for later
                            _liquidityFeePendingSwap += liquidityFee;
                        }
                    }
                }
            }
            // Burn
            uint256 burnFee = 0;
            if(_burnFeeEnabled && extraBurnFee > 0) {
                burnFee = extraBurnFee;
                _totalSupply -= burnFee;
                emit Transfer(sender, address(0), amount);
            }
            // Final transfer amount
            uint256 totalFees = devFee + liquidityFee + opsFee + archaFee + burnFee;
            require (amount > totalFees, "ScratchToken: Token fees exceeds transfer amount");
            amountMinusFees = amount - totalFees;
        } else {
            amountMinusFees = amount;
        }
        _balances[sender] -= amount;
        _balances[recipient] += amountMinusFees;
        emit Transfer(sender, recipient, amountMinusFees);
    }

    // ERC20

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

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

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens in the contract
     * should be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() external view returns (uint8) {
        return _DECIMALS;
    }

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

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

    /**
     * @dev Max supply of the token, cannot be increased after deployment.
     */
    function maxSupply() external view returns (uint256) {
        return _MAX_SUPPLY;
    }

    // Transfer

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

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external virtual override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        unchecked {
            _approve(sender, _msgSender(), currentAllowance - amount);
        }

        return true;
    }
    
    
    // Allowance

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) external virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

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

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

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

        return true;
    }

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

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

    // Mint & Burn

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

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);
    }

}

File 2 of 15 : ERC20Burnable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Burnable.sol)

pragma solidity ^0.8.0;

import "../ERC20.sol";
import "../../../utils/Context.sol";

/**
 * @dev Extension of {ERC20} that allows token holders to destroy both their own
 * tokens and those that they have an allowance for, in a way that can be
 * recognized off-chain (via event analysis).
 */
abstract contract ERC20Burnable is Context, ERC20 {
    /**
     * @dev Destroys `amount` tokens from the caller.
     *
     * See {ERC20-_burn}.
     */
    function burn(uint256 amount) public virtual {
        _burn(_msgSender(), amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, deducting from the caller's
     * allowance.
     *
     * See {ERC20-_burn} and {ERC20-allowance}.
     *
     * Requirements:
     *
     * - the caller must have allowance for ``accounts``'s tokens of at least
     * `amount`.
     */
    function burnFrom(address account, uint256 amount) public virtual {
        uint256 currentAllowance = allowance(account, _msgSender());
        require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance");
        unchecked {
            _approve(account, _msgSender(), currentAllowance - amount);
        }
        _burn(account, amount);
    }
}

File 3 of 15 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

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

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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

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

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

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

File 4 of 15 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

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

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

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

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

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

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

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 5 of 15 : IUniswapV2Pair.sol
pragma solidity >=0.5.0;

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

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

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

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

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}

File 6 of 15 : IUniswapV2Factory.sol
pragma solidity >=0.5.0;

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

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

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

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

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

File 7 of 15 : IUniswapV2Router02.sol
pragma solidity >=0.6.2;

import './IUniswapV2Router01.sol';

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

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

File 8 of 15 : FoundersTimelock.sol
// SPDX-License-Identifier: UNLICENSED
/** 
 *   Copyright © 2022 Scratch Engine LLC. All rights reserved.
 *   Limited license is afforded to Etherscan, in accordance with its Terms of Use, 
 *   in order to publish this material.
 *   In connection with the foregoing, redistribution and use on the part of Etherscan,
 *   in source and binary forms, without modification, are permitted, 
 *   provided that such redistributions of source code retain the foregoing copyright notice
 *   and this disclaimer.
 */

pragma solidity 0.8.4;

// import "hardhat/console.sol";

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";

/**
 * @title FoundersTimelock
 * @dev A token holder contract that can release its token balance gradually like a
 * typical vesting scheme, with a cliff and vesting period.
 */
contract FoundersTimelock is Ownable {
    // The vesting schedule is time-based (i.e. using block timestamps as opposed to e.g. block numbers), and is
    // therefore sensitive to timestamp manipulation (which is something miners can do, to a certain degree). Therefore,
    // it is recommended to avoid using short time durations (less than a minute). Typical vesting schemes, with a
    // cliff period of a year and a duration of four years, are safe to use.

    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    event TokensReleased(address token, uint256 amount);

    // beneficiary of tokens after they are released
    address private immutable _beneficiary;

    // ERC20 basic token contract being held
    IERC20 private immutable _token;

    uint256 private immutable _cliff; // cliff period in seconds
    uint256 private immutable _vestingPeriod; // ie: 1 month
    uint8 private immutable _vestingDuration; // ie: 10 (vesting will last for 10 months and release linearly every month)

    uint256 private _released = 0;

    /**
     * @dev Creates a vesting contract that vests its balance of any ERC20 token to the
     * beneficiary, gradually in a linear fashion until start + duration. By then all
     * of the balance will have vested.
     * @param token_ ERC20 basic token contract being held
     * @param beneficiary_ address of the beneficiary to whom vested tokens are transferred
     * @param cliffDuration_ duration in seconds of the cliff in which tokens will begin to vest
     * @param vestingPeriod_ the frequency (as Unix time) at which tokens are released
     * @param vestingDuration_ the total count of vesting periods
     */
    constructor (IERC20 token_, address beneficiary_, uint256 cliffDuration_, uint256 vestingPeriod_, uint8 vestingDuration_) {
        require(beneficiary_ != address(0), "FoundersTimelock: beneficiary is the zero address");
        require(vestingPeriod_ > 0, "FoundersTimelock: vestingPeriod is 0");
        require(vestingDuration_ > 0, "FoundersTimelock: vestingDuration is 0");
        require(vestingDuration_ < 256, "FoundersTimelock: vestingDuration is bigger than 255");

        _token = token_;
        _beneficiary = beneficiary_;
        // solhint-disable-next-line not-rely-on-time
        _cliff = block.timestamp.add(cliffDuration_); // safe the use with the 15-seconds rule 
        _vestingPeriod = vestingPeriod_;
        _vestingDuration = vestingDuration_;
    }

    /**
     * @return the beneficiary of the tokens.
     */
    function beneficiary() external view returns (address) {
        return _beneficiary;
    }

    /**
     * @return the cliff time of the token vesting.
     */
    function cliff() external view returns (uint256) {
        return _cliff;
    }

    /**
     * @return the vesting frequency of the token vesting.
     */
    function vestingPeriod() external view returns (uint256) {
        return _vestingPeriod;
    }

    /**
     * @return the duration of the token vesting.
     */
    function vestingDuration() external view returns (uint256) {
        return _vestingDuration;
    }

    /**
     * @return the amount of tokens released.
     */
    function releasedBalance() external view returns (uint256) {
        return _released;
    }

    /**
     * @return the amount of tokens still locked
     */
    function lockedBalance() external view returns (uint256) {
        return _token.balanceOf(address(this));
    }


    /**
     * @notice Transfers vested tokens to beneficiary.
     */
    function release() external {
        require (msg.sender == _beneficiary, "FoundersTimelock: only beneficiary can release tokens");

        uint256 unreleased = _releasableAmount();

        require(unreleased > 0, "FoundersTimelock: no tokens are due");

        _released = _released + unreleased;

        _token.safeTransfer(_beneficiary, unreleased);

        emit TokensReleased(address(_token), unreleased);
    }

    /**
     * @dev Calculates the amount that has already vested but hasn't been released yet.
     */
    function _releasableAmount() private view returns (uint256) {
        return _vestedAmount().sub(_released);
    }

    /**
     * @dev Calculates the amount that has already vested.
     */
    function _vestedAmount() private view returns (uint256) {
        uint256 currentBalance = _token.balanceOf(address(this));
        uint256 totalBalance = currentBalance.add(_released);

        if (block.timestamp < _cliff) {
            return 0;
        } else if (block.timestamp >= _cliff.add(_vestingDuration * _vestingPeriod)) { // solhint-disable-line not-rely-on-time
            return totalBalance;
        } else {
            // Vesting period
            uint256 vestingElapsed = block.timestamp.sub(_cliff);
            uint256 vestingStep = (vestingElapsed / _vestingPeriod) + 1; // Round up
            if(vestingStep > _vestingDuration) {
                vestingStep = _vestingDuration;
            }
            return totalBalance.mul(vestingStep).div(_vestingDuration);
        }
    }
}

File 9 of 15 : ERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";

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

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

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

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

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

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

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

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

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

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

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        unchecked {
            _approve(sender, _msgSender(), currentAllowance - amount);
        }

        return true;
    }

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

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

        return true;
    }

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

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[sender] = senderBalance - amount;
        }
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);

        _afterTokenTransfer(sender, recipient, amount);
    }

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

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

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

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

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

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

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

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

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

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

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

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

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

File 10 of 15 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

File 11 of 15 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

File 12 of 15 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";

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

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

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

File 13 of 15 : IUniswapV2Router01.sol
pragma solidity >=0.6.2;

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

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

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

File 14 of 15 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../../../utils/Address.sol";

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

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 15 of 15 : SafeMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"founder1Wallet_","type":"address"},{"internalType":"address","name":"founder2Wallet_","type":"address"},{"internalType":"address","name":"founder3Wallet_","type":"address"},{"internalType":"address","name":"founder4Wallet_","type":"address"},{"internalType":"address","name":"founder5Wallet_","type":"address"},{"internalType":"address","name":"developmentWallet_","type":"address"},{"internalType":"address","name":"exchangeWallet_","type":"address"},{"internalType":"address","name":"operationsWallet_","type":"address"},{"internalType":"address","name":"archaWallet_","type":"address"},{"internalType":"address","name":"uniswapV2RouterAddress_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"ArchaFeeEnabledUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newWallet","type":"address"}],"name":"ArchaWalletUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"BurnFeeEnabledUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"DevFeeEnabledUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"ExclusionFromFeesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"wallet","type":"address"},{"indexed":false,"internalType":"address","name":"timelockContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokensAmount","type":"uint256"}],"name":"FounderLiquidityLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"LiquidityFeeEnabledUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newWallet","type":"address"}],"name":"LiquidityWalletUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minTokensBeforeSwap","type":"uint256"}],"name":"MinTokensBeforeSwapUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"OpsFeeEnabledUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokensSwapped","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethReceived","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokensAddedToLiquidity","type":"uint256"}],"name":"SwapAndLiquify","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"SwapAndLiquifyEnabledUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"TokenStabilityProtectionEnabledUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"archaFeeEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"archaWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burnFeeEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"devFeeEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"devFeePendingSwap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"isEnabled","type":"bool"}],"name":"enableArchaFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isEnabled","type":"bool"}],"name":"enableBurnFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isEnabled","type":"bool"}],"name":"enableDevFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isEnabled","type":"bool"}],"name":"enableLiquidityFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isEnabled","type":"bool"}],"name":"enableOpsFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isEnabled","type":"bool"}],"name":"enableSwapAndLiquify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isEnabled","type":"bool"}],"name":"enableTokenStabilityProtection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"excludeFromFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"foundersTimelocks","outputs":[{"internalType":"contract FoundersTimelock","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokenReserves","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromFees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidityFeeEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidityFeePendingSwap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidityWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minTokensBeforeSwapAndLiquify","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":"opsFeeEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"opsFeePendingSwap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newWallet","type":"address"}],"name":"setArchaWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newWallet","type":"address"}],"name":"setLiquidityWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minTokens","type":"uint256"}],"name":"setMinTokensBeforeSwapAndLiquify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapAndLiquifyEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenStabilityProtectionEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapV2Pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60c06040526001600560006101000a81548160ff0219169083151502179055506001600560016101000a81548160ff0219169083151502179055506001600560026101000a81548160ff0219169083151502179055506001600560036101000a81548160ff0219169083151502179055506001600560046101000a81548160ff02191690831515021790555060016005806101000a81548160ff02191690831515021790555060006009556000600a556000600b556000600d60146101000a81548160ff0219169083151502179055506001600d60156101000a81548160ff0219169083151502179055506009600a620000fa9190620018da565b600162000108919062001a17565b600e556000600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503480156200015a57600080fd5b50604051620082fb380380620082fb833981810160405281019062000180919062001486565b620001a06200019462000a0160201b60201c565b62000a0960201b60201c565b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16141562000213576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200020a9062001734565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141562000286576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200027d9062001734565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415620002f9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002f09062001734565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156200036c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003639062001734565b60405180910390fd5b6001600660008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600660003073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600660008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600660008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600660008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550620007478a60fa62000acd60201b60201c565b6200075a8960fa62000acd60201b60201c565b6200076d8860fa62000acd60201b60201c565b620007808760fa62000acd60201b60201c565b620007938660fa62000acd60201b60201c565b620007b784620007ab6102ee62000c6360201b60201c565b62000cad60201b60201c565b8373ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b815250506200081285620008066101f462000c6360201b60201c565b62000cad60201b60201c565b8473ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250506200086c8362000860609662000c6360201b60201c565b62000cad60201b60201c565b82600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006200090361073a62000c6360201b60201c565b9050600073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051620009669190620017bc565b60405180910390a3620009cd8c826200098462000dff60201b60201c565b6009600a620009949190620018da565b67016345785d8a0000620009a9919062001a17565b620009b5919062001a78565b620009c1919062001a78565b62000cad60201b60201c565b620009de8262000e0960201b60201c565b620009ef8c620012f660201b60201c565b50505050505050505050505062001c9b565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000308362ed4e0062278d00600a60405162000ae99062001435565b62000af9959493929190620016d7565b604051809103906000f08015801562000b16573d6000803e3d6000fd5b50905080600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555062000c118162000c058462000c6360201b60201c565b62000cad60201b60201c565b7fa0fefdf37d6cb3a4f225940e23d3ccf7b3a6364a0fb73985b05da648116e9b55838262000c458562000c6360201b60201c565b60405162000c56939291906200169a565b60405180910390a1505050565b6000612710826009600a62000c799190620018da565b67016345785d8a000062000c8e919062001a17565b62000c9a919062001a17565b62000ca6919062001847565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141562000d20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000d17906200179a565b60405180910390fd5b806001600082825462000d349190620017ea565b9250508190555080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825462000d8c9190620017ea565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405162000df39190620017bc565b60405180910390a35050565b6000600154905090565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c45a01556040518163ffffffff1660e01b815260040160206040518083038186803b15801562000eb557600080fd5b505afa15801562000eca573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ef091906200145a565b73ffffffffffffffffffffffffffffffffffffffff1663e6a4390530600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b15801562000f7557600080fd5b505afa15801562000f8a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000fb091906200145a565b6040518363ffffffff1660e01b815260040162000fcf9291906200166d565b60206040518083038186803b15801562000fe857600080fd5b505afa15801562000ffd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200102391906200145a565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156200123757600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c45a01556040518163ffffffff1660e01b815260040160206040518083038186803b158015620010c457600080fd5b505afa158015620010d9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620010ff91906200145a565b73ffffffffffffffffffffffffffffffffffffffff1663c9c6539630600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b1580156200118457600080fd5b505afa15801562001199573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620011bf91906200145a565b6040518363ffffffff1660e01b8152600401620011de9291906200166d565b602060405180830381600087803b158015620011f957600080fd5b505af11580156200120e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200123491906200145a565b90505b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160066000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6200130662000a0160201b60201c565b73ffffffffffffffffffffffffffffffffffffffff166200132c6200140c60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff161462001385576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200137c9062001778565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415620013f8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620013ef9062001756565b60405180910390fd5b620014098162000a0960201b60201c565b50565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611e0a80620064f183390190565b600081519050620014548162001c81565b92915050565b6000602082840312156200146d57600080fd5b60006200147d8482850162001443565b91505092915050565b60008060008060008060008060008060006101608c8e031215620014a957600080fd5b6000620014b98e828f0162001443565b9b50506020620014cc8e828f0162001443565b9a50506040620014df8e828f0162001443565b9950506060620014f28e828f0162001443565b9850506080620015058e828f0162001443565b97505060a0620015188e828f0162001443565b96505060c06200152b8e828f0162001443565b95505060e06200153e8e828f0162001443565b945050610100620015528e828f0162001443565b935050610120620015668e828f0162001443565b9250506101406200157a8e828f0162001443565b9150509295989b509295989b9093969950565b620015988162001ab3565b82525050565b620015a98162001afe565b82525050565b6000620015be602c83620017d9565b9150620015cb8262001b91565b604082019050919050565b6000620015e5602683620017d9565b9150620015f28262001be0565b604082019050919050565b60006200160c602083620017d9565b9150620016198262001c2f565b602082019050919050565b600062001633601f83620017d9565b9150620016408262001c58565b602082019050919050565b620016568162001ae7565b82525050565b620016678162001af1565b82525050565b60006040820190506200168460008301856200158d565b6200169360208301846200158d565b9392505050565b6000606082019050620016b160008301866200158d565b620016c060208301856200158d565b620016cf60408301846200164b565b949350505050565b600060a082019050620016ee60008301886200159e565b620016fd60208301876200158d565b6200170c60408301866200164b565b6200171b60608301856200164b565b6200172a60808301846200165c565b9695505050505050565b600060208201905081810360008301526200174f81620015af565b9050919050565b600060208201905081810360008301526200177181620015d6565b9050919050565b600060208201905081810360008301526200179381620015fd565b9050919050565b60006020820190508181036000830152620017b58162001624565b9050919050565b6000602082019050620017d360008301846200164b565b92915050565b600082825260208201905092915050565b6000620017f78262001ae7565b9150620018048362001ae7565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156200183c576200183b62001b26565b5b828201905092915050565b6000620018548262001ae7565b9150620018618362001ae7565b92508262001874576200187362001b55565b5b828204905092915050565b6000808291508390505b6001851115620018d157808604811115620018a957620018a862001b26565b5b6001851615620018b95780820291505b8081029050620018c98562001b84565b945062001889565b94509492505050565b6000620018e78262001ae7565b9150620018f48362001af1565b9250620019237fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846200192b565b905092915050565b6000826200193d576001905062001a10565b816200194d576000905062001a10565b81600181146200196657600281146200197157620019a7565b600191505062001a10565b60ff84111562001986576200198562001b26565b5b8360020a915084821115620019a0576200199f62001b26565b5b5062001a10565b5060208310610133831016604e8410600b8410161715620019e15782820a905083811115620019db57620019da62001b26565b5b62001a10565b620019f084848460016200187f565b9250905081840481111562001a0a5762001a0962001b26565b5b81810290505b9392505050565b600062001a248262001ae7565b915062001a318362001ae7565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161562001a6d5762001a6c62001b26565b5b828202905092915050565b600062001a858262001ae7565b915062001a928362001ae7565b92508282101562001aa85762001aa762001b26565b5b828203905092915050565b600062001ac08262001ac7565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600062001b0b8262001b12565b9050919050565b600062001b1f8262001ac7565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008160011c9050919050565b7f53637261746368546f6b656e3a207365742077616c6c657420746f207468652060008201527f7a65726f20616464726573730000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b62001c8c8162001ab3565b811462001c9857600080fd5b50565b60805160601c60a05160601c61482362001cce60003960006134c50152600081816128f5015261291b01526148236000f3fe6080604052600436106102605760003560e01c806378652cdb11610144578063b9c3426a116100b6578063d46980161161007a578063d46980161461090d578063d5abeb0114610938578063d5e3725114610963578063dd62ed3e1461098c578063ecde5773146109c9578063f2fde38b146109f257610267565b8063b9c3426a1461083c578063b9cf500514610867578063c024666814610892578063d0dd80cc146108bb578063d2cd01e4146108e457610267565b806395d89b411161010857806395d89b411461071657806396bca32514610741578063a457c2d71461076c578063a9059cbb146107a9578063af6dbabf146107e6578063b938230d1461081157610267565b806378652cdb1461064357806387fbfc841461066c5780638da5cb5b14610697578063906d4e79146106c25780639252c9fe146106eb57610267565b806334c8949b116101dd5780634fbee193116101a15780634fbee193146105335780636394b4671461057057806364af5f8a1461059b57806368265b94146105c657806370a08231146105ef578063715018a61461062c57610267565b806334c8949b1461044c578063395093511461047557806349bd5a5e146104b257806349c89116146104dd5780634a74bb021461050857610267565b806323b872dd1161022457806323b872dd1461035357806325b6a98914610390578063296f0a0c146103cd5780632cc60f41146103f6578063313ce5671461042157610267565b8063014c423d1461026c57806306fdde0314610295578063095ea7b3146102c057806310759a6c146102fd57806318160ddd1461032857610267565b3661026757005b600080fd5b34801561027857600080fd5b50610293600480360381019061028e9190613753565b610a1b565b005b3480156102a157600080fd5b506102aa610aeb565b6040516102b79190613c43565b60405180910390f35b3480156102cc57600080fd5b506102e760048036038101906102e29190613717565b610b28565b6040516102f49190613c0d565b60405180910390f35b34801561030957600080fd5b50610312610b46565b60405161031f9190613c0d565b60405180910390f35b34801561033457600080fd5b5061033d610b5b565b60405161034a9190613e45565b60405180910390f35b34801561035f57600080fd5b5061037a6004803603810190610375919061368c565b610b65565b6040516103879190613c0d565b60405180910390f35b34801561039c57600080fd5b506103b760048036038101906103b291906135fe565b610c5d565b6040516103c49190613c28565b60405180910390f35b3480156103d957600080fd5b506103f460048036038101906103ef91906135fe565b610c90565b005b34801561040257600080fd5b5061040b610ddf565b6040516104189190613e45565b60405180910390f35b34801561042d57600080fd5b50610436610e65565b6040516104439190613ef1565b60405180910390f35b34801561045857600080fd5b50610473600480360381019061046e9190613753565b610e6e565b005b34801561048157600080fd5b5061049c60048036038101906104979190613717565b610f3e565b6040516104a99190613c0d565b60405180910390f35b3480156104be57600080fd5b506104c7610fea565b6040516104d49190613b68565b60405180910390f35b3480156104e957600080fd5b506104f2611014565b6040516104ff9190613c0d565b60405180910390f35b34801561051457600080fd5b5061051d61102b565b60405161052a9190613c0d565b60405180910390f35b34801561053f57600080fd5b5061055a600480360381019061055591906135fe565b611042565b6040516105679190613c0d565b60405180910390f35b34801561057c57600080fd5b50610585611098565b6040516105929190613b68565b60405180910390f35b3480156105a757600080fd5b506105b06110c2565b6040516105bd9190613e45565b60405180910390f35b3480156105d257600080fd5b506105ed60048036038101906105e89190613753565b6110cc565b005b3480156105fb57600080fd5b50610616600480360381019061061191906135fe565b61119b565b6040516106239190613e45565b60405180910390f35b34801561063857600080fd5b506106416111e4565b005b34801561064f57600080fd5b5061066a600480360381019061066591906137cb565b61126c565b005b34801561067857600080fd5b5061068161136d565b60405161068e9190613e45565b60405180910390f35b3480156106a357600080fd5b506106ac6113f3565b6040516106b99190613b68565b60405180910390f35b3480156106ce57600080fd5b506106e960048036038101906106e49190613753565b61141c565b005b3480156106f757600080fd5b506107006114ec565b60405161070d9190613e45565b60405180910390f35b34801561072257600080fd5b5061072b611572565b6040516107389190613c43565b60405180910390f35b34801561074d57600080fd5b506107566115af565b6040516107639190613c0d565b60405180910390f35b34801561077857600080fd5b50610793600480360381019061078e9190613717565b6115c6565b6040516107a09190613c0d565b60405180910390f35b3480156107b557600080fd5b506107d060048036038101906107cb9190613717565b6116b1565b6040516107dd9190613c0d565b60405180910390f35b3480156107f257600080fd5b506107fb6116cf565b6040516108089190613c0d565b60405180910390f35b34801561081d57600080fd5b506108266116e6565b6040516108339190613c0d565b60405180910390f35b34801561084857600080fd5b506108516116fd565b60405161085e9190613c0d565b60405180910390f35b34801561087357600080fd5b5061087c611714565b6040516108899190613e45565b60405180910390f35b34801561089e57600080fd5b506108b960048036038101906108b491906136db565b611956565b005b3480156108c757600080fd5b506108e260048036038101906108dd91906135fe565b611a66565b005b3480156108f057600080fd5b5061090b60048036038101906109069190613753565b611bcd565b005b34801561091957600080fd5b50610922611c9d565b60405161092f9190613b68565b60405180910390f35b34801561094457600080fd5b5061094d611cc7565b60405161095a9190613e45565b60405180910390f35b34801561096f57600080fd5b5061098a60048036038101906109859190613753565b611cef565b005b34801561099857600080fd5b506109b360048036038101906109ae9190613650565b611dbf565b6040516109c09190613e45565b60405180910390f35b3480156109d557600080fd5b506109f060048036038101906109eb9190613753565b611e46565b005b3480156109fe57600080fd5b50610a196004803603810190610a1491906135fe565b611f16565b005b610a2361200e565b73ffffffffffffffffffffffffffffffffffffffff16610a416113f3565b73ffffffffffffffffffffffffffffffffffffffff1614610a97576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8e90613d85565b60405180910390fd5b80600560016101000a81548160ff0219169083151502179055507f5e53419f1b199d608bc95940c6feac6304119df8e7220df0f0f012dd05dc107981604051610ae09190613c0d565b60405180910390a150565b60606040518060400160405280600c81526020017f53637261746368546f6b656e0000000000000000000000000000000000000000815250905090565b6000610b3c610b3561200e565b8484612016565b6001905092915050565b600060058054906101000a900460ff16905090565b6000600154905090565b6000610b728484846121e1565b6000600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610bbd61200e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610c3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3490613d65565b60405180910390fd5b610c5185610c4961200e565b858403612016565b60019150509392505050565b60046020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610c9861200e565b73ffffffffffffffffffffffffffffffffffffffff16610cb66113f3565b73ffffffffffffffffffffffffffffffffffffffff1614610d0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0390613d85565b60405180910390fd5b6001600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fc0f8ad2683cf240266d4f868f5b59a16c13e4a0ff63dfcfb0f0cd3843a12178481604051610dd49190613b68565b60405180910390a150565b6000610de961200e565b73ffffffffffffffffffffffffffffffffffffffff16610e076113f3565b73ffffffffffffffffffffffffffffffffffffffff1614610e5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5490613d85565b60405180910390fd5b600a54905090565b60006009905090565b610e7661200e565b73ffffffffffffffffffffffffffffffffffffffff16610e946113f3565b73ffffffffffffffffffffffffffffffffffffffff1614610eea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee190613d85565b60405180910390fd5b80600560006101000a81548160ff0219169083151502179055507f2382013a67bdd277bca4e0ce5eb981b49ba9ec918aa36ff6bafc39014fced9c181604051610f339190613c0d565b60405180910390a150565b6000610fe0610f4b61200e565b848460036000610f5961200e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610fdb9190613f61565b612016565b6001905092915050565b6000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600560029054906101000a900460ff16905090565b6000600d60159054906101000a900460ff16905090565b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600e54905090565b6110d461200e565b73ffffffffffffffffffffffffffffffffffffffff166110f26113f3565b73ffffffffffffffffffffffffffffffffffffffff1614611148576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113f90613d85565b60405180910390fd5b806005806101000a81548160ff0219169083151502179055507f71f1ffeba507d80a20023b73caeef61f21584479384492e4f89bc585d4ea9b4b816040516111909190613c0d565b60405180910390a150565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6111ec61200e565b73ffffffffffffffffffffffffffffffffffffffff1661120a6113f3565b73ffffffffffffffffffffffffffffffffffffffff1614611260576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125790613d85565b60405180910390fd5b61126a6000612558565b565b61127461200e565b73ffffffffffffffffffffffffffffffffffffffff166112926113f3565b73ffffffffffffffffffffffffffffffffffffffff16146112e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112df90613d85565b60405180910390fd5b600154811061132c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132390613da5565b60405180910390fd5b80600e819055507f5948780118f41f7c4577ae4619d5cbd064057bd8562d9f7b7e60324053375c00816040516113629190613e45565b60405180910390a150565b600061137761200e565b73ffffffffffffffffffffffffffffffffffffffff166113956113f3565b73ffffffffffffffffffffffffffffffffffffffff16146113eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113e290613d85565b60405180910390fd5b600954905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61142461200e565b73ffffffffffffffffffffffffffffffffffffffff166114426113f3565b73ffffffffffffffffffffffffffffffffffffffff1614611498576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161148f90613d85565b60405180910390fd5b80600560026101000a81548160ff0219169083151502179055507f52939f30dc39fa94d132d7a51ddd4ed7823c47331c99def6d711368a8e58480d816040516114e19190613c0d565b60405180910390a150565b60006114f661200e565b73ffffffffffffffffffffffffffffffffffffffff166115146113f3565b73ffffffffffffffffffffffffffffffffffffffff161461156a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161156190613d85565b60405180910390fd5b600b54905090565b60606040518060400160405280600781526020017f5343524154434800000000000000000000000000000000000000000000000000815250905090565b6000600560039054906101000a900460ff16905090565b600080600360006115d561200e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015611692576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168990613e25565b60405180910390fd5b6116a661169d61200e565b85858403612016565b600191505092915050565b60006116c56116be61200e565b84846121e1565b6001905092915050565b6000600560009054906101000a900460ff16905090565b6000600560049054906101000a900460ff16905090565b6000600560019054906101000a900460ff16905090565b6000803073ffffffffffffffffffffffffffffffffffffffff16600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561179657600080fd5b505afa1580156117aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ce9190613627565b73ffffffffffffffffffffffffffffffffffffffff16141561189657600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561185257600080fd5b505afa158015611866573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188a919061377c565b9050508091505061193f565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156118fe57600080fd5b505afa158015611912573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611936919061377c565b90915050809150505b806dffffffffffffffffffffffffffff1691505090565b61195e61200e565b73ffffffffffffffffffffffffffffffffffffffff1661197c6113f3565b73ffffffffffffffffffffffffffffffffffffffff16146119d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c990613d85565b60405180910390fd5b80600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f7d6ed9923d9694a8a8bff10356e468f0af9bec35f6b1a5ee816a01af44aaf1888282604051611a5a929190613b83565b60405180910390a15050565b611a6e61200e565b73ffffffffffffffffffffffffffffffffffffffff16611a8c6113f3565b73ffffffffffffffffffffffffffffffffffffffff1614611ae2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ad990613d85565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611b52576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4990613ca5565b60405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f307e0e414c30bfcaff60c1a4e53e0fb2c7e8e9b6918f6088e685fb8803d1459681604051611bc29190613b68565b60405180910390a150565b611bd561200e565b73ffffffffffffffffffffffffffffffffffffffff16611bf36113f3565b73ffffffffffffffffffffffffffffffffffffffff1614611c49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c4090613d85565b60405180910390fd5b80600560046101000a81548160ff0219169083151502179055507f757ae5872a1b50050237a412cd2cee3dabf7e3be4c56d81d5babcbc83d51721381604051611c929190613c0d565b60405180910390a150565b6000600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60006009600a611cd7919061403b565b67016345785d8a0000611cea9190614159565b905090565b611cf761200e565b73ffffffffffffffffffffffffffffffffffffffff16611d156113f3565b73ffffffffffffffffffffffffffffffffffffffff1614611d6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d6290613d85565b60405180910390fd5b80600d60156101000a81548160ff0219169083151502179055507f53726dfcaf90650aa7eb35524f4d3220f07413c8d6cb404cc8c18bf5591bc15981604051611db49190613c0d565b60405180910390a150565b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b611e4e61200e565b73ffffffffffffffffffffffffffffffffffffffff16611e6c6113f3565b73ffffffffffffffffffffffffffffffffffffffff1614611ec2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb990613d85565b60405180910390fd5b80600560036101000a81548160ff0219169083151502179055507fd70aabca147583df26b8037d31d0ba9bfa8af7f83b82f543abc5e86a415676b481604051611f0b9190613c0d565b60405180910390a150565b611f1e61200e565b73ffffffffffffffffffffffffffffffffffffffff16611f3c6113f3565b73ffffffffffffffffffffffffffffffffffffffff1614611f92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f8990613d85565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612002576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ff990613ce5565b60405180910390fd5b61200b81612558565b50565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612086576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207d90613de5565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156120f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120ed90613d05565b60405180910390fd5b80600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516121d49190613e45565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612251576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161224890613dc5565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156122c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b890613c65565b60405180910390fd5b60008111612304576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122fb90613e05565b60405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015612386576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161237d90613d25565b60405180910390fd5b6000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161490506000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480156124885750600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614155b9050600082806124955750815b80156125415750600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161580156125405750600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b5b9050612550868686848661261c565b505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008390508215612f0357600080600084158015612644575060058054906101000a900460ff165b8015612670575061271060c8612658611714565b6126629190614159565b61266c9190613fb7565b8710155b156126cd576127106103e8886126869190614159565b6126909190613fb7565b92506127106101f4886126a39190614159565b6126ad9190613fb7565b91506127106101f4886126c09190614159565b6126ca9190613fb7565b90505b6000600560039054906101000a900460ff161561280a576127106064896126f49190614159565b6126fe9190613fb7565b90506000811115612809578060026000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461277a9190613f61565b92505081905550600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516128009190613e45565b60405180910390a35b5b6000600560009054906101000a900460ff16156129b6578361271060c88b6128329190614159565b61283c9190613fb7565b6128469190613f61565b905060008111156129b55780600260003073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546128a09190613f61565b9250508190555086806128bf5750600d60149054906101000a900460ff165b156128e25780600960008282546128d69190613f61565b925050819055506129b4565b612919600954826128f39190613f61565b7f0000000000000000000000000000000000000000000000000000000000000000613020565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600954846129969190613f61565b6040516129a39190613e45565b60405180910390a360006009819055505b5b5b6000600560019054906101000a900460ff1615612b5b5761271060648b6129dd9190614159565b6129e79190613fb7565b90506000811115612b5a5780600260003073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612a419190613f61565b925050819055508780612a605750600d60149054906101000a900460ff165b15612a835780600a6000828254612a779190613f61565b92505081905550612b59565b612abc600a5482612a949190613f61565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16613020565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168c73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600a5484612b3b9190613f61565b604051612b489190613e45565b60405180910390a36000600a819055505b5b5b6000600560029054906101000a900460ff1615612dce578661271060c88d612b839190614159565b612b8d9190613fb7565b612b979190613f61565b90506000811115612dcd5780600260003073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612bf19190613f61565b925050819055508880612c105750600d60149054906101000a900460ff165b15612c335780600b6000828254612c279190613f61565b92505081905550612dcc565b6000600b5482612c439190613f61565b9050600d60159054906101000a900460ff1615612c9957600e54811115612c7a57612c6d81613377565b6000600b81905550612c94565b81600b6000828254612c8c9190613f61565b925050819055505b612dca565b600073ffffffffffffffffffffffffffffffffffffffff16600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612daf57612d1b81600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16613020565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168e73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612d9a9190613e45565b60405180910390a36000600b81905550612dc9565b81600b6000828254612dc19190613f61565b925050819055505b5b505b5b5b6000600560049054906101000a900460ff168015612dec5750600086115b15612e74578590508060016000828254612e0691906141b3565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168e73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8e604051612e6b9190613e45565b60405180910390a35b60008186858588612e859190613f61565b612e8f9190613f61565b612e999190613f61565b612ea39190613f61565b9050808d11612ee7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ede90613d45565b60405180910390fd5b808d612ef391906141b3565b9950505050505050505050612f07565b8390505b83600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612f5691906141b3565b9250508190555080600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612fac9190613f61565b925050819055508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516130109190613e45565b60405180910390a3505050505050565b600d60149054906101000a900460ff1615613070576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161306790613c85565b60405180910390fd5b6001600d60146101000a81548160ff0219169083151502179055506000600267ffffffffffffffff8111156130ce577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156130fc5781602001602082028036833780820191505090505b509050308160008151811061313a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b1580156131dc57600080fd5b505afa1580156131f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132149190613627565b8160018151811061324e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506132b530600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685612016565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663791ac9478460008486603c426133059190613f61565b6040518663ffffffff1660e01b8152600401613325959493929190613e60565b600060405180830381600087803b15801561333f57600080fd5b505af1158015613353573d6000803e3d6000fd5b50505050506000600d60146101000a81548160ff0219169083151502179055505050565b600d60159054906101000a900460ff166133c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133bd90613cc5565b60405180910390fd5b60006002826133d59190613fb7565b9050600081836133e591906141b3565b905060004790506133f68330613020565b6000814761340491906141b3565b90506134108184613452565b7f17bbfb9a6069321b6ded73bd96327c9e6b7212a5cd51ff219cd61370acafb56184828560405161344393929190613eba565b60405180910390a15050505050565b61347f30600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683612016565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f305d7198330846000807f0000000000000000000000000000000000000000000000000000000000000000603c426134f19190613f61565b6040518863ffffffff1660e01b815260040161351296959493929190613bac565b6060604051808303818588803b15801561352b57600080fd5b505af115801561353f573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061356491906137f4565b5050505050565b60008135905061357a8161477a565b92915050565b60008151905061358f8161477a565b92915050565b6000813590506135a481614791565b92915050565b6000815190506135b9816147a8565b92915050565b6000813590506135ce816147bf565b92915050565b6000815190506135e3816147bf565b92915050565b6000815190506135f8816147d6565b92915050565b60006020828403121561361057600080fd5b600061361e8482850161356b565b91505092915050565b60006020828403121561363957600080fd5b600061364784828501613580565b91505092915050565b6000806040838503121561366357600080fd5b60006136718582860161356b565b92505060206136828582860161356b565b9150509250929050565b6000806000606084860312156136a157600080fd5b60006136af8682870161356b565b93505060206136c08682870161356b565b92505060406136d1868287016135bf565b9150509250925092565b600080604083850312156136ee57600080fd5b60006136fc8582860161356b565b925050602061370d85828601613595565b9150509250929050565b6000806040838503121561372a57600080fd5b60006137388582860161356b565b9250506020613749858286016135bf565b9150509250929050565b60006020828403121561376557600080fd5b600061377384828501613595565b91505092915050565b60008060006060848603121561379157600080fd5b600061379f868287016135aa565b93505060206137b0868287016135aa565b92505060406137c1868287016135e9565b9150509250925092565b6000602082840312156137dd57600080fd5b60006137eb848285016135bf565b91505092915050565b60008060006060848603121561380957600080fd5b6000613817868287016135d4565b9350506020613828868287016135d4565b9250506040613839868287016135d4565b9150509250925092565b600061384f838361385b565b60208301905092915050565b613864816141e7565b82525050565b613873816141e7565b82525050565b600061388482613f1c565b61388e8185613f3f565b935061389983613f0c565b8060005b838110156138ca5781516138b18882613843565b97506138bc83613f32565b92505060018101905061389d565b5085935050505092915050565b6138e0816141f9565b82525050565b6138ef81614266565b82525050565b6138fe8161428a565b82525050565b600061390f82613f27565b6139198185613f50565b935061392981856020860161429c565b6139328161432d565b840191505092915050565b600061394a602383613f50565b91506139558261434b565b604082019050919050565b600061396d601283613f50565b91506139788261439a565b602082019050919050565b6000613990602c83613f50565b915061399b826143c3565b604082019050919050565b60006139b3601c83613f50565b91506139be82614412565b602082019050919050565b60006139d6602683613f50565b91506139e18261443b565b604082019050919050565b60006139f9602283613f50565b9150613a048261448a565b604082019050919050565b6000613a1c602683613f50565b9150613a27826144d9565b604082019050919050565b6000613a3f603083613f50565b9150613a4a82614528565b604082019050919050565b6000613a62602883613f50565b9150613a6d82614577565b604082019050919050565b6000613a85602083613f50565b9150613a90826145c6565b602082019050919050565b6000613aa8602a83613f50565b9150613ab3826145ef565b604082019050919050565b6000613acb602583613f50565b9150613ad68261463e565b604082019050919050565b6000613aee602483613f50565b9150613af98261468d565b604082019050919050565b6000613b11603783613f50565b9150613b1c826146dc565b604082019050919050565b6000613b34602583613f50565b9150613b3f8261472b565b604082019050919050565b613b538161423f565b82525050565b613b6281614259565b82525050565b6000602082019050613b7d600083018461386a565b92915050565b6000604082019050613b98600083018561386a565b613ba560208301846138d7565b9392505050565b600060c082019050613bc1600083018961386a565b613bce6020830188613b4a565b613bdb60408301876138f5565b613be860608301866138f5565b613bf5608083018561386a565b613c0260a0830184613b4a565b979650505050505050565b6000602082019050613c2260008301846138d7565b92915050565b6000602082019050613c3d60008301846138e6565b92915050565b60006020820190508181036000830152613c5d8184613904565b905092915050565b60006020820190508181036000830152613c7e8161393d565b9050919050565b60006020820190508181036000830152613c9e81613960565b9050919050565b60006020820190508181036000830152613cbe81613983565b9050919050565b60006020820190508181036000830152613cde816139a6565b9050919050565b60006020820190508181036000830152613cfe816139c9565b9050919050565b60006020820190508181036000830152613d1e816139ec565b9050919050565b60006020820190508181036000830152613d3e81613a0f565b9050919050565b60006020820190508181036000830152613d5e81613a32565b9050919050565b60006020820190508181036000830152613d7e81613a55565b9050919050565b60006020820190508181036000830152613d9e81613a78565b9050919050565b60006020820190508181036000830152613dbe81613a9b565b9050919050565b60006020820190508181036000830152613dde81613abe565b9050919050565b60006020820190508181036000830152613dfe81613ae1565b9050919050565b60006020820190508181036000830152613e1e81613b04565b9050919050565b60006020820190508181036000830152613e3e81613b27565b9050919050565b6000602082019050613e5a6000830184613b4a565b92915050565b600060a082019050613e756000830188613b4a565b613e8260208301876138f5565b8181036040830152613e948186613879565b9050613ea3606083018561386a565b613eb06080830184613b4a565b9695505050505050565b6000606082019050613ecf6000830186613b4a565b613edc6020830185613b4a565b613ee96040830184613b4a565b949350505050565b6000602082019050613f066000830184613b59565b92915050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b6000613f6c8261423f565b9150613f778361423f565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613fac57613fab6142cf565b5b828201905092915050565b6000613fc28261423f565b9150613fcd8361423f565b925082613fdd57613fdc6142fe565b5b828204905092915050565b6000808291508390505b60018511156140325780860481111561400e5761400d6142cf565b5b600185161561401d5780820291505b808102905061402b8561433e565b9450613ff2565b94509492505050565b60006140468261423f565b915061405183614259565b925061407e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484614086565b905092915050565b6000826140965760019050614152565b816140a45760009050614152565b81600181146140ba57600281146140c4576140f3565b6001915050614152565b60ff8411156140d6576140d56142cf565b5b8360020a9150848211156140ed576140ec6142cf565b5b50614152565b5060208310610133831016604e8410600b84101617156141285782820a905083811115614123576141226142cf565b5b614152565b6141358484846001613fe8565b9250905081840481111561414c5761414b6142cf565b5b81810290505b9392505050565b60006141648261423f565b915061416f8361423f565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156141a8576141a76142cf565b5b828202905092915050565b60006141be8261423f565b91506141c98361423f565b9250828210156141dc576141db6142cf565b5b828203905092915050565b60006141f28261421f565b9050919050565b60008115159050919050565b60006dffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b600060ff82169050919050565b600061427182614278565b9050919050565b60006142838261421f565b9050919050565b60006142958261423f565b9050919050565b60005b838110156142ba57808201518184015260208101905061429f565b838111156142c9576000848401525b50505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000601f19601f8301169050919050565b60008160011c9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f43757272656e746c7920696e20737761702e0000000000000000000000000000600082015250565b7f53637261746368546f6b656e3a207365742077616c6c657420746f207468652060008201527f7a65726f20616464726573730000000000000000000000000000000000000000602082015250565b7f5377617020416e64204c6971756966792069732064697361626c656400000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b7f53637261746368546f6b656e3a20546f6b656e2066656573206578636565647360008201527f207472616e7366657220616d6f756e7400000000000000000000000000000000602082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206160008201527f6c6c6f77616e6365000000000000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4e65772076616c7565206d757374206265206c6f776572207468616e20746f7460008201527f616c20737570706c792e00000000000000000000000000000000000000000000602082015250565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f53637261746368546f6b656e3a205472616e7366657220616d6f756e74206d7560008201527f73742062652067726561746572207468616e207a65726f000000000000000000602082015250565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b614783816141e7565b811461478e57600080fd5b50565b61479a816141f9565b81146147a557600080fd5b50565b6147b181614205565b81146147bc57600080fd5b50565b6147c88161423f565b81146147d357600080fd5b50565b6147df81614249565b81146147ea57600080fd5b5056fea26469706673582212202fdd3146c960dd8a32b3687e5a4258260f5036502fe45ed706c8b2c0199dca6264736f6c6343000804003361012060405260006001553480156200001757600080fd5b5060405162001e0a38038062001e0a83398181016040528101906200003d91906200039d565b6200005d620000516200025d60201b60201c565b6200026560201b60201c565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415620000d0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000c790620004dd565b60405180910390fd5b6000821162000116576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200010d90620004ff565b60405180910390fd5b60008160ff16116200015f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001569062000521565b60405180910390fd5b6101008160ff1610620001a9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001a090620004bb565b60405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b815250508373ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250506200023183426200032960201b620006631790919060201c565b60c081815250508160e081815250508060ff166101008160ff1660f81b815250505050505050620007e3565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000818362000339919062000554565b905092915050565b60008151905062000352816200077b565b92915050565b600081519050620003698162000795565b92915050565b6000815190506200038081620007af565b92915050565b6000815190506200039781620007c9565b92915050565b600080600080600060a08688031215620003b657600080fd5b6000620003c68882890162000358565b9550506020620003d98882890162000341565b9450506040620003ec888289016200036f565b9350506060620003ff888289016200036f565b9250506080620004128882890162000386565b9150509295509295909350565b60006200042e60348362000543565b91506200043b826200063f565b604082019050919050565b60006200045560318362000543565b915062000462826200068e565b604082019050919050565b60006200047c60248362000543565b91506200048982620006dd565b604082019050919050565b6000620004a360268362000543565b9150620004b0826200072c565b604082019050919050565b60006020820190508181036000830152620004d6816200041f565b9050919050565b60006020820190508181036000830152620004f88162000446565b9050919050565b600060208201905081810360008301526200051a816200046d565b9050919050565b600060208201905081810360008301526200053c8162000494565b9050919050565b600082825260208201905092915050565b60006200056182620005f9565b91506200056e83620005f9565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115620005a657620005a562000610565b5b828201905092915050565b6000620005be82620005d9565b9050919050565b6000620005d282620005b1565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f466f756e6465727354696d656c6f636b3a2076657374696e674475726174696f60008201527f6e20697320626967676572207468616e20323535000000000000000000000000602082015250565b7f466f756e6465727354696d656c6f636b3a2062656e656669636961727920697360008201527f20746865207a65726f2061646472657373000000000000000000000000000000602082015250565b7f466f756e6465727354696d656c6f636b3a2076657374696e67506572696f642060008201527f6973203000000000000000000000000000000000000000000000000000000000602082015250565b7f466f756e6465727354696d656c6f636b3a2076657374696e674475726174696f60008201527f6e20697320300000000000000000000000000000000000000000000000000000602082015250565b6200078681620005b1565b81146200079257600080fd5b50565b620007a081620005c5565b8114620007ac57600080fd5b50565b620007ba81620005f9565b8114620007c657600080fd5b50565b620007d48162000603565b8114620007e057600080fd5b50565b60805160601c60a05160601c60c05160e0516101005160f81c61157762000893600039600081816101d10152818161090e015281816109ee01528181610a190152610a430152600081816102ac015281816108ed01526109b60152600081816101a9015281816108b70152818161093c01526109800152600081816102d401528181610498015281816104ff01526107f30152600081816101fc01528181610382015261047601526115776000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c80637b80889b116100665780637b80889b1461012557806386d1a69f146101435780638da5cb5b1461014d5780639ab4b22f1461016b578063f2fde38b146101895761009e565b806313d033c0146100a35780631514617e146100c157806338af3eed146100df578063715018a6146100fd5780637313ee5a14610107575b600080fd5b6100ab6101a5565b6040516100b891906110d3565b60405180910390f35b6100c96101cd565b6040516100d691906110d3565b60405180910390f35b6100e76101f8565b6040516100f49190610f8d565b60405180910390f35b610105610220565b005b61010f6102a8565b60405161011c91906110d3565b60405180910390f35b61012d6102d0565b60405161013a91906110d3565b60405180910390f35b61014b610380565b005b610155610538565b6040516101629190610f8d565b60405180910390f35b610173610561565b60405161018091906110d3565b60405180910390f35b6101a3600480360381019061019e9190610d7e565b61056b565b005b60007f0000000000000000000000000000000000000000000000000000000000000000905090565b60007f000000000000000000000000000000000000000000000000000000000000000060ff16905090565b60007f0000000000000000000000000000000000000000000000000000000000000000905090565b610228610679565b73ffffffffffffffffffffffffffffffffffffffff16610246610538565b73ffffffffffffffffffffffffffffffffffffffff161461029c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161029390611053565b60405180910390fd5b6102a66000610681565b565b60007f0000000000000000000000000000000000000000000000000000000000000000905090565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161032b9190610f8d565b60206040518083038186803b15801561034357600080fd5b505afa158015610357573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061037b9190610dd0565b905090565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461040e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161040590611073565b60405180910390fd5b6000610418610745565b90506000811161045d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161045490611033565b60405180910390fd5b8060015461046b9190611120565b6001819055506104dc7f0000000000000000000000000000000000000000000000000000000000000000827f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166107689092919063ffffffff16565b7fc7798891864187665ac6dd119286e44ec13f014527aeeb2b8eb3fd413df931797f00000000000000000000000000000000000000000000000000000000000000008260405161052d929190610fa8565b60405180910390a150565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600154905090565b610573610679565b73ffffffffffffffffffffffffffffffffffffffff16610591610538565b73ffffffffffffffffffffffffffffffffffffffff16146105e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105de90611053565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610657576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161064e90610ff3565b60405180910390fd5b61066081610681565b50565b600081836106719190611120565b905092915050565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006107636001546107556107ee565b610a9090919063ffffffff16565b905090565b6107e98363a9059cbb60e01b8484604051602401610787929190610fa8565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610aa6565b505050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161084a9190610f8d565b60206040518083038186803b15801561086257600080fd5b505afa158015610876573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089a9190610dd0565b905060006108b36001548361066390919063ffffffff16565b90507f00000000000000000000000000000000000000000000000000000000000000004210156108e857600092505050610a8d565b6109697f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060ff1661093a91906111a7565b7f000000000000000000000000000000000000000000000000000000000000000061066390919063ffffffff16565b4210610979578092505050610a8d565b60006109ae7f000000000000000000000000000000000000000000000000000000000000000042610a9090919063ffffffff16565b9050600060017f0000000000000000000000000000000000000000000000000000000000000000836109e09190611176565b6109ea9190611120565b90507f000000000000000000000000000000000000000000000000000000000000000060ff16811115610a3e577f000000000000000000000000000000000000000000000000000000000000000060ff1690505b610a867f000000000000000000000000000000000000000000000000000000000000000060ff16610a788386610b6d90919063ffffffff16565b610b8390919063ffffffff16565b9450505050505b90565b60008183610a9e9190611201565b905092915050565b6000610b08826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610b999092919063ffffffff16565b9050600081511115610b685780806020019051810190610b289190610da7565b610b67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5e906110b3565b60405180910390fd5b5b505050565b60008183610b7b91906111a7565b905092915050565b60008183610b919190611176565b905092915050565b6060610ba88484600085610bb1565b90509392505050565b606082471015610bf6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bed90611013565b60405180910390fd5b610bff85610cc5565b610c3e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3590611093565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610c679190610f76565b60006040518083038185875af1925050503d8060008114610ca4576040519150601f19603f3d011682016040523d82523d6000602084013e610ca9565b606091505b5091509150610cb9828286610cd8565b92505050949350505050565b600080823b905060008111915050919050565b60608315610ce857829050610d38565b600083511115610cfb5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d2f9190610fd1565b60405180910390fd5b9392505050565b600081359050610d4e816114fc565b92915050565b600081519050610d6381611513565b92915050565b600081519050610d788161152a565b92915050565b600060208284031215610d9057600080fd5b6000610d9e84828501610d3f565b91505092915050565b600060208284031215610db957600080fd5b6000610dc784828501610d54565b91505092915050565b600060208284031215610de257600080fd5b6000610df084828501610d69565b91505092915050565b610e0281611235565b82525050565b6000610e13826110ee565b610e1d8185611104565b9350610e2d81856020860161127d565b80840191505092915050565b6000610e44826110f9565b610e4e818561110f565b9350610e5e81856020860161127d565b610e678161130e565b840191505092915050565b6000610e7f60268361110f565b9150610e8a8261131f565b604082019050919050565b6000610ea260268361110f565b9150610ead8261136e565b604082019050919050565b6000610ec560238361110f565b9150610ed0826113bd565b604082019050919050565b6000610ee860208361110f565b9150610ef38261140c565b602082019050919050565b6000610f0b60358361110f565b9150610f1682611435565b604082019050919050565b6000610f2e601d8361110f565b9150610f3982611484565b602082019050919050565b6000610f51602a8361110f565b9150610f5c826114ad565b604082019050919050565b610f7081611273565b82525050565b6000610f828284610e08565b915081905092915050565b6000602082019050610fa26000830184610df9565b92915050565b6000604082019050610fbd6000830185610df9565b610fca6020830184610f67565b9392505050565b60006020820190508181036000830152610feb8184610e39565b905092915050565b6000602082019050818103600083015261100c81610e72565b9050919050565b6000602082019050818103600083015261102c81610e95565b9050919050565b6000602082019050818103600083015261104c81610eb8565b9050919050565b6000602082019050818103600083015261106c81610edb565b9050919050565b6000602082019050818103600083015261108c81610efe565b9050919050565b600060208201905081810360008301526110ac81610f21565b9050919050565b600060208201905081810360008301526110cc81610f44565b9050919050565b60006020820190506110e86000830184610f67565b92915050565b600081519050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b600061112b82611273565b915061113683611273565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561116b5761116a6112b0565b5b828201905092915050565b600061118182611273565b915061118c83611273565b92508261119c5761119b6112df565b5b828204905092915050565b60006111b282611273565b91506111bd83611273565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156111f6576111f56112b0565b5b828202905092915050565b600061120c82611273565b915061121783611273565b92508282101561122a576112296112b0565b5b828203905092915050565b600061124082611253565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b8381101561129b578082015181840152602081019050611280565b838111156112aa576000848401525b50505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000601f19601f8301169050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b7f466f756e6465727354696d656c6f636b3a206e6f20746f6b656e73206172652060008201527f6475650000000000000000000000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f466f756e6465727354696d656c6f636b3a206f6e6c792062656e65666963696160008201527f72792063616e2072656c6561736520746f6b656e730000000000000000000000602082015250565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b61150581611235565b811461151057600080fd5b50565b61151c81611247565b811461152757600080fd5b50565b61153381611273565b811461153e57600080fd5b5056fea26469706673582212205a040f986d47916bc2e6de0357febee494a7a09c762d8898801fe2df25eb3de264736f6c634300080400330000000000000000000000001c6353c75b5e28d4fd17e76271a4784707500a8d000000000000000000000000272256a91cd6d51584f4bfa4de2f4dfd4bcd3a5700000000000000000000000002c856c3252c41d4c0424ea82d56503062e8db4a0000000000000000000000003b8db4b26abd5c96be44d5e024168e74afaac48e00000000000000000000000066d940ac77c54eee20a75c2eb72cb7c473801941000000000000000000000000317e529ed3c2b7a3a6da5ab7b37fd1d56520520b000000000000000000000000d001c86042aef72f519a56d8bb02d3b3c2c87b200000000000000000000000002718758a03fdce9e6e23d5c6b3fd270b26e0cfc5000000000000000000000000a353de1c926e136b6ccb516f31c38cf40004acce0000000000000000000000007b8404be6480c44e25ee8c8446e408b1bfc924510000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d

Deployed Bytecode

0x6080604052600436106102605760003560e01c806378652cdb11610144578063b9c3426a116100b6578063d46980161161007a578063d46980161461090d578063d5abeb0114610938578063d5e3725114610963578063dd62ed3e1461098c578063ecde5773146109c9578063f2fde38b146109f257610267565b8063b9c3426a1461083c578063b9cf500514610867578063c024666814610892578063d0dd80cc146108bb578063d2cd01e4146108e457610267565b806395d89b411161010857806395d89b411461071657806396bca32514610741578063a457c2d71461076c578063a9059cbb146107a9578063af6dbabf146107e6578063b938230d1461081157610267565b806378652cdb1461064357806387fbfc841461066c5780638da5cb5b14610697578063906d4e79146106c25780639252c9fe146106eb57610267565b806334c8949b116101dd5780634fbee193116101a15780634fbee193146105335780636394b4671461057057806364af5f8a1461059b57806368265b94146105c657806370a08231146105ef578063715018a61461062c57610267565b806334c8949b1461044c578063395093511461047557806349bd5a5e146104b257806349c89116146104dd5780634a74bb021461050857610267565b806323b872dd1161022457806323b872dd1461035357806325b6a98914610390578063296f0a0c146103cd5780632cc60f41146103f6578063313ce5671461042157610267565b8063014c423d1461026c57806306fdde0314610295578063095ea7b3146102c057806310759a6c146102fd57806318160ddd1461032857610267565b3661026757005b600080fd5b34801561027857600080fd5b50610293600480360381019061028e9190613753565b610a1b565b005b3480156102a157600080fd5b506102aa610aeb565b6040516102b79190613c43565b60405180910390f35b3480156102cc57600080fd5b506102e760048036038101906102e29190613717565b610b28565b6040516102f49190613c0d565b60405180910390f35b34801561030957600080fd5b50610312610b46565b60405161031f9190613c0d565b60405180910390f35b34801561033457600080fd5b5061033d610b5b565b60405161034a9190613e45565b60405180910390f35b34801561035f57600080fd5b5061037a6004803603810190610375919061368c565b610b65565b6040516103879190613c0d565b60405180910390f35b34801561039c57600080fd5b506103b760048036038101906103b291906135fe565b610c5d565b6040516103c49190613c28565b60405180910390f35b3480156103d957600080fd5b506103f460048036038101906103ef91906135fe565b610c90565b005b34801561040257600080fd5b5061040b610ddf565b6040516104189190613e45565b60405180910390f35b34801561042d57600080fd5b50610436610e65565b6040516104439190613ef1565b60405180910390f35b34801561045857600080fd5b50610473600480360381019061046e9190613753565b610e6e565b005b34801561048157600080fd5b5061049c60048036038101906104979190613717565b610f3e565b6040516104a99190613c0d565b60405180910390f35b3480156104be57600080fd5b506104c7610fea565b6040516104d49190613b68565b60405180910390f35b3480156104e957600080fd5b506104f2611014565b6040516104ff9190613c0d565b60405180910390f35b34801561051457600080fd5b5061051d61102b565b60405161052a9190613c0d565b60405180910390f35b34801561053f57600080fd5b5061055a600480360381019061055591906135fe565b611042565b6040516105679190613c0d565b60405180910390f35b34801561057c57600080fd5b50610585611098565b6040516105929190613b68565b60405180910390f35b3480156105a757600080fd5b506105b06110c2565b6040516105bd9190613e45565b60405180910390f35b3480156105d257600080fd5b506105ed60048036038101906105e89190613753565b6110cc565b005b3480156105fb57600080fd5b50610616600480360381019061061191906135fe565b61119b565b6040516106239190613e45565b60405180910390f35b34801561063857600080fd5b506106416111e4565b005b34801561064f57600080fd5b5061066a600480360381019061066591906137cb565b61126c565b005b34801561067857600080fd5b5061068161136d565b60405161068e9190613e45565b60405180910390f35b3480156106a357600080fd5b506106ac6113f3565b6040516106b99190613b68565b60405180910390f35b3480156106ce57600080fd5b506106e960048036038101906106e49190613753565b61141c565b005b3480156106f757600080fd5b506107006114ec565b60405161070d9190613e45565b60405180910390f35b34801561072257600080fd5b5061072b611572565b6040516107389190613c43565b60405180910390f35b34801561074d57600080fd5b506107566115af565b6040516107639190613c0d565b60405180910390f35b34801561077857600080fd5b50610793600480360381019061078e9190613717565b6115c6565b6040516107a09190613c0d565b60405180910390f35b3480156107b557600080fd5b506107d060048036038101906107cb9190613717565b6116b1565b6040516107dd9190613c0d565b60405180910390f35b3480156107f257600080fd5b506107fb6116cf565b6040516108089190613c0d565b60405180910390f35b34801561081d57600080fd5b506108266116e6565b6040516108339190613c0d565b60405180910390f35b34801561084857600080fd5b506108516116fd565b60405161085e9190613c0d565b60405180910390f35b34801561087357600080fd5b5061087c611714565b6040516108899190613e45565b60405180910390f35b34801561089e57600080fd5b506108b960048036038101906108b491906136db565b611956565b005b3480156108c757600080fd5b506108e260048036038101906108dd91906135fe565b611a66565b005b3480156108f057600080fd5b5061090b60048036038101906109069190613753565b611bcd565b005b34801561091957600080fd5b50610922611c9d565b60405161092f9190613b68565b60405180910390f35b34801561094457600080fd5b5061094d611cc7565b60405161095a9190613e45565b60405180910390f35b34801561096f57600080fd5b5061098a60048036038101906109859190613753565b611cef565b005b34801561099857600080fd5b506109b360048036038101906109ae9190613650565b611dbf565b6040516109c09190613e45565b60405180910390f35b3480156109d557600080fd5b506109f060048036038101906109eb9190613753565b611e46565b005b3480156109fe57600080fd5b50610a196004803603810190610a1491906135fe565b611f16565b005b610a2361200e565b73ffffffffffffffffffffffffffffffffffffffff16610a416113f3565b73ffffffffffffffffffffffffffffffffffffffff1614610a97576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8e90613d85565b60405180910390fd5b80600560016101000a81548160ff0219169083151502179055507f5e53419f1b199d608bc95940c6feac6304119df8e7220df0f0f012dd05dc107981604051610ae09190613c0d565b60405180910390a150565b60606040518060400160405280600c81526020017f53637261746368546f6b656e0000000000000000000000000000000000000000815250905090565b6000610b3c610b3561200e565b8484612016565b6001905092915050565b600060058054906101000a900460ff16905090565b6000600154905090565b6000610b728484846121e1565b6000600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610bbd61200e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610c3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3490613d65565b60405180910390fd5b610c5185610c4961200e565b858403612016565b60019150509392505050565b60046020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610c9861200e565b73ffffffffffffffffffffffffffffffffffffffff16610cb66113f3565b73ffffffffffffffffffffffffffffffffffffffff1614610d0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0390613d85565b60405180910390fd5b6001600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fc0f8ad2683cf240266d4f868f5b59a16c13e4a0ff63dfcfb0f0cd3843a12178481604051610dd49190613b68565b60405180910390a150565b6000610de961200e565b73ffffffffffffffffffffffffffffffffffffffff16610e076113f3565b73ffffffffffffffffffffffffffffffffffffffff1614610e5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5490613d85565b60405180910390fd5b600a54905090565b60006009905090565b610e7661200e565b73ffffffffffffffffffffffffffffffffffffffff16610e946113f3565b73ffffffffffffffffffffffffffffffffffffffff1614610eea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee190613d85565b60405180910390fd5b80600560006101000a81548160ff0219169083151502179055507f2382013a67bdd277bca4e0ce5eb981b49ba9ec918aa36ff6bafc39014fced9c181604051610f339190613c0d565b60405180910390a150565b6000610fe0610f4b61200e565b848460036000610f5961200e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610fdb9190613f61565b612016565b6001905092915050565b6000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600560029054906101000a900460ff16905090565b6000600d60159054906101000a900460ff16905090565b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600e54905090565b6110d461200e565b73ffffffffffffffffffffffffffffffffffffffff166110f26113f3565b73ffffffffffffffffffffffffffffffffffffffff1614611148576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113f90613d85565b60405180910390fd5b806005806101000a81548160ff0219169083151502179055507f71f1ffeba507d80a20023b73caeef61f21584479384492e4f89bc585d4ea9b4b816040516111909190613c0d565b60405180910390a150565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6111ec61200e565b73ffffffffffffffffffffffffffffffffffffffff1661120a6113f3565b73ffffffffffffffffffffffffffffffffffffffff1614611260576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125790613d85565b60405180910390fd5b61126a6000612558565b565b61127461200e565b73ffffffffffffffffffffffffffffffffffffffff166112926113f3565b73ffffffffffffffffffffffffffffffffffffffff16146112e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112df90613d85565b60405180910390fd5b600154811061132c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132390613da5565b60405180910390fd5b80600e819055507f5948780118f41f7c4577ae4619d5cbd064057bd8562d9f7b7e60324053375c00816040516113629190613e45565b60405180910390a150565b600061137761200e565b73ffffffffffffffffffffffffffffffffffffffff166113956113f3565b73ffffffffffffffffffffffffffffffffffffffff16146113eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113e290613d85565b60405180910390fd5b600954905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61142461200e565b73ffffffffffffffffffffffffffffffffffffffff166114426113f3565b73ffffffffffffffffffffffffffffffffffffffff1614611498576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161148f90613d85565b60405180910390fd5b80600560026101000a81548160ff0219169083151502179055507f52939f30dc39fa94d132d7a51ddd4ed7823c47331c99def6d711368a8e58480d816040516114e19190613c0d565b60405180910390a150565b60006114f661200e565b73ffffffffffffffffffffffffffffffffffffffff166115146113f3565b73ffffffffffffffffffffffffffffffffffffffff161461156a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161156190613d85565b60405180910390fd5b600b54905090565b60606040518060400160405280600781526020017f5343524154434800000000000000000000000000000000000000000000000000815250905090565b6000600560039054906101000a900460ff16905090565b600080600360006115d561200e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015611692576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168990613e25565b60405180910390fd5b6116a661169d61200e565b85858403612016565b600191505092915050565b60006116c56116be61200e565b84846121e1565b6001905092915050565b6000600560009054906101000a900460ff16905090565b6000600560049054906101000a900460ff16905090565b6000600560019054906101000a900460ff16905090565b6000803073ffffffffffffffffffffffffffffffffffffffff16600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561179657600080fd5b505afa1580156117aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ce9190613627565b73ffffffffffffffffffffffffffffffffffffffff16141561189657600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561185257600080fd5b505afa158015611866573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188a919061377c565b9050508091505061193f565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156118fe57600080fd5b505afa158015611912573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611936919061377c565b90915050809150505b806dffffffffffffffffffffffffffff1691505090565b61195e61200e565b73ffffffffffffffffffffffffffffffffffffffff1661197c6113f3565b73ffffffffffffffffffffffffffffffffffffffff16146119d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c990613d85565b60405180910390fd5b80600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f7d6ed9923d9694a8a8bff10356e468f0af9bec35f6b1a5ee816a01af44aaf1888282604051611a5a929190613b83565b60405180910390a15050565b611a6e61200e565b73ffffffffffffffffffffffffffffffffffffffff16611a8c6113f3565b73ffffffffffffffffffffffffffffffffffffffff1614611ae2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ad990613d85565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611b52576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4990613ca5565b60405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f307e0e414c30bfcaff60c1a4e53e0fb2c7e8e9b6918f6088e685fb8803d1459681604051611bc29190613b68565b60405180910390a150565b611bd561200e565b73ffffffffffffffffffffffffffffffffffffffff16611bf36113f3565b73ffffffffffffffffffffffffffffffffffffffff1614611c49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c4090613d85565b60405180910390fd5b80600560046101000a81548160ff0219169083151502179055507f757ae5872a1b50050237a412cd2cee3dabf7e3be4c56d81d5babcbc83d51721381604051611c929190613c0d565b60405180910390a150565b6000600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60006009600a611cd7919061403b565b67016345785d8a0000611cea9190614159565b905090565b611cf761200e565b73ffffffffffffffffffffffffffffffffffffffff16611d156113f3565b73ffffffffffffffffffffffffffffffffffffffff1614611d6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d6290613d85565b60405180910390fd5b80600d60156101000a81548160ff0219169083151502179055507f53726dfcaf90650aa7eb35524f4d3220f07413c8d6cb404cc8c18bf5591bc15981604051611db49190613c0d565b60405180910390a150565b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b611e4e61200e565b73ffffffffffffffffffffffffffffffffffffffff16611e6c6113f3565b73ffffffffffffffffffffffffffffffffffffffff1614611ec2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb990613d85565b60405180910390fd5b80600560036101000a81548160ff0219169083151502179055507fd70aabca147583df26b8037d31d0ba9bfa8af7f83b82f543abc5e86a415676b481604051611f0b9190613c0d565b60405180910390a150565b611f1e61200e565b73ffffffffffffffffffffffffffffffffffffffff16611f3c6113f3565b73ffffffffffffffffffffffffffffffffffffffff1614611f92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f8990613d85565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612002576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ff990613ce5565b60405180910390fd5b61200b81612558565b50565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612086576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207d90613de5565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156120f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120ed90613d05565b60405180910390fd5b80600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516121d49190613e45565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612251576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161224890613dc5565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156122c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b890613c65565b60405180910390fd5b60008111612304576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122fb90613e05565b60405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015612386576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161237d90613d25565b60405180910390fd5b6000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161490506000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480156124885750600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614155b9050600082806124955750815b80156125415750600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161580156125405750600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b5b9050612550868686848661261c565b505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008390508215612f0357600080600084158015612644575060058054906101000a900460ff165b8015612670575061271060c8612658611714565b6126629190614159565b61266c9190613fb7565b8710155b156126cd576127106103e8886126869190614159565b6126909190613fb7565b92506127106101f4886126a39190614159565b6126ad9190613fb7565b91506127106101f4886126c09190614159565b6126ca9190613fb7565b90505b6000600560039054906101000a900460ff161561280a576127106064896126f49190614159565b6126fe9190613fb7565b90506000811115612809578060026000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461277a9190613f61565b92505081905550600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516128009190613e45565b60405180910390a35b5b6000600560009054906101000a900460ff16156129b6578361271060c88b6128329190614159565b61283c9190613fb7565b6128469190613f61565b905060008111156129b55780600260003073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546128a09190613f61565b9250508190555086806128bf5750600d60149054906101000a900460ff165b156128e25780600960008282546128d69190613f61565b925050819055506129b4565b612919600954826128f39190613f61565b7f000000000000000000000000d001c86042aef72f519a56d8bb02d3b3c2c87b20613020565b7f000000000000000000000000d001c86042aef72f519a56d8bb02d3b3c2c87b2073ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600954846129969190613f61565b6040516129a39190613e45565b60405180910390a360006009819055505b5b5b6000600560019054906101000a900460ff1615612b5b5761271060648b6129dd9190614159565b6129e79190613fb7565b90506000811115612b5a5780600260003073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612a419190613f61565b925050819055508780612a605750600d60149054906101000a900460ff165b15612a835780600a6000828254612a779190613f61565b92505081905550612b59565b612abc600a5482612a949190613f61565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16613020565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168c73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600a5484612b3b9190613f61565b604051612b489190613e45565b60405180910390a36000600a819055505b5b5b6000600560029054906101000a900460ff1615612dce578661271060c88d612b839190614159565b612b8d9190613fb7565b612b979190613f61565b90506000811115612dcd5780600260003073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612bf19190613f61565b925050819055508880612c105750600d60149054906101000a900460ff165b15612c335780600b6000828254612c279190613f61565b92505081905550612dcc565b6000600b5482612c439190613f61565b9050600d60159054906101000a900460ff1615612c9957600e54811115612c7a57612c6d81613377565b6000600b81905550612c94565b81600b6000828254612c8c9190613f61565b925050819055505b612dca565b600073ffffffffffffffffffffffffffffffffffffffff16600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612daf57612d1b81600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16613020565b600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168e73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612d9a9190613e45565b60405180910390a36000600b81905550612dc9565b81600b6000828254612dc19190613f61565b925050819055505b5b505b5b5b6000600560049054906101000a900460ff168015612dec5750600086115b15612e74578590508060016000828254612e0691906141b3565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168e73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8e604051612e6b9190613e45565b60405180910390a35b60008186858588612e859190613f61565b612e8f9190613f61565b612e999190613f61565b612ea39190613f61565b9050808d11612ee7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ede90613d45565b60405180910390fd5b808d612ef391906141b3565b9950505050505050505050612f07565b8390505b83600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612f5691906141b3565b9250508190555080600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612fac9190613f61565b925050819055508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516130109190613e45565b60405180910390a3505050505050565b600d60149054906101000a900460ff1615613070576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161306790613c85565b60405180910390fd5b6001600d60146101000a81548160ff0219169083151502179055506000600267ffffffffffffffff8111156130ce577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156130fc5781602001602082028036833780820191505090505b509050308160008151811061313a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b1580156131dc57600080fd5b505afa1580156131f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132149190613627565b8160018151811061324e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506132b530600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685612016565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663791ac9478460008486603c426133059190613f61565b6040518663ffffffff1660e01b8152600401613325959493929190613e60565b600060405180830381600087803b15801561333f57600080fd5b505af1158015613353573d6000803e3d6000fd5b50505050506000600d60146101000a81548160ff0219169083151502179055505050565b600d60159054906101000a900460ff166133c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133bd90613cc5565b60405180910390fd5b60006002826133d59190613fb7565b9050600081836133e591906141b3565b905060004790506133f68330613020565b6000814761340491906141b3565b90506134108184613452565b7f17bbfb9a6069321b6ded73bd96327c9e6b7212a5cd51ff219cd61370acafb56184828560405161344393929190613eba565b60405180910390a15050505050565b61347f30600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683612016565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f305d7198330846000807f0000000000000000000000002718758a03fdce9e6e23d5c6b3fd270b26e0cfc5603c426134f19190613f61565b6040518863ffffffff1660e01b815260040161351296959493929190613bac565b6060604051808303818588803b15801561352b57600080fd5b505af115801561353f573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061356491906137f4565b5050505050565b60008135905061357a8161477a565b92915050565b60008151905061358f8161477a565b92915050565b6000813590506135a481614791565b92915050565b6000815190506135b9816147a8565b92915050565b6000813590506135ce816147bf565b92915050565b6000815190506135e3816147bf565b92915050565b6000815190506135f8816147d6565b92915050565b60006020828403121561361057600080fd5b600061361e8482850161356b565b91505092915050565b60006020828403121561363957600080fd5b600061364784828501613580565b91505092915050565b6000806040838503121561366357600080fd5b60006136718582860161356b565b92505060206136828582860161356b565b9150509250929050565b6000806000606084860312156136a157600080fd5b60006136af8682870161356b565b93505060206136c08682870161356b565b92505060406136d1868287016135bf565b9150509250925092565b600080604083850312156136ee57600080fd5b60006136fc8582860161356b565b925050602061370d85828601613595565b9150509250929050565b6000806040838503121561372a57600080fd5b60006137388582860161356b565b9250506020613749858286016135bf565b9150509250929050565b60006020828403121561376557600080fd5b600061377384828501613595565b91505092915050565b60008060006060848603121561379157600080fd5b600061379f868287016135aa565b93505060206137b0868287016135aa565b92505060406137c1868287016135e9565b9150509250925092565b6000602082840312156137dd57600080fd5b60006137eb848285016135bf565b91505092915050565b60008060006060848603121561380957600080fd5b6000613817868287016135d4565b9350506020613828868287016135d4565b9250506040613839868287016135d4565b9150509250925092565b600061384f838361385b565b60208301905092915050565b613864816141e7565b82525050565b613873816141e7565b82525050565b600061388482613f1c565b61388e8185613f3f565b935061389983613f0c565b8060005b838110156138ca5781516138b18882613843565b97506138bc83613f32565b92505060018101905061389d565b5085935050505092915050565b6138e0816141f9565b82525050565b6138ef81614266565b82525050565b6138fe8161428a565b82525050565b600061390f82613f27565b6139198185613f50565b935061392981856020860161429c565b6139328161432d565b840191505092915050565b600061394a602383613f50565b91506139558261434b565b604082019050919050565b600061396d601283613f50565b91506139788261439a565b602082019050919050565b6000613990602c83613f50565b915061399b826143c3565b604082019050919050565b60006139b3601c83613f50565b91506139be82614412565b602082019050919050565b60006139d6602683613f50565b91506139e18261443b565b604082019050919050565b60006139f9602283613f50565b9150613a048261448a565b604082019050919050565b6000613a1c602683613f50565b9150613a27826144d9565b604082019050919050565b6000613a3f603083613f50565b9150613a4a82614528565b604082019050919050565b6000613a62602883613f50565b9150613a6d82614577565b604082019050919050565b6000613a85602083613f50565b9150613a90826145c6565b602082019050919050565b6000613aa8602a83613f50565b9150613ab3826145ef565b604082019050919050565b6000613acb602583613f50565b9150613ad68261463e565b604082019050919050565b6000613aee602483613f50565b9150613af98261468d565b604082019050919050565b6000613b11603783613f50565b9150613b1c826146dc565b604082019050919050565b6000613b34602583613f50565b9150613b3f8261472b565b604082019050919050565b613b538161423f565b82525050565b613b6281614259565b82525050565b6000602082019050613b7d600083018461386a565b92915050565b6000604082019050613b98600083018561386a565b613ba560208301846138d7565b9392505050565b600060c082019050613bc1600083018961386a565b613bce6020830188613b4a565b613bdb60408301876138f5565b613be860608301866138f5565b613bf5608083018561386a565b613c0260a0830184613b4a565b979650505050505050565b6000602082019050613c2260008301846138d7565b92915050565b6000602082019050613c3d60008301846138e6565b92915050565b60006020820190508181036000830152613c5d8184613904565b905092915050565b60006020820190508181036000830152613c7e8161393d565b9050919050565b60006020820190508181036000830152613c9e81613960565b9050919050565b60006020820190508181036000830152613cbe81613983565b9050919050565b60006020820190508181036000830152613cde816139a6565b9050919050565b60006020820190508181036000830152613cfe816139c9565b9050919050565b60006020820190508181036000830152613d1e816139ec565b9050919050565b60006020820190508181036000830152613d3e81613a0f565b9050919050565b60006020820190508181036000830152613d5e81613a32565b9050919050565b60006020820190508181036000830152613d7e81613a55565b9050919050565b60006020820190508181036000830152613d9e81613a78565b9050919050565b60006020820190508181036000830152613dbe81613a9b565b9050919050565b60006020820190508181036000830152613dde81613abe565b9050919050565b60006020820190508181036000830152613dfe81613ae1565b9050919050565b60006020820190508181036000830152613e1e81613b04565b9050919050565b60006020820190508181036000830152613e3e81613b27565b9050919050565b6000602082019050613e5a6000830184613b4a565b92915050565b600060a082019050613e756000830188613b4a565b613e8260208301876138f5565b8181036040830152613e948186613879565b9050613ea3606083018561386a565b613eb06080830184613b4a565b9695505050505050565b6000606082019050613ecf6000830186613b4a565b613edc6020830185613b4a565b613ee96040830184613b4a565b949350505050565b6000602082019050613f066000830184613b59565b92915050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b6000613f6c8261423f565b9150613f778361423f565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613fac57613fab6142cf565b5b828201905092915050565b6000613fc28261423f565b9150613fcd8361423f565b925082613fdd57613fdc6142fe565b5b828204905092915050565b6000808291508390505b60018511156140325780860481111561400e5761400d6142cf565b5b600185161561401d5780820291505b808102905061402b8561433e565b9450613ff2565b94509492505050565b60006140468261423f565b915061405183614259565b925061407e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484614086565b905092915050565b6000826140965760019050614152565b816140a45760009050614152565b81600181146140ba57600281146140c4576140f3565b6001915050614152565b60ff8411156140d6576140d56142cf565b5b8360020a9150848211156140ed576140ec6142cf565b5b50614152565b5060208310610133831016604e8410600b84101617156141285782820a905083811115614123576141226142cf565b5b614152565b6141358484846001613fe8565b9250905081840481111561414c5761414b6142cf565b5b81810290505b9392505050565b60006141648261423f565b915061416f8361423f565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156141a8576141a76142cf565b5b828202905092915050565b60006141be8261423f565b91506141c98361423f565b9250828210156141dc576141db6142cf565b5b828203905092915050565b60006141f28261421f565b9050919050565b60008115159050919050565b60006dffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b600060ff82169050919050565b600061427182614278565b9050919050565b60006142838261421f565b9050919050565b60006142958261423f565b9050919050565b60005b838110156142ba57808201518184015260208101905061429f565b838111156142c9576000848401525b50505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000601f19601f8301169050919050565b60008160011c9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f43757272656e746c7920696e20737761702e0000000000000000000000000000600082015250565b7f53637261746368546f6b656e3a207365742077616c6c657420746f207468652060008201527f7a65726f20616464726573730000000000000000000000000000000000000000602082015250565b7f5377617020416e64204c6971756966792069732064697361626c656400000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b7f53637261746368546f6b656e3a20546f6b656e2066656573206578636565647360008201527f207472616e7366657220616d6f756e7400000000000000000000000000000000602082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206160008201527f6c6c6f77616e6365000000000000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4e65772076616c7565206d757374206265206c6f776572207468616e20746f7460008201527f616c20737570706c792e00000000000000000000000000000000000000000000602082015250565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f53637261746368546f6b656e3a205472616e7366657220616d6f756e74206d7560008201527f73742062652067726561746572207468616e207a65726f000000000000000000602082015250565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b614783816141e7565b811461478e57600080fd5b50565b61479a816141f9565b81146147a557600080fd5b50565b6147b181614205565b81146147bc57600080fd5b50565b6147c88161423f565b81146147d357600080fd5b50565b6147df81614249565b81146147ea57600080fd5b5056fea26469706673582212202fdd3146c960dd8a32b3687e5a4258260f5036502fe45ed706c8b2c0199dca6264736f6c63430008040033

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

0000000000000000000000001c6353c75b5e28d4fd17e76271a4784707500a8d000000000000000000000000272256a91cd6d51584f4bfa4de2f4dfd4bcd3a5700000000000000000000000002c856c3252c41d4c0424ea82d56503062e8db4a0000000000000000000000003b8db4b26abd5c96be44d5e024168e74afaac48e00000000000000000000000066d940ac77c54eee20a75c2eb72cb7c473801941000000000000000000000000317e529ed3c2b7a3a6da5ab7b37fd1d56520520b000000000000000000000000d001c86042aef72f519a56d8bb02d3b3c2c87b200000000000000000000000002718758a03fdce9e6e23d5c6b3fd270b26e0cfc5000000000000000000000000a353de1c926e136b6ccb516f31c38cf40004acce0000000000000000000000007b8404be6480c44e25ee8c8446e408b1bfc924510000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d

-----Decoded View---------------
Arg [0] : owner (address): 0x1C6353C75B5e28D4fD17e76271A4784707500A8D
Arg [1] : founder1Wallet_ (address): 0x272256a91cD6D51584F4BfA4DE2f4Dfd4BcD3a57
Arg [2] : founder2Wallet_ (address): 0x02c856c3252C41d4c0424Ea82d56503062E8dB4a
Arg [3] : founder3Wallet_ (address): 0x3B8dB4B26Abd5C96be44d5e024168e74AfaaC48E
Arg [4] : founder4Wallet_ (address): 0x66D940ac77C54eEE20a75C2EB72cB7C473801941
Arg [5] : founder5Wallet_ (address): 0x317E529ED3c2B7a3a6Da5Ab7b37Fd1d56520520B
Arg [6] : developmentWallet_ (address): 0xD001C86042aef72F519A56d8Bb02D3b3c2c87B20
Arg [7] : exchangeWallet_ (address): 0x2718758A03FdCe9e6e23D5c6b3Fd270b26E0cfC5
Arg [8] : operationsWallet_ (address): 0xa353de1C926e136B6ccb516f31c38cF40004aCCE
Arg [9] : archaWallet_ (address): 0x7b8404be6480C44e25EE8c8446E408b1bfc92451
Arg [10] : uniswapV2RouterAddress_ (address): 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D

-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 0000000000000000000000001c6353c75b5e28d4fd17e76271a4784707500a8d
Arg [1] : 000000000000000000000000272256a91cd6d51584f4bfa4de2f4dfd4bcd3a57
Arg [2] : 00000000000000000000000002c856c3252c41d4c0424ea82d56503062e8db4a
Arg [3] : 0000000000000000000000003b8db4b26abd5c96be44d5e024168e74afaac48e
Arg [4] : 00000000000000000000000066d940ac77c54eee20a75c2eb72cb7c473801941
Arg [5] : 000000000000000000000000317e529ed3c2b7a3a6da5ab7b37fd1d56520520b
Arg [6] : 000000000000000000000000d001c86042aef72f519a56d8bb02d3b3c2c87b20
Arg [7] : 0000000000000000000000002718758a03fdce9e6e23d5c6b3fd270b26e0cfc5
Arg [8] : 000000000000000000000000a353de1c926e136b6ccb516f31c38cf40004acce
Arg [9] : 0000000000000000000000007b8404be6480c44e25ee8c8446e408b1bfc92451
Arg [10] : 0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

OVERVIEW

The Scratch Engine outputs a concise scoring report complete with a Scratch Valuation. Scratch Valuation creates an unbiased market standard assessment enabling investors to easily research, assess, borrow against or sell their digital assets. Essentially become the “Kelly Blue Book” of NFTs.

Validator Index Block Amount
View All Withdrawals

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

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