ETH Price: $3,493.96 (-0.16%)
Gas: 6 Gwei

Token

ApplePYE (APPLEPYE)
 

Overview

Max Total Supply

23,492,707.383710661089349774 APPLEPYE

Holders

103

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
2,436,723.871141458033404258 APPLEPYE

Value
$0.00
0x0f07f722ef5f50ad5a7aa431ea558fc83beea36e
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
APPLE

Compiler Version
v0.8.1+commit.df193b15

Optimization Enabled:
Yes with 999 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-05-25
*/

// File: contracts-eth/interfaces/IBEP20.sol



pragma solidity >=0.4.0;

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

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

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

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

    /**
     * @dev Returns the bep token owner.
     */
    function getOwner() external view returns (address);

    /**
     * @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: contracts-eth/interfaces/IPYESwapRouter01.sol



pragma solidity ^0.8.0;

interface IPYESwapRouter01 {
    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: contracts-eth/interfaces/IPYESwapRouter.sol



pragma solidity >=0.6.2;


interface IPYESwapRouter is IPYESwapRouter01 {
    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;
    function pairFeeAddress(address pair) external view returns (address);
    function adminFee() external view returns (uint256);
    function feeAddressGet() external view returns (address);
}

// File: contracts-eth/interfaces/IPYESwapPair.sol



pragma solidity >=0.5.0;

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

    function baseToken() external view returns (address);
    function getTotalFee() external view returns (uint);
    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 updateTotalFee(uint totalFee) external returns (bool);

    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, address _baseToken);
    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, uint amount0Fee, uint amount1Fee, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
    function setBaseToken(address _baseToken) external;
}

// File: contracts-eth/interfaces/IPYESwapFactory.sol



pragma solidity >=0.5.0;

interface IPYESwapFactory {
    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 pairExist(address pair) external view returns (bool);

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

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
    function routerInitialize(address) external;
    function routerAddress() external view returns (address);
}

// File: contracts-eth/interfaces/IWETH.sol



pragma solidity >=0.5.0;

interface IWETH {
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);
    function deposit() external payable;
    function transfer(address to, uint value) external returns (bool);
    function withdraw(uint) external;
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.5.0) (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 `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

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

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

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

    /**
     * @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: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol


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

pragma solidity ^0.8.0;


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

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

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

// File: @openzeppelin/contracts/utils/Counters.sol


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

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

// File: @openzeppelin/contracts/utils/math/Math.sol


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

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

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

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

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

// File: @openzeppelin/contracts/utils/Arrays.sol


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

pragma solidity ^0.8.0;


/**
 * @dev Collection of functions related to array types.
 */
library Arrays {
    /**
     * @dev Searches a sorted `array` and returns the first index that contains
     * a value greater or equal to `element`. If no such index exists (i.e. all
     * values in the array are strictly less than `element`), the array length is
     * returned. Time complexity O(log n).
     *
     * `array` is expected to be sorted in ascending order, and to contain no
     * repeated elements.
     */
    function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
        if (array.length == 0) {
            return 0;
        }

        uint256 low = 0;
        uint256 high = array.length;

        while (low < high) {
            uint256 mid = Math.average(low, high);

            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
            // because Math.average rounds down (it does integer division with truncation).
            if (array[mid] > element) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.
        if (low > 0 && array[low - 1] == element) {
            return low - 1;
        } else {
            return low;
        }
    }
}

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol


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

pragma solidity ^0.8.0;

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

// File: @openzeppelin/contracts/utils/introspection/ERC165.sol


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

pragma solidity ^0.8.0;


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

// File: @openzeppelin/contracts/utils/Strings.sol


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

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

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

// File: @openzeppelin/contracts/access/IAccessControl.sol


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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts/utils/Address.sol


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

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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


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

pragma solidity ^0.8.0;

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

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

// File: @openzeppelin/contracts/token/ERC20/ERC20.sol


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

pragma solidity ^0.8.0;




/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.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:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

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

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

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

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

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

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

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

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

        _totalSupply += amount;
        _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 Spend `amount` form the allowance of `owner` toward `spender`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

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

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

// File: @openzeppelin/contracts/access/AccessControl.sol


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

pragma solidity ^0.8.0;





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

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

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

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

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

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

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

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

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

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

        _revokeRole(role, account);
    }

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

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

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

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

// File: @openzeppelin/contracts/access/Ownable.sol


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

pragma solidity ^0.8.0;


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

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

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

    /**
     * @dev 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: @openzeppelin/contracts/utils/math/SafeMath.sol


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

// File: contracts-eth/libs/BEP20.sol



pragma solidity >=0.4.0;






/**
 * @dev Implementation of the {IBEP20} 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 {BEP20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-BEP20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of BEP20 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 {IBEP20-approve}.
 */
contract BEP20 is Context, IBEP20, Ownable {
    using SafeMath for uint256;
    using Address for address;

    mapping(address => uint256) private _balances;

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with
     * a default value of 18.
     *
     * To select a different value for {decimals}, use {_setupDecimals}.
     *
     * All three of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
        _decimals = 18;
    }

    /**
     * @dev Returns the bep token owner.
     */
    function getOwner() external override view returns (address) {
        return owner();
    }

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

    /**
     * @dev Returns the token decimals.
     */
    function decimals() public override view returns (uint8) {
        return _decimals;
    }

    /**
     * @dev Returns the token symbol.
     */
    function symbol() public override view returns (string memory) {
        return _symbol;
    }

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

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

    /**
     * @dev See {BEP20-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 override virtual returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

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

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

    /**
     * @dev See {BEP20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {BEP20};
     *
     * 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 override virtual returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(
            sender,
            _msgSender(),
            _allowances[sender][_msgSender()].sub(amount, 'BEP20: transfer amount exceeds allowance')
        );
        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 {BEP20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(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 {BEP20-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 returns (bool) {
        _approve(
            _msgSender(),
            spender,
            _allowances[_msgSender()][spender].sub(subtractedValue, 'BEP20: decreased allowance below zero')
        );
        return true;
    }

    /**
     * @dev Creates `amount` tokens and assigns them to `msg.sender`, increasing
     * the total supply.
     *
     * Requirements
     *
     * - `msg.sender` must be the token owner
     */
    function mint(uint256 amount) public onlyOwner returns (bool) {
        _mint(_msgSender(), amount);
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is 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 {
        require(sender != address(0), 'BEP20: transfer from the zero address');
        require(recipient != address(0), 'BEP20: transfer to the zero address');

        _balances[sender] = _balances[sender].sub(amount, 'BEP20: transfer amount exceeds balance');
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(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
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal {
        require(account != address(0), 'BEP20: mint to the zero address');

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(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 {
        require(account != address(0), 'BEP20: burn from the zero address');

        _balances[account] = _balances[account].sub(amount, 'BEP20: burn amount exceeds balance');
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.
     *
     * This is 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), 'BEP20: approve from the zero address');
        require(spender != address(0), 'BEP20: approve to the zero address');

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

    /**
     * @dev Destroys `amount` tokens from `account`.`amount` is then deducted
     * from the caller's allowance.
     *
     * See {_burn} and {_approve}.
     */
    function _burnFrom(address account, uint256 amount) internal {
        _burn(account, amount);
        _approve(
            account,
            _msgSender(),
            _allowances[account][_msgSender()].sub(amount, 'BEP20: burn amount exceeds allowance')
        );
    }
}
// File: contracts-eth/Apple2.sol


pragma solidity ^0.8.0;
pragma experimental ABIEncoderV2;















contract APPLE is Context, Ownable, AccessControl, ERC20 {
    using SafeMath for uint256;
    using Address for address;

    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
    bytes32 public constant FEE_SETTER_ROLE = keccak256("FEE_SETTER_ROLE");

    // staked struct	
    struct Staked {	
        uint256 amount;	
    }	
    address[] holders;	
    mapping (address => uint256) holderIndexes;	
    uint256 public totalStaked;

    // Fees
    // Add and remove fee types and destinations here as needed
    struct Fees {
        uint256 developmentFee;
        uint256 buybackFee;
        uint256 burnFee;
        address developmentAddress;
    }

    // Transaction fee values
    // Add and remove fee value types here as needed
    struct FeeValues {
        uint256 transferAmount;
        uint256 development;
        uint256 buyback;
        uint256 burn;
    }

    // Token details
    mapping (address => uint256) _balances;
    mapping (address => mapping (address => uint256)) private _allowances;
    mapping (address => Staked) public staked;

    // blacklist and staking contract mappings	
    mapping (address => bool) isBlacklisted; 	
    mapping (address => bool) isStakingContract; 


    // Set total supply here
    uint256 private _tTotal;

    // auto set buyback to false. additional buyback params. blockPeriod acts as a time delay in the shouldAutoBuyback(). Last uint represents last block for buyback occurance.
    struct Settings {
        bool autoBuybackEnabled;
        uint256 autoBuybackCap;
        uint256 autoBuybackAccumulator;
        uint256 autoBuybackAmount;
        uint256 autoBuybackBlockPeriod;
        uint256 autoBuybackBlockLast;
        uint256 minimumBuyBackThreshold;
    }

    // Users states
    mapping (address => bool) private _isExcludedFromFee;

    // Outside Swap Pairs
    mapping (address => bool) private _includeSwapFee;


    // Pair Details
    mapping (uint256 => address) private pairs;
    mapping (uint256 => address) private tokens;
    uint256 private pairsLength;
    mapping (address => bool) public _isPairAddress;


    // Set the name, symbol, and decimals here
    string constant _name = "ApplePYE";
    string constant _symbol = "APPLEPYE";
    uint8 constant _decimals = 18;

    Fees public _defaultFees;
    Fees public _defaultSellFees;
    Fees private _previousFees;
    Fees private _emptyFees;
    Fees private _sellFees;
    Fees private _outsideBuyFees;
    Fees private _outsideSellFees;

    Settings public _buyback;

    IPYESwapRouter public pyeSwapRouter;
    address public pyeSwapPair;
    address public WETH;
    address public constant _burnAddress = 0x000000000000000000000000000000000000dEaD;

    bool public swapEnabled = true;
    bool inSwap;

    modifier swapping() { inSwap = true; _; inSwap = false; }
    modifier onlyExchange() {
        bool isPair = false;
        for(uint i = 0; i < pairsLength; i++) {
            if(pairs[i] == msg.sender) isPair = true;
        }
        require(
            msg.sender == address(pyeSwapRouter)
            || isPair
            , "PYE: NOT_ALLOWED"
        );
        _;
    }

    /// @dev A record of each accounts delegate
    mapping (address => address) public delegates;

    /// @notice A checkpoint for marking number of votes from a given block
    struct Checkpoint {
        uint32 fromBlock;
        uint256 votes;
    }

    /// @notice A record of votes checkpoints for each account, by index
    mapping (address => mapping (uint32 => Checkpoint)) public checkpoints;

    /// @notice The number of checkpoints for each account
    mapping (address => uint32) public numCheckpoints;

    /// @notice The EIP-712 typehash for the contract's domain
    bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");

    /// @notice The EIP-712 typehash for the delegation struct used by the contract
    bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");

    /// @notice A record of states for signing / validating signatures
    mapping (address => uint) public nonces;

    /// @notice An event thats emitted when an account changes its delegate
    event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

    /// @notice An event thats emitted when a delegate account's vote balance changes
    event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);

    // Edit the constructor in order to declare default fees on deployment
    constructor (address _router, address _development, uint256 _developmentFee, uint256 _buybackFee, uint256 _burnFee) ERC20("","") {
        _setupRole(MINTER_ROLE, msg.sender);
        _setupRole(BURNER_ROLE, msg.sender);
        _setupRole(FEE_SETTER_ROLE, msg.sender);
        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);

        pyeSwapRouter = IPYESwapRouter(_router);
        WETH = pyeSwapRouter.WETH();
        pyeSwapPair = IPYESwapFactory(pyeSwapRouter.factory())
        .createPair(address(this), WETH, true);

        tokens[pairsLength] = WETH;
        pairs[pairsLength] = pyeSwapPair;
        pairsLength += 1;
        _isPairAddress[pyeSwapPair] = true;

        _isExcludedFromFee[_msgSender()] = true;
        _isExcludedFromFee[pyeSwapPair] = true;
        _isExcludedFromFee[address(this)] = true;
        _isExcludedFromFee[_burnAddress] = true;

        // This should match the struct Fee
        _defaultFees = Fees(
            _developmentFee,
            _buybackFee,
            0,
            _development
        );

        _defaultSellFees = Fees(
            _developmentFee,
            _buybackFee,
            _burnFee,
            _development
        );

        _sellFees = Fees(
            0,
            0,
            _burnFee,
            _development
        );

        _outsideBuyFees = Fees(
            _developmentFee.add(_buybackFee),
            0,
            0,
            _development
        );

        _outsideSellFees = Fees(
            _developmentFee.add(_buybackFee),
            0,
            _burnFee,
            _development
        );

        IPYESwapPair(pyeSwapPair).updateTotalFee(400);
        
        emit Transfer(address(0), _msgSender(), _tTotal);
    }

    function name() public pure override returns (string memory) {
        return _name;
    }

    function symbol() public pure override returns (string memory) {
        return _symbol;
    }

    function decimals() public pure override returns (uint8) {
        return _decimals;
    }

    function totalSupply() public view override returns (uint256) {
        return _tTotal;
    }

    function balanceOf(address account) public view override returns (uint256) {
        return _balances[account];
    }

    function transfer(address recipient, uint256 amount) public override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    function allowance(address owner, address spender) public view override returns (uint256) {
        return _allowances[owner][spender];
    }

    function approve(address spender, uint256 amount) public override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "BEP20: transfer amount exceeds allowance"));
        return true;
    }

    function increaseAllowance(address spender, uint256 addedValue) public virtual override returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual override returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "BEP20: decreased allowance below zero"));
        return true;
    }

    function excludeFromFee(address account) public {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        _isExcludedFromFee[account] = true;
    }

    function includeInFee(address account) public {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        _isExcludedFromFee[account] = false;
    }

    function addOutsideSwapPair(address account) public {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        _includeSwapFee[account] = true;
    }

    function removeOutsideSwapPair(address account) public {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        _includeSwapFee[account] = false;
    }

    function _updatePairsFee() internal {
        for (uint j = 0; j < pairsLength; j++) {
            IPYESwapPair(pairs[j]).updateTotalFee(getTotalFee());
        }
    }


    // Functions to update fees and addresses 

    function setBuybackPercent(uint256 _buybackFee) external {
        require(hasRole(FEE_SETTER_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        require(_defaultSellFees.developmentFee.add(_defaultSellFees.burnFee).add(_buybackFee) <= 2500, "Fees exceed max limit.");
        _defaultFees.buybackFee = _buybackFee;
        _defaultSellFees.buybackFee = _buybackFee;
        _outsideBuyFees.developmentFee = _outsideBuyFees.developmentFee.add(_buybackFee);
        _outsideSellFees.developmentFee = _outsideSellFees.developmentFee.add(_buybackFee);
        _updatePairsFee();
    }

    function setDevelopmentPercent(uint256 _developmentFee) external {
        require(hasRole(FEE_SETTER_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        require(_defaultSellFees.buybackFee.add(_defaultSellFees.burnFee).add(_developmentFee) <= 2500, "Fees exceed max limit.");
        _defaultFees.developmentFee = _developmentFee;
        _defaultSellFees.developmentFee = _developmentFee;
        _outsideBuyFees.developmentFee = _outsideBuyFees.buybackFee.add(_developmentFee);
        _outsideSellFees.developmentFee = _outsideSellFees.buybackFee.add(_developmentFee);
        _updatePairsFee();
    }

    function setdevelopmentAddress(address _development) external {
        require(hasRole(FEE_SETTER_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        require(_development != address(0), "PYE: Address Zero is not allowed");
        _defaultFees.developmentAddress = _development;
        _defaultSellFees.developmentAddress = _development;
        _outsideBuyFees.developmentAddress = _development;
        _outsideSellFees.developmentAddress = _development;
    }

    function setSellBurnFee(uint256 _burnFee) external {
        require(hasRole(FEE_SETTER_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        require(_defaultSellFees.buybackFee.add(_defaultSellFees.developmentFee).add(_burnFee) <= 2500, "Fees exceed max limit.");
        _sellFees.burnFee = _burnFee;
        _defaultSellFees.burnFee = _burnFee;
        _outsideSellFees.burnFee = _burnFee;
    }



    function updateRouterAndPair(address _router, address _pair) public {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        _isExcludedFromFee[pyeSwapPair] = false;
        pyeSwapRouter = IPYESwapRouter(_router);
        pyeSwapPair = _pair;
        WETH = pyeSwapRouter.WETH();

        _isPairAddress[pyeSwapPair] = true;
        _isExcludedFromFee[pyeSwapPair] = true;

        pairs[0] = pyeSwapPair;
        tokens[0] = WETH;

        IPYESwapPair(pyeSwapPair).updateTotalFee(getTotalFee());
    }

    //to receive ETH from pyeRouter when swapping
    receive() external payable {}

    function _getValues(uint256 tAmount) private view returns (FeeValues memory) {
        FeeValues memory values = FeeValues(
            0,
            calculateFee(tAmount, _defaultFees.developmentFee),
            calculateFee(tAmount, _defaultFees.buybackFee),
            calculateFee(tAmount, _defaultFees.burnFee)
        );

        values.transferAmount = tAmount.sub(values.development).sub(values.buyback).sub(values.burn);
        return values;
    }

    function calculateFee(uint256 _amount, uint256 _fee) private pure returns (uint256) {
        if(_fee == 0) return 0;
        return _amount.mul(_fee).div(
            10**4
        );
    }

    function removeAllFee() private {
        _previousFees = _defaultFees;
        _defaultFees = _emptyFees;
    }

    function setSellFee() private {
        _previousFees = _defaultFees;
        _defaultFees = _sellFees;
    }

    function setOutsideBuyFee() private {
        _previousFees = _defaultFees;
        _defaultFees = _outsideBuyFees;
    }

    function setOutsideSellFee() private {
        _previousFees = _defaultFees;
        _defaultFees = _outsideSellFees;
    }

    function restoreAllFee() private {
        _defaultFees = _previousFees;
    }

    function isExcludedFromFee(address account) public view returns(bool) {
        return _isExcludedFromFee[account];
    }

    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal override {
        require(owner != address(0), "BEP20: approve from the zero address");
        require(spender != address(0), "BEP20: approve to the zero address");

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

    function getBalance(address keeper) public view returns (uint256){
        return _balances[keeper];
    }

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal override {
        require(from != address(0), "BEP20: transfer from the zero address");
        require(to != address(0), "BEP20: transfer to the zero address");
        require(amount > 0, "Transfer amount must be greater than zero");
        require(!isBlacklisted[to]);
        _beforeTokenTransfer(from, to, amount);

        if(shouldAutoBuyback(amount)){ triggerAutoBuyback(); }

        if(isStakingContract[to]) { 	
            uint256 newAmountAdd = staked[from].amount.add(amount);	
            setStaked(from, newAmountAdd);	
        }	
        if(isStakingContract[from]) {	
            uint256 newAmountSub = staked[to].amount.sub(amount);	
            setStaked(to, newAmountSub);	
        }

        //indicates if fee should be deducted from transfer of tokens
        uint8 takeFee = 0;
        if(_isPairAddress[to] && from != address(pyeSwapRouter) && !isExcludedFromFee(from)) {
            takeFee = 1;
        } else if(_includeSwapFee[from]) {
            takeFee = 2;
        } else if(_includeSwapFee[to]) {
            takeFee = 3;
        }

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

    function getCirculatingSupply() public view returns (uint256) {
        return _tTotal.sub(balanceOf(_burnAddress)).sub(balanceOf(address(0)));
    }

    function getTotalFee() public view returns (uint256) {
        return _defaultFees.developmentFee
            .add(_defaultFees.buybackFee)
            .add(_defaultFees.burnFee);
    }

    //this method is responsible for taking all fee, if takeFee is true
    function _tokenTransfer(address sender, address recipient, uint256 amount, uint8 takeFee) private {
        if(takeFee == 0) {
            removeAllFee();
        } else if(takeFee == 1) {
            setSellFee();
        } else if(takeFee == 2) {
            setOutsideBuyFee();
        } else if(takeFee == 3) {
            setOutsideSellFee();
        }

        FeeValues memory _values = _getValues(amount);
        _balances[sender] = _balances[sender].sub(amount, "Insufficient Balance");
        _balances[recipient] = _balances[recipient].add(_values.transferAmount);
        _takeFees(_values);

        emit Transfer(sender, recipient, _values.transferAmount);

        if(delegates[sender] == address(0)) {
            delegates[sender] = sender;
        }

        if(delegates[recipient] == address(0)) {
            delegates[recipient] = recipient;
        }

        if(amount == _values.transferAmount) {	
            _moveDelegates(delegates[sender], delegates[recipient], amount);	
        } else {	
            _moveDelegates(delegates[sender], delegates[recipient], _values.transferAmount);	
            _moveDelegates(delegates[sender], delegates[_defaultFees.developmentAddress], _values.development);	
            _moveDelegates(delegates[sender], address(0), _values.burn);	
        }

        if(takeFee == 0 || takeFee == 1) {
            restoreAllFee();
        } else if(takeFee == 2 || takeFee == 3) {
            restoreAllFee();
            emit Transfer(sender, _defaultFees.developmentAddress, _values.development);
        }
    }

    function _takeFees(FeeValues memory values) private {
        _takeFee(values.development, _defaultFees.developmentAddress);
        _takeBurnFee(values.burn);
    }

    function _takeFee(uint256 tAmount, address recipient) private {
        if(recipient == address(0)) return;
        if(tAmount == 0) return;

        _balances[recipient] = _balances[recipient].add(tAmount);
    }

    function _takeBurnFee(uint256 amount) private {
        if(amount == 0) return;

        _balances[address(this)] = _balances[address(this)].add(amount);
        _burn(address(this), amount);
    }

    // This function transfers the fees to the correct addresses. 
    function depositLPFee(uint256 amount, address token) public onlyExchange {
        uint256 tokenIndex = _getTokenIndex(token);
        if(tokenIndex < pairsLength) {
            uint256 allowanceT = IERC20(token).allowance(msg.sender, address(this));
            if(allowanceT >= amount) {
                IERC20(token).transferFrom(msg.sender, address(this), amount);

                if(token != WETH) {
                    uint256 balanceBefore = IERC20(address(WETH)).balanceOf(address(this));
                    swapToWETH(amount, token);
                    uint256 fAmount = IERC20(address(WETH)).balanceOf(address(this)).sub(balanceBefore);
                    
                    // All fees to be declared here in order to be calculated and sent
                    uint256 totalFee = getTotalFee();
                    uint256 developmentFeeAmount = fAmount.mul(_defaultFees.developmentFee).div(totalFee);

                    IERC20(WETH).transfer(_defaultFees.developmentAddress, developmentFeeAmount);
                } else {
                    // All fees to be declared here in order to be calculated and sent
                    uint256 totalFee = getTotalFee();
                    uint256 developmentFeeAmount = amount.mul(_defaultFees.developmentFee).div(totalFee);

                    IERC20(token).transfer(_defaultFees.developmentAddress, developmentFeeAmount);
                }
            }
        }
    }

    function swapToWETH(uint256 amount, address token) internal {
        address[] memory path = new address[](2);
        path[0] = token;
        path[1] = WETH;

        IERC20(token).approve(address(pyeSwapRouter), amount);
        pyeSwapRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens(
            amount,
            0,
            path,
            address(this),
            block.timestamp
        );
    }

    // runs check to see if autobuyback should trigger
    function shouldAutoBuyback(uint256 amount) internal view returns (bool) {
        return msg.sender != pyeSwapPair
        && !inSwap
        && _buyback.autoBuybackEnabled
        && _buyback.autoBuybackBlockLast + _buyback.autoBuybackBlockPeriod <= block.number // After N blocks from last buyback
        && IERC20(address(WETH)).balanceOf(address(this)) >= _buyback.autoBuybackAmount
        && amount >= _buyback.minimumBuyBackThreshold;
    }

    // triggers auto buyback
    function triggerAutoBuyback() internal {
        buyTokens(_buyback.autoBuybackAmount, _burnAddress);
        _buyback.autoBuybackBlockLast = block.number;
        _buyback.autoBuybackAccumulator = _buyback.autoBuybackAccumulator.add(_buyback.autoBuybackAmount);
        if(_buyback.autoBuybackAccumulator > _buyback.autoBuybackCap){ _buyback.autoBuybackEnabled = false; }
    }

    // logic to purchase moonforce tokens
    function buyTokens(uint256 amount, address to) internal swapping {
        address[] memory path = new address[](2);
        path[0] = WETH;
        path[1] = address(this);

        IERC20(WETH).approve(address(pyeSwapRouter), amount);
        pyeSwapRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens(
            amount,
            0,
            path,
            to,
            block.timestamp
        );
    }

    // manually adjust the buyback settings to suit your needs
    function setAutoBuybackSettings(bool _enabled, uint256 _cap, uint256 _amount, uint256 _period, uint256 _minimumThreshold) external {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        _buyback.autoBuybackEnabled = _enabled;
        _buyback.autoBuybackCap = _cap;
        _buyback.autoBuybackAccumulator = 0;
        _buyback.autoBuybackAmount = _amount;
        _buyback.autoBuybackBlockPeriod = _period;
        _buyback.autoBuybackBlockLast = block.number;
        _buyback.minimumBuyBackThreshold = _minimumThreshold;
    }

    function _getTokenIndex(address _token) internal view returns (uint256) {
        uint256 index = pairsLength + 1;
        for(uint256 i = 0; i < pairsLength; i++) {
            if(tokens[i] == _token) index = i;
        }

        return index;
    }

    function addPair(address _pair, address _token) public {
        address factory = pyeSwapRouter.factory();
        require(
            msg.sender == factory
            || msg.sender == address(pyeSwapRouter)
            || msg.sender == address(this)
        , "PYE: NOT_ALLOWED"
        );

        if(!_checkPairRegistered(_pair)) {
            _isExcludedFromFee[_pair] = true;
            _isPairAddress[_pair] = true;

            pairs[pairsLength] = _pair;
            tokens[pairsLength] = _token;

            pairsLength += 1;

            IPYESwapPair(_pair).updateTotalFee(getTotalFee());
        }
    }

    function _checkPairRegistered(address _pair) internal view returns (bool) {
        bool isPair = false;
        for(uint i = 0; i < pairsLength; i++) {
            if(pairs[i] == _pair) isPair = true;
        }

        return isPair;
    }

    // Rescue eth that is sent here by mistake
    function rescueETH(uint256 amount, address to) external {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        payable(to).transfer(amount);
      }

    // Rescue tokens that are sent here by mistake
    function rescueToken(IERC20 token, uint256 amount, address to) external {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        if( token.balanceOf(address(this)) < amount ) {
            amount = token.balanceOf(address(this));
        }
        token.transfer(to, amount);
    }

    /**	
     * @dev Spend `amount` form the allowance of `owner` toward `spender`.	
     *	
     * Does not update the allowance amount in case of infinite allowance.	
     * Revert if not enough allowance is available.	
     *	
     * Might emit an {Approval} event.	
     */	
    function _spendAllowance(	
        address owner,	
        address spender,	
        uint256 amount	
    ) internal override virtual {	
        uint256 currentAllowance = allowance(owner, spender);	
        if (currentAllowance != type(uint256).max) {	
            require(currentAllowance >= amount, "ERC20: insufficient allowance");	
            unchecked {	
                _approve(owner, spender, currentAllowance - 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
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) override internal {
        require(account != address(0), 'BEP20: mint to the zero address');

        _tTotal = _tTotal.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(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) override internal {	
        require(account != address(0), 'BEP20: burn from the zero address');	
        _balances[account] = _balances[account].sub(amount, 'BEP20: burn amount exceeds balance');	
        _tTotal = _tTotal.sub(amount);	
        emit Transfer(account, address(0), amount);	
    }

    
    function burnFrom(address _from, uint256 _amount) public {	
        require(hasRole(BURNER_ROLE, msg.sender), "APPLE: NOT_ALLOWED");	
        _spendAllowance(_from, msg.sender, _amount);
        _beforeTokenTransfer(_from, address(0), _amount);		
        _burn(_from, _amount);	
        if(delegates[_from] == address(0)) {	
            delegates[_from] = _from;	
        }	
        _moveDelegates(delegates[_from], address(0), _amount);	
    }	


    /// @notice Creates `_amount` token to `_to`. Must only be called by the owner (MasterChef).
    function mint(address _to, uint256 _amount) public {
        require(hasRole(MINTER_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        _beforeTokenTransfer(address(0), _to, _amount);
        _mint(_to, _amount);
        
        if(delegates[_to] == address(0)) {
            delegates[_to] = _to;
        }
        _moveDelegates(address(0), delegates[_to], _amount);
    }

    function burn(uint256 _amount) public {
        require(hasRole(BURNER_ROLE, msg.sender), "APPLE: NOT_ALLOWED");
        _beforeTokenTransfer(msg.sender, address(0), _amount);
        _burn(msg.sender, _amount);

        if(delegates[msg.sender] == address(0)) {
            delegates[msg.sender] = msg.sender;
        }
        _moveDelegates(delegates[msg.sender], address(0), _amount);
    }

    // Copied and modified from YAM code:
    // https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernanceStorage.sol
    // https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernance.sol
    // Which is copied and modified from COMPOUND:
    // https://github.com/compound-finance/compound-protocol/blob/master/contracts/Governance/Comp.sol

    /**
     * @notice Delegate votes from `msg.sender` to `delegatee`
    * @param delegatee The address to delegate votes to
    */
    function delegate(address delegatee) external {
        return _delegate(msg.sender, delegatee);
    }

    /**
     * @notice Delegates votes from signatory to `delegatee`
     * @param delegatee The address to delegate votes to
     * @param nonce The contract state required to match the signature
     * @param expiry The time at which to expire the signature
     * @param v The recovery byte of the signature
     * @param r Half of the ECDSA signature pair
     * @param s Half of the ECDSA signature pair
     */
    function delegateBySig(
        address delegatee,
        uint nonce,
        uint expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    )
    external
    {
        bytes32 domainSeparator = keccak256(
            abi.encode(
                DOMAIN_TYPEHASH,
                keccak256(bytes(name())),
                getChainId(),
                address(this)
            )
        );

        bytes32 structHash = keccak256(
            abi.encode(
                DELEGATION_TYPEHASH,
                delegatee,
                nonce,
                expiry
            )
        );

        bytes32 digest = keccak256(
            abi.encodePacked(
                "\x19\x01",
                domainSeparator,
                structHash
            )
        );

        address signatory = ecrecover(digest, v, r, s);
        require(signatory != address(0), "APPLE::delegateBySig: invalid signature");
        require(nonce == nonces[signatory]++, "APPLE::delegateBySig: invalid nonce");
        require(block.timestamp <= expiry, "APPLE::delegateBySig: signature expired");
        return _delegate(signatory, delegatee);
    }

    /**
     * @notice Gets the current votes balance for `account`
     * @param account The address to get votes balance
     * @return The number of current votes for `account`
     */
    function getCurrentVotes(address account)
    external
    view
    returns (uint256)
    {
        uint32 nCheckpoints = numCheckpoints[account];
        return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;
    }

    /**
     * @notice Determine the prior number of votes for an account as of a block number
     * @dev Block number must be a finalized block or else this function will revert to prevent misinformation.
     * @param account The address of the account to check
     * @param blockNumber The block number to get the vote balance at
     * @return The number of votes the account had as of the given block
     */
    function getPriorVotes(address account, uint blockNumber)
    external
    view
    returns (uint256)
    {
        require(blockNumber < block.number, "APPLE::getPriorVotes: not yet determined");

        uint32 nCheckpoints = numCheckpoints[account];
        if (nCheckpoints == 0) {
            return 0;
        }

        // First check most recent balance
        if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {
            return checkpoints[account][nCheckpoints - 1].votes;
        }

        // Next check implicit zero balance
        if (checkpoints[account][0].fromBlock > blockNumber) {
            return 0;
        }

        uint32 lower = 0;
        uint32 upper = nCheckpoints - 1;
        while (upper > lower) {
            uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
            Checkpoint memory cp = checkpoints[account][center];
            if (cp.fromBlock == blockNumber) {
                return cp.votes;
            } else if (cp.fromBlock < blockNumber) {
                lower = center;
            } else {
                upper = center - 1;
            }
        }
        return checkpoints[account][lower].votes;
    }

    function _delegate(address delegator, address delegatee)
    internal
    {
        address currentDelegate = delegates[delegator];
        uint256 delegatorBalance = balanceOf(delegator); // balance of underlying APPLE (not scaled);
        delegates[delegator] = delegatee;

        emit DelegateChanged(delegator, currentDelegate, delegatee);

        _moveDelegates(currentDelegate, delegatee, delegatorBalance);
    }

    function _moveDelegates(address srcRep, address dstRep, uint256 amount) internal {
        if (srcRep != dstRep && amount > 0) {
            if (srcRep != address(0)) {
                // decrease old representative
                uint32 srcRepNum = numCheckpoints[srcRep];
                uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;
                uint256 srcRepNew = srcRepOld.sub(amount);
                _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
            }

            if (dstRep != address(0)) {
                // increase new representative
                uint32 dstRepNum = numCheckpoints[dstRep];
                uint256 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;
                uint256 dstRepNew = dstRepOld.add(amount);
                _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
            }
        }
    }

    function _writeCheckpoint(
        address delegatee,
        uint32 nCheckpoints,
        uint256 oldVotes,
        uint256 newVotes
    )
    internal
    {
        uint32 blockNumber = safe32(block.number, "APPLE::_writeCheckpoint: block number exceeds 32 bits");

        if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {
            checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;
        } else {
            checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);
            numCheckpoints[delegatee] = nCheckpoints + 1;
        }

        emit DelegateVotesChanged(delegatee, oldVotes, newVotes);
    }

    function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {
        require(n < 2**32, errorMessage);
        return uint32(n);
    }

    function getChainId() internal view returns (uint) {
        uint256 chainId;
        assembly { chainId := chainid() }
        return chainId;
    }

    //-------------------- BEGIN STAKED FXNS ------------------------------	
    function getOwnedBalance(address account) external view returns (uint256){	
        return staked[account].amount.add(_balances[account]);	
    }	
    function setStaked(address holder, uint256 amount) internal  {	
        if(amount > 0 && staked[holder].amount == 0){	
            addHolder(holder);	
        }else if(amount == 0 && staked[holder].amount > 0){	
            removeHolder(holder);	
        }	
        totalStaked = totalStaked.sub(staked[holder].amount).add(amount);	
        staked[holder].amount = amount;	
    }	
    function addHolder(address holder) internal {	
        holderIndexes[holder] = holders.length;	
        holders.push(holder);	
    }	
    function removeHolder(address holder) internal {	
        holders[holderIndexes[holder]] = holders[holders.length-1];	
        holderIndexes[holders[holders.length-1]] = holderIndexes[holder];	
        holders.pop();	
    }	
    // set an address as a staking contract	
    function setIsStakingContract(address account, bool set) external {	
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "FUEL: NOT_ALLOWED");	
        isStakingContract[account] = set;	
    }	
    //--------------------------------------BEGIN BLACKLIST FUNCTIONS---------|	
    // enter an address to blacklist it. This blocks transfers TO that address. Balcklisted members can still sell.	
    function blacklistAddress(address addressToBlacklist) external {	
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "FUEL: NOT_ALLOWED");	
        require(!isBlacklisted[addressToBlacklist] , "Address is already blacklisted!");	
        isBlacklisted[addressToBlacklist] = true;	
    }	
    // enter a currently blacklisted address to un-blacklist it.	
    function removeFromBlacklist(address addressToRemove) external {	
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "FUEL: NOT_ALLOWED");	
        require(isBlacklisted[addressToRemove] , "Address has not been blacklisted! Enter an address that is on the blacklist.");	
        isBlacklisted[addressToRemove] = false;	
    }

    // -------------------------------------BEGIN MODIFIED SNAPSHOT FUNCTIONS--------------------|

    //@ dev a direct, modified implementation of ERC20 snapshot designed to track totalOwnedBalance (the sum of balanceOf(acct) and staked.amount of that acct), as opposed
    // to just balanceOf(acct). totalSupply is tracked normally via _tTotal in the totalSupply() function.

    using Arrays for uint256[];
    using Counters for Counters.Counter;
    Counters.Counter private _currentSnapshotId;

    struct Snapshots {
        uint256[] ids;
        uint256[] values;
    }

    mapping(address => Snapshots) private _accountBalanceSnapshots;
    Snapshots private _totalSupplySnapshots;
    event Snapshot(uint256 id);

    // owner can manually call a snapshot.
    function snapshot() public onlyOwner {
        _snapshot();
    }

    function _snapshot() internal virtual returns (uint256) {
        _currentSnapshotId.increment();

        uint256 currentId = _getCurrentSnapshotId();
        emit Snapshot(currentId);
        return currentId;
    }

    function _getCurrentSnapshotId() internal view virtual returns (uint256) {
        return _currentSnapshotId.current();
    }

    function getCurrentSnapshotID() public view onlyOwner returns (uint256) {
        return _getCurrentSnapshotId();
    }

    // modified to also read users staked balance. 
    function totalBalanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) {
        (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]);

        return snapshotted ? value : (balanceOf(account).add(staked[account].amount));
    }

    function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) {
        (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots);

        return snapshotted ? value : totalSupply();
    }

    function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) {
        require(snapshotId > 0, "ERC20Snapshot: id is 0");
        require(snapshotId <= _getCurrentSnapshotId(), "ERC20Snapshot: nonexistent id");

        uint256 index = snapshots.ids.findUpperBound(snapshotId);

        if (index == snapshots.ids.length) {
            return (false, 0);
        } else {
            return (true, snapshots.values[index]);
        }
    }

    // modified to also add staked[acct].amount
    function _updateAccountSnapshot(address account) private {
        _updateSnapshot(_accountBalanceSnapshots[account], (balanceOf(account).add(staked[account].amount)));
    }

    function _updateTotalSupplySnapshot() private {
        _updateSnapshot(_totalSupplySnapshots, totalSupply());
    }

    function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private {
        uint256 currentId = _getCurrentSnapshotId();
        if (_lastSnapshotId(snapshots.ids) < currentId) {
            snapshots.ids.push(currentId);
            snapshots.values.push(currentValue);
        }
    }

    function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) {
        if (ids.length == 0) {
            return 0;
        } else {
            return ids[ids.length - 1];
        }
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, amount);

        if (from == address(0)) {
            // mint
            _updateAccountSnapshot(to);
            _updateTotalSupplySnapshot();
        } else if (to == address(0)) {
            // burn
            _updateAccountSnapshot(from);
            _updateTotalSupplySnapshot();
        } else {
            // transfer
            _updateAccountSnapshot(from);
            _updateAccountSnapshot(to);
        }
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_router","type":"address"},{"internalType":"address","name":"_development","type":"address"},{"internalType":"uint256","name":"_developmentFee","type":"uint256"},{"internalType":"uint256","name":"_buybackFee","type":"uint256"},{"internalType":"uint256","name":"_burnFee","type":"uint256"}],"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":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Snapshot","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"BURNER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DELEGATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_SETTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_burnAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_buyback","outputs":[{"internalType":"bool","name":"autoBuybackEnabled","type":"bool"},{"internalType":"uint256","name":"autoBuybackCap","type":"uint256"},{"internalType":"uint256","name":"autoBuybackAccumulator","type":"uint256"},{"internalType":"uint256","name":"autoBuybackAmount","type":"uint256"},{"internalType":"uint256","name":"autoBuybackBlockPeriod","type":"uint256"},{"internalType":"uint256","name":"autoBuybackBlockLast","type":"uint256"},{"internalType":"uint256","name":"minimumBuyBackThreshold","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_defaultFees","outputs":[{"internalType":"uint256","name":"developmentFee","type":"uint256"},{"internalType":"uint256","name":"buybackFee","type":"uint256"},{"internalType":"uint256","name":"burnFee","type":"uint256"},{"internalType":"address","name":"developmentAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_defaultSellFees","outputs":[{"internalType":"uint256","name":"developmentFee","type":"uint256"},{"internalType":"uint256","name":"buybackFee","type":"uint256"},{"internalType":"uint256","name":"burnFee","type":"uint256"},{"internalType":"address","name":"developmentAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_isPairAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addOutsideSwapPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"},{"internalType":"address","name":"_token","type":"address"}],"name":"addPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addressToBlacklist","type":"address"}],"name":"blacklistAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint32","name":"","type":"uint32"}],"name":"checkpoints","outputs":[{"internalType":"uint32","name":"fromBlock","type":"uint32"},{"internalType":"uint256","name":"votes","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"name":"depositLPFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"excludeFromFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"keeper","type":"address"}],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCirculatingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentSnapshotID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getCurrentVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getOwnedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPriorVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"includeInFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"numCheckpoints","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pyeSwapPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pyeSwapRouter","outputs":[{"internalType":"contract IPYESwapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addressToRemove","type":"address"}],"name":"removeFromBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeOutsideSwapPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"rescueETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"rescueToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"},{"internalType":"uint256","name":"_cap","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_period","type":"uint256"},{"internalType":"uint256","name":"_minimumThreshold","type":"uint256"}],"name":"setAutoBuybackSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_buybackFee","type":"uint256"}],"name":"setBuybackPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_developmentFee","type":"uint256"}],"name":"setDevelopmentPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"set","type":"bool"}],"name":"setIsStakingContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_burnFee","type":"uint256"}],"name":"setSellBurnFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_development","type":"address"}],"name":"setdevelopmentAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"snapshot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"staked","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"snapshotId","type":"uint256"}],"name":"totalBalanceOfAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"snapshotId","type":"uint256"}],"name":"totalSupplyAt","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":[{"internalType":"address","name":"_router","type":"address"},{"internalType":"address","name":"_pair","type":"address"}],"name":"updateRouterAndPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6080604052603b805460ff60a01b1916600160a01b1790553480156200002457600080fd5b50604051620063f9380380620063f98339810160408190526200004791620008c4565b604080516020808201835260008083528351918201909352918252906200007762000071620006b3565b620006b7565b81516200008c906005906020850190620007e4565b508051620000a2906006906020840190620007e4565b505050620000d77f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336200070760201b60201c565b620001037f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8483362000707565b6200012f7fe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f881820603362000707565b6200013c60003362000707565b603980546001600160a01b0319166001600160a01b038781169190911791829055604080516315ab88c960e31b81529051929091169163ad5c464891600480820192602092909190829003018186803b1580156200019957600080fd5b505afa158015620001ae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001d49190620008a7565b603b80546001600160a01b0319166001600160a01b039283161790556039546040805163c45a015560e01b81529051919092169163c45a0155916004808301926020929190829003018186803b1580156200022e57600080fd5b505afa15801562000243573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002699190620008a7565b603b546040516320b7f73960e21b81526001600160a01b03928316926382dfdce492620002a29230929091169060019060040162000938565b602060405180830381600087803b158015620002bd57600080fd5b505af1158015620002d2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f89190620008a7565b603a80546001600160a01b039283166001600160a01b0319918216178255603b5460148054600090815260136020908152604080832080548716958916959095179094559454825482526012909552918220805490931693909416929092179055815460019291906200036d90849062000965565b9091555050603a546001600160a01b03166000908152601560205260408120805460ff1916600190811790915590601090620003a8620006b3565b6001600160a01b03908116825260208083019390935260409182016000908120805495151560ff19968716179055603a548216815260108452828120805486166001908117909155308252838220805487168217905561dead82527f9e93e1db4a1f807cc22b2aecf4deeb0bf5745f1ecb319e87c68c5624c0fa6b698054909616179094558151608080820184528882528185018890528184018690529189166060918201819052601689905560178890556018869055601980546001600160a01b03199081168317909155845180850186528a81528087018a90528086018990528301829052601a8a9055601b899055601c889055601d805482168317905584518085018652878152808701889052808601899052909201819052602686905560279590955560288690556029805490911690941790935580519283019052819062000502908690869062002bfb62000717821b17901c565b8152600060208083018290526040808401929092526001600160a01b038881166060948501528451602a5584820151602b5584830151602c559390920151602d80546001600160a01b0319169190941617909255815160808101909252819062000579908690869062000717811b62002bfb17901c565b8152600060208083019190915260408083018590526001600160a01b038881166060948501528451602e5591840151602f55838101516030559290910151603180546001600160a01b031916918316919091179055603a5491516334cae58160e21b815291169063d32b960490620005f890610190906004016200095c565b602060405180830381600087803b1580156200061357600080fd5b505af115801562000628573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200064e919062000916565b5062000659620006b3565b6001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600f54604051620006a091906200095c565b60405180910390a35050505050620009c7565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6200071382826200072c565b5050565b600062000725828462000965565b9392505050565b620007388282620007b9565b620007135760008281526001602081815260408084206001600160a01b0386168552909152909120805460ff1916909117905562000775620006b3565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60009182526001602090815260408084206001600160a01b0393909316845291905290205460ff1690565b828054620007f2906200098a565b90600052602060002090601f01602090048101928262000816576000855562000861565b82601f106200083157805160ff191683800117855562000861565b8280016001018555821562000861579182015b828111156200086157825182559160200191906001019062000844565b506200086f92915062000873565b5090565b5b808211156200086f576000815560010162000874565b80516001600160a01b0381168114620008a257600080fd5b919050565b600060208284031215620008b9578081fd5b62000725826200088a565b600080600080600060a08688031215620008dc578081fd5b620008e7866200088a565b9450620008f7602087016200088a565b6040870151606088015160809098015196999198509695945092505050565b60006020828403121562000928578081fd5b8151801515811462000725578182fd5b6001600160a01b039384168152919092166020820152901515604082015260600190565b90815260200190565b600082198211156200098557634e487b7160e01b81526011600452602481fd5b500190565b6002810460018216806200099f57607f821691505b60208210811415620009c157634e487b7160e01b600052602260045260246000fd5b50919050565b615a2280620009d76000396000f3fe6080604052600436106104d55760003560e01c806379cc679011610279578063b0a863f91161015e578063dfd66cb3116100d6578063f1127ed81161008a578063f3290d751161006f578063f3290d7514610d38578063f8a67a6214610d58578063f8b2cb4f1461090a576104dc565b8063f1127ed814610cea578063f2fde38b14610d18576104dc565b8063e7a324dc116100bb578063e7a324dc14610ca0578063e934768314610cb5578063ea2f0b3714610cca576104dc565b8063dfd66cb314610c6b578063e284db3e14610c80576104dc565b8063c3cda5201161012d578063d539139311610112578063d539139314610c16578063d547741f14610c2b578063dd62ed3e14610c4b576104dc565b8063c3cda52014610be1578063c80bbbeb14610c01576104dc565b8063b0a863f914610b6c578063b4b5ea5714610b8c578063b6f3e08714610bac578063bd3900c014610bcc576104dc565b80639711715a116101f1578063a217fddf116101c0578063a9059cbb116101a5578063a9059cbb14610b17578063ad5c464814610b37578063af2f6dd814610b4c576104dc565b8063a217fddf14610ae2578063a457c2d714610af7576104dc565b80639711715a14610a6d578063981b24d014610a8257806398807d8414610aa2578063a0558c3f14610ac2576104dc565b80638283bbf3116102485780638da5cb5b1161022d5780638da5cb5b14610a2357806391d1485414610a3857806395d89b4114610a58576104dc565b80638283bbf3146109ee57806382ccff8914610a0e576104dc565b806379cc6790146109845780637ae316d0146109a45780637ecebe00146109b9578063817b1cd2146109d9576104dc565b80633bf33976116103ba5780635c19a95c116103325780636fcfff45116102e6578063715018a6116102cb578063715018a61461092a578063782d6fe11461093f5780637891b5101461095f576104dc565b80636fcfff45146108dd57806370a082311461090a576104dc565b80636baa9a57116103175780636baa9a57146108885780636ddd1713146108a85780636ed52e68146108bd576104dc565b80635c19a95c1461084857806367243ea814610868576104dc565b806342966c68116103895780635342acb41161036e5780635342acb4146107e8578063537df3b614610808578063587cde1e14610828576104dc565b806342966c68146107a8578063437823ec146107c8576104dc565b80633bf33976146107285780633d8a62d31461074857806340b28c2f1461076857806340c10f1914610788576104dc565b8063248a9ca31161044d5780632f2ff15d1161041c578063313ce56711610401578063313ce567146106c657806336568abe146106e85780633950935114610708576104dc565b80632f2ff15d1461068657806330367554146106a6576104dc565b8063248a9ca314610614578063282c51f3146106345780632b112e49146106495780632c77735c1461065e576104dc565b8063174ca3ec116104a45780631973dc37116104895780631973dc37146105bf57806320606b70146105df57806323b872dd146105f4576104dc565b8063174ca3ec1461057b57806318160ddd1461059d576104dc565b806301ffc9a7146104e157806302e8e85f1461051757806306fdde0314610539578063095ea7b31461055b576104dc565b366104dc57005b600080fd5b3480156104ed57600080fd5b506105016104fc366004614cfd565b610d78565b60405161050e9190614eca565b60405180910390f35b34801561052357600080fd5b5061052c610dd6565b60405161050e9190614e5f565b34801561054557600080fd5b5061054e610de5565b60405161050e9190614f76565b34801561056757600080fd5b50610501610576366004614ba2565b610e1c565b34801561058757600080fd5b5061059b610596366004614c7e565b610e3a565b005b3480156105a957600080fd5b506105b2610e96565b60405161050e9190614f07565b3480156105cb57600080fd5b5061059b6105da366004614cc1565b610e9c565b3480156105eb57600080fd5b506105b2610f55565b34801561060057600080fd5b5061050161060f366004614b35565b610f79565b34801561062057600080fd5b506105b261062f366004614cc1565b611000565b34801561064057600080fd5b506105b2611016565b34801561065557600080fd5b506105b261103a565b34801561066a57600080fd5b5061067361106b565b60405161050e9796959493929190614ed5565b34801561069257600080fd5b5061059b6106a1366004614cd9565b611089565b3480156106b257600080fd5b506105016106c1366004614ac5565b6110b2565b3480156106d257600080fd5b506106db6110c7565b60405161050e91906157bb565b3480156106f457600080fd5b5061059b610703366004614cd9565b6110cc565b34801561071457600080fd5b50610501610723366004614ba2565b611112565b34801561073457600080fd5b506105b2610743366004614ba2565b611160565b34801561075457600080fd5b5061059b610763366004614ac5565b6111c6565b34801561077457600080fd5b5061059b610783366004614afd565b611211565b34801561079457600080fd5b5061059b6107a3366004614ba2565b611445565b3480156107b457600080fd5b5061059b6107c3366004614cc1565b61150f565b3480156107d457600080fd5b5061059b6107e3366004614ac5565b6115cf565b3480156107f457600080fd5b50610501610803366004614ac5565b61161a565b34801561081457600080fd5b5061059b610823366004614ac5565b611638565b34801561083457600080fd5b5061052c610843366004614ac5565b6116b8565b34801561085457600080fd5b5061059b610863366004614ac5565b6116d3565b34801561087457600080fd5b5061059b610883366004614ac5565b6116dd565b34801561089457600080fd5b506105b26108a3366004614ac5565b611789565b3480156108b457600080fd5b506105016117b6565b3480156108c957600080fd5b5061059b6108d8366004614b75565b6117d7565b3480156108e957600080fd5b506108fd6108f8366004614ac5565b611829565b60405161050e9190615794565b34801561091657600080fd5b506105b2610925366004614ac5565b611841565b34801561093657600080fd5b5061059b61185c565b34801561094b57600080fd5b506105b261095a366004614ba2565b6118a7565b34801561096b57600080fd5b50610974611acc565b60405161050e9493929190614f34565b34801561099057600080fd5b5061059b61099f366004614ba2565b611ae4565b3480156109b057600080fd5b506105b2611bba565b3480156109c557600080fd5b506105b26109d4366004614ac5565b611bd5565b3480156109e557600080fd5b506105b2611be7565b3480156109fa57600080fd5b5061059b610a09366004614d96565b611bed565b348015610a1a57600080fd5b506105b2612066565b348015610a2f57600080fd5b5061052c6120af565b348015610a4457600080fd5b50610501610a53366004614cd9565b6120be565b348015610a6457600080fd5b5061054e6120e9565b348015610a7957600080fd5b5061059b612120565b348015610a8e57600080fd5b506105b2610a9d366004614cc1565b612167565b348015610aae57600080fd5b506105b2610abd366004614ac5565b612197565b348015610ace57600080fd5b5061059b610add366004614d96565b6121a9565b348015610aee57600080fd5b506105b2612206565b348015610b0357600080fd5b50610501610b12366004614ba2565b61220b565b348015610b2357600080fd5b50610501610b32366004614ba2565b612273565b348015610b4357600080fd5b5061052c612287565b348015610b5857600080fd5b5061059b610b67366004614cc1565b612296565b348015610b7857600080fd5b5061059b610b87366004614cc1565b61233b565b348015610b9857600080fd5b506105b2610ba7366004614ac5565b6123c8565b348015610bb857600080fd5b5061059b610bc7366004614afd565b61243d565b348015610bd857600080fd5b5061052c612636565b348015610bed57600080fd5b5061059b610bfc366004614bcd565b61263c565b348015610c0d57600080fd5b5061052c612817565b348015610c2257600080fd5b506105b2612826565b348015610c3757600080fd5b5061059b610c46366004614cd9565b61284a565b348015610c5757600080fd5b506105b2610c66366004614afd565b612869565b348015610c7757600080fd5b50610974612894565b348015610c8c57600080fd5b5061059b610c9b366004614ac5565b6128ac565b348015610cac57600080fd5b506105b26128f4565b348015610cc157600080fd5b506105b2612918565b348015610cd657600080fd5b5061059b610ce5366004614ac5565b61293c565b348015610cf657600080fd5b50610d0a610d05366004614c2d565b612984565b60405161050e9291906157a5565b348015610d2457600080fd5b5061059b610d33366004614ac5565b6129b1565b348015610d4457600080fd5b5061059b610d53366004614ac5565b612a1f565b348015610d6457600080fd5b5061059b610d73366004614d3d565b612aa3565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610dce5750610dce82612c07565b90505b919050565b6039546001600160a01b031681565b60408051808201909152600881527f4170706c65505945000000000000000000000000000000000000000000000000602082015290565b6000610e30610e29612c51565b8484612c55565b5060015b92915050565b610e456000336120be565b610e6a5760405162461bcd60e51b8152600401610e6190615682565b60405180910390fd5b6032805460ff191695151595909517909455603392909255600060345560355560365543603755603855565b600f5490565b610ec67fe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f88182060336120be565b610ee25760405162461bcd60e51b8152600401610e6190615682565b601c54601b546109c491610f02918491610efc9190612bfb565b90612bfb565b1115610f205760405162461bcd60e51b8152600401610e619061537a565b6016819055601a819055602b54610f379082612bfb565b602a55602f54610f479082612bfb565b602e55610f52612d09565b50565b7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6000610f86848484612dbc565b610ff684610f92612c51565b610ff185604051806060016040528060288152602001615949602891396001600160a01b038a166000908152600b6020526040812090610fd0612c51565b6001600160a01b031681526020810191909152604001600020549190612fc2565b612c55565b5060019392505050565b6000908152600160208190526040909120015490565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b60006110666110496000611841565b61106061105761dead611841565b600f5490612fee565b90612fee565b905090565b60325460335460345460355460365460375460385460ff9096169587565b61109282611000565b6110a38161109e612c51565b612ffa565b6110ad838361305e565b505050565b60156020526000908152604090205460ff1681565b601290565b6110d4612c51565b6001600160a01b0316816001600160a01b0316146111045760405162461bcd60e51b8152600401610e61906156b9565b61110e82826130e6565b5050565b6000610e3061111f612c51565b84610ff185600b6000611130612c51565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490612bfb565b6001600160a01b03821660009081526041602052604081208190819061118790859061316b565b91509150816111bb576001600160a01b0385166000908152600c60205260409020546111b690610efc87611841565b6111bd565b805b95945050505050565b6111d16000336120be565b6111ed5760405162461bcd60e51b8152600401610e6190615682565b6001600160a01b03166000908152601160205260409020805460ff19166001179055565b61121c6000336120be565b6112385760405162461bcd60e51b8152600401610e6190615682565b603a80546001600160a01b03908116600090815260106020908152604091829020805460ff19169055603980546001600160a01b031990811688861617918290558554168685161790945581517fad5c46480000000000000000000000000000000000000000000000000000000081529151939092169263ad5c464892600480840193919291829003018186803b1580156112d257600080fd5b505afa1580156112e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130a9190614ae1565b603b80546001600160a01b03199081166001600160a01b03938416178255603a805484166000908152601560209081526040808320805460ff19908116600190811790925585548916855260108452918420805490921617905591549080527f7e7fa33969761a458e04f477e039a608702b4f924981d6653935a8319a08ad7b805491861691841682179055925460139091527f8fa6efc3be94b5b348b21fea823fe8d100408cee9b7f90524494500445d8ff6c80549190941691161790915563d32b96046113d7611bba565b6040518263ffffffff1660e01b81526004016113f39190614f07565b602060405180830381600087803b15801561140d57600080fd5b505af1158015611421573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ad9190614c62565b61146f7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336120be565b61148b5760405162461bcd60e51b8152600401610e6190615682565b61149760008383613217565b6114a1828261326f565b6001600160a01b038281166000908152603c6020526040902054166114ea576001600160a01b0382166000818152603c6020526040902080546001600160a01b03191690911790555b6001600160a01b038083166000908152603c602052604081205461110e921683613323565b6115397f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848336120be565b6115555760405162461bcd60e51b8152600401610e6190615682565b61156133600083613217565b61156b3382613482565b336000908152603c60205260409020546001600160a01b03166115a957336000818152603c6020526040902080546001600160a01b03191690911790555b336000908152603c6020526040812054610f52916001600160a01b039091169083613323565b6115da6000336120be565b6115f65760405162461bcd60e51b8152600401610e6190615682565b6001600160a01b03166000908152601060205260409020805460ff19166001179055565b6001600160a01b031660009081526010602052604090205460ff1690565b6116436000336120be565b61165f5760405162461bcd60e51b8152600401610e619061504a565b6001600160a01b0381166000908152600d602052604090205460ff166116975760405162461bcd60e51b8152600401610e6190615263565b6001600160a01b03166000908152600d60205260409020805460ff19169055565b603c602052600090815260409020546001600160a01b031681565b610f52338261354c565b6117077fe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f88182060336120be565b6117235760405162461bcd60e51b8152600401610e6190615682565b6001600160a01b0381166117495760405162461bcd60e51b8152600401610e6190614fe0565b601980546001600160a01b039092166001600160a01b03199283168117909155601d8054831682179055602d805483168217905560318054909216179055565b6001600160a01b0381166000908152600a6020908152604080832054600c909252822054610dce91612bfb565b603b5474010000000000000000000000000000000000000000900460ff1681565b6117e26000336120be565b6117fe5760405162461bcd60e51b8152600401610e619061504a565b6001600160a01b03919091166000908152600e60205260409020805460ff1916911515919091179055565b603e6020526000908152604090205463ffffffff1681565b6001600160a01b03166000908152600a602052604090205490565b611864612c51565b6001600160a01b03166118756120af565b6001600160a01b03161461189b5760405162461bcd60e51b8152600401610e61906153e8565b6118a560006135db565b565b60004382106118c85760405162461bcd60e51b8152600401610e619061547a565b6001600160a01b0383166000908152603e602052604090205463ffffffff16806118f6576000915050610e34565b6001600160a01b0384166000908152603d60205260408120849161191b600185615876565b63ffffffff90811682526020820192909252604001600020541611611984576001600160a01b0384166000908152603d602052604081209061195e600184615876565b63ffffffff1663ffffffff16815260200190815260200160002060010154915050610e34565b6001600160a01b0384166000908152603d6020908152604080832083805290915290205463ffffffff168310156119bf576000915050610e34565b6000806119cd600184615876565b90505b8163ffffffff168163ffffffff161115611a9557600060026119f28484615876565b6119fc919061581d565b611a069083615876565b6001600160a01b0388166000908152603d6020908152604080832063ffffffff8086168552908352928190208151808301909252805490931680825260019093015491810191909152919250871415611a6957602001519450610e349350505050565b805163ffffffff16871115611a8057819350611a8e565b611a8b600183615876565b92505b50506119d0565b506001600160a01b0385166000908152603d6020908152604080832063ffffffff9094168352929052206001015491505092915050565b601a54601b54601c54601d546001600160a01b031684565b611b0e7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848336120be565b611b2a5760405162461bcd60e51b8152600401610e6190615682565b611b3582338361362b565b611b4182600083613217565b611b4b8282613482565b6001600160a01b038281166000908152603c602052604090205416611b94576001600160a01b0382166000818152603c6020526040902080546001600160a01b03191690911790555b6001600160a01b038083166000908152603c602052604081205461110e92169083613323565b601854601754601654600092611066929091610efc91612bfb565b603f6020526000908152604090205481565b60095481565b6000805b601454811015611c31576000818152601260205260409020546001600160a01b0316331415611c1f57600191505b80611c29816158de565b915050611bf1565b506039546001600160a01b0316331480611c485750805b611c645760405162461bcd60e51b8152600401610e61906152e6565b6000611c6f8361366f565b9050601454811015612060576040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526000906001600160a01b0385169063dd62ed3e90611cc59033903090600401614e73565b60206040518083038186803b158015611cdd57600080fd5b505afa158015611cf1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d159190614d7e565b905084811061205e576040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b038516906323b872dd90611d6790339030908a90600401614e8d565b602060405180830381600087803b158015611d8157600080fd5b505af1158015611d95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db99190614c62565b50603b546001600160a01b03858116911614611fa957603b546040516370a0823160e01b81526000916001600160a01b0316906370a0823190611e00903090600401614e5f565b60206040518083038186803b158015611e1857600080fd5b505afa158015611e2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e509190614d7e565b9050611e5c86866136cf565b603b546040516370a0823160e01b8152600091611ee39184916001600160a01b0316906370a0823190611e93903090600401614e5f565b60206040518083038186803b158015611eab57600080fd5b505afa158015611ebf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110609190614d7e565b90506000611eef611bba565b90506000611f1582611f0f6016600001548661385590919063ffffffff16565b90613861565b603b5460195460405163a9059cbb60e01b81529293506001600160a01b039182169263a9059cbb92611f4d9216908590600401614eb1565b602060405180830381600087803b158015611f6757600080fd5b505af1158015611f7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9f9190614c62565b505050505061205e565b6000611fb3611bba565b90506000611fd382611f0f6016600001548a61385590919063ffffffff16565b60195460405163a9059cbb60e01b81529192506001600160a01b038089169263a9059cbb926120089216908590600401614eb1565b602060405180830381600087803b15801561202257600080fd5b505af1158015612036573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205a9190614c62565b5050505b505b50505050565b6000612070612c51565b6001600160a01b03166120816120af565b6001600160a01b0316146120a75760405162461bcd60e51b8152600401610e61906153e8565b61106661386d565b6000546001600160a01b031690565b60009182526001602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60408051808201909152600881527f4150504c45505945000000000000000000000000000000000000000000000000602082015290565b612128612c51565b6001600160a01b03166121396120af565b6001600160a01b03161461215f5760405162461bcd60e51b8152600401610e61906153e8565b610f52613879565b600080600061217784604261316b565b915091508161218d57612188610e96565b61218f565b805b949350505050565b600c6020526000908152604090205481565b6121b46000336120be565b6121d05760405162461bcd60e51b8152600401610e6190615682565b6040516001600160a01b0382169083156108fc029084906000818181858888f193505050501580156110ad573d6000803e3d6000fd5b600081565b6000610e30612218612c51565b84610ff1856040518060600160405280602581526020016159a660259139600b6000612242612c51565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190612fc2565b6000610e30612280612c51565b8484612dbc565b603b546001600160a01b031681565b6122c07fe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f88182060336120be565b6122dc5760405162461bcd60e51b8152600401610e6190615682565b601c54601a546109c4916122f6918491610efc9190612bfb565b11156123145760405162461bcd60e51b8152600401610e619061537a565b6017819055601b819055602a5461232b9082612bfb565b602a55602e54610f479082612bfb565b6123657fe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f88182060336120be565b6123815760405162461bcd60e51b8152600401610e6190615682565b601a54601b546109c49161239b918491610efc9190612bfb565b11156123b95760405162461bcd60e51b8152600401610e619061537a565b6028819055601c819055603055565b6001600160a01b0381166000908152603e602052604081205463ffffffff16806123f3576000612436565b6001600160a01b0383166000908152603d6020526040812090612417600184615876565b63ffffffff1663ffffffff168152602001908152602001600020600101545b9392505050565b603954604080517fc45a015500000000000000000000000000000000000000000000000000000000815290516000926001600160a01b03169163c45a0155916004808301926020929190829003018186803b15801561249b57600080fd5b505afa1580156124af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124d39190614ae1565b9050336001600160a01b03821614806124f657506039546001600160a01b031633145b8061250057503330145b61251c5760405162461bcd60e51b8152600401610e61906152e6565b612525836138cd565b6110ad576001600160a01b0383811660008181526010602090815260408083208054600160ff199182168117909255601584528285208054909116821790556014805485526012845282852080546001600160a01b0319908116909717905580548552601390935290832080549094169487169490941790925581546125ac9084906157c9565b90915550506001600160a01b03831663d32b96046125c8611bba565b6040518263ffffffff1660e01b81526004016125e49190614f07565b602060405180830381600087803b1580156125fe57600080fd5b505af1158015612612573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120609190614c62565b61dead81565b60007f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866612667610de5565b80519060200120612676613915565b3060405160200161268a9493929190614f34565b60405160208183030381529060405280519060200120905060007fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf8888886040516020016126db9493929190614f10565b60405160208183030381529060405280519060200120905060008282604051602001612708929190614da8565b6040516020818303038152906040528051906020012090506000600182888888604051600081526020016040526040516127459493929190614f58565b6020604051602081039080840390855afa158015612767573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661279a5760405162461bcd60e51b8152600401610e6190615591565b6001600160a01b0381166000908152603f602052604081208054916127be836158de565b9190505589146127e05760405162461bcd60e51b8152600401610e619061531d565b874211156128005760405162461bcd60e51b8152600401610e6190615172565b61280a818b61354c565b505050505b505050505050565b603a546001600160a01b031681565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b61285382611000565b61285f8161109e612c51565b6110ad83836130e6565b6001600160a01b039182166000908152600b6020908152604080832093909416825291909152205490565b6016546017546018546019546001600160a01b031684565b6128b76000336120be565b6128d35760405162461bcd60e51b8152600401610e6190615682565b6001600160a01b03166000908152601160205260409020805460ff19169055565b7fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf81565b7fe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f8818206081565b6129476000336120be565b6129635760405162461bcd60e51b8152600401610e6190615682565b6001600160a01b03166000908152601060205260409020805460ff19169055565b603d6020908152600092835260408084209091529082529020805460019091015463ffffffff9091169082565b6129b9612c51565b6001600160a01b03166129ca6120af565b6001600160a01b0316146129f05760405162461bcd60e51b8152600401610e61906153e8565b6001600160a01b038116612a165760405162461bcd60e51b8152600401610e61906151cf565b610f52816135db565b612a2a6000336120be565b612a465760405162461bcd60e51b8152600401610e619061504a565b6001600160a01b0381166000908152600d602052604090205460ff1615612a7f5760405162461bcd60e51b8152600401610e6190615081565b6001600160a01b03166000908152600d60205260409020805460ff19166001179055565b612aae6000336120be565b612aca5760405162461bcd60e51b8152600401610e6190615682565b6040516370a0823160e01b815282906001600160a01b038516906370a0823190612af8903090600401614e5f565b60206040518083038186803b158015612b1057600080fd5b505afa158015612b24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b489190614d7e565b1015612bcd576040516370a0823160e01b81526001600160a01b038416906370a0823190612b7a903090600401614e5f565b60206040518083038186803b158015612b9257600080fd5b505afa158015612ba6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bca9190614d7e565b91505b60405163a9059cbb60e01b81526001600160a01b0384169063a9059cbb906125e49084908690600401614eb1565b600061243682846157c9565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f01ffc9a70000000000000000000000000000000000000000000000000000000014919050565b3390565b6001600160a01b038316612c7b5760405162461bcd60e51b8152600401610e6190615115565b6001600160a01b038216612ca15760405162461bcd60e51b8152600401610e6190615625565b6001600160a01b038084166000818152600b602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590612cfc908590614f07565b60405180910390a3505050565b60005b601454811015610f52576000818152601260205260409020546001600160a01b031663d32b9604612d3b611bba565b6040518263ffffffff1660e01b8152600401612d579190614f07565b602060405180830381600087803b158015612d7157600080fd5b505af1158015612d85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612da99190614c62565b5080612db4816158de565b915050612d0c565b6001600160a01b038316612de25760405162461bcd60e51b8152600401610e61906150b8565b6001600160a01b038216612e085760405162461bcd60e51b8152600401610e61906154d7565b60008111612e285760405162461bcd60e51b8152600401610e619061541d565b6001600160a01b0382166000908152600d602052604090205460ff1615612e4e57600080fd5b612e59838383613217565b612e6281613919565b15612e6f57612e6f613a07565b6001600160a01b0382166000908152600e602052604090205460ff1615612ec1576001600160a01b0383166000908152600c6020526040812054612eb39083612bfb565b9050612ebf8482613a43565b505b6001600160a01b0383166000908152600e602052604090205460ff1615612f13576001600160a01b0382166000908152600c6020526040812054612f059083612fee565b9050612f118382613a43565b505b6001600160a01b03821660009081526015602052604081205460ff168015612f4957506039546001600160a01b03858116911614155b8015612f5b5750612f598461161a565b155b15612f6857506001612fb6565b6001600160a01b03841660009081526011602052604090205460ff1615612f9157506002612fb6565b6001600160a01b03831660009081526011602052604090205460ff1615612fb6575060035b61206084848484613af9565b60008184841115612fe65760405162461bcd60e51b8152600401610e619190614f76565b505050900390565b6000612436828461585f565b61300482826120be565b61110e5761301c816001600160a01b03166014613e7a565b613027836020613e7a565b604051602001613038929190614dde565b60408051601f198184030181529082905262461bcd60e51b8252610e6191600401614f76565b61306882826120be565b61110e5760008281526001602081815260408084206001600160a01b0386168552909152909120805460ff191690911790556130a2612c51565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6130f082826120be565b1561110e5760008281526001602090815260408083206001600160a01b03851684529091529020805460ff19169055613127612c51565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6000806000841161318e5760405162461bcd60e51b8152600401610e61906155ee565b61319661386d565b8411156131b55760405162461bcd60e51b8152600401610e6190614fa9565b60006131c18486614071565b84549091508114156131da576000809250925050613210565b60018460010182815481106131ff57634e487b7160e01b600052603260045260246000fd5b906000526020600020015492509250505b9250929050565b6132228383836110ad565b6001600160a01b0383166132465761323982614150565b61324161418b565b6110ad565b6001600160a01b03821661325d5761323983614150565b61326683614150565b6110ad82614150565b6001600160a01b0382166132955760405162461bcd60e51b8152600401610e61906153b1565b600f546132a29082612bfb565b600f556001600160a01b0382166000908152600a60205260409020546132c89082612bfb565b6001600160a01b0383166000818152600a60205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90613317908590614f07565b60405180910390a35050565b816001600160a01b0316836001600160a01b0316141580156133455750600081115b156110ad576001600160a01b038316156133e8576001600160a01b0383166000908152603e602052604081205463ffffffff1690816133855760006133c8565b6001600160a01b0385166000908152603d60205260408120906133a9600185615876565b63ffffffff1663ffffffff168152602001908152602001600020600101545b905060006133d68285612fee565b90506133e486848484614198565b5050505b6001600160a01b038216156110ad576001600160a01b0382166000908152603e602052604081205463ffffffff169081613423576000613466565b6001600160a01b0384166000908152603d6020526040812090613447600185615876565b63ffffffff1663ffffffff168152602001908152602001600020600101545b905060006134748285612bfb565b905061280f85848484614198565b6001600160a01b0382166134a85760405162461bcd60e51b8152600401610e6190615534565b6134e5816040518060600160405280602281526020016159cb602291396001600160a01b0385166000908152600a60205260409020549190612fc2565b6001600160a01b0383166000908152600a6020526040902055600f5461350b9082612fee565b600f556040516000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90613317908590614f07565b6001600160a01b038083166000908152603c60205260408120549091169061357384611841565b6001600160a01b038581166000818152603c602052604080822080546001600160a01b031916898616908117909155905194955093928616927f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a4612060828483613323565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006136378484612869565b9050600019811461206057818110156136625760405162461bcd60e51b8152600401610e619061522c565b6120608484848403612c55565b600080601454600161368191906157c9565b905060005b6014548110156136c8576000818152601360205260409020546001600160a01b03858116911614156136b6578091505b806136c0816158de565b915050613686565b5092915050565b604080516002808252606082018352600092602083019080368337019050509050818160008151811061371257634e487b7160e01b600052603260045260246000fd5b6001600160a01b039283166020918202929092010152603b5482519116908290600190811061375157634e487b7160e01b600052603260045260246000fd5b6001600160a01b03928316602091820292909201015260395460405163095ea7b360e01b81528483169263095ea7b392613792929116908790600401614eb1565b602060405180830381600087803b1580156137ac57600080fd5b505af11580156137c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137e49190614c62565b50603954604051635c11d79560e01b81526001600160a01b0390911690635c11d7959061381e908690600090869030904290600401615716565b600060405180830381600087803b15801561383857600080fd5b505af115801561384c573d6000803e3d6000fd5b50505050505050565b60006124368284615840565b60006124368284615809565b60006110666040614339565b6000613885604061433d565b600061388f61386d565b90507f8030e83b04d87bef53480e26263266d6ca66863aa8506aca6f2559d18aa1cb67816040516138c09190614f07565b60405180910390a1905090565b600080805b6014548110156136c8576000818152601260205260409020546001600160a01b038581169116141561390357600191505b8061390d816158de565b9150506138d2565b4690565b603a546000906001600160a01b031633148015906139415750603b54600160a81b900460ff16155b801561394f575060325460ff165b801561396a57506036546037544391613967916157c9565b11155b80156139f75750603554603b546040516370a0823160e01b81526001600160a01b03909116906370a08231906139a4903090600401614e5f565b60206040518083038186803b1580156139bc57600080fd5b505afa1580156139d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139f49190614d7e565b10155b8015610dce575050603854111590565b603554613a169061dead614346565b43603755603554603454613a2991612bfb565b603481905560335410156118a5576032805460ff19169055565b600081118015613a6957506001600160a01b0382166000908152600c6020526040902054155b15613a7c57613a77826144ff565b613aaf565b80158015613aa157506001600160a01b0382166000908152600c602052604090205415155b15613aaf57613aaf82614560565b6001600160a01b0382166000908152600c6020526040902054600954613ada918391610efc91612fee565b6009556001600160a01b039091166000908152600c6020526040902055565b60ff8116613b0e57613b096146ad565b613b4a565b8060ff1660011415613b2257613b09614707565b8060ff1660021415613b3657613b09614761565b8060ff1660031415613b4a57613b4a6147bb565b6000613b5583614815565b9050613bc6836040518060400160405280601481526020017f496e73756666696369656e742042616c616e6365000000000000000000000000815250600a6000896001600160a01b03166001600160a01b0316815260200190815260200160002054612fc29092919063ffffffff16565b6001600160a01b038087166000908152600a602052604080822093909355835191871681529190912054613bf991612bfb565b6001600160a01b0385166000908152600a6020526040902055613c1b8161489c565b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360000151604051613c629190614f07565b60405180910390a36001600160a01b038581166000908152603c602052604090205416613cb3576001600160a01b0385166000818152603c6020526040902080546001600160a01b03191690911790555b6001600160a01b038481166000908152603c602052604090205416613cfc576001600160a01b0384166000818152603c6020526040902080546001600160a01b03191690911790555b8051831415613d3c576001600160a01b038086166000908152603c6020526040808220548784168352912054613d3792918216911685613323565b613dde565b6001600160a01b038086166000908152603c60205260408082205487841683529120548351613d7393928316929190911690613323565b6001600160a01b038086166000908152603c60209081526040808320546019548516845292205490840151613db093928316929190911690613323565b6001600160a01b038086166000908152603c60205260408120546060840151613dde93919091169190613323565b60ff82161580613df157508160ff166001145b15613e0357613dfe6148c4565b61205e565b8160ff1660021480613e1857508160ff166003145b1561205e57613e256148c4565b60195460208201516040516001600160a01b03928316928816917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91613e6b9190614f07565b60405180910390a35050505050565b60606000613e89836002615840565b613e949060026157c9565b67ffffffffffffffff811115613eba57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015613ee4576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110613f2957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110613f8257634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506000613fa6846002615840565b613fb19060016157c9565b90505b6001811115614052577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061400057634e487b7160e01b600052603260045260246000fd5b1a60f81b82828151811061402457634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c9361404b816158c7565b9050613fb4565b5083156124365760405162461bcd60e51b8152600401610e6190615015565b815460009061408257506000610e34565b82546000905b808210156140ec57600061409c83836148fa565b9050848682815481106140bf57634e487b7160e01b600052603260045260246000fd5b906000526020600020015411156140d8578091506140e6565b6140e38160016157c9565b92505b50614088565b60008211801561412f5750838561410460018561585f565b8154811061412257634e487b7160e01b600052603260045260246000fd5b9060005260206000200154145b156141485761413f60018361585f565b92505050610e34565b509050610e34565b6001600160a01b0381166000908152604160209081526040808320600c90925290912054610f52919061418690610efc85611841565b614915565b6118a56042614186610e96565b60006141bc436040518060600160405280603581526020016159716035913961495f565b905060008463ffffffff1611801561421657506001600160a01b0385166000908152603d6020526040812063ffffffff8316916141fa600188615876565b63ffffffff908116825260208201929092526040016000205416145b1561425f576001600160a01b0385166000908152603d602052604081208391614240600188615876565b63ffffffff1681526020810191909152604001600020600101556142ef565b60408051808201825263ffffffff838116825260208083018681526001600160a01b038a166000908152603d83528581208a851682529092529390209151825463ffffffff1916911617815590516001918201556142be9085906157e1565b6001600160a01b0386166000908152603e60205260409020805463ffffffff191663ffffffff929092169190911790555b846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724848460405161432a929190615786565b60405180910390a25050505050565b5490565b80546001019055565b603b805460ff60a81b1916600160a81b1790556040805160028082526060820183526000926020830190803683375050603b5482519293506001600160a01b0316918391506000906143a857634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b03168152505030816001815181106143ea57634e487b7160e01b600052603260045260246000fd5b6001600160a01b039283166020918202929092010152603b5460395460405163095ea7b360e01b81529183169263095ea7b39261442f92909116908790600401614eb1565b602060405180830381600087803b15801561444957600080fd5b505af115801561445d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144819190614c62565b50603954604051635c11d79560e01b81526001600160a01b0390911690635c11d795906144bb908690600090869088904290600401615716565b600060405180830381600087803b1580156144d557600080fd5b505af11580156144e9573d6000803e3d6000fd5b5050603b805460ff60a81b191690555050505050565b600780546001600160a01b039092166000818152600860205260408120849055600184018355919091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68890910180546001600160a01b0319169091179055565b600780546145709060019061585f565b8154811061458e57634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b03848116845260089092526040909220546007805492909316929181106145da57634e487b7160e01b600052603260045260246000fd5b600091825260208083209190910180546001600160a01b0319166001600160a01b039485161790559183168152600891829052604081205460078054919392916146269060019061585f565b8154811061464457634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b03168352820192909252604001902055600780548061468857634e487b7160e01b600052603160045260246000fd5b600082815260209020810160001990810180546001600160a01b031916905501905550565b60168054601e5560178054601f556018805460205560198054602180546001600160a01b038084166001600160a01b0319928316179092556022549096556023549094556024549092556025549092169216919091179055565b60168054601e5560178054601f556018805460205560198054602180546001600160a01b038084166001600160a01b0319928316179092556026549096556027549094556028549092556029549092169216919091179055565b60168054601e5560178054601f556018805460205560198054602180546001600160a01b038084166001600160a01b031992831617909255602a54909655602b54909455602c54909255602d549092169216919091179055565b60168054601e5560178054601f556018805460205560198054602180546001600160a01b038084166001600160a01b031992831617909255602e54909655602f549094556030549092556031549092169216919091179055565b61481d614a9d565b60006040518060800160405280600081526020016148408560166000015461498f565b81526020016148548560166001015461498f565b81526020016148688560166002015461498f565b815250905061489481606001516110608360400151611060856020015188612fee90919063ffffffff16565b815292915050565b60208101516019546148b791906001600160a01b03166149ae565b610f528160600151614a0b565b601e54601655601f54601755602054601855602154601980546001600160a01b0319166001600160a01b03909216919091179055565b60006149096002848418615809565b612436908484166157c9565b600061491f61386d565b90508061492b84614a4c565b10156110ad578254600180820185556000858152602080822090930193909355938401805494850181558252902090910155565b60008164010000000084106149875760405162461bcd60e51b8152600401610e619190614f76565b509192915050565b60008161499e57506000610e34565b612436612710611f0f8585613855565b6001600160a01b0381166149c15761110e565b816149cb5761110e565b6001600160a01b0381166000908152600a60205260409020546149ee9083612bfb565b6001600160a01b0382166000908152600a60205260409020555050565b80614a1557610f52565b306000908152600a6020526040902054614a2f9082612bfb565b306000818152600a6020526040902091909155610f529082613482565b8054600090614a5d57506000610dd1565b81548290614a6d9060019061585f565b81548110614a8b57634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050610dd1565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b600060208284031215614ad6578081fd5b813561243681615925565b600060208284031215614af2578081fd5b815161243681615925565b60008060408385031215614b0f578081fd5b8235614b1a81615925565b91506020830135614b2a81615925565b809150509250929050565b600080600060608486031215614b49578081fd5b8335614b5481615925565b92506020840135614b6481615925565b929592945050506040919091013590565b60008060408385031215614b87578182fd5b8235614b9281615925565b91506020830135614b2a8161593a565b60008060408385031215614bb4578182fd5b8235614bbf81615925565b946020939093013593505050565b60008060008060008060c08789031215614be5578182fd5b8635614bf081615925565b95506020870135945060408701359350606087013560ff81168114614c13578283fd5b9598949750929560808101359460a0909101359350915050565b60008060408385031215614c3f578182fd5b8235614c4a81615925565b9150602083013563ffffffff81168114614b2a578182fd5b600060208284031215614c73578081fd5b81516124368161593a565b600080600080600060a08688031215614c95578081fd5b8535614ca08161593a565b97602087013597506040870135966060810135965060800135945092505050565b600060208284031215614cd2578081fd5b5035919050565b60008060408385031215614ceb578081fd5b823591506020830135614b2a81615925565b600060208284031215614d0e578081fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114612436578182fd5b600080600060608486031215614d51578081fd5b8335614d5c81615925565b9250602084013591506040840135614d7381615925565b809150509250925092565b600060208284031215614d8f578081fd5b5051919050565b60008060408385031215614ceb578182fd5b7f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b60007f416363657373436f6e74726f6c3a206163636f756e742000000000000000000082528351614e1681601785016020880161589b565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351614e5381602884016020880161589b565b01602801949350505050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b9615158752602087019590955260408601939093526060850191909152608084015260a083015260c082015260e00190565b90815260200190565b9384526001600160a01b039290921660208401526040830152606082015260800190565b938452602084019290925260408301526001600160a01b0316606082015260800190565b93845260ff9290921660208401526040830152606082015260800190565b6000602082528251806020840152614f9581604085016020870161589b565b601f01601f19169190910160400192915050565b6020808252601d908201527f4552433230536e617073686f743a206e6f6e6578697374656e74206964000000604082015260600190565b6020808252818101527f5059453a2041646472657373205a65726f206973206e6f7420616c6c6f776564604082015260600190565b6020808252818101527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604082015260600190565b60208082526011908201527f4655454c3a204e4f545f414c4c4f574544000000000000000000000000000000604082015260600190565b6020808252601f908201527f4164647265737320697320616c726561647920626c61636b6c69737465642100604082015260600190565b60208082526025908201527f42455032303a207472616e736665722066726f6d20746865207a65726f20616460408201527f6472657373000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f42455032303a20617070726f76652066726f6d20746865207a65726f2061646460408201527f7265737300000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526027908201527f4150504c453a3a64656c656761746542795369673a207369676e61747572652060408201527f6578706972656400000000000000000000000000000000000000000000000000606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201527f6464726573730000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601d908201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604082015260600190565b6020808252604c908201527f4164647265737320686173206e6f74206265656e20626c61636b6c697374656460408201527f2120456e74657220616e20616464726573732074686174206973206f6e20746860608201527f6520626c61636b6c6973742e0000000000000000000000000000000000000000608082015260a00190565b60208082526010908201527f5059453a204e4f545f414c4c4f57454400000000000000000000000000000000604082015260600190565b60208082526023908201527f4150504c453a3a64656c656761746542795369673a20696e76616c6964206e6f60408201527f6e63650000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526016908201527f4665657320657863656564206d6178206c696d69742e00000000000000000000604082015260600190565b6020808252601f908201527f42455032303a206d696e7420746f20746865207a65726f206164647265737300604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526029908201527f5472616e7366657220616d6f756e74206d75737420626520677265617465722060408201527f7468616e207a65726f0000000000000000000000000000000000000000000000606082015260800190565b60208082526028908201527f4150504c453a3a6765745072696f72566f7465733a206e6f742079657420646560408201527f7465726d696e6564000000000000000000000000000000000000000000000000606082015260800190565b60208082526023908201527f42455032303a207472616e7366657220746f20746865207a65726f206164647260408201527f6573730000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526021908201527f42455032303a206275726e2066726f6d20746865207a65726f2061646472657360408201527f7300000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526027908201527f4150504c453a3a64656c656761746542795369673a20696e76616c696420736960408201527f676e617475726500000000000000000000000000000000000000000000000000606082015260800190565b60208082526016908201527f4552433230536e617073686f743a206964206973203000000000000000000000604082015260600190565b60208082526022908201527f42455032303a20617070726f766520746f20746865207a65726f20616464726560408201527f7373000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526012908201527f4150504c453a204e4f545f414c4c4f5745440000000000000000000000000000604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201527f20726f6c657320666f722073656c660000000000000000000000000000000000606082015260800190565b600060a082018783526020878185015260a0604085015281875180845260c0860191508289019350845b818110156157655784516001600160a01b031683529383019391830191600101615740565b50506001600160a01b03969096166060850152505050608001529392505050565b918252602082015260400190565b63ffffffff91909116815260200190565b63ffffffff929092168252602082015260400190565b60ff91909116815260200190565b600082198211156157dc576157dc6158f9565b500190565b600063ffffffff808316818516808303821115615800576158006158f9565b01949350505050565b6000826158185761581861590f565b500490565b600063ffffffff808416806158345761583461590f565b92169190910492915050565b600081600019048311821515161561585a5761585a6158f9565b500290565b600082821015615871576158716158f9565b500390565b600063ffffffff83811690831681811015615893576158936158f9565b039392505050565b60005b838110156158b657818101518382015260200161589e565b838111156120605750506000910152565b6000816158d6576158d66158f9565b506000190190565b60006000198214156158f2576158f26158f9565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b6001600160a01b0381168114610f5257600080fd5b8015158114610f5257600080fdfe42455032303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654150504c453a3a5f7772697465436865636b706f696e743a20626c6f636b206e756d6265722065786365656473203332206269747342455032303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726f42455032303a206275726e20616d6f756e7420657863656564732062616c616e6365a264697066735822122093326db4c60c592a130c9c7446f9ddcd2680334aaecc8fb38f8152b9477e62fa64736f6c634300080100330000000000000000000000004f71e29c3d5934a15308005b19ca263061e99616000000000000000000000000c71b2b3dd4a0a72f8857e4f5fbac53b401f2735500000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000003e8

Deployed Bytecode

0x6080604052600436106104d55760003560e01c806379cc679011610279578063b0a863f91161015e578063dfd66cb3116100d6578063f1127ed81161008a578063f3290d751161006f578063f3290d7514610d38578063f8a67a6214610d58578063f8b2cb4f1461090a576104dc565b8063f1127ed814610cea578063f2fde38b14610d18576104dc565b8063e7a324dc116100bb578063e7a324dc14610ca0578063e934768314610cb5578063ea2f0b3714610cca576104dc565b8063dfd66cb314610c6b578063e284db3e14610c80576104dc565b8063c3cda5201161012d578063d539139311610112578063d539139314610c16578063d547741f14610c2b578063dd62ed3e14610c4b576104dc565b8063c3cda52014610be1578063c80bbbeb14610c01576104dc565b8063b0a863f914610b6c578063b4b5ea5714610b8c578063b6f3e08714610bac578063bd3900c014610bcc576104dc565b80639711715a116101f1578063a217fddf116101c0578063a9059cbb116101a5578063a9059cbb14610b17578063ad5c464814610b37578063af2f6dd814610b4c576104dc565b8063a217fddf14610ae2578063a457c2d714610af7576104dc565b80639711715a14610a6d578063981b24d014610a8257806398807d8414610aa2578063a0558c3f14610ac2576104dc565b80638283bbf3116102485780638da5cb5b1161022d5780638da5cb5b14610a2357806391d1485414610a3857806395d89b4114610a58576104dc565b80638283bbf3146109ee57806382ccff8914610a0e576104dc565b806379cc6790146109845780637ae316d0146109a45780637ecebe00146109b9578063817b1cd2146109d9576104dc565b80633bf33976116103ba5780635c19a95c116103325780636fcfff45116102e6578063715018a6116102cb578063715018a61461092a578063782d6fe11461093f5780637891b5101461095f576104dc565b80636fcfff45146108dd57806370a082311461090a576104dc565b80636baa9a57116103175780636baa9a57146108885780636ddd1713146108a85780636ed52e68146108bd576104dc565b80635c19a95c1461084857806367243ea814610868576104dc565b806342966c68116103895780635342acb41161036e5780635342acb4146107e8578063537df3b614610808578063587cde1e14610828576104dc565b806342966c68146107a8578063437823ec146107c8576104dc565b80633bf33976146107285780633d8a62d31461074857806340b28c2f1461076857806340c10f1914610788576104dc565b8063248a9ca31161044d5780632f2ff15d1161041c578063313ce56711610401578063313ce567146106c657806336568abe146106e85780633950935114610708576104dc565b80632f2ff15d1461068657806330367554146106a6576104dc565b8063248a9ca314610614578063282c51f3146106345780632b112e49146106495780632c77735c1461065e576104dc565b8063174ca3ec116104a45780631973dc37116104895780631973dc37146105bf57806320606b70146105df57806323b872dd146105f4576104dc565b8063174ca3ec1461057b57806318160ddd1461059d576104dc565b806301ffc9a7146104e157806302e8e85f1461051757806306fdde0314610539578063095ea7b31461055b576104dc565b366104dc57005b600080fd5b3480156104ed57600080fd5b506105016104fc366004614cfd565b610d78565b60405161050e9190614eca565b60405180910390f35b34801561052357600080fd5b5061052c610dd6565b60405161050e9190614e5f565b34801561054557600080fd5b5061054e610de5565b60405161050e9190614f76565b34801561056757600080fd5b50610501610576366004614ba2565b610e1c565b34801561058757600080fd5b5061059b610596366004614c7e565b610e3a565b005b3480156105a957600080fd5b506105b2610e96565b60405161050e9190614f07565b3480156105cb57600080fd5b5061059b6105da366004614cc1565b610e9c565b3480156105eb57600080fd5b506105b2610f55565b34801561060057600080fd5b5061050161060f366004614b35565b610f79565b34801561062057600080fd5b506105b261062f366004614cc1565b611000565b34801561064057600080fd5b506105b2611016565b34801561065557600080fd5b506105b261103a565b34801561066a57600080fd5b5061067361106b565b60405161050e9796959493929190614ed5565b34801561069257600080fd5b5061059b6106a1366004614cd9565b611089565b3480156106b257600080fd5b506105016106c1366004614ac5565b6110b2565b3480156106d257600080fd5b506106db6110c7565b60405161050e91906157bb565b3480156106f457600080fd5b5061059b610703366004614cd9565b6110cc565b34801561071457600080fd5b50610501610723366004614ba2565b611112565b34801561073457600080fd5b506105b2610743366004614ba2565b611160565b34801561075457600080fd5b5061059b610763366004614ac5565b6111c6565b34801561077457600080fd5b5061059b610783366004614afd565b611211565b34801561079457600080fd5b5061059b6107a3366004614ba2565b611445565b3480156107b457600080fd5b5061059b6107c3366004614cc1565b61150f565b3480156107d457600080fd5b5061059b6107e3366004614ac5565b6115cf565b3480156107f457600080fd5b50610501610803366004614ac5565b61161a565b34801561081457600080fd5b5061059b610823366004614ac5565b611638565b34801561083457600080fd5b5061052c610843366004614ac5565b6116b8565b34801561085457600080fd5b5061059b610863366004614ac5565b6116d3565b34801561087457600080fd5b5061059b610883366004614ac5565b6116dd565b34801561089457600080fd5b506105b26108a3366004614ac5565b611789565b3480156108b457600080fd5b506105016117b6565b3480156108c957600080fd5b5061059b6108d8366004614b75565b6117d7565b3480156108e957600080fd5b506108fd6108f8366004614ac5565b611829565b60405161050e9190615794565b34801561091657600080fd5b506105b2610925366004614ac5565b611841565b34801561093657600080fd5b5061059b61185c565b34801561094b57600080fd5b506105b261095a366004614ba2565b6118a7565b34801561096b57600080fd5b50610974611acc565b60405161050e9493929190614f34565b34801561099057600080fd5b5061059b61099f366004614ba2565b611ae4565b3480156109b057600080fd5b506105b2611bba565b3480156109c557600080fd5b506105b26109d4366004614ac5565b611bd5565b3480156109e557600080fd5b506105b2611be7565b3480156109fa57600080fd5b5061059b610a09366004614d96565b611bed565b348015610a1a57600080fd5b506105b2612066565b348015610a2f57600080fd5b5061052c6120af565b348015610a4457600080fd5b50610501610a53366004614cd9565b6120be565b348015610a6457600080fd5b5061054e6120e9565b348015610a7957600080fd5b5061059b612120565b348015610a8e57600080fd5b506105b2610a9d366004614cc1565b612167565b348015610aae57600080fd5b506105b2610abd366004614ac5565b612197565b348015610ace57600080fd5b5061059b610add366004614d96565b6121a9565b348015610aee57600080fd5b506105b2612206565b348015610b0357600080fd5b50610501610b12366004614ba2565b61220b565b348015610b2357600080fd5b50610501610b32366004614ba2565b612273565b348015610b4357600080fd5b5061052c612287565b348015610b5857600080fd5b5061059b610b67366004614cc1565b612296565b348015610b7857600080fd5b5061059b610b87366004614cc1565b61233b565b348015610b9857600080fd5b506105b2610ba7366004614ac5565b6123c8565b348015610bb857600080fd5b5061059b610bc7366004614afd565b61243d565b348015610bd857600080fd5b5061052c612636565b348015610bed57600080fd5b5061059b610bfc366004614bcd565b61263c565b348015610c0d57600080fd5b5061052c612817565b348015610c2257600080fd5b506105b2612826565b348015610c3757600080fd5b5061059b610c46366004614cd9565b61284a565b348015610c5757600080fd5b506105b2610c66366004614afd565b612869565b348015610c7757600080fd5b50610974612894565b348015610c8c57600080fd5b5061059b610c9b366004614ac5565b6128ac565b348015610cac57600080fd5b506105b26128f4565b348015610cc157600080fd5b506105b2612918565b348015610cd657600080fd5b5061059b610ce5366004614ac5565b61293c565b348015610cf657600080fd5b50610d0a610d05366004614c2d565b612984565b60405161050e9291906157a5565b348015610d2457600080fd5b5061059b610d33366004614ac5565b6129b1565b348015610d4457600080fd5b5061059b610d53366004614ac5565b612a1f565b348015610d6457600080fd5b5061059b610d73366004614d3d565b612aa3565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610dce5750610dce82612c07565b90505b919050565b6039546001600160a01b031681565b60408051808201909152600881527f4170706c65505945000000000000000000000000000000000000000000000000602082015290565b6000610e30610e29612c51565b8484612c55565b5060015b92915050565b610e456000336120be565b610e6a5760405162461bcd60e51b8152600401610e6190615682565b60405180910390fd5b6032805460ff191695151595909517909455603392909255600060345560355560365543603755603855565b600f5490565b610ec67fe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f88182060336120be565b610ee25760405162461bcd60e51b8152600401610e6190615682565b601c54601b546109c491610f02918491610efc9190612bfb565b90612bfb565b1115610f205760405162461bcd60e51b8152600401610e619061537a565b6016819055601a819055602b54610f379082612bfb565b602a55602f54610f479082612bfb565b602e55610f52612d09565b50565b7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6000610f86848484612dbc565b610ff684610f92612c51565b610ff185604051806060016040528060288152602001615949602891396001600160a01b038a166000908152600b6020526040812090610fd0612c51565b6001600160a01b031681526020810191909152604001600020549190612fc2565b612c55565b5060019392505050565b6000908152600160208190526040909120015490565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b60006110666110496000611841565b61106061105761dead611841565b600f5490612fee565b90612fee565b905090565b60325460335460345460355460365460375460385460ff9096169587565b61109282611000565b6110a38161109e612c51565b612ffa565b6110ad838361305e565b505050565b60156020526000908152604090205460ff1681565b601290565b6110d4612c51565b6001600160a01b0316816001600160a01b0316146111045760405162461bcd60e51b8152600401610e61906156b9565b61110e82826130e6565b5050565b6000610e3061111f612c51565b84610ff185600b6000611130612c51565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490612bfb565b6001600160a01b03821660009081526041602052604081208190819061118790859061316b565b91509150816111bb576001600160a01b0385166000908152600c60205260409020546111b690610efc87611841565b6111bd565b805b95945050505050565b6111d16000336120be565b6111ed5760405162461bcd60e51b8152600401610e6190615682565b6001600160a01b03166000908152601160205260409020805460ff19166001179055565b61121c6000336120be565b6112385760405162461bcd60e51b8152600401610e6190615682565b603a80546001600160a01b03908116600090815260106020908152604091829020805460ff19169055603980546001600160a01b031990811688861617918290558554168685161790945581517fad5c46480000000000000000000000000000000000000000000000000000000081529151939092169263ad5c464892600480840193919291829003018186803b1580156112d257600080fd5b505afa1580156112e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130a9190614ae1565b603b80546001600160a01b03199081166001600160a01b03938416178255603a805484166000908152601560209081526040808320805460ff19908116600190811790925585548916855260108452918420805490921617905591549080527f7e7fa33969761a458e04f477e039a608702b4f924981d6653935a8319a08ad7b805491861691841682179055925460139091527f8fa6efc3be94b5b348b21fea823fe8d100408cee9b7f90524494500445d8ff6c80549190941691161790915563d32b96046113d7611bba565b6040518263ffffffff1660e01b81526004016113f39190614f07565b602060405180830381600087803b15801561140d57600080fd5b505af1158015611421573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ad9190614c62565b61146f7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336120be565b61148b5760405162461bcd60e51b8152600401610e6190615682565b61149760008383613217565b6114a1828261326f565b6001600160a01b038281166000908152603c6020526040902054166114ea576001600160a01b0382166000818152603c6020526040902080546001600160a01b03191690911790555b6001600160a01b038083166000908152603c602052604081205461110e921683613323565b6115397f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848336120be565b6115555760405162461bcd60e51b8152600401610e6190615682565b61156133600083613217565b61156b3382613482565b336000908152603c60205260409020546001600160a01b03166115a957336000818152603c6020526040902080546001600160a01b03191690911790555b336000908152603c6020526040812054610f52916001600160a01b039091169083613323565b6115da6000336120be565b6115f65760405162461bcd60e51b8152600401610e6190615682565b6001600160a01b03166000908152601060205260409020805460ff19166001179055565b6001600160a01b031660009081526010602052604090205460ff1690565b6116436000336120be565b61165f5760405162461bcd60e51b8152600401610e619061504a565b6001600160a01b0381166000908152600d602052604090205460ff166116975760405162461bcd60e51b8152600401610e6190615263565b6001600160a01b03166000908152600d60205260409020805460ff19169055565b603c602052600090815260409020546001600160a01b031681565b610f52338261354c565b6117077fe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f88182060336120be565b6117235760405162461bcd60e51b8152600401610e6190615682565b6001600160a01b0381166117495760405162461bcd60e51b8152600401610e6190614fe0565b601980546001600160a01b039092166001600160a01b03199283168117909155601d8054831682179055602d805483168217905560318054909216179055565b6001600160a01b0381166000908152600a6020908152604080832054600c909252822054610dce91612bfb565b603b5474010000000000000000000000000000000000000000900460ff1681565b6117e26000336120be565b6117fe5760405162461bcd60e51b8152600401610e619061504a565b6001600160a01b03919091166000908152600e60205260409020805460ff1916911515919091179055565b603e6020526000908152604090205463ffffffff1681565b6001600160a01b03166000908152600a602052604090205490565b611864612c51565b6001600160a01b03166118756120af565b6001600160a01b03161461189b5760405162461bcd60e51b8152600401610e61906153e8565b6118a560006135db565b565b60004382106118c85760405162461bcd60e51b8152600401610e619061547a565b6001600160a01b0383166000908152603e602052604090205463ffffffff16806118f6576000915050610e34565b6001600160a01b0384166000908152603d60205260408120849161191b600185615876565b63ffffffff90811682526020820192909252604001600020541611611984576001600160a01b0384166000908152603d602052604081209061195e600184615876565b63ffffffff1663ffffffff16815260200190815260200160002060010154915050610e34565b6001600160a01b0384166000908152603d6020908152604080832083805290915290205463ffffffff168310156119bf576000915050610e34565b6000806119cd600184615876565b90505b8163ffffffff168163ffffffff161115611a9557600060026119f28484615876565b6119fc919061581d565b611a069083615876565b6001600160a01b0388166000908152603d6020908152604080832063ffffffff8086168552908352928190208151808301909252805490931680825260019093015491810191909152919250871415611a6957602001519450610e349350505050565b805163ffffffff16871115611a8057819350611a8e565b611a8b600183615876565b92505b50506119d0565b506001600160a01b0385166000908152603d6020908152604080832063ffffffff9094168352929052206001015491505092915050565b601a54601b54601c54601d546001600160a01b031684565b611b0e7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848336120be565b611b2a5760405162461bcd60e51b8152600401610e6190615682565b611b3582338361362b565b611b4182600083613217565b611b4b8282613482565b6001600160a01b038281166000908152603c602052604090205416611b94576001600160a01b0382166000818152603c6020526040902080546001600160a01b03191690911790555b6001600160a01b038083166000908152603c602052604081205461110e92169083613323565b601854601754601654600092611066929091610efc91612bfb565b603f6020526000908152604090205481565b60095481565b6000805b601454811015611c31576000818152601260205260409020546001600160a01b0316331415611c1f57600191505b80611c29816158de565b915050611bf1565b506039546001600160a01b0316331480611c485750805b611c645760405162461bcd60e51b8152600401610e61906152e6565b6000611c6f8361366f565b9050601454811015612060576040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526000906001600160a01b0385169063dd62ed3e90611cc59033903090600401614e73565b60206040518083038186803b158015611cdd57600080fd5b505afa158015611cf1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d159190614d7e565b905084811061205e576040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b038516906323b872dd90611d6790339030908a90600401614e8d565b602060405180830381600087803b158015611d8157600080fd5b505af1158015611d95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db99190614c62565b50603b546001600160a01b03858116911614611fa957603b546040516370a0823160e01b81526000916001600160a01b0316906370a0823190611e00903090600401614e5f565b60206040518083038186803b158015611e1857600080fd5b505afa158015611e2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e509190614d7e565b9050611e5c86866136cf565b603b546040516370a0823160e01b8152600091611ee39184916001600160a01b0316906370a0823190611e93903090600401614e5f565b60206040518083038186803b158015611eab57600080fd5b505afa158015611ebf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110609190614d7e565b90506000611eef611bba565b90506000611f1582611f0f6016600001548661385590919063ffffffff16565b90613861565b603b5460195460405163a9059cbb60e01b81529293506001600160a01b039182169263a9059cbb92611f4d9216908590600401614eb1565b602060405180830381600087803b158015611f6757600080fd5b505af1158015611f7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9f9190614c62565b505050505061205e565b6000611fb3611bba565b90506000611fd382611f0f6016600001548a61385590919063ffffffff16565b60195460405163a9059cbb60e01b81529192506001600160a01b038089169263a9059cbb926120089216908590600401614eb1565b602060405180830381600087803b15801561202257600080fd5b505af1158015612036573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205a9190614c62565b5050505b505b50505050565b6000612070612c51565b6001600160a01b03166120816120af565b6001600160a01b0316146120a75760405162461bcd60e51b8152600401610e61906153e8565b61106661386d565b6000546001600160a01b031690565b60009182526001602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60408051808201909152600881527f4150504c45505945000000000000000000000000000000000000000000000000602082015290565b612128612c51565b6001600160a01b03166121396120af565b6001600160a01b03161461215f5760405162461bcd60e51b8152600401610e61906153e8565b610f52613879565b600080600061217784604261316b565b915091508161218d57612188610e96565b61218f565b805b949350505050565b600c6020526000908152604090205481565b6121b46000336120be565b6121d05760405162461bcd60e51b8152600401610e6190615682565b6040516001600160a01b0382169083156108fc029084906000818181858888f193505050501580156110ad573d6000803e3d6000fd5b600081565b6000610e30612218612c51565b84610ff1856040518060600160405280602581526020016159a660259139600b6000612242612c51565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190612fc2565b6000610e30612280612c51565b8484612dbc565b603b546001600160a01b031681565b6122c07fe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f88182060336120be565b6122dc5760405162461bcd60e51b8152600401610e6190615682565b601c54601a546109c4916122f6918491610efc9190612bfb565b11156123145760405162461bcd60e51b8152600401610e619061537a565b6017819055601b819055602a5461232b9082612bfb565b602a55602e54610f479082612bfb565b6123657fe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f88182060336120be565b6123815760405162461bcd60e51b8152600401610e6190615682565b601a54601b546109c49161239b918491610efc9190612bfb565b11156123b95760405162461bcd60e51b8152600401610e619061537a565b6028819055601c819055603055565b6001600160a01b0381166000908152603e602052604081205463ffffffff16806123f3576000612436565b6001600160a01b0383166000908152603d6020526040812090612417600184615876565b63ffffffff1663ffffffff168152602001908152602001600020600101545b9392505050565b603954604080517fc45a015500000000000000000000000000000000000000000000000000000000815290516000926001600160a01b03169163c45a0155916004808301926020929190829003018186803b15801561249b57600080fd5b505afa1580156124af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124d39190614ae1565b9050336001600160a01b03821614806124f657506039546001600160a01b031633145b8061250057503330145b61251c5760405162461bcd60e51b8152600401610e61906152e6565b612525836138cd565b6110ad576001600160a01b0383811660008181526010602090815260408083208054600160ff199182168117909255601584528285208054909116821790556014805485526012845282852080546001600160a01b0319908116909717905580548552601390935290832080549094169487169490941790925581546125ac9084906157c9565b90915550506001600160a01b03831663d32b96046125c8611bba565b6040518263ffffffff1660e01b81526004016125e49190614f07565b602060405180830381600087803b1580156125fe57600080fd5b505af1158015612612573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120609190614c62565b61dead81565b60007f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866612667610de5565b80519060200120612676613915565b3060405160200161268a9493929190614f34565b60405160208183030381529060405280519060200120905060007fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf8888886040516020016126db9493929190614f10565b60405160208183030381529060405280519060200120905060008282604051602001612708929190614da8565b6040516020818303038152906040528051906020012090506000600182888888604051600081526020016040526040516127459493929190614f58565b6020604051602081039080840390855afa158015612767573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661279a5760405162461bcd60e51b8152600401610e6190615591565b6001600160a01b0381166000908152603f602052604081208054916127be836158de565b9190505589146127e05760405162461bcd60e51b8152600401610e619061531d565b874211156128005760405162461bcd60e51b8152600401610e6190615172565b61280a818b61354c565b505050505b505050505050565b603a546001600160a01b031681565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b61285382611000565b61285f8161109e612c51565b6110ad83836130e6565b6001600160a01b039182166000908152600b6020908152604080832093909416825291909152205490565b6016546017546018546019546001600160a01b031684565b6128b76000336120be565b6128d35760405162461bcd60e51b8152600401610e6190615682565b6001600160a01b03166000908152601160205260409020805460ff19169055565b7fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf81565b7fe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f8818206081565b6129476000336120be565b6129635760405162461bcd60e51b8152600401610e6190615682565b6001600160a01b03166000908152601060205260409020805460ff19169055565b603d6020908152600092835260408084209091529082529020805460019091015463ffffffff9091169082565b6129b9612c51565b6001600160a01b03166129ca6120af565b6001600160a01b0316146129f05760405162461bcd60e51b8152600401610e61906153e8565b6001600160a01b038116612a165760405162461bcd60e51b8152600401610e61906151cf565b610f52816135db565b612a2a6000336120be565b612a465760405162461bcd60e51b8152600401610e619061504a565b6001600160a01b0381166000908152600d602052604090205460ff1615612a7f5760405162461bcd60e51b8152600401610e6190615081565b6001600160a01b03166000908152600d60205260409020805460ff19166001179055565b612aae6000336120be565b612aca5760405162461bcd60e51b8152600401610e6190615682565b6040516370a0823160e01b815282906001600160a01b038516906370a0823190612af8903090600401614e5f565b60206040518083038186803b158015612b1057600080fd5b505afa158015612b24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b489190614d7e565b1015612bcd576040516370a0823160e01b81526001600160a01b038416906370a0823190612b7a903090600401614e5f565b60206040518083038186803b158015612b9257600080fd5b505afa158015612ba6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bca9190614d7e565b91505b60405163a9059cbb60e01b81526001600160a01b0384169063a9059cbb906125e49084908690600401614eb1565b600061243682846157c9565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f01ffc9a70000000000000000000000000000000000000000000000000000000014919050565b3390565b6001600160a01b038316612c7b5760405162461bcd60e51b8152600401610e6190615115565b6001600160a01b038216612ca15760405162461bcd60e51b8152600401610e6190615625565b6001600160a01b038084166000818152600b602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590612cfc908590614f07565b60405180910390a3505050565b60005b601454811015610f52576000818152601260205260409020546001600160a01b031663d32b9604612d3b611bba565b6040518263ffffffff1660e01b8152600401612d579190614f07565b602060405180830381600087803b158015612d7157600080fd5b505af1158015612d85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612da99190614c62565b5080612db4816158de565b915050612d0c565b6001600160a01b038316612de25760405162461bcd60e51b8152600401610e61906150b8565b6001600160a01b038216612e085760405162461bcd60e51b8152600401610e61906154d7565b60008111612e285760405162461bcd60e51b8152600401610e619061541d565b6001600160a01b0382166000908152600d602052604090205460ff1615612e4e57600080fd5b612e59838383613217565b612e6281613919565b15612e6f57612e6f613a07565b6001600160a01b0382166000908152600e602052604090205460ff1615612ec1576001600160a01b0383166000908152600c6020526040812054612eb39083612bfb565b9050612ebf8482613a43565b505b6001600160a01b0383166000908152600e602052604090205460ff1615612f13576001600160a01b0382166000908152600c6020526040812054612f059083612fee565b9050612f118382613a43565b505b6001600160a01b03821660009081526015602052604081205460ff168015612f4957506039546001600160a01b03858116911614155b8015612f5b5750612f598461161a565b155b15612f6857506001612fb6565b6001600160a01b03841660009081526011602052604090205460ff1615612f9157506002612fb6565b6001600160a01b03831660009081526011602052604090205460ff1615612fb6575060035b61206084848484613af9565b60008184841115612fe65760405162461bcd60e51b8152600401610e619190614f76565b505050900390565b6000612436828461585f565b61300482826120be565b61110e5761301c816001600160a01b03166014613e7a565b613027836020613e7a565b604051602001613038929190614dde565b60408051601f198184030181529082905262461bcd60e51b8252610e6191600401614f76565b61306882826120be565b61110e5760008281526001602081815260408084206001600160a01b0386168552909152909120805460ff191690911790556130a2612c51565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6130f082826120be565b1561110e5760008281526001602090815260408083206001600160a01b03851684529091529020805460ff19169055613127612c51565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6000806000841161318e5760405162461bcd60e51b8152600401610e61906155ee565b61319661386d565b8411156131b55760405162461bcd60e51b8152600401610e6190614fa9565b60006131c18486614071565b84549091508114156131da576000809250925050613210565b60018460010182815481106131ff57634e487b7160e01b600052603260045260246000fd5b906000526020600020015492509250505b9250929050565b6132228383836110ad565b6001600160a01b0383166132465761323982614150565b61324161418b565b6110ad565b6001600160a01b03821661325d5761323983614150565b61326683614150565b6110ad82614150565b6001600160a01b0382166132955760405162461bcd60e51b8152600401610e61906153b1565b600f546132a29082612bfb565b600f556001600160a01b0382166000908152600a60205260409020546132c89082612bfb565b6001600160a01b0383166000818152600a60205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90613317908590614f07565b60405180910390a35050565b816001600160a01b0316836001600160a01b0316141580156133455750600081115b156110ad576001600160a01b038316156133e8576001600160a01b0383166000908152603e602052604081205463ffffffff1690816133855760006133c8565b6001600160a01b0385166000908152603d60205260408120906133a9600185615876565b63ffffffff1663ffffffff168152602001908152602001600020600101545b905060006133d68285612fee565b90506133e486848484614198565b5050505b6001600160a01b038216156110ad576001600160a01b0382166000908152603e602052604081205463ffffffff169081613423576000613466565b6001600160a01b0384166000908152603d6020526040812090613447600185615876565b63ffffffff1663ffffffff168152602001908152602001600020600101545b905060006134748285612bfb565b905061280f85848484614198565b6001600160a01b0382166134a85760405162461bcd60e51b8152600401610e6190615534565b6134e5816040518060600160405280602281526020016159cb602291396001600160a01b0385166000908152600a60205260409020549190612fc2565b6001600160a01b0383166000908152600a6020526040902055600f5461350b9082612fee565b600f556040516000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90613317908590614f07565b6001600160a01b038083166000908152603c60205260408120549091169061357384611841565b6001600160a01b038581166000818152603c602052604080822080546001600160a01b031916898616908117909155905194955093928616927f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a4612060828483613323565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006136378484612869565b9050600019811461206057818110156136625760405162461bcd60e51b8152600401610e619061522c565b6120608484848403612c55565b600080601454600161368191906157c9565b905060005b6014548110156136c8576000818152601360205260409020546001600160a01b03858116911614156136b6578091505b806136c0816158de565b915050613686565b5092915050565b604080516002808252606082018352600092602083019080368337019050509050818160008151811061371257634e487b7160e01b600052603260045260246000fd5b6001600160a01b039283166020918202929092010152603b5482519116908290600190811061375157634e487b7160e01b600052603260045260246000fd5b6001600160a01b03928316602091820292909201015260395460405163095ea7b360e01b81528483169263095ea7b392613792929116908790600401614eb1565b602060405180830381600087803b1580156137ac57600080fd5b505af11580156137c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137e49190614c62565b50603954604051635c11d79560e01b81526001600160a01b0390911690635c11d7959061381e908690600090869030904290600401615716565b600060405180830381600087803b15801561383857600080fd5b505af115801561384c573d6000803e3d6000fd5b50505050505050565b60006124368284615840565b60006124368284615809565b60006110666040614339565b6000613885604061433d565b600061388f61386d565b90507f8030e83b04d87bef53480e26263266d6ca66863aa8506aca6f2559d18aa1cb67816040516138c09190614f07565b60405180910390a1905090565b600080805b6014548110156136c8576000818152601260205260409020546001600160a01b038581169116141561390357600191505b8061390d816158de565b9150506138d2565b4690565b603a546000906001600160a01b031633148015906139415750603b54600160a81b900460ff16155b801561394f575060325460ff165b801561396a57506036546037544391613967916157c9565b11155b80156139f75750603554603b546040516370a0823160e01b81526001600160a01b03909116906370a08231906139a4903090600401614e5f565b60206040518083038186803b1580156139bc57600080fd5b505afa1580156139d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139f49190614d7e565b10155b8015610dce575050603854111590565b603554613a169061dead614346565b43603755603554603454613a2991612bfb565b603481905560335410156118a5576032805460ff19169055565b600081118015613a6957506001600160a01b0382166000908152600c6020526040902054155b15613a7c57613a77826144ff565b613aaf565b80158015613aa157506001600160a01b0382166000908152600c602052604090205415155b15613aaf57613aaf82614560565b6001600160a01b0382166000908152600c6020526040902054600954613ada918391610efc91612fee565b6009556001600160a01b039091166000908152600c6020526040902055565b60ff8116613b0e57613b096146ad565b613b4a565b8060ff1660011415613b2257613b09614707565b8060ff1660021415613b3657613b09614761565b8060ff1660031415613b4a57613b4a6147bb565b6000613b5583614815565b9050613bc6836040518060400160405280601481526020017f496e73756666696369656e742042616c616e6365000000000000000000000000815250600a6000896001600160a01b03166001600160a01b0316815260200190815260200160002054612fc29092919063ffffffff16565b6001600160a01b038087166000908152600a602052604080822093909355835191871681529190912054613bf991612bfb565b6001600160a01b0385166000908152600a6020526040902055613c1b8161489c565b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360000151604051613c629190614f07565b60405180910390a36001600160a01b038581166000908152603c602052604090205416613cb3576001600160a01b0385166000818152603c6020526040902080546001600160a01b03191690911790555b6001600160a01b038481166000908152603c602052604090205416613cfc576001600160a01b0384166000818152603c6020526040902080546001600160a01b03191690911790555b8051831415613d3c576001600160a01b038086166000908152603c6020526040808220548784168352912054613d3792918216911685613323565b613dde565b6001600160a01b038086166000908152603c60205260408082205487841683529120548351613d7393928316929190911690613323565b6001600160a01b038086166000908152603c60209081526040808320546019548516845292205490840151613db093928316929190911690613323565b6001600160a01b038086166000908152603c60205260408120546060840151613dde93919091169190613323565b60ff82161580613df157508160ff166001145b15613e0357613dfe6148c4565b61205e565b8160ff1660021480613e1857508160ff166003145b1561205e57613e256148c4565b60195460208201516040516001600160a01b03928316928816917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91613e6b9190614f07565b60405180910390a35050505050565b60606000613e89836002615840565b613e949060026157c9565b67ffffffffffffffff811115613eba57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015613ee4576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110613f2957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110613f8257634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506000613fa6846002615840565b613fb19060016157c9565b90505b6001811115614052577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061400057634e487b7160e01b600052603260045260246000fd5b1a60f81b82828151811061402457634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c9361404b816158c7565b9050613fb4565b5083156124365760405162461bcd60e51b8152600401610e6190615015565b815460009061408257506000610e34565b82546000905b808210156140ec57600061409c83836148fa565b9050848682815481106140bf57634e487b7160e01b600052603260045260246000fd5b906000526020600020015411156140d8578091506140e6565b6140e38160016157c9565b92505b50614088565b60008211801561412f5750838561410460018561585f565b8154811061412257634e487b7160e01b600052603260045260246000fd5b9060005260206000200154145b156141485761413f60018361585f565b92505050610e34565b509050610e34565b6001600160a01b0381166000908152604160209081526040808320600c90925290912054610f52919061418690610efc85611841565b614915565b6118a56042614186610e96565b60006141bc436040518060600160405280603581526020016159716035913961495f565b905060008463ffffffff1611801561421657506001600160a01b0385166000908152603d6020526040812063ffffffff8316916141fa600188615876565b63ffffffff908116825260208201929092526040016000205416145b1561425f576001600160a01b0385166000908152603d602052604081208391614240600188615876565b63ffffffff1681526020810191909152604001600020600101556142ef565b60408051808201825263ffffffff838116825260208083018681526001600160a01b038a166000908152603d83528581208a851682529092529390209151825463ffffffff1916911617815590516001918201556142be9085906157e1565b6001600160a01b0386166000908152603e60205260409020805463ffffffff191663ffffffff929092169190911790555b846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724848460405161432a929190615786565b60405180910390a25050505050565b5490565b80546001019055565b603b805460ff60a81b1916600160a81b1790556040805160028082526060820183526000926020830190803683375050603b5482519293506001600160a01b0316918391506000906143a857634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b03168152505030816001815181106143ea57634e487b7160e01b600052603260045260246000fd5b6001600160a01b039283166020918202929092010152603b5460395460405163095ea7b360e01b81529183169263095ea7b39261442f92909116908790600401614eb1565b602060405180830381600087803b15801561444957600080fd5b505af115801561445d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144819190614c62565b50603954604051635c11d79560e01b81526001600160a01b0390911690635c11d795906144bb908690600090869088904290600401615716565b600060405180830381600087803b1580156144d557600080fd5b505af11580156144e9573d6000803e3d6000fd5b5050603b805460ff60a81b191690555050505050565b600780546001600160a01b039092166000818152600860205260408120849055600184018355919091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68890910180546001600160a01b0319169091179055565b600780546145709060019061585f565b8154811061458e57634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b03848116845260089092526040909220546007805492909316929181106145da57634e487b7160e01b600052603260045260246000fd5b600091825260208083209190910180546001600160a01b0319166001600160a01b039485161790559183168152600891829052604081205460078054919392916146269060019061585f565b8154811061464457634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b03168352820192909252604001902055600780548061468857634e487b7160e01b600052603160045260246000fd5b600082815260209020810160001990810180546001600160a01b031916905501905550565b60168054601e5560178054601f556018805460205560198054602180546001600160a01b038084166001600160a01b0319928316179092556022549096556023549094556024549092556025549092169216919091179055565b60168054601e5560178054601f556018805460205560198054602180546001600160a01b038084166001600160a01b0319928316179092556026549096556027549094556028549092556029549092169216919091179055565b60168054601e5560178054601f556018805460205560198054602180546001600160a01b038084166001600160a01b031992831617909255602a54909655602b54909455602c54909255602d549092169216919091179055565b60168054601e5560178054601f556018805460205560198054602180546001600160a01b038084166001600160a01b031992831617909255602e54909655602f549094556030549092556031549092169216919091179055565b61481d614a9d565b60006040518060800160405280600081526020016148408560166000015461498f565b81526020016148548560166001015461498f565b81526020016148688560166002015461498f565b815250905061489481606001516110608360400151611060856020015188612fee90919063ffffffff16565b815292915050565b60208101516019546148b791906001600160a01b03166149ae565b610f528160600151614a0b565b601e54601655601f54601755602054601855602154601980546001600160a01b0319166001600160a01b03909216919091179055565b60006149096002848418615809565b612436908484166157c9565b600061491f61386d565b90508061492b84614a4c565b10156110ad578254600180820185556000858152602080822090930193909355938401805494850181558252902090910155565b60008164010000000084106149875760405162461bcd60e51b8152600401610e619190614f76565b509192915050565b60008161499e57506000610e34565b612436612710611f0f8585613855565b6001600160a01b0381166149c15761110e565b816149cb5761110e565b6001600160a01b0381166000908152600a60205260409020546149ee9083612bfb565b6001600160a01b0382166000908152600a60205260409020555050565b80614a1557610f52565b306000908152600a6020526040902054614a2f9082612bfb565b306000818152600a6020526040902091909155610f529082613482565b8054600090614a5d57506000610dd1565b81548290614a6d9060019061585f565b81548110614a8b57634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050610dd1565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b600060208284031215614ad6578081fd5b813561243681615925565b600060208284031215614af2578081fd5b815161243681615925565b60008060408385031215614b0f578081fd5b8235614b1a81615925565b91506020830135614b2a81615925565b809150509250929050565b600080600060608486031215614b49578081fd5b8335614b5481615925565b92506020840135614b6481615925565b929592945050506040919091013590565b60008060408385031215614b87578182fd5b8235614b9281615925565b91506020830135614b2a8161593a565b60008060408385031215614bb4578182fd5b8235614bbf81615925565b946020939093013593505050565b60008060008060008060c08789031215614be5578182fd5b8635614bf081615925565b95506020870135945060408701359350606087013560ff81168114614c13578283fd5b9598949750929560808101359460a0909101359350915050565b60008060408385031215614c3f578182fd5b8235614c4a81615925565b9150602083013563ffffffff81168114614b2a578182fd5b600060208284031215614c73578081fd5b81516124368161593a565b600080600080600060a08688031215614c95578081fd5b8535614ca08161593a565b97602087013597506040870135966060810135965060800135945092505050565b600060208284031215614cd2578081fd5b5035919050565b60008060408385031215614ceb578081fd5b823591506020830135614b2a81615925565b600060208284031215614d0e578081fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114612436578182fd5b600080600060608486031215614d51578081fd5b8335614d5c81615925565b9250602084013591506040840135614d7381615925565b809150509250925092565b600060208284031215614d8f578081fd5b5051919050565b60008060408385031215614ceb578182fd5b7f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b60007f416363657373436f6e74726f6c3a206163636f756e742000000000000000000082528351614e1681601785016020880161589b565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351614e5381602884016020880161589b565b01602801949350505050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b9615158752602087019590955260408601939093526060850191909152608084015260a083015260c082015260e00190565b90815260200190565b9384526001600160a01b039290921660208401526040830152606082015260800190565b938452602084019290925260408301526001600160a01b0316606082015260800190565b93845260ff9290921660208401526040830152606082015260800190565b6000602082528251806020840152614f9581604085016020870161589b565b601f01601f19169190910160400192915050565b6020808252601d908201527f4552433230536e617073686f743a206e6f6e6578697374656e74206964000000604082015260600190565b6020808252818101527f5059453a2041646472657373205a65726f206973206e6f7420616c6c6f776564604082015260600190565b6020808252818101527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604082015260600190565b60208082526011908201527f4655454c3a204e4f545f414c4c4f574544000000000000000000000000000000604082015260600190565b6020808252601f908201527f4164647265737320697320616c726561647920626c61636b6c69737465642100604082015260600190565b60208082526025908201527f42455032303a207472616e736665722066726f6d20746865207a65726f20616460408201527f6472657373000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f42455032303a20617070726f76652066726f6d20746865207a65726f2061646460408201527f7265737300000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526027908201527f4150504c453a3a64656c656761746542795369673a207369676e61747572652060408201527f6578706972656400000000000000000000000000000000000000000000000000606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201527f6464726573730000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601d908201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604082015260600190565b6020808252604c908201527f4164647265737320686173206e6f74206265656e20626c61636b6c697374656460408201527f2120456e74657220616e20616464726573732074686174206973206f6e20746860608201527f6520626c61636b6c6973742e0000000000000000000000000000000000000000608082015260a00190565b60208082526010908201527f5059453a204e4f545f414c4c4f57454400000000000000000000000000000000604082015260600190565b60208082526023908201527f4150504c453a3a64656c656761746542795369673a20696e76616c6964206e6f60408201527f6e63650000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526016908201527f4665657320657863656564206d6178206c696d69742e00000000000000000000604082015260600190565b6020808252601f908201527f42455032303a206d696e7420746f20746865207a65726f206164647265737300604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526029908201527f5472616e7366657220616d6f756e74206d75737420626520677265617465722060408201527f7468616e207a65726f0000000000000000000000000000000000000000000000606082015260800190565b60208082526028908201527f4150504c453a3a6765745072696f72566f7465733a206e6f742079657420646560408201527f7465726d696e6564000000000000000000000000000000000000000000000000606082015260800190565b60208082526023908201527f42455032303a207472616e7366657220746f20746865207a65726f206164647260408201527f6573730000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526021908201527f42455032303a206275726e2066726f6d20746865207a65726f2061646472657360408201527f7300000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526027908201527f4150504c453a3a64656c656761746542795369673a20696e76616c696420736960408201527f676e617475726500000000000000000000000000000000000000000000000000606082015260800190565b60208082526016908201527f4552433230536e617073686f743a206964206973203000000000000000000000604082015260600190565b60208082526022908201527f42455032303a20617070726f766520746f20746865207a65726f20616464726560408201527f7373000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526012908201527f4150504c453a204e4f545f414c4c4f5745440000000000000000000000000000604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201527f20726f6c657320666f722073656c660000000000000000000000000000000000606082015260800190565b600060a082018783526020878185015260a0604085015281875180845260c0860191508289019350845b818110156157655784516001600160a01b031683529383019391830191600101615740565b50506001600160a01b03969096166060850152505050608001529392505050565b918252602082015260400190565b63ffffffff91909116815260200190565b63ffffffff929092168252602082015260400190565b60ff91909116815260200190565b600082198211156157dc576157dc6158f9565b500190565b600063ffffffff808316818516808303821115615800576158006158f9565b01949350505050565b6000826158185761581861590f565b500490565b600063ffffffff808416806158345761583461590f565b92169190910492915050565b600081600019048311821515161561585a5761585a6158f9565b500290565b600082821015615871576158716158f9565b500390565b600063ffffffff83811690831681811015615893576158936158f9565b039392505050565b60005b838110156158b657818101518382015260200161589e565b838111156120605750506000910152565b6000816158d6576158d66158f9565b506000190190565b60006000198214156158f2576158f26158f9565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b6001600160a01b0381168114610f5257600080fd5b8015158114610f5257600080fdfe42455032303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654150504c453a3a5f7772697465436865636b706f696e743a20626c6f636b206e756d6265722065786365656473203332206269747342455032303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726f42455032303a206275726e20616d6f756e7420657863656564732062616c616e6365a264697066735822122093326db4c60c592a130c9c7446f9ddcd2680334aaecc8fb38f8152b9477e62fa64736f6c63430008010033

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

0000000000000000000000004f71e29c3d5934a15308005b19ca263061e99616000000000000000000000000c71b2b3dd4a0a72f8857e4f5fbac53b401f2735500000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000003e8

-----Decoded View---------------
Arg [0] : _router (address): 0x4F71E29C3D5934A15308005B19Ca263061E99616
Arg [1] : _development (address): 0xC71B2b3DD4a0A72f8857e4f5fBac53b401F27355
Arg [2] : _developmentFee (uint256): 200
Arg [3] : _buybackFee (uint256): 200
Arg [4] : _burnFee (uint256): 1000

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000004f71e29c3d5934a15308005b19ca263061e99616
Arg [1] : 000000000000000000000000c71b2b3dd4a0a72f8857e4f5fbac53b401f27355
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000c8
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000c8
Arg [4] : 00000000000000000000000000000000000000000000000000000000000003e8


Deployed Bytecode Sourcemap

77494:40406:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52630:204;;;;;;;;;;-1:-1:-1;52630:204:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80190:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;84152:92::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;85012:161::-;;;;;;;;;;-1:-1:-1;85012:161:0;;;;;:::i;:::-;;:::i;99135:573::-;;;;;;;;;;-1:-1:-1;99135:573:0;;;;;:::i;:::-;;:::i;:::-;;84456:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;87615:611::-;;;;;;;;;;-1:-1:-1;87615:611:0;;;;;:::i;:::-;;:::i;81435:122::-;;;;;;;;;;;;;:::i;85181:313::-;;;;;;;;;;-1:-1:-1;85181:313:0;;;;;:::i;:::-;;:::i;54057:131::-;;;;;;;;;;-1:-1:-1;54057:131:0;;;;;:::i;:::-;;:::i;77694:62::-;;;;;;;;;;;;;:::i;92997:151::-;;;;;;;;;;;;;:::i;80157:24::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;54450:147::-;;;;;;;;;;-1:-1:-1;54450:147:0;;;;;:::i;:::-;;:::i;79698:47::-;;;;;;;;;;-1:-1:-1;79698:47:0;;;;;:::i;:::-;;:::i;84356:92::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;55498:218::-;;;;;;;;;;-1:-1:-1;55498:218:0;;;;;:::i;:::-;;:::i;85502:227::-;;;;;;;;;;-1:-1:-1;85502:227:0;;;;;:::i;:::-;;:::i;115324:301::-;;;;;;;;;;-1:-1:-1;115324:301:0;;;;;:::i;:::-;;:::i;86402:183::-;;;;;;;;;;-1:-1:-1;86402:183:0;;;;;:::i;:::-;;:::i;89123:551::-;;;;;;;;;;-1:-1:-1;89123:551:0;;;;;:::i;:::-;;:::i;104114:382::-;;;;;;;;;;-1:-1:-1;104114:382:0;;;;;:::i;:::-;;:::i;104504:403::-;;;;;;;;;;-1:-1:-1;104504:403:0;;;;;:::i;:::-;;:::i;86023:182::-;;;;;;;;;;-1:-1:-1;86023:182:0;;;;;:::i;:::-;;:::i;91049:123::-;;;;;;;;;;-1:-1:-1;91049:123:0;;;;;:::i;:::-;;:::i;113568:335::-;;;;;;;;;;-1:-1:-1;113568:335:0;;;;;:::i;:::-;;:::i;80884:45::-;;;;;;;;;;-1:-1:-1;80884:45:0;;;;;:::i;:::-;;:::i;105457:104::-;;;;;;;;;;-1:-1:-1;105457:104:0;;;;;:::i;:::-;;:::i;88234:469::-;;;;;;;;;;-1:-1:-1;88234:469:0;;;;;:::i;:::-;;:::i;111821:147::-;;;;;;;;;;-1:-1:-1;111821:147:0;;;;;:::i;:::-;;:::i;80381:30::-;;;;;;;;;;;;;:::i;112791:200::-;;;;;;;;;;-1:-1:-1;112791:200:0;;;;;:::i;:::-;;:::i;81313:49::-;;;;;;;;;;-1:-1:-1;81313:49:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;84559:119::-;;;;;;;;;;-1:-1:-1;84559:119:0;;;;;:::i;:::-;;:::i;59328:103::-;;;;;;;;;;;;;:::i;108059:1242::-;;;;;;;;;;-1:-1:-1;108059:1242:0;;;;;:::i;:::-;;:::i;79957:28::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;103552:453::-;;;;;;;;;;-1:-1:-1;103552:453:0;;;;;:::i;:::-;;:::i;93156:189::-;;;;;;;;;;;;;:::i;81849:39::-;;;;;;;;;;-1:-1:-1;81849:39:0;;;;;:::i;:::-;;:::i;77996:26::-;;;;;;;;;;;;;:::i;95722:1463::-;;;;;;;;;;-1:-1:-1;95722:1463:0;;;;;:::i;:::-;;:::i;115142:121::-;;;;;;;;;;;;;:::i;58677:87::-;;;;;;;;;;;;;:::i;52926:147::-;;;;;;;;;;-1:-1:-1;52926:147:0;;;;;:::i;:::-;;:::i;84252:96::-;;;;;;;;;;;;;:::i;114701:67::-;;;;;;;;;;;;;:::i;115633:234::-;;;;;;;;;;-1:-1:-1;115633:234:0;;;;;:::i;:::-;;:::i;78635:41::-;;;;;;;;;;-1:-1:-1;78635:41:0;;;;;:::i;:::-;;:::i;100933:186::-;;;;;;;;;;-1:-1:-1;100933:186:0;;;;;:::i;:::-;;:::i;52017:49::-;;;;;;;;;;;;;:::i;85737:278::-;;;;;;;;;;-1:-1:-1;85737:278:0;;;;;:::i;:::-;;:::i;84686:167::-;;;;;;;;;;-1:-1:-1;84686:167:0;;;;;:::i;:::-;;:::i;80265:19::-;;;;;;;;;;;;;:::i;87020:587::-;;;;;;;;;;-1:-1:-1;87020:587:0;;;;;:::i;:::-;;:::i;88711:400::-;;;;;;;;;;-1:-1:-1;88711:400:0;;;;;:::i;:::-;;:::i;107385:243::-;;;;;;;;;;-1:-1:-1;107385:243:0;;;;;:::i;:::-;;:::i;99982:639::-;;;;;;;;;;-1:-1:-1;99982:639:0;;;;;:::i;:::-;;:::i;80291:81::-;;;;;;;;;;;;;:::i;105995:1189::-;;;;;;;;;;-1:-1:-1;105995:1189:0;;;;;:::i;:::-;;:::i;80232:26::-;;;;;;;;;;;;;:::i;77625:62::-;;;;;;;;;;;;;:::i;54842:149::-;;;;;;;;;;-1:-1:-1;54842:149:0;;;;;:::i;:::-;;:::i;84861:143::-;;;;;;;;;;-1:-1:-1;84861:143:0;;;;;:::i;:::-;;:::i;79926:24::-;;;;;;;;;;;;;:::i;86593:187::-;;;;;;;;;;-1:-1:-1;86593:187:0;;;;;:::i;:::-;;:::i;81651:117::-;;;;;;;;;;;;;:::i;77763:70::-;;;;;;;;;;;;;:::i;86213:181::-;;;;;;;;;;-1:-1:-1;86213:181:0;;;;;:::i;:::-;;:::i;81174:70::-;;;;;;;;;;-1:-1:-1;81174:70:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;59586:201::-;;;;;;;;;;-1:-1:-1;59586:201:0;;;;;:::i;:::-;;:::i;113198:296::-;;;;;;;;;;-1:-1:-1;113198:296:0;;;;;:::i;:::-;;:::i;101179:320::-;;;;;;;;;;-1:-1:-1;101179:320:0;;;;;:::i;:::-;;:::i;52630:204::-;52715:4;52739:47;;;52754:32;52739:47;;:87;;;52790:36;52814:11;52790:23;:36::i;:::-;52732:94;;52630:204;;;;:::o;80190:35::-;;;-1:-1:-1;;;;;80190:35:0;;:::o;84152:92::-;84231:5;;;;;;;;;;;;;;;;;84152:92;:::o;85012:161::-;85087:4;85104:39;85113:12;:10;:12::i;:::-;85127:7;85136:6;85104:8;:39::i;:::-;-1:-1:-1;85161:4:0;85012:161;;;;;:::o;99135:573::-;99285:39;52062:4;99313:10;99285:7;:39::i;:::-;99277:70;;;;-1:-1:-1;;;99277:70:0;;;;;;;:::i;:::-;;;;;;;;;99358:8;:38;;-1:-1:-1;;99358:38:0;;;;;;;;;;;99407:23;:30;;;;-1:-1:-1;99448:31:0;:35;99494:26;:36;99541:31;:41;99625:12;99593:29;:44;99648:32;:52;99135:573::o;84456:95::-;84536:7;;84456:95;:::o;87615:611::-;87699:36;77805:28;87724:10;87699:7;:36::i;:::-;87691:67;;;;-1:-1:-1;;;87691:67:0;;;;;;;:::i;:::-;87809:24;;87777:27;;87859:4;;87777:78;;87839:15;;87777:57;;:27;:31;:57::i;:::-;:61;;:78::i;:::-;:86;;87769:121;;;;-1:-1:-1;;;87769:121:0;;;;;;;:::i;:::-;87901:12;:45;;;87957:16;:49;;;88050:26;;:47;;87931:15;88050:30;:47::i;:::-;88017:15;:80;88142:27;;:48;;88174:15;88142:31;:48::i;:::-;88108:16;:82;88201:17;:15;:17::i;:::-;87615:611;:::o;81435:122::-;81477:80;81435:122;:::o;85181:313::-;85279:4;85296:36;85306:6;85314:9;85325:6;85296:9;:36::i;:::-;85343:121;85352:6;85360:12;:10;:12::i;:::-;85374:89;85412:6;85374:89;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;85374:19:0;;;;;;:11;:19;;;;;;85394:12;:10;:12::i;:::-;-1:-1:-1;;;;;85374:33:0;;;;;;;;;;;;-1:-1:-1;85374:33:0;;;:89;:37;:89::i;:::-;85343:8;:121::i;:::-;-1:-1:-1;85482:4:0;85181:313;;;;;:::o;54057:131::-;54131:7;54158:12;;;:6;:12;;;;;;;;:22;;;54057:131::o;77694:62::-;77732:24;77694:62;:::o;92997:151::-;93050:7;93077:63;93118:21;93136:1;93118:9;:21::i;:::-;93077:36;93089:23;80330:42;93089:9;:23::i;:::-;93077:7;;;:11;:36::i;:::-;:40;;:63::i;:::-;93070:70;;92997:151;:::o;80157:24::-;;;;;;;;;;;;;;;;;;;;;:::o;54450:147::-;54533:18;54546:4;54533:12;:18::i;:::-;52508:30;52519:4;52525:12;:10;:12::i;:::-;52508:10;:30::i;:::-;54564:25:::1;54575:4;54581:7;54564:10;:25::i;:::-;54450:147:::0;;;:::o;79698:47::-;;;;;;;;;;;;;;;:::o;84356:92::-;79915:2;84356:92;:::o;55498:218::-;55605:12;:10;:12::i;:::-;-1:-1:-1;;;;;55594:23:0;:7;-1:-1:-1;;;;;55594:23:0;;55586:83;;;;-1:-1:-1;;;55586:83:0;;;;;;;:::i;:::-;55682:26;55694:4;55700:7;55682:11;:26::i;:::-;55498:218;;:::o;85502:227::-;85599:4;85616:83;85625:12;:10;:12::i;:::-;85639:7;85648:50;85687:10;85648:11;:25;85660:12;:10;:12::i;:::-;-1:-1:-1;;;;;85648:25:0;;;;;;;;;;;;;;;;;-1:-1:-1;85648:25:0;;;:34;;;;;;;;;;;:38;:50::i;115324:301::-;-1:-1:-1;;;;;115493:33:0;;115416:7;115493:33;;;:24;:33;;;;;115416:7;;;;115472:55;;115481:10;;115472:8;:55::i;:::-;115436:91;;;;115547:11;:70;;-1:-1:-1;;;;;115593:15:0;;;;;;:6;:15;;;;;:22;115570:46;;:18;115600:7;115570:9;:18::i;:46::-;115547:70;;;115561:5;115547:70;115540:77;115324:301;-1:-1:-1;;;;;115324:301:0:o;86402:183::-;86473:39;52062:4;86501:10;86473:7;:39::i;:::-;86465:70;;;;-1:-1:-1;;;86465:70:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;86546:24:0;;;;;:15;:24;;;;;:31;;-1:-1:-1;;86546:31:0;86573:4;86546:31;;;86402:183::o;89123:551::-;89210:39;52062:4;89238:10;89210:7;:39::i;:::-;89202:70;;;;-1:-1:-1;;;89202:70:0;;;;;;;:::i;:::-;89302:11;;;-1:-1:-1;;;;;89302:11:0;;;89317:5;89283:31;;;:18;:31;;;;;;;;;:39;;-1:-1:-1;;89283:39:0;;;89333:13;:39;;-1:-1:-1;;;;;;89333:39:0;;;;;;;;;;;89383:19;;;;;;;;;;89420:20;;;;;;;:13;;;;;:18;;:20;;;;;89283:31;;89420:20;;;;;;:13;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;89413:4;:27;;-1:-1:-1;;;;;;89413:27:0;;;-1:-1:-1;;;;;89413:27:0;;;;;;89468:11;;;;;-1:-1:-1;89453:27:0;;;:14;:27;;;;;;;;:34;;-1:-1:-1;;89453:34:0;;;-1:-1:-1;89453:34:0;;;;;;89517:11;;;;89498:31;;:18;:31;;;;;:38;;;;;;;;89560:11;;89549:8;;;;:22;;89560:11;;;89549:22;;;;;;;89594:4;;89582:6;:9;;;;:16;;89594:4;;;;89582:16;;;;;;89611:40;89652:13;:11;:13::i;:::-;89611:55;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;104114:382::-;104184:32;77663:24;104205:10;104184:7;:32::i;:::-;104176:63;;;;-1:-1:-1;;;104176:63:0;;;;;;;:::i;:::-;104250:46;104279:1;104283:3;104288:7;104250:20;:46::i;:::-;104307:19;104313:3;104318:7;104307:5;:19::i;:::-;-1:-1:-1;;;;;104350:14:0;;;104376:1;104350:14;;;:9;:14;;;;;;;104347:80;;-1:-1:-1;;;;;104395:14:0;;;;;;:9;:14;;;;;:20;;-1:-1:-1;;;;;;104395:20:0;;;;;;104347:80;-1:-1:-1;;;;;104464:14:0;;;104460:1;104464:14;;;:9;:14;;;;;;104437:51;;104464:14;104480:7;104437:14;:51::i;104504:403::-;104561:32;77732:24;104582:10;104561:7;:32::i;:::-;104553:63;;;;-1:-1:-1;;;104553:63:0;;;;;;;:::i;:::-;104627:53;104648:10;104668:1;104672:7;104627:20;:53::i;:::-;104691:26;104697:10;104709:7;104691:5;:26::i;:::-;104743:10;104766:1;104733:21;;;:9;:21;;;;;;-1:-1:-1;;;;;104733:21:0;104730:101;;104809:10;104785:21;;;;:9;:21;;;;;:34;;-1:-1:-1;;;;;;104785:34:0;;;;;;104730:101;104866:10;104856:21;;;;:9;:21;;;;;;104841:58;;-1:-1:-1;;;;;104856:21:0;;;;104891:7;104841:14;:58::i;86023:182::-;86090:39;52062:4;86118:10;86090:7;:39::i;:::-;86082:70;;;;-1:-1:-1;;;86082:70:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;86163:27:0;;;;;:18;:27;;;;;:34;;-1:-1:-1;;86163:34:0;86193:4;86163:34;;;86023:182::o;91049:123::-;-1:-1:-1;;;;;91137:27:0;91113:4;91137:27;;;:18;:27;;;;;;;;;91049:123::o;113568:335::-;113651:39;52062:4;113679:10;113651:7;:39::i;:::-;113643:69;;;;-1:-1:-1;;;113643:69:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;113732:30:0;;;;;;:13;:30;;;;;;;;113724:120;;;;-1:-1:-1;;;113724:120:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;113856:30:0;113889:5;113856:30;;;:13;:30;;;;;:38;;-1:-1:-1;;113856:38:0;;;113568:335::o;80884:45::-;;;;;;;;;;;;-1:-1:-1;;;;;80884:45:0;;:::o;105457:104::-;105521:32;105531:10;105543:9;105521;:32::i;88234:469::-;88315:36;77805:28;88340:10;88315:7;:36::i;:::-;88307:67;;;;-1:-1:-1;;;88307:67:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;88393:26:0;;88385:71;;;;-1:-1:-1;;;88385:71:0;;;;;;;:::i;:::-;88467:31;:46;;-1:-1:-1;;;;;88467:46:0;;;-1:-1:-1;;;;;;88467:46:0;;;;;;;;88524:35;:50;;;;;;;;88585:34;:49;;;;;;;;88645:35;:50;;;;;;;;88234:469::o;111821:147::-;-1:-1:-1;;;;;111940:18:0;;111886:7;111940:18;;;:9;:18;;;;;;;;;111913:6;:15;;;;;:22;:46;;:26;:46::i;80381:30::-;;;;;;;;;:::o;112791:200::-;112877:39;52062:4;112905:10;112877:7;:39::i;:::-;112869:69;;;;-1:-1:-1;;;112869:69:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;112950:26:0;;;;;;;;:17;:26;;;;;:32;;-1:-1:-1;;112950:32:0;;;;;;;;;;112791:200::o;81313:49::-;;;;;;;;;;;;;;;:::o;84559:119::-;-1:-1:-1;;;;;84652:18:0;84625:7;84652:18;;;:9;:18;;;;;;;84559:119::o;59328:103::-;58908:12;:10;:12::i;:::-;-1:-1:-1;;;;;58897:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;58897:23:0;;58889:68;;;;-1:-1:-1;;;58889:68:0;;;;;;;:::i;:::-;59393:30:::1;59420:1;59393:18;:30::i;:::-;59328:103::o:0;108059:1242::-;108155:7;108202:12;108188:11;:26;108180:79;;;;-1:-1:-1;;;108180:79:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;108294:23:0;;108272:19;108294:23;;;:14;:23;;;;;;;;108332:17;108328:58;;108373:1;108366:8;;;;;108328:58;-1:-1:-1;;;;;108446:20:0;;;;;;:11;:20;;;;;108498:11;;108467:16;108482:1;108467:12;:16;:::i;:::-;108446:38;;;;;;;;;;;;;;;-1:-1:-1;108446:38:0;:48;;:63;108442:147;;-1:-1:-1;;;;;108533:20:0;;;;;;:11;:20;;;;;;108554:16;108569:1;108554:12;:16;:::i;:::-;108533:38;;;;;;;;;;;;;;;:44;;;108526:51;;;;;108442:147;-1:-1:-1;;;;;108650:20:0;;;;;;:11;:20;;;;;;;;:23;;;;;;;;:33;:23;:33;:47;-1:-1:-1;108646:88:0;;;108721:1;108714:8;;;;;108646:88;108746:12;;108788:16;108803:1;108788:12;:16;:::i;:::-;108773:31;;108815:428;108830:5;108822:13;;:5;:13;;;108815:428;;;108852:13;108894:1;108877:13;108885:5;108877;:13;:::i;:::-;108876:19;;;;:::i;:::-;108868:27;;:5;:27;:::i;:::-;-1:-1:-1;;;;;108960:20:0;;108937;108960;;;:11;:20;;;;;;;;:28;;;;;;;;;;;;;108937:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;108852:43;;-1:-1:-1;109007:27:0;;109003:229;;;109062:8;;;;-1:-1:-1;109055:15:0;;-1:-1:-1;;;;109055:15:0;109003:229;109096:12;;:26;;;-1:-1:-1;109092:140:0;;;109151:6;109143:14;;109092:140;;;109206:10;109215:1;109206:6;:10;:::i;:::-;109198:18;;109092:140;108815:428;;;;;-1:-1:-1;;;;;;109260:20:0;;;;;;:11;:20;;;;;;;;:27;;;;;;;;;;:33;;;;-1:-1:-1;;108059:1242:0;;;;:::o;79957:28::-;;;;;;;;;-1:-1:-1;;;;;79957:28:0;;:::o;103552:453::-;103629:32;77732:24;103650:10;103629:7;:32::i;:::-;103621:63;;;;-1:-1:-1;;;103621:63:0;;;;;;;:::i;:::-;103696:43;103712:5;103719:10;103731:7;103696:15;:43::i;:::-;103750:48;103771:5;103786:1;103790:7;103750:20;:48::i;:::-;103811:21;103817:5;103824:7;103811:5;:21::i;:::-;-1:-1:-1;;;;;103847:16:0;;;103875:1;103847:16;;;:9;:16;;;;;;;103844:88;;-1:-1:-1;;;;;103895:16:0;;;;;;:9;:16;;;;;:24;;-1:-1:-1;;;;;;103895:24:0;;;;;;103844:88;-1:-1:-1;;;;;103958:16:0;;;;;;;:9;:16;;;;;;103943:53;;103958:16;;103988:7;103943:14;:53::i;93156:189::-;93316:20;;93273:23;;93316:12;93227:27;93200:7;;93227:110;;93316:20;;93227:70;;:45;:70::i;81849:39::-;;;;;;;;;;;;;:::o;77996:26::-;;;;:::o;95722:1463::-;80536:11;80570:6;80566:105;80586:11;;80582:1;:15;80566:105;;;80622:8;;;;:5;:8;;;;;;-1:-1:-1;;;;;80622:8:0;80634:10;80622:22;80619:40;;;80655:4;80646:13;;80619:40;80599:3;;;;:::i;:::-;;;;80566:105;;;-1:-1:-1;80725:13:0;;-1:-1:-1;;;;;80725:13:0;80703:10;:36;;:59;;;80756:6;80703:59;80681:126;;;;-1:-1:-1;;;80681:126:0;;;;;;;:::i;:::-;95806:18:::1;95827:21;95842:5;95827:14;:21::i;:::-;95806:42;;95875:11;;95862:10;:24;95859:1319;;;95924:50;::::0;;;;95903:18:::1;::::0;-1:-1:-1;;;;;95924:23:0;::::1;::::0;::::1;::::0;:50:::1;::::0;95948:10:::1;::::0;95968:4:::1;::::0;95924:50:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;95903:71;;96006:6;95992:10;:20;95989:1178;;96033:61;::::0;;;;-1:-1:-1;;;;;96033:26:0;::::1;::::0;::::1;::::0;:61:::1;::::0;96060:10:::1;::::0;96080:4:::1;::::0;96087:6;;96033:61:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;96127:4:0::1;::::0;-1:-1:-1;;;;;96118:13:0;;::::1;96127:4:::0;::::1;96118:13;96115:1037;;96195:4;::::0;96180:46:::1;::::0;-1:-1:-1;;;96180:46:0;;96156:21:::1;::::0;-1:-1:-1;;;;;96195:4:0::1;::::0;96180:31:::1;::::0;:46:::1;::::0;96220:4:::1;::::0;96180:46:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;96156:70;;96249:25;96260:6;96268:5;96249:10;:25::i;:::-;96330:4;::::0;96315:46:::1;::::0;-1:-1:-1;;;96315:46:0;;96297:15:::1;::::0;96315:65:::1;::::0;96366:13;;-1:-1:-1;;;;;96330:4:0::1;::::0;96315:31:::1;::::0;:46:::1;::::0;96355:4:::1;::::0;96315:46:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:65::-;96297:83;;96513:16;96532:13;:11;:13::i;:::-;96513:32;;96568:28;96599:54;96644:8;96599:40;96611:12;:27;;;96599:7;:11;;:40;;;;:::i;:::-;:44:::0;::::1;:54::i;:::-;96685:4;::::0;96700:31;;96678:76:::1;::::0;-1:-1:-1;;;96678:76:0;;96568:85;;-1:-1:-1;;;;;;96685:4:0;;::::1;::::0;96678:21:::1;::::0;:76:::1;::::0;96700:31:::1;::::0;96568:85;;96678:76:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;96115:1037;;;;;;;96891:16;96910:13;:11;:13::i;:::-;96891:32;;96946:28;96977:53;97021:8;96977:39;96988:12;:27;;;96977:6;:10;;:39;;;;:::i;:53::-;97078:31:::0;;97055:77:::1;::::0;-1:-1:-1;;;97055:77:0;;96946:84;;-1:-1:-1;;;;;;97055:22:0;;::::1;::::0;::::1;::::0;:77:::1;::::0;97078:31:::1;::::0;96946:84;;97055:77:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;96115:1037;;;95859:1319;;80818:1;95722:1463:::0;;;:::o;115142:121::-;115205:7;58908:12;:10;:12::i;:::-;-1:-1:-1;;;;;58897:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;58897:23:0;;58889:68;;;;-1:-1:-1;;;58889:68:0;;;;;;;:::i;:::-;115232:23:::1;:21;:23::i;58677:87::-:0;58723:7;58750:6;-1:-1:-1;;;;;58750:6:0;58677:87;:::o;52926:147::-;53012:4;53036:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;53036:29:0;;;;;;;;;;;;;;;52926:147::o;84252:96::-;84333:7;;;;;;;;;;;;;;;;;84252:96;:::o;114701:67::-;58908:12;:10;:12::i;:::-;-1:-1:-1;;;;;58897:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;58897:23:0;;58889:68;;;;-1:-1:-1;;;58889:68:0;;;;;;;:::i;:::-;114749:11:::1;:9;:11::i;115633:234::-:0;115705:7;115726:16;115744:13;115761:43;115770:10;115782:21;115761:8;:43::i;:::-;115725:79;;;;115824:11;:35;;115846:13;:11;:13::i;:::-;115824:35;;;115838:5;115824:35;115817:42;115633:234;-1:-1:-1;;;;115633:234:0:o;78635:41::-;;;;;;;;;;;;;:::o;100933:186::-;101008:39;52062:4;101036:10;101008:7;:39::i;:::-;101000:70;;;;-1:-1:-1;;;101000:70:0;;;;;;;:::i;:::-;101081:28;;-1:-1:-1;;;;;101081:20:0;;;:28;;;;;101102:6;;101081:28;;;;101102:6;101081:20;:28;;;;;;;;;;;;;;;;;;;52017:49;52062:4;52017:49;:::o;85737:278::-;85839:4;85856:129;85865:12;:10;:12::i;:::-;85879:7;85888:96;85927:15;85888:96;;;;;;;;;;;;;;;;;:11;:25;85900:12;:10;:12::i;:::-;-1:-1:-1;;;;;85888:25:0;;;;;;;;;;;;;;;;;-1:-1:-1;85888:25:0;;;:34;;;;;;;;;;;:96;:38;:96::i;84686:167::-;84764:4;84781:42;84791:12;:10;:12::i;:::-;84805:9;84816:6;84781:9;:42::i;80265:19::-;;;-1:-1:-1;;;;;80265:19:0;;:::o;87020:587::-;87096:36;77805:28;87121:10;87096:7;:36::i;:::-;87088:67;;;;-1:-1:-1;;;87088:67:0;;;;;;;:::i;:::-;87210:24;;:16;87174:31;87256:4;;87174:78;;87240:11;;87174:61;;:31;:35;:61::i;:78::-;:86;;87166:121;;;;-1:-1:-1;;;87166:121:0;;;;;;;:::i;:::-;87298:23;:37;;;87346:27;:41;;;87431:15;:30;:47;;87324:11;87431:34;:47::i;:::-;87398:15;:80;87523:16;:31;:48;;87559:11;87523:35;:48::i;88711:400::-;88781:36;77805:28;88806:10;88781:7;:36::i;:::-;88773:67;;;;-1:-1:-1;;;88773:67:0;;;;;;;:::i;:::-;88891:16;:31;88859:27;;88941:4;;88859:78;;88928:8;;88859:64;;:27;:31;:64::i;:78::-;:86;;88851:121;;;;-1:-1:-1;;;88851:121:0;;;;;;;:::i;:::-;88983:17;:28;;;89022:24;:35;;;89068:24;:35;88711:400::o;107385:243::-;-1:-1:-1;;;;;107512:23:0;;107465:7;107512:23;;;:14;:23;;;;;;;;107553:16;:67;;107619:1;107553:67;;;-1:-1:-1;;;;;107572:20:0;;;;;;:11;:20;;;;;;107593:16;107608:1;107593:12;:16;:::i;:::-;107572:38;;;;;;;;;;;;;;;:44;;;107553:67;107546:74;107385:243;-1:-1:-1;;;107385:243:0:o;99982:639::-;100066:13;;:23;;;;;;;;100048:15;;-1:-1:-1;;;;;100066:13:0;;:21;;:23;;;;;;;;;;;;;;:13;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;100048:41;-1:-1:-1;100122:10:0;-1:-1:-1;;;;;100122:21:0;;;;:74;;-1:-1:-1;100182:13:0;;-1:-1:-1;;;;;100182:13:0;100160:10;:36;100122:74;:118;;;-1:-1:-1;100213:10:0;100235:4;100213:27;100122:118;100100:181;;;;-1:-1:-1;;;100100:181:0;;;;;;;:::i;:::-;100298:27;100319:5;100298:20;:27::i;:::-;100294:320;;-1:-1:-1;;;;;100342:25:0;;;;;;;:18;:25;;;;;;;;:32;;100370:4;-1:-1:-1;;100342:32:0;;;;;;;;100389:14;:21;;;;;:28;;;;;;;;;100440:11;;;100434:18;;:5;:18;;;;;:26;;-1:-1:-1;;;;;;100434:26:0;;;;;;;;100482:11;;100475:19;;:6;:19;;;;;;:28;;;;;;;;;;;;;;;100520:16;;;;100370:4;;100520:16;:::i;:::-;;;;-1:-1:-1;;;;;;;100553:34:0;;;100588:13;:11;:13::i;:::-;100553:49;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;80291:81::-;80330:42;80291:81;:::o;105995:1189::-;106184:23;81477:80;106313:6;:4;:6::i;:::-;106297:24;;;;;;106340:12;:10;:12::i;:::-;106379:4;106234:165;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;106210:200;;;;;;106184:226;;106423:18;81697:71;106535:9;106563:5;106587:6;106468:140;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;106444:175;;;;;;106423:196;;106632:14;106737:15;106771:10;106673:123;;;;;;;;;:::i;:::-;;;;;;;;;;;;;106649:158;;;;;;106632:175;;106820:17;106840:26;106850:6;106858:1;106861;106864;106840:26;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;106840:26:0;;-1:-1:-1;;106840:26:0;;;-1:-1:-1;;;;;;;106885:23:0;;106877:75;;;;-1:-1:-1;;;106877:75:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;106980:17:0;;;;;;:6;:17;;;;;:19;;;;;;:::i;:::-;;;;;106971:5;:28;106963:76;;;;-1:-1:-1;;;106963:76:0;;;;;;;:::i;:::-;107077:6;107058:15;:25;;107050:77;;;;-1:-1:-1;;;107050:77:0;;;;;;;:::i;:::-;107145:31;107155:9;107166;107145;:31::i;:::-;107138:38;;;;105995:1189;;;;;;;:::o;80232:26::-;;;-1:-1:-1;;;;;80232:26:0;;:::o;77625:62::-;77663:24;77625:62;:::o;54842:149::-;54926:18;54939:4;54926:12;:18::i;:::-;52508:30;52519:4;52525:12;:10;:12::i;52508:30::-;54957:26:::1;54969:4;54975:7;54957:11;:26::i;84861:143::-:0;-1:-1:-1;;;;;84969:18:0;;;84942:7;84969:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;84861:143::o;79926:24::-;;;;;;;;;-1:-1:-1;;;;;79926:24:0;;:::o;86593:187::-;86667:39;52062:4;86695:10;86667:7;:39::i;:::-;86659:70;;;;-1:-1:-1;;;86659:70:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;86740:24:0;86767:5;86740:24;;;:15;:24;;;;;:32;;-1:-1:-1;;86740:32:0;;;86593:187::o;81651:117::-;81697:71;81651:117;:::o;77763:70::-;77805:28;77763:70;:::o;86213:181::-;86278:39;52062:4;86306:10;86278:7;:39::i;:::-;86270:70;;;;-1:-1:-1;;;86270:70:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;86351:27:0;86381:5;86351:27;;;:18;:27;;;;;:35;;-1:-1:-1;;86351:35:0;;;86213:181::o;81174:70::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;59586:201::-;58908:12;:10;:12::i;:::-;-1:-1:-1;;;;;58897:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;58897:23:0;;58889:68;;;;-1:-1:-1;;;58889:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;59675:22:0;::::1;59667:73;;;;-1:-1:-1::0;;;59667:73:0::1;;;;;;;:::i;:::-;59751:28;59770:8;59751:18;:28::i;113198:296::-:0;113281:39;52062:4;113309:10;113281:7;:39::i;:::-;113273:69;;;;-1:-1:-1;;;113273:69:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;113363:33:0;;;;;;:13;:33;;;;;;;;113362:34;113354:79;;;;-1:-1:-1;;;113354:79:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;113445:33:0;;;;;:13;:33;;;;;:40;;-1:-1:-1;;113445:40:0;113481:4;113445:40;;;113198:296::o;101179:320::-;101270:39;52062:4;101298:10;101270:7;:39::i;:::-;101262:70;;;;-1:-1:-1;;;101262:70:0;;;;;;;:::i;:::-;101347:30;;-1:-1:-1;;;101347:30:0;;101380:6;;-1:-1:-1;;;;;101347:15:0;;;;;:30;;101371:4;;101347:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:39;101343:112;;;101413:30;;-1:-1:-1;;;101413:30:0;;-1:-1:-1;;;;;101413:15:0;;;;;:30;;101437:4;;101413:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;101404:39;;101343:112;101465:26;;-1:-1:-1;;;101465:26:0;;-1:-1:-1;;;;;101465:14:0;;;;;:26;;101480:2;;101484:6;;101465:26;;;:::i;63007:98::-;63065:7;63092:5;63096:1;63092;:5;:::i;22373:157::-;22482:40;;;22497:25;22482:40;22373:157;;;:::o;36884:98::-;36964:10;36884:98;:::o;91180:381::-;-1:-1:-1;;;;;91317:19:0;;91309:68;;;;-1:-1:-1;;;91309:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;91396:21:0;;91388:68;;;;-1:-1:-1;;;91388:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;91469:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;;:36;;;91521:32;;;;;91499:6;;91521:32;:::i;:::-;;;;;;;;91180:381;;;:::o;86788:172::-;86840:6;86835:118;86856:11;;86852:1;:15;86835:118;;;86902:8;;;;:5;:8;;;;;;-1:-1:-1;;;;;86902:8:0;86889:37;86927:13;:11;:13::i;:::-;86889:52;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;86869:3:0;;;;:::i;:::-;;;;86835:118;;91685:1304;-1:-1:-1;;;;;91817:18:0;;91809:68;;;;-1:-1:-1;;;91809:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;91896:16:0;;91888:64;;;;-1:-1:-1;;;91888:64:0;;;;;;;:::i;:::-;91980:1;91971:6;:10;91963:64;;;;-1:-1:-1;;;91963:64:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;92047:17:0;;;;;;:13;:17;;;;;;;;92046:18;92038:27;;;;;;92076:38;92097:4;92103:2;92107:6;92076:20;:38::i;:::-;92130:25;92148:6;92130:17;:25::i;:::-;92127:54;;;92158:20;:18;:20::i;:::-;-1:-1:-1;;;;;92196:21:0;;;;;;:17;:21;;;;;;;;92193:155;;;-1:-1:-1;;;;;92259:12:0;;92236:20;92259:12;;;:6;:12;;;;;:19;:31;;92283:6;92259:23;:31::i;:::-;92236:54;;92306:29;92316:4;92322:12;92306:9;:29::i;:::-;92193:155;;-1:-1:-1;;;;;92362:23:0;;;;;;:17;:23;;;;;;;;92359:152;;;-1:-1:-1;;;;;92426:10:0;;92403:20;92426:10;;;:6;:10;;;;;:17;:29;;92448:6;92426:21;:29::i;:::-;92403:52;;92471:27;92481:2;92485:12;92471:9;:27::i;:::-;92359:152;;-1:-1:-1;;;;;92625:18:0;;92594:13;92625:18;;;:14;:18;;;;;;;;:52;;;;-1:-1:-1;92663:13:0;;-1:-1:-1;;;;;92647:30:0;;;92663:13;;92647:30;;92625:52;:80;;;;;92682:23;92700:4;92682:17;:23::i;:::-;92681:24;92625:80;92622:261;;;-1:-1:-1;92732:1:0;92622:261;;;-1:-1:-1;;;;;92754:21:0;;;;;;:15;:21;;;;;;;;92751:132;;;-1:-1:-1;92802:1:0;92751:132;;;-1:-1:-1;;;;;92824:19:0;;;;;;:15;:19;;;;;;;;92821:62;;;-1:-1:-1;92870:1:0;92821:62;92940:41;92955:4;92961:2;92965:6;92973:7;92940:14;:41::i;65286:240::-;65406:7;65467:12;65459:6;;;;65451:29;;;;-1:-1:-1;;;65451:29:0;;;;;;;;:::i;:::-;-1:-1:-1;;;65502:5:0;;;65286:240::o;63388:98::-;63446:7;63473:5;63477:1;63473;:5;:::i;53363:505::-;53452:22;53460:4;53466:7;53452;:22::i;:::-;53447:414;;53640:41;53668:7;-1:-1:-1;;;;;53640:41:0;53678:2;53640:19;:41::i;:::-;53754:38;53782:4;53789:2;53754:19;:38::i;:::-;53545:270;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;53545:270:0;;;;;;;;;;-1:-1:-1;;;53491:358:0;;;;;;;:::i;56999:238::-;57083:22;57091:4;57097:7;57083;:22::i;:::-;57078:152;;57122:12;;;;57154:4;57122:12;;;;;;;;-1:-1:-1;;;;;57122:29:0;;;;;;;;;;:36;;-1:-1:-1;;57122:36:0;;;;;;57205:12;:10;:12::i;:::-;-1:-1:-1;;;;;57178:40:0;57196:7;-1:-1:-1;;;;;57178:40:0;57190:4;57178:40;;;;;;;;;;56999:238;;:::o;57369:239::-;57453:22;57461:4;57467:7;57453;:22::i;:::-;57449:152;;;57524:5;57492:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;57492:29:0;;;;;;;;;:37;;-1:-1:-1;;57492:37:0;;;57576:12;:10;:12::i;:::-;-1:-1:-1;;;;;57549:40:0;57567:7;-1:-1:-1;;;;;57549:40:0;57561:4;57549:40;;;;;;;;;;57369:239;;:::o;115875:493::-;115964:4;115970:7;116011:1;115998:10;:14;115990:49;;;;-1:-1:-1;;;115990:49:0;;;;;;;:::i;:::-;116072:23;:21;:23::i;:::-;116058:10;:37;;116050:79;;;;-1:-1:-1;;;116050:79:0;;;;;;;:::i;:::-;116142:13;116158:40;:9;116187:10;116158:28;:40::i;:::-;116224:20;;116142:56;;-1:-1:-1;116215:29:0;;116211:150;;;116269:5;116276:1;116261:17;;;;;;;116211:150;116319:4;116325:9;:16;;116342:5;116325:23;;;;;;-1:-1:-1;;;116325:23:0;;;;;;;;;;;;;;;;;116311:38;;;;;115875:493;;;;;;:::o;117273:622::-;117416:44;117443:4;117449:2;117453:6;117416:26;:44::i;:::-;-1:-1:-1;;;;;117477:18:0;;117473:415;;117533:26;117556:2;117533:22;:26::i;:::-;117574:28;:26;:28::i;:::-;117473:415;;;-1:-1:-1;;;;;117624:16:0;;117620:268;;117678:28;117701:4;117678:22;:28::i;117620:268::-;117807:28;117830:4;117807:22;:28::i;:::-;117850:26;117873:2;117850:22;:26::i;102549:307::-;-1:-1:-1;;;;;102634:21:0;;102626:65;;;;-1:-1:-1;;;102626:65:0;;;;;;;:::i;:::-;102714:7;;:19;;102726:6;102714:11;:19::i;:::-;102704:7;:29;-1:-1:-1;;;;;102765:18:0;;;;;;:9;:18;;;;;;:30;;102788:6;102765:22;:30::i;:::-;-1:-1:-1;;;;;102744:18:0;;;;;;:9;:18;;;;;;:51;;;;102811:37;;102744:18;;;102811:37;;;;102841:6;;102811:37;:::i;:::-;;;;;;;;102549:307;;:::o;109749:947::-;109855:6;-1:-1:-1;;;;;109845:16:0;:6;-1:-1:-1;;;;;109845:16:0;;;:30;;;;;109874:1;109865:6;:10;109845:30;109841:848;;;-1:-1:-1;;;;;109896:20:0;;;109892:385;;-1:-1:-1;;;;;110004:22:0;;109985:16;110004:22;;;:14;:22;;;;;;;;;110065:13;:60;;110124:1;110065:60;;;-1:-1:-1;;;;;110081:19:0;;;;;;:11;:19;;;;;;110101:13;110113:1;110101:9;:13;:::i;:::-;110081:34;;;;;;;;;;;;;;;:40;;;110065:60;110045:80;-1:-1:-1;110144:17:0;110164:21;110045:80;110178:6;110164:13;:21::i;:::-;110144:41;;110204:57;110221:6;110229:9;110240;110251;110204:16;:57::i;:::-;109892:385;;;;-1:-1:-1;;;;;110297:20:0;;;110293:385;;-1:-1:-1;;;;;110405:22:0;;110386:16;110405:22;;;:14;:22;;;;;;;;;110466:13;:60;;110525:1;110466:60;;;-1:-1:-1;;;;;110482:19:0;;;;;;:11;:19;;;;;;110502:13;110514:1;110502:9;:13;:::i;:::-;110482:34;;;;;;;;;;;;;;;:40;;;110466:60;110446:80;-1:-1:-1;110545:17:0;110565:21;110446:80;110579:6;110565:13;:21::i;:::-;110545:41;;110605:57;110622:6;110630:9;110641;110652;110605:16;:57::i;103188:350::-;-1:-1:-1;;;;;103274:21:0;;103266:67;;;;-1:-1:-1;;;103266:67:0;;;;;;;:::i;:::-;103366:68;103389:6;103366:68;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;103366:18:0;;;;;;:9;:18;;;;;;;:68;:22;:68::i;:::-;-1:-1:-1;;;;;103345:18:0;;;;;;:9;:18;;;;;:89;103456:7;;:19;;103468:6;103456:11;:19::i;:::-;103446:7;:29;103492:37;;103518:1;;-1:-1:-1;;;;;103492:37:0;;;;;;;103522:6;;103492:37;:::i;109309:432::-;-1:-1:-1;;;;;109422:20:0;;;109396:23;109422:20;;;:9;:20;;;;;;;;;;109480;109432:9;109480;:20::i;:::-;-1:-1:-1;;;;;109556:20:0;;;;;;;:9;:20;;;;;;:32;;-1:-1:-1;;;;;;109556:32:0;;;;;;;;;;109606:54;;109453:47;;-1:-1:-1;109556:32:0;109606:54;;;;;;109556:20;109606:54;109673:60;109688:15;109705:9;109716:16;109673:14;:60::i;59947:191::-;60021:16;60040:6;;-1:-1:-1;;;;;60057:17:0;;;-1:-1:-1;;;;;;60057:17:0;;;;;;60090:40;;60040:6;;;;;;;60090:40;;60021:16;60090:40;59947:191;;:::o;101794:474::-;101943:24;101970:25;101980:5;101987:7;101970:9;:25::i;:::-;101943:52;;-1:-1:-1;;102011:16:0;:37;102007:253;;102094:6;102074:16;:26;;102066:68;;;;-1:-1:-1;;;102066:68:0;;;;;;;:::i;:::-;102180:51;102189:5;102196:7;102224:6;102205:16;:25;102180:8;:51::i;99716:258::-;99779:7;99799:13;99815:11;;99829:1;99815:15;;;;:::i;:::-;99799:31;;99845:9;99841:101;99864:11;;99860:1;:15;99841:101;;;99900:9;;;;:6;:9;;;;;;-1:-1:-1;;;;;99900:19:0;;;:9;;:19;99897:33;;;99929:1;99921:9;;99897:33;99877:3;;;;:::i;:::-;;;;99841:101;;;-1:-1:-1;99961:5:0;99716:258;-1:-1:-1;;99716:258:0:o;97193:439::-;97288:16;;;97302:1;97288:16;;;;;;;;97264:21;;97288:16;;;;;;;;;;-1:-1:-1;97288:16:0;97264:40;;97325:5;97315:4;97320:1;97315:7;;;;;;-1:-1:-1;;;97315:7:0;;;;;;;;;-1:-1:-1;;;;;97315:15:0;;;:7;;;;;;;;;:15;97351:4;;97341:7;;97351:4;;;97341;;97351;;97341:7;;;;-1:-1:-1;;;97341:7:0;;;;;;;;;-1:-1:-1;;;;;97341:14:0;;;:7;;;;;;;;;:14;97398:13;;97368:53;;-1:-1:-1;;;97368:53:0;;:21;;;;;;:53;;97398:13;;;97414:6;;97368:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;97432:13:0;;:192;;-1:-1:-1;;;97432:192:0;;-1:-1:-1;;;;;97432:13:0;;;;:67;;:192;;97514:6;;97432:13;;97551:4;;97578;;97598:15;;97432:192;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97193:439;;;:::o;63745:98::-;63803:7;63830:5;63834:1;63830;:5;:::i;64144:98::-;64202:7;64229:5;64233:1;64229;:5;:::i;115007:127::-;115071:7;115098:28;:18;:26;:28::i;114776:223::-;114823:7;114843:30;:18;:28;:30::i;:::-;114886:17;114906:23;:21;:23::i;:::-;114886:43;;114945:19;114954:9;114945:19;;;;;;:::i;:::-;;;;;;;;114982:9;-1:-1:-1;114776:223:0;:::o;100629:248::-;100697:4;;;100744:100;100764:11;;100760:1;:15;100744:100;;;100800:8;;;;:5;:8;;;;;;-1:-1:-1;;;;;100800:17:0;;;:8;;:17;100797:35;;;100828:4;100819:13;;100797:35;100777:3;;;;:::i;:::-;;;;100744:100;;111582:153;111692:9;111582:153;:::o;97696:455::-;97800:11;;97762:4;;-1:-1:-1;;;;;97800:11:0;97786:10;:25;;;;:45;;-1:-1:-1;97825:6:0;;-1:-1:-1;;;97825:6:0;;;;97824:7;97786:45;:85;;;;-1:-1:-1;97844:8:0;:27;;;97786:85;:177;;;;-1:-1:-1;97916:31:0;;97884:29;;97951:12;;97884:63;;;:::i;:::-;:79;;97786:177;:302;;;;-1:-1:-1;98062:26:0;;98027:4;;98012:46;;-1:-1:-1;;;98012:46:0;;-1:-1:-1;;;;;98027:4:0;;;;98012:31;;:46;;98052:4;;98012:46;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:76;;97786:302;:357;;;;-1:-1:-1;;98111:32:0;;-1:-1:-1;98101:42:0;;97696:455::o;98189:383::-;98249:26;;98239:51;;80330:42;98239:9;:51::i;:::-;98333:12;98301:29;:44;98426:26;;98390:31;;:63;;:35;:63::i;:::-;98356:31;:97;;;98501:23;;-1:-1:-1;98464:101:0;;;98527:8;:35;;-1:-1:-1;;98527:35:0;;;98189:383::o;111975:387::-;112060:1;112051:6;:10;:40;;;;-1:-1:-1;;;;;;112065:14:0;;;;;;:6;:14;;;;;:21;:26;112051:40;112048:188;;;112108:17;112118:6;112108:9;:17::i;:::-;112048:188;;;112146:11;;:40;;;;-1:-1:-1;;;;;;112161:14:0;;112185:1;112161:14;;;:6;:14;;;;;:21;:25;;112146:40;112143:93;;;112203:20;112216:6;112203:12;:20::i;:::-;-1:-1:-1;;;;;112277:14:0;;;;;;:6;:14;;;;;:21;112261:11;;:50;;112304:6;;112261:38;;:15;:38::i;:50::-;112247:11;:64;-1:-1:-1;;;;;112323:14:0;;;;;;;:6;:14;;;;;:30;111975:387::o;93426:1608::-;93538:12;;;93535:257;;93567:14;:12;:14::i;:::-;93535:257;;;93602:7;:12;;93613:1;93602:12;93599:193;;;93631:12;:10;:12::i;93599:193::-;93664:7;:12;;93675:1;93664:12;93661:131;;;93693:18;:16;:18::i;93661:131::-;93732:7;:12;;93743:1;93732:12;93729:63;;;93761:19;:17;:19::i;:::-;93804:24;93831:18;93842:6;93831:10;:18::i;:::-;93804:45;;93880:53;93902:6;93880:53;;;;;;;;;;;;;;;;;:9;:17;93890:6;-1:-1:-1;;;;;93880:17:0;-1:-1:-1;;;;;93880:17:0;;;;;;;;;;;;;:21;;:53;;;;;:::i;:::-;-1:-1:-1;;;;;93860:17:0;;;;;;;:9;:17;;;;;;:73;;;;93992:22;;93967:20;;;;;;;;;;:48;;:24;:48::i;:::-;-1:-1:-1;;;;;93944:20:0;;;;;;:9;:20;;;;;:71;94026:18;94036:7;94026:9;:18::i;:::-;94079:9;-1:-1:-1;;;;;94062:51:0;94071:6;-1:-1:-1;;;;;94062:51:0;;94090:7;:22;;;94062:51;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;94129:17:0;;;94158:1;94129:17;;;:9;:17;;;;;;;94126:89;;-1:-1:-1;;;;;94177:17:0;;;;;;:9;:17;;;;;:26;;-1:-1:-1;;;;;;94177:26:0;;;;;;94126:89;-1:-1:-1;;;;;94230:20:0;;;94262:1;94230:20;;;:9;:20;;;;;;;94227:98;;-1:-1:-1;;;;;94281:20:0;;;;;;:9;:20;;;;;:32;;-1:-1:-1;;;;;;94281:32:0;;;;;;94227:98;94350:22;;94340:32;;94337:432;;;-1:-1:-1;;;;;94405:17:0;;;;;;;:9;:17;;;;;;;94424:20;;;;;;;;94390:63;;94405:17;;;;94424:20;94446:6;94390:14;:63::i;:::-;94337:432;;;-1:-1:-1;;;;;94503:17:0;;;;;;;:9;:17;;;;;;;94522:20;;;;;;;;94544:22;;94488:79;;94503:17;;;;94522:20;;;;;94488:14;:79::i;:::-;-1:-1:-1;;;;;94598:17:0;;;;;;;:9;:17;;;;;;;;;94627:31;;;;94617:42;;;;;94661:19;;;;94583:98;;94598:17;;;;94617:42;;;;;94583:14;:98::i;:::-;-1:-1:-1;;;;;94712:17:0;;;;;;;:9;:17;;;;;;94743:12;;;;94697:59;;94712:17;;;;;;94697:14;:59::i;:::-;94784:12;;;;;:28;;;94800:7;:12;;94811:1;94800:12;94784:28;94781:246;;;94829:15;:13;:15::i;:::-;94781:246;;;94865:7;:12;;94876:1;94865:12;:28;;;;94881:7;:12;;94892:1;94881:12;94865:28;94862:165;;;94910:15;:13;:15::i;:::-;94962:31;;94995:19;;;;94945:70;;-1:-1:-1;;;;;94962:31:0;;;;94945:70;;;;;;;94995:19;94945:70;:::i;:::-;;;;;;;;93426:1608;;;;;:::o;24203:451::-;24278:13;24304:19;24336:10;24340:6;24336:1;:10;:::i;:::-;:14;;24349:1;24336:14;:::i;:::-;24326:25;;;;;;-1:-1:-1;;;24326:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;24326:25:0;;24304:47;;24362:15;:6;24369:1;24362:9;;;;;;-1:-1:-1;;;24362:9:0;;;;;;;;;;;;:15;-1:-1:-1;;;;;24362:15:0;;;;;;;;;24388;:6;24395:1;24388:9;;;;;;-1:-1:-1;;;24388:9:0;;;;;;;;;;;;:15;-1:-1:-1;;;;;24388:15:0;;;;;;;;-1:-1:-1;24419:9:0;24431:10;24435:6;24431:1;:10;:::i;:::-;:14;;24444:1;24431:14;:::i;:::-;24419:26;;24414:135;24451:1;24447;:5;24414:135;;;24486:12;24499:5;24507:3;24499:11;24486:25;;;;;-1:-1:-1;;;24486:25:0;;;;;;;;;;;;24474:6;24481:1;24474:9;;;;;;-1:-1:-1;;;24474:9:0;;;;;;;;;;;;:37;-1:-1:-1;;;;;24474:37:0;;;;;;;;-1:-1:-1;24536:1:0;24526:11;;;;;24454:3;;;:::i;:::-;;;24414:135;;;-1:-1:-1;24567:10:0;;24559:55;;;;-1:-1:-1;;;24559:55:0;;;;;;;:::i;19666:918::-;19779:12;;19755:7;;19775:58;;-1:-1:-1;19820:1:0;19813:8;;19775:58;19886:12;;19845:11;;19911:424;19924:4;19918:3;:10;19911:424;;;19945:11;19959:23;19972:3;19977:4;19959:12;:23::i;:::-;19945:37;;20216:7;20203:5;20209:3;20203:10;;;;;;-1:-1:-1;;;20203:10:0;;;;;;;;;;;;;;;;;:20;20199:125;;;20251:3;20244:10;;20199:125;;;20301:7;:3;20307:1;20301:7;:::i;:::-;20295:13;;20199:125;19911:424;;;;20461:1;20455:3;:7;:36;;;;-1:-1:-1;20484:7:0;20466:5;20472:7;20478:1;20472:3;:7;:::i;:::-;20466:14;;;;;;-1:-1:-1;;;20466:14:0;;;;;;;;;;;;;;;;;:25;20455:36;20451:126;;;20515:7;20521:1;20515:3;:7;:::i;:::-;20508:14;;;;;;20451:126;-1:-1:-1;20562:3:0;-1:-1:-1;20555:10:0;;116425:176;-1:-1:-1;;;;;116509:33:0;;;;;;:24;:33;;;;;;;;116568:6;:15;;;;;;:22;116493:100;;116509:33;116545:46;;:18;116534:7;116545:9;:18::i;:46::-;116493:15;:100::i;116609:118::-;116666:53;116682:21;116705:13;:11;:13::i;110704:701::-;110879:18;110900:77;110907:12;110900:77;;;;;;;;;;;;;;;;;:6;:77::i;:::-;110879:98;;111009:1;110994:12;:16;;;:85;;;;-1:-1:-1;;;;;;111014:22:0;;;;;;:11;:22;;;;;:65;;;;111037:16;111052:1;111037:12;:16;:::i;:::-;111014:40;;;;;;;;;;;;;;;-1:-1:-1;111014:40:0;:50;;:65;110994:85;110990:339;;;-1:-1:-1;;;;;111096:22:0;;;;;;:11;:22;;;;;111145:8;;111119:16;111134:1;111119:12;:16;:::i;:::-;111096:40;;;;;;;;;;;;;-1:-1:-1;111096:40:0;:46;;:57;110990:339;;;111225:33;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;111186:22:0;;-1:-1:-1;111186:22:0;;;:11;:22;;;;;:36;;;;;;;;;;;:72;;;;-1:-1:-1;;111186:72:0;;;;;;;;-1:-1:-1;111186:72:0;;;;111301:16;;111186:36;;111301:16;:::i;:::-;-1:-1:-1;;;;;111273:25:0;;;;;;:14;:25;;;;;:44;;-1:-1:-1;;111273:44:0;;;;;;;;;;;;110990:339;111367:9;-1:-1:-1;;;;;111346:51:0;;111378:8;111388;111346:51;;;;;;;:::i;:::-;;;;;;;;110704:701;;;;;:::o;17127:114::-;17219:14;;17127:114::o;17249:127::-;17338:19;;17356:1;17338:19;;;17249:127::o;98623:440::-;80460:6;:13;;-1:-1:-1;;;;80460:13:0;-1:-1:-1;;;80460:13:0;;;98723:16:::1;::::0;;98737:1:::1;98723:16:::0;;;;;::::1;::::0;;-1:-1:-1;;98723:16:0::1;::::0;::::1;::::0;;::::1;::::0;::::1;-1:-1:-1::0;;98760:4:0::1;::::0;98750:7;;;;-1:-1:-1;;;;;;98760:4:0::1;::::0;98750:7;;-1:-1:-1;98760:4:0::1;::::0;98750:7:::1;;-1:-1:-1::0;;;98750:7:0::1;;;;;;;;;;;;;;:14;-1:-1:-1::0;;;;;98750:14:0::1;;;-1:-1:-1::0;;;;;98750:14:0::1;;;::::0;::::1;98793:4;98775;98780:1;98775:7;;;;;;-1:-1:-1::0;;;98775:7:0::1;;;;;;;;;-1:-1:-1::0;;;;;98775:23:0;;::::1;:7;::::0;;::::1;::::0;;;;;:23;98818:4:::1;::::0;98840:13:::1;::::0;98811:52:::1;::::0;-1:-1:-1;;;98811:52:0;;98818:4;;::::1;::::0;98811:20:::1;::::0;:52:::1;::::0;98840:13;;::::1;::::0;98856:6;;98811:52:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;98874:13:0::1;::::0;:181:::1;::::0;-1:-1:-1;;;98874:181:0;;-1:-1:-1;;;;;98874:13:0;;::::1;::::0;:67:::1;::::0;:181:::1;::::0;98956:6;;98874:13:::1;::::0;98993:4;;99012:2;;99029:15:::1;::::0;98874:181:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;80478:6:0;:14;;-1:-1:-1;;;;80478:14:0;;;-1:-1:-1;;;;;98623:440:0:o;112369:135::-;112449:7;:14;;-1:-1:-1;;;;;112425:21:0;;;;;;;:13;:21;;;;;:38;;;112475:20;;;;;;;;;;;;;;;-1:-1:-1;;;;;;112475:20:0;;;;;;112369:135::o;112511:227::-;112603:7;112611:14;;:16;;112626:1;;112611:16;:::i;:::-;112603:25;;;;;;-1:-1:-1;;;112603:25:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;112578:21:0;;;;;:13;:21;;;;;;;;112570:7;:30;;112603:25;;;;;112570:7;:30;;;;-1:-1:-1;;;112570:30:0;;;;;;;;;;;;;;;;;;;;;:58;;-1:-1:-1;;;;;;112570:58:0;-1:-1:-1;;;;;112570:58:0;;;;;;112683:21;;;;;:13;:21;;;;;;;;112654:7;112662:14;;112683:21;;:13;112570:30;112662:16;;-1:-1:-1;;112662:16:0;:::i;:::-;112654:25;;;;;;-1:-1:-1;;;112654:25:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;112654:25:0;112640:40;;;;;;;;;;;;:64;112716:7;:13;;;;;-1:-1:-1;;;112716:13:0;;;;;;;;;;;;;;;;;;-1:-1:-1;;112716:13:0;;;;;-1:-1:-1;;;;;;112716:13:0;;;;;;-1:-1:-1;112511:227:0:o;90452:115::-;90511:12;90495:28;;:13;:28;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;90495:28:0;;;-1:-1:-1;;;;;;90495:28:0;;;;;;;90549:10;90534:25;;;;;;;;;;;;;;;;;;;;;;;;;;;90452:115::o;90575:112::-;90632:12;90616:28;;:13;:28;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;90616:28:0;;;-1:-1:-1;;;;;;90616:28:0;;;;;;;90670:9;90655:24;;;;;;;;;;;;;;;;;;;;;;;;;;;90575:112::o;90695:124::-;90758:12;90742:28;;:13;:28;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;90742:28:0;;;-1:-1:-1;;;;;;90742:28:0;;;;;;;90796:15;90781:30;;;;;;;;;;;;;;;;;;;;;;;;;;;90695:124::o;90827:126::-;90891:12;90875:28;;:13;:28;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;90875:28:0;;;-1:-1:-1;;;;;;90875:28:0;;;;;;;90929:16;90914:31;;;;;;;;;;;;;;;;;;;;;;;;;;;90827:126::o;89770:471::-;89829:16;;:::i;:::-;89858:23;89884:220;;;;;;;;89908:1;89884:220;;;;89924:50;89937:7;89946:12;:27;;;89924:12;:50::i;:::-;89884:220;;;;89989:46;90002:7;90011:12;:23;;;89989:12;:46::i;:::-;89884:220;;;;90050:43;90063:7;90072:12;:20;;;90050:12;:43::i;:::-;89884:220;;;89858:246;;90141:68;90197:6;:11;;;90141:51;90177:6;:14;;;90141:31;90153:6;:18;;;90141:7;:11;;:31;;;;:::i;:68::-;90117:92;;;89770:471;-1:-1:-1;;89770:471:0:o;95042:168::-;95114:18;;;;95134:31;;95105:61;;95114:18;-1:-1:-1;;;;;95134:31:0;95105:8;:61::i;:::-;95177:25;95190:6;:11;;;95177:12;:25::i;90961:80::-;91020:13;91005:28;:12;:28;;;;;;;;;;;;;;-1:-1:-1;;;;;;91005:28:0;-1:-1:-1;;;;;91005:28:0;;;;;;;;;90961:80::o;18450:156::-;18512:7;18587:11;18597:1;18588:5;;;18587:11;:::i;:::-;18577:21;;18578:5;;;18577:21;:::i;116735:310::-;116830:17;116850:23;:21;:23::i;:::-;116830:43;-1:-1:-1;116830:43:0;116888:30;116904:9;116888:15;:30::i;:::-;:42;116884:154;;;116947:29;;;;;;;;-1:-1:-1;116947:29:0;;;;;;;;;;;;;;116991:16;;;:35;;;;;;;;;;;;;;;116735:310::o;111413:161::-;111488:6;111526:12;111519:5;111515:9;;111507:32;;;;-1:-1:-1;;;111507:32:0;;;;;;;;:::i;:::-;-1:-1:-1;111564:1:0;;111413:161;-1:-1:-1;;111413:161:0:o;90249:195::-;90324:7;90347:9;90344:22;;-1:-1:-1;90365:1:0;90358:8;;90344:22;90384:52;90420:5;90384:17;:7;90396:4;90384:11;:17::i;95218:218::-;-1:-1:-1;;;;;95294:23:0;;95291:35;;95319:7;;95291:35;95339:12;95336:24;;95353:7;;95336:24;-1:-1:-1;;;;;95395:20:0;;;;;;:9;:20;;;;;;:33;;95420:7;95395:24;:33::i;:::-;-1:-1:-1;;;;;95372:20:0;;;;;;:9;:20;;;;;:56;95218:218;;:::o;95444:202::-;95504:11;95501:23;;95517:7;;95501:23;95581:4;95563:24;;;;:9;:24;;;;;;:36;;95592:6;95563:28;:36::i;:::-;95554:4;95536:24;;;;:9;:24;;;;;:63;;;;95610:28;;95631:6;95610:5;:28::i;117053:212::-;117147:10;;117123:7;;117143:115;;-1:-1:-1;117186:1:0;117179:8;;117143:115;117231:10;;117227:3;;117231:14;;117244:1;;117231:14;:::i;:::-;117227:19;;;;;;-1:-1:-1;;;117227:19:0;;;;;;;;;;;;;;;;;117220:26;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:259:1:-;;126:2;114:9;105:7;101:23;97:32;94:2;;;147:6;139;132:22;94:2;191:9;178:23;210:33;237:5;210:33;:::i;278:263::-;;401:2;389:9;380:7;376:23;372:32;369:2;;;422:6;414;407:22;369:2;459:9;453:16;478:33;505:5;478:33;:::i;546:402::-;;;675:2;663:9;654:7;650:23;646:32;643:2;;;696:6;688;681:22;643:2;740:9;727:23;759:33;786:5;759:33;:::i;:::-;811:5;-1:-1:-1;868:2:1;853:18;;840:32;881:35;840:32;881:35;:::i;:::-;935:7;925:17;;;633:315;;;;;:::o;953:470::-;;;;1099:2;1087:9;1078:7;1074:23;1070:32;1067:2;;;1120:6;1112;1105:22;1067:2;1164:9;1151:23;1183:33;1210:5;1183:33;:::i;:::-;1235:5;-1:-1:-1;1292:2:1;1277:18;;1264:32;1305:35;1264:32;1305:35;:::i;:::-;1057:366;;1359:7;;-1:-1:-1;;;1413:2:1;1398:18;;;;1385:32;;1057:366::o;1428:396::-;;;1554:2;1542:9;1533:7;1529:23;1525:32;1522:2;;;1575:6;1567;1560:22;1522:2;1619:9;1606:23;1638:33;1665:5;1638:33;:::i;:::-;1690:5;-1:-1:-1;1747:2:1;1732:18;;1719:32;1760;1719;1760;:::i;1829:327::-;;;1958:2;1946:9;1937:7;1933:23;1929:32;1926:2;;;1979:6;1971;1964:22;1926:2;2023:9;2010:23;2042:33;2069:5;2042:33;:::i;:::-;2094:5;2146:2;2131:18;;;;2118:32;;-1:-1:-1;;;1916:240:1:o;2161:709::-;;;;;;;2356:3;2344:9;2335:7;2331:23;2327:33;2324:2;;;2378:6;2370;2363:22;2324:2;2422:9;2409:23;2441:33;2468:5;2441:33;:::i;:::-;2493:5;-1:-1:-1;2545:2:1;2530:18;;2517:32;;-1:-1:-1;2596:2:1;2581:18;;2568:32;;-1:-1:-1;2652:2:1;2637:18;;2624:32;2700:4;2687:18;;2675:31;;2665:2;;2725:6;2717;2710:22;2665:2;2314:556;;;;-1:-1:-1;2314:556:1;;2807:3;2792:19;;2779:33;;2859:3;2844:19;;;2831:33;;-1:-1:-1;2314:556:1;-1:-1:-1;;2314:556:1:o;2875:441::-;;;3003:2;2991:9;2982:7;2978:23;2974:32;2971:2;;;3024:6;3016;3009:22;2971:2;3068:9;3055:23;3087:33;3114:5;3087:33;:::i;:::-;3139:5;-1:-1:-1;3196:2:1;3181:18;;3168:32;3244:10;3231:24;;3219:37;;3209:2;;3275:6;3267;3260:22;3321:257;;3441:2;3429:9;3420:7;3416:23;3412:32;3409:2;;;3462:6;3454;3447:22;3409:2;3499:9;3493:16;3518:30;3542:5;3518:30;:::i;3583:527::-;;;;;;3760:3;3748:9;3739:7;3735:23;3731:33;3728:2;;;3782:6;3774;3767:22;3728:2;3826:9;3813:23;3845:30;3869:5;3845:30;:::i;:::-;3894:5;3946:2;3931:18;;3918:32;;-1:-1:-1;3997:2:1;3982:18;;3969:32;;4048:2;4033:18;;4020:32;;-1:-1:-1;4099:3:1;4084:19;4071:33;;-1:-1:-1;3718:392:1;-1:-1:-1;;;3718:392:1:o;4115:190::-;;4227:2;4215:9;4206:7;4202:23;4198:32;4195:2;;;4248:6;4240;4233:22;4195:2;-1:-1:-1;4276:23:1;;4185:120;-1:-1:-1;4185:120:1:o;4310:327::-;;;4439:2;4427:9;4418:7;4414:23;4410:32;4407:2;;;4460:6;4452;4445:22;4407:2;4501:9;4488:23;4478:33;;4561:2;4550:9;4546:18;4533:32;4574:33;4601:5;4574:33;:::i;4642:352::-;;4753:2;4741:9;4732:7;4728:23;4724:32;4721:2;;;4774:6;4766;4759:22;4721:2;4818:9;4805:23;4868:66;4861:5;4857:78;4850:5;4847:89;4837:2;;4955:6;4947;4940:22;4999:484;;;;5159:2;5147:9;5138:7;5134:23;5130:32;5127:2;;;5180:6;5172;5165:22;5127:2;5224:9;5211:23;5243:33;5270:5;5243:33;:::i;:::-;5295:5;-1:-1:-1;5347:2:1;5332:18;;5319:32;;-1:-1:-1;5403:2:1;5388:18;;5375:32;5416:35;5375:32;5416:35;:::i;:::-;5470:7;5460:17;;;5117:366;;;;;:::o;5683:194::-;;5806:2;5794:9;5785:7;5781:23;5777:32;5774:2;;;5827:6;5819;5812:22;5774:2;-1:-1:-1;5855:16:1;;5764:113;-1:-1:-1;5764:113:1:o;5882:327::-;;;6011:2;5999:9;5990:7;5986:23;5982:32;5979:2;;;6032:6;6024;6017:22;6214:444;6484:66;6472:79;;6576:1;6567:11;;6560:27;;;;6612:2;6603:12;;6596:28;6649:2;6640:12;;6462:196::o;6663:786::-;;7074:25;7069:3;7062:38;7129:6;7123:13;7145:62;7200:6;7195:2;7190:3;7186:12;7179:4;7171:6;7167:17;7145:62;:::i;:::-;7271:19;7266:2;7226:16;;;7258:11;;;7251:40;7316:13;;7338:63;7316:13;7387:2;7379:11;;7372:4;7360:17;;7338:63;:::i;:::-;7421:17;7440:2;7417:26;;7052:397;-1:-1:-1;;;;7052:397:1:o;7454:226::-;-1:-1:-1;;;;;7618:55:1;;;;7600:74;;7588:2;7573:18;;7555:125::o;7685:327::-;-1:-1:-1;;;;;7938:15:1;;;7920:34;;7990:15;;7985:2;7970:18;;7963:43;7847:2;7832:18;;7814:198::o;8017:398::-;-1:-1:-1;;;;;8298:15:1;;;8280:34;;8350:15;;;;8345:2;8330:18;;8323:43;8397:2;8382:18;;8375:34;;;;8207:2;8192:18;;8174:241::o;8420:297::-;-1:-1:-1;;;;;8612:55:1;;;;8594:74;;8699:2;8684:18;;8677:34;8582:2;8567:18;;8549:168::o;8722:187::-;8887:14;;8880:22;8862:41;;8850:2;8835:18;;8817:92::o;8914:617::-;9248:14;;9241:22;9223:41;;9295:2;9280:18;;9273:34;;;;9338:2;9323:18;;9316:34;;;;9381:2;9366:18;;9359:34;;;;9424:3;9409:19;;9402:35;9468:3;9453:19;;9446:35;9512:3;9497:19;;9490:35;9210:3;9195:19;;9177:354::o;9536:177::-;9682:25;;;9670:2;9655:18;;9637:76::o;9718:440::-;9949:25;;;-1:-1:-1;;;;;10010:55:1;;;;10005:2;9990:18;;9983:83;10097:2;10082:18;;10075:34;10140:2;10125:18;;10118:34;9936:3;9921:19;;9903:255::o;10163:440::-;10394:25;;;10450:2;10435:18;;10428:34;;;;10493:2;10478:18;;10471:34;-1:-1:-1;;;;;10541:55:1;10536:2;10521:18;;10514:83;10381:3;10366:19;;10348:255::o;10608:398::-;10835:25;;;10908:4;10896:17;;;;10891:2;10876:18;;10869:45;10945:2;10930:18;;10923:34;10988:2;10973:18;;10966:34;10822:3;10807:19;;10789:217::o;11264:383::-;;11413:2;11402:9;11395:21;11445:6;11439:13;11488:6;11483:2;11472:9;11468:18;11461:34;11504:66;11563:6;11558:2;11547:9;11543:18;11538:2;11530:6;11526:15;11504:66;:::i;:::-;11631:2;11610:15;-1:-1:-1;;11606:29:1;11591:45;;;;11638:2;11587:54;;11385:262;-1:-1:-1;;11385:262:1:o;11652:353::-;11854:2;11836:21;;;11893:2;11873:18;;;11866:30;11932:31;11927:2;11912:18;;11905:59;11996:2;11981:18;;11826:179::o;12010:356::-;12212:2;12194:21;;;12231:18;;;12224:30;12290:34;12285:2;12270:18;;12263:62;12357:2;12342:18;;12184:182::o;12371:356::-;12573:2;12555:21;;;12592:18;;;12585:30;12651:34;12646:2;12631:18;;12624:62;12718:2;12703:18;;12545:182::o;12732:341::-;12934:2;12916:21;;;12973:2;12953:18;;;12946:30;13012:19;13007:2;12992:18;;12985:47;13064:2;13049:18;;12906:167::o;13078:355::-;13280:2;13262:21;;;13319:2;13299:18;;;13292:30;13358:33;13353:2;13338:18;;13331:61;13424:2;13409:18;;13252:181::o;13438:401::-;13640:2;13622:21;;;13679:2;13659:18;;;13652:30;13718:34;13713:2;13698:18;;13691:62;13789:7;13784:2;13769:18;;13762:35;13829:3;13814:19;;13612:227::o;13844:400::-;14046:2;14028:21;;;14085:2;14065:18;;;14058:30;14124:34;14119:2;14104:18;;14097:62;14195:6;14190:2;14175:18;;14168:34;14234:3;14219:19;;14018:226::o;14249:403::-;14451:2;14433:21;;;14490:2;14470:18;;;14463:30;14529:34;14524:2;14509:18;;14502:62;14600:9;14595:2;14580:18;;14573:37;14642:3;14627:19;;14423:229::o;14657:402::-;14859:2;14841:21;;;14898:2;14878:18;;;14871:30;14937:34;14932:2;14917:18;;14910:62;15008:8;15003:2;14988:18;;14981:36;15049:3;15034:19;;14831:228::o;15064:353::-;15266:2;15248:21;;;15305:2;15285:18;;;15278:30;15344:31;15339:2;15324:18;;15317:59;15408:2;15393:18;;15238:179::o;15422:480::-;15624:2;15606:21;;;15663:2;15643:18;;;15636:30;15702:34;15697:2;15682:18;;15675:62;15773:34;15768:2;15753:18;;15746:62;15845:14;15839:3;15824:19;;15817:43;15892:3;15877:19;;15596:306::o;15907:340::-;16109:2;16091:21;;;16148:2;16128:18;;;16121:30;16187:18;16182:2;16167:18;;16160:46;16238:2;16223:18;;16081:166::o;16252:399::-;16454:2;16436:21;;;16493:2;16473:18;;;16466:30;16532:34;16527:2;16512:18;;16505:62;16603:5;16598:2;16583:18;;16576:33;16641:3;16626:19;;16426:225::o;16656:346::-;16858:2;16840:21;;;16897:2;16877:18;;;16870:30;16936:24;16931:2;16916:18;;16909:52;16993:2;16978:18;;16830:172::o;17007:355::-;17209:2;17191:21;;;17248:2;17228:18;;;17221:30;17287:33;17282:2;17267:18;;17260:61;17353:2;17338:18;;17181:181::o;17367:356::-;17569:2;17551:21;;;17588:18;;;17581:30;17647:34;17642:2;17627:18;;17620:62;17714:2;17699:18;;17541:182::o;17728:405::-;17930:2;17912:21;;;17969:2;17949:18;;;17942:30;18008:34;18003:2;17988:18;;17981:62;18079:11;18074:2;18059:18;;18052:39;18123:3;18108:19;;17902:231::o;18138:404::-;18340:2;18322:21;;;18379:2;18359:18;;;18352:30;18418:34;18413:2;18398:18;;18391:62;18489:10;18484:2;18469:18;;18462:38;18532:3;18517:19;;18312:230::o;18547:399::-;18749:2;18731:21;;;18788:2;18768:18;;;18761:30;18827:34;18822:2;18807:18;;18800:62;18898:5;18893:2;18878:18;;18871:33;18936:3;18921:19;;18721:225::o;18951:397::-;19153:2;19135:21;;;19192:2;19172:18;;;19165:30;19231:34;19226:2;19211:18;;19204:62;19302:3;19297:2;19282:18;;19275:31;19338:3;19323:19;;19125:223::o;19353:403::-;19555:2;19537:21;;;19594:2;19574:18;;;19567:30;19633:34;19628:2;19613:18;;19606:62;19704:9;19699:2;19684:18;;19677:37;19746:3;19731:19;;19527:229::o;19761:346::-;19963:2;19945:21;;;20002:2;19982:18;;;19975:30;20041:24;20036:2;20021:18;;20014:52;20098:2;20083:18;;19935:172::o;20112:398::-;20314:2;20296:21;;;20353:2;20333:18;;;20326:30;20392:34;20387:2;20372:18;;20365:62;20463:4;20458:2;20443:18;;20436:32;20500:3;20485:19;;20286:224::o;20515:342::-;20717:2;20699:21;;;20756:2;20736:18;;;20729:30;20795:20;20790:2;20775:18;;20768:48;20848:2;20833:18;;20689:168::o;20862:411::-;21064:2;21046:21;;;21103:2;21083:18;;;21076:30;21142:34;21137:2;21122:18;;21115:62;21213:17;21208:2;21193:18;;21186:45;21263:3;21248:19;;21036:237::o;21460:1029::-;;21770:3;21759:9;21755:19;21801:6;21790:9;21783:25;21827:2;21865:6;21860:2;21849:9;21845:18;21838:34;21908:3;21903:2;21892:9;21888:18;21881:31;21932:6;21967;21961:13;21998:6;21990;21983:22;22036:3;22025:9;22021:19;22014:26;;22075:2;22067:6;22063:15;22049:29;;22096:4;22109:218;22123:6;22120:1;22117:13;22109:218;;;22188:13;;-1:-1:-1;;;;;22184:62:1;22172:75;;22302:15;;;;22267:12;;;;22145:1;22138:9;22109:218;;;-1:-1:-1;;;;;;;22383:55:1;;;;22378:2;22363:18;;22356:83;-1:-1:-1;;;22470:3:1;22455:19;22448:35;22344:3;21731:758;-1:-1:-1;;;21731:758:1:o;22494:248::-;22668:25;;;22724:2;22709:18;;22702:34;22656:2;22641:18;;22623:119::o;23192:192::-;23366:10;23354:23;;;;23336:42;;23324:2;23309:18;;23291:93::o;23389:263::-;23591:10;23579:23;;;;23561:42;;23634:2;23619:18;;23612:34;23549:2;23534:18;;23516:136::o;23657:184::-;23829:4;23817:17;;;;23799:36;;23787:2;23772:18;;23754:87::o;23846:128::-;;23917:1;23913:6;23910:1;23907:13;23904:2;;;23923:18;;:::i;:::-;-1:-1:-1;23959:9:1;;23894:80::o;23979:228::-;;24046:10;24083:2;24080:1;24076:10;24113:2;24110:1;24106:10;24144:3;24140:2;24136:12;24131:3;24128:21;24125:2;;;24152:18;;:::i;:::-;24188:13;;24026:181;-1:-1:-1;;;;24026:181:1:o;24212:120::-;;24278:1;24268:2;;24283:18;;:::i;:::-;-1:-1:-1;24317:9:1;;24258:74::o;24337:191::-;;24402:10;24439:2;24436:1;24432:10;24461:3;24451:2;;24468:18;;:::i;:::-;24506:10;;24502:20;;;;;24382:146;-1:-1:-1;;24382:146:1:o;24533:168::-;;24639:1;24635;24631:6;24627:14;24624:1;24621:21;24616:1;24609:9;24602:17;24598:45;24595:2;;;24646:18;;:::i;:::-;-1:-1:-1;24686:9:1;;24585:116::o;24706:125::-;;24774:1;24771;24768:8;24765:2;;;24779:18;;:::i;:::-;-1:-1:-1;24816:9:1;;24755:76::o;24836:221::-;;24904:10;24964;;;;24934;;24986:12;;;24983:2;;;25001:18;;:::i;:::-;25038:13;;24884:173;-1:-1:-1;;;24884:173:1:o;25062:258::-;25134:1;25144:113;25158:6;25155:1;25152:13;25144:113;;;25234:11;;;25228:18;25215:11;;;25208:39;25180:2;25173:10;25144:113;;;25275:6;25272:1;25269:13;25266:2;;;-1:-1:-1;;25310:1:1;25292:16;;25285:27;25115:205::o;25325:136::-;;25392:5;25382:2;;25401:18;;:::i;:::-;-1:-1:-1;;;25437:18:1;;25372:89::o;25466:135::-;;-1:-1:-1;;25526:17:1;;25523:2;;;25546:18;;:::i;:::-;-1:-1:-1;25593:1:1;25582:13;;25513:88::o;25606:184::-;-1:-1:-1;;;25655:1:1;25648:88;25755:4;25752:1;25745:15;25779:4;25776:1;25769:15;25795:184;-1:-1:-1;;;25844:1:1;25837:88;25944:4;25941:1;25934:15;25968:4;25965:1;25958:15;25984:156;-1:-1:-1;;;;;26065:5:1;26061:54;26054:5;26051:65;26041:2;;26130:1;26127;26120:12;26145:120;26233:5;26226:13;26219:21;26212:5;26209:32;26199:2;;26255:1;26252;26245:12

Swarm Source

ipfs://93326db4c60c592a130c9c7446f9ddcd2680334aaecc8fb38f8152b9477e62fa
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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