ETH Price: $2,521.76 (-0.03%)

Token

Maia (Maia)
 

Overview

Max Total Supply

3,716,935,386.30758506 Maia

Holders

422

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 9 Decimals)

Balance
1,135,890.194527209 Maia

Value
$0.00
0xfe362f889a2c843708daf7d32ed70ec6188a3a47
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
Maia

Compiler Version
v0.8.2+commit.661d1103

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-08-22
*/

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


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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol


// OpenZeppelin Contracts (last updated v4.6.0) (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 SafeMathUpgradeable {
    /**
     * @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 subtraction 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: @openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)

pragma solidity ^0.8.0;

/**
 * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such an operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 *
 * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
 * all math on `uint256` and `int256` and then downcasting.
 */
library SafeCastUpgradeable {
    /**
     * @dev Returns the downcasted uint248 from uint256, reverting on
     * overflow (when the input is greater than largest uint248).
     *
     * Counterpart to Solidity's `uint248` operator.
     *
     * Requirements:
     *
     * - input must fit into 248 bits
     *
     * _Available since v4.7._
     */
    function toUint248(uint256 value) internal pure returns (uint248) {
        require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
        return uint248(value);
    }

    /**
     * @dev Returns the downcasted uint240 from uint256, reverting on
     * overflow (when the input is greater than largest uint240).
     *
     * Counterpart to Solidity's `uint240` operator.
     *
     * Requirements:
     *
     * - input must fit into 240 bits
     *
     * _Available since v4.7._
     */
    function toUint240(uint256 value) internal pure returns (uint240) {
        require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
        return uint240(value);
    }

    /**
     * @dev Returns the downcasted uint232 from uint256, reverting on
     * overflow (when the input is greater than largest uint232).
     *
     * Counterpart to Solidity's `uint232` operator.
     *
     * Requirements:
     *
     * - input must fit into 232 bits
     *
     * _Available since v4.7._
     */
    function toUint232(uint256 value) internal pure returns (uint232) {
        require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
        return uint232(value);
    }

    /**
     * @dev Returns the downcasted uint224 from uint256, reverting on
     * overflow (when the input is greater than largest uint224).
     *
     * Counterpart to Solidity's `uint224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     *
     * _Available since v4.2._
     */
    function toUint224(uint256 value) internal pure returns (uint224) {
        require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
        return uint224(value);
    }

    /**
     * @dev Returns the downcasted uint216 from uint256, reverting on
     * overflow (when the input is greater than largest uint216).
     *
     * Counterpart to Solidity's `uint216` operator.
     *
     * Requirements:
     *
     * - input must fit into 216 bits
     *
     * _Available since v4.7._
     */
    function toUint216(uint256 value) internal pure returns (uint216) {
        require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
        return uint216(value);
    }

    /**
     * @dev Returns the downcasted uint208 from uint256, reverting on
     * overflow (when the input is greater than largest uint208).
     *
     * Counterpart to Solidity's `uint208` operator.
     *
     * Requirements:
     *
     * - input must fit into 208 bits
     *
     * _Available since v4.7._
     */
    function toUint208(uint256 value) internal pure returns (uint208) {
        require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
        return uint208(value);
    }

    /**
     * @dev Returns the downcasted uint200 from uint256, reverting on
     * overflow (when the input is greater than largest uint200).
     *
     * Counterpart to Solidity's `uint200` operator.
     *
     * Requirements:
     *
     * - input must fit into 200 bits
     *
     * _Available since v4.7._
     */
    function toUint200(uint256 value) internal pure returns (uint200) {
        require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
        return uint200(value);
    }

    /**
     * @dev Returns the downcasted uint192 from uint256, reverting on
     * overflow (when the input is greater than largest uint192).
     *
     * Counterpart to Solidity's `uint192` operator.
     *
     * Requirements:
     *
     * - input must fit into 192 bits
     *
     * _Available since v4.7._
     */
    function toUint192(uint256 value) internal pure returns (uint192) {
        require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
        return uint192(value);
    }

    /**
     * @dev Returns the downcasted uint184 from uint256, reverting on
     * overflow (when the input is greater than largest uint184).
     *
     * Counterpart to Solidity's `uint184` operator.
     *
     * Requirements:
     *
     * - input must fit into 184 bits
     *
     * _Available since v4.7._
     */
    function toUint184(uint256 value) internal pure returns (uint184) {
        require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
        return uint184(value);
    }

    /**
     * @dev Returns the downcasted uint176 from uint256, reverting on
     * overflow (when the input is greater than largest uint176).
     *
     * Counterpart to Solidity's `uint176` operator.
     *
     * Requirements:
     *
     * - input must fit into 176 bits
     *
     * _Available since v4.7._
     */
    function toUint176(uint256 value) internal pure returns (uint176) {
        require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
        return uint176(value);
    }

    /**
     * @dev Returns the downcasted uint168 from uint256, reverting on
     * overflow (when the input is greater than largest uint168).
     *
     * Counterpart to Solidity's `uint168` operator.
     *
     * Requirements:
     *
     * - input must fit into 168 bits
     *
     * _Available since v4.7._
     */
    function toUint168(uint256 value) internal pure returns (uint168) {
        require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
        return uint168(value);
    }

    /**
     * @dev Returns the downcasted uint160 from uint256, reverting on
     * overflow (when the input is greater than largest uint160).
     *
     * Counterpart to Solidity's `uint160` operator.
     *
     * Requirements:
     *
     * - input must fit into 160 bits
     *
     * _Available since v4.7._
     */
    function toUint160(uint256 value) internal pure returns (uint160) {
        require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
        return uint160(value);
    }

    /**
     * @dev Returns the downcasted uint152 from uint256, reverting on
     * overflow (when the input is greater than largest uint152).
     *
     * Counterpart to Solidity's `uint152` operator.
     *
     * Requirements:
     *
     * - input must fit into 152 bits
     *
     * _Available since v4.7._
     */
    function toUint152(uint256 value) internal pure returns (uint152) {
        require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
        return uint152(value);
    }

    /**
     * @dev Returns the downcasted uint144 from uint256, reverting on
     * overflow (when the input is greater than largest uint144).
     *
     * Counterpart to Solidity's `uint144` operator.
     *
     * Requirements:
     *
     * - input must fit into 144 bits
     *
     * _Available since v4.7._
     */
    function toUint144(uint256 value) internal pure returns (uint144) {
        require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
        return uint144(value);
    }

    /**
     * @dev Returns the downcasted uint136 from uint256, reverting on
     * overflow (when the input is greater than largest uint136).
     *
     * Counterpart to Solidity's `uint136` operator.
     *
     * Requirements:
     *
     * - input must fit into 136 bits
     *
     * _Available since v4.7._
     */
    function toUint136(uint256 value) internal pure returns (uint136) {
        require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
        return uint136(value);
    }

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v2.5._
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint120 from uint256, reverting on
     * overflow (when the input is greater than largest uint120).
     *
     * Counterpart to Solidity's `uint120` operator.
     *
     * Requirements:
     *
     * - input must fit into 120 bits
     *
     * _Available since v4.7._
     */
    function toUint120(uint256 value) internal pure returns (uint120) {
        require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
        return uint120(value);
    }

    /**
     * @dev Returns the downcasted uint112 from uint256, reverting on
     * overflow (when the input is greater than largest uint112).
     *
     * Counterpart to Solidity's `uint112` operator.
     *
     * Requirements:
     *
     * - input must fit into 112 bits
     *
     * _Available since v4.7._
     */
    function toUint112(uint256 value) internal pure returns (uint112) {
        require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
        return uint112(value);
    }

    /**
     * @dev Returns the downcasted uint104 from uint256, reverting on
     * overflow (when the input is greater than largest uint104).
     *
     * Counterpart to Solidity's `uint104` operator.
     *
     * Requirements:
     *
     * - input must fit into 104 bits
     *
     * _Available since v4.7._
     */
    function toUint104(uint256 value) internal pure returns (uint104) {
        require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
        return uint104(value);
    }

    /**
     * @dev Returns the downcasted uint96 from uint256, reverting on
     * overflow (when the input is greater than largest uint96).
     *
     * Counterpart to Solidity's `uint96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     *
     * _Available since v4.2._
     */
    function toUint96(uint256 value) internal pure returns (uint96) {
        require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
        return uint96(value);
    }

    /**
     * @dev Returns the downcasted uint88 from uint256, reverting on
     * overflow (when the input is greater than largest uint88).
     *
     * Counterpart to Solidity's `uint88` operator.
     *
     * Requirements:
     *
     * - input must fit into 88 bits
     *
     * _Available since v4.7._
     */
    function toUint88(uint256 value) internal pure returns (uint88) {
        require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
        return uint88(value);
    }

    /**
     * @dev Returns the downcasted uint80 from uint256, reverting on
     * overflow (when the input is greater than largest uint80).
     *
     * Counterpart to Solidity's `uint80` operator.
     *
     * Requirements:
     *
     * - input must fit into 80 bits
     *
     * _Available since v4.7._
     */
    function toUint80(uint256 value) internal pure returns (uint80) {
        require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
        return uint80(value);
    }

    /**
     * @dev Returns the downcasted uint72 from uint256, reverting on
     * overflow (when the input is greater than largest uint72).
     *
     * Counterpart to Solidity's `uint72` operator.
     *
     * Requirements:
     *
     * - input must fit into 72 bits
     *
     * _Available since v4.7._
     */
    function toUint72(uint256 value) internal pure returns (uint72) {
        require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
        return uint72(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v2.5._
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint56 from uint256, reverting on
     * overflow (when the input is greater than largest uint56).
     *
     * Counterpart to Solidity's `uint56` operator.
     *
     * Requirements:
     *
     * - input must fit into 56 bits
     *
     * _Available since v4.7._
     */
    function toUint56(uint256 value) internal pure returns (uint56) {
        require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
        return uint56(value);
    }

    /**
     * @dev Returns the downcasted uint48 from uint256, reverting on
     * overflow (when the input is greater than largest uint48).
     *
     * Counterpart to Solidity's `uint48` operator.
     *
     * Requirements:
     *
     * - input must fit into 48 bits
     *
     * _Available since v4.7._
     */
    function toUint48(uint256 value) internal pure returns (uint48) {
        require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
        return uint48(value);
    }

    /**
     * @dev Returns the downcasted uint40 from uint256, reverting on
     * overflow (when the input is greater than largest uint40).
     *
     * Counterpart to Solidity's `uint40` operator.
     *
     * Requirements:
     *
     * - input must fit into 40 bits
     *
     * _Available since v4.7._
     */
    function toUint40(uint256 value) internal pure returns (uint40) {
        require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
        return uint40(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v2.5._
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint24 from uint256, reverting on
     * overflow (when the input is greater than largest uint24).
     *
     * Counterpart to Solidity's `uint24` operator.
     *
     * Requirements:
     *
     * - input must fit into 24 bits
     *
     * _Available since v4.7._
     */
    function toUint24(uint256 value) internal pure returns (uint24) {
        require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
        return uint24(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v2.5._
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits
     *
     * _Available since v2.5._
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     *
     * _Available since v3.0._
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        require(value >= 0, "SafeCast: value must be positive");
        return uint256(value);
    }

    /**
     * @dev Returns the downcasted int248 from int256, reverting on
     * overflow (when the input is less than smallest int248 or
     * greater than largest int248).
     *
     * Counterpart to Solidity's `int248` operator.
     *
     * Requirements:
     *
     * - input must fit into 248 bits
     *
     * _Available since v4.7._
     */
    function toInt248(int256 value) internal pure returns (int248) {
        require(value >= type(int248).min && value <= type(int248).max, "SafeCast: value doesn't fit in 248 bits");
        return int248(value);
    }

    /**
     * @dev Returns the downcasted int240 from int256, reverting on
     * overflow (when the input is less than smallest int240 or
     * greater than largest int240).
     *
     * Counterpart to Solidity's `int240` operator.
     *
     * Requirements:
     *
     * - input must fit into 240 bits
     *
     * _Available since v4.7._
     */
    function toInt240(int256 value) internal pure returns (int240) {
        require(value >= type(int240).min && value <= type(int240).max, "SafeCast: value doesn't fit in 240 bits");
        return int240(value);
    }

    /**
     * @dev Returns the downcasted int232 from int256, reverting on
     * overflow (when the input is less than smallest int232 or
     * greater than largest int232).
     *
     * Counterpart to Solidity's `int232` operator.
     *
     * Requirements:
     *
     * - input must fit into 232 bits
     *
     * _Available since v4.7._
     */
    function toInt232(int256 value) internal pure returns (int232) {
        require(value >= type(int232).min && value <= type(int232).max, "SafeCast: value doesn't fit in 232 bits");
        return int232(value);
    }

    /**
     * @dev Returns the downcasted int224 from int256, reverting on
     * overflow (when the input is less than smallest int224 or
     * greater than largest int224).
     *
     * Counterpart to Solidity's `int224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     *
     * _Available since v4.7._
     */
    function toInt224(int256 value) internal pure returns (int224) {
        require(value >= type(int224).min && value <= type(int224).max, "SafeCast: value doesn't fit in 224 bits");
        return int224(value);
    }

    /**
     * @dev Returns the downcasted int216 from int256, reverting on
     * overflow (when the input is less than smallest int216 or
     * greater than largest int216).
     *
     * Counterpart to Solidity's `int216` operator.
     *
     * Requirements:
     *
     * - input must fit into 216 bits
     *
     * _Available since v4.7._
     */
    function toInt216(int256 value) internal pure returns (int216) {
        require(value >= type(int216).min && value <= type(int216).max, "SafeCast: value doesn't fit in 216 bits");
        return int216(value);
    }

    /**
     * @dev Returns the downcasted int208 from int256, reverting on
     * overflow (when the input is less than smallest int208 or
     * greater than largest int208).
     *
     * Counterpart to Solidity's `int208` operator.
     *
     * Requirements:
     *
     * - input must fit into 208 bits
     *
     * _Available since v4.7._
     */
    function toInt208(int256 value) internal pure returns (int208) {
        require(value >= type(int208).min && value <= type(int208).max, "SafeCast: value doesn't fit in 208 bits");
        return int208(value);
    }

    /**
     * @dev Returns the downcasted int200 from int256, reverting on
     * overflow (when the input is less than smallest int200 or
     * greater than largest int200).
     *
     * Counterpart to Solidity's `int200` operator.
     *
     * Requirements:
     *
     * - input must fit into 200 bits
     *
     * _Available since v4.7._
     */
    function toInt200(int256 value) internal pure returns (int200) {
        require(value >= type(int200).min && value <= type(int200).max, "SafeCast: value doesn't fit in 200 bits");
        return int200(value);
    }

    /**
     * @dev Returns the downcasted int192 from int256, reverting on
     * overflow (when the input is less than smallest int192 or
     * greater than largest int192).
     *
     * Counterpart to Solidity's `int192` operator.
     *
     * Requirements:
     *
     * - input must fit into 192 bits
     *
     * _Available since v4.7._
     */
    function toInt192(int256 value) internal pure returns (int192) {
        require(value >= type(int192).min && value <= type(int192).max, "SafeCast: value doesn't fit in 192 bits");
        return int192(value);
    }

    /**
     * @dev Returns the downcasted int184 from int256, reverting on
     * overflow (when the input is less than smallest int184 or
     * greater than largest int184).
     *
     * Counterpart to Solidity's `int184` operator.
     *
     * Requirements:
     *
     * - input must fit into 184 bits
     *
     * _Available since v4.7._
     */
    function toInt184(int256 value) internal pure returns (int184) {
        require(value >= type(int184).min && value <= type(int184).max, "SafeCast: value doesn't fit in 184 bits");
        return int184(value);
    }

    /**
     * @dev Returns the downcasted int176 from int256, reverting on
     * overflow (when the input is less than smallest int176 or
     * greater than largest int176).
     *
     * Counterpart to Solidity's `int176` operator.
     *
     * Requirements:
     *
     * - input must fit into 176 bits
     *
     * _Available since v4.7._
     */
    function toInt176(int256 value) internal pure returns (int176) {
        require(value >= type(int176).min && value <= type(int176).max, "SafeCast: value doesn't fit in 176 bits");
        return int176(value);
    }

    /**
     * @dev Returns the downcasted int168 from int256, reverting on
     * overflow (when the input is less than smallest int168 or
     * greater than largest int168).
     *
     * Counterpart to Solidity's `int168` operator.
     *
     * Requirements:
     *
     * - input must fit into 168 bits
     *
     * _Available since v4.7._
     */
    function toInt168(int256 value) internal pure returns (int168) {
        require(value >= type(int168).min && value <= type(int168).max, "SafeCast: value doesn't fit in 168 bits");
        return int168(value);
    }

    /**
     * @dev Returns the downcasted int160 from int256, reverting on
     * overflow (when the input is less than smallest int160 or
     * greater than largest int160).
     *
     * Counterpart to Solidity's `int160` operator.
     *
     * Requirements:
     *
     * - input must fit into 160 bits
     *
     * _Available since v4.7._
     */
    function toInt160(int256 value) internal pure returns (int160) {
        require(value >= type(int160).min && value <= type(int160).max, "SafeCast: value doesn't fit in 160 bits");
        return int160(value);
    }

    /**
     * @dev Returns the downcasted int152 from int256, reverting on
     * overflow (when the input is less than smallest int152 or
     * greater than largest int152).
     *
     * Counterpart to Solidity's `int152` operator.
     *
     * Requirements:
     *
     * - input must fit into 152 bits
     *
     * _Available since v4.7._
     */
    function toInt152(int256 value) internal pure returns (int152) {
        require(value >= type(int152).min && value <= type(int152).max, "SafeCast: value doesn't fit in 152 bits");
        return int152(value);
    }

    /**
     * @dev Returns the downcasted int144 from int256, reverting on
     * overflow (when the input is less than smallest int144 or
     * greater than largest int144).
     *
     * Counterpart to Solidity's `int144` operator.
     *
     * Requirements:
     *
     * - input must fit into 144 bits
     *
     * _Available since v4.7._
     */
    function toInt144(int256 value) internal pure returns (int144) {
        require(value >= type(int144).min && value <= type(int144).max, "SafeCast: value doesn't fit in 144 bits");
        return int144(value);
    }

    /**
     * @dev Returns the downcasted int136 from int256, reverting on
     * overflow (when the input is less than smallest int136 or
     * greater than largest int136).
     *
     * Counterpart to Solidity's `int136` operator.
     *
     * Requirements:
     *
     * - input must fit into 136 bits
     *
     * _Available since v4.7._
     */
    function toInt136(int256 value) internal pure returns (int136) {
        require(value >= type(int136).min && value <= type(int136).max, "SafeCast: value doesn't fit in 136 bits");
        return int136(value);
    }

    /**
     * @dev Returns the downcasted int128 from int256, reverting on
     * overflow (when the input is less than smallest int128 or
     * greater than largest int128).
     *
     * Counterpart to Solidity's `int128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v3.1._
     */
    function toInt128(int256 value) internal pure returns (int128) {
        require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits");
        return int128(value);
    }

    /**
     * @dev Returns the downcasted int120 from int256, reverting on
     * overflow (when the input is less than smallest int120 or
     * greater than largest int120).
     *
     * Counterpart to Solidity's `int120` operator.
     *
     * Requirements:
     *
     * - input must fit into 120 bits
     *
     * _Available since v4.7._
     */
    function toInt120(int256 value) internal pure returns (int120) {
        require(value >= type(int120).min && value <= type(int120).max, "SafeCast: value doesn't fit in 120 bits");
        return int120(value);
    }

    /**
     * @dev Returns the downcasted int112 from int256, reverting on
     * overflow (when the input is less than smallest int112 or
     * greater than largest int112).
     *
     * Counterpart to Solidity's `int112` operator.
     *
     * Requirements:
     *
     * - input must fit into 112 bits
     *
     * _Available since v4.7._
     */
    function toInt112(int256 value) internal pure returns (int112) {
        require(value >= type(int112).min && value <= type(int112).max, "SafeCast: value doesn't fit in 112 bits");
        return int112(value);
    }

    /**
     * @dev Returns the downcasted int104 from int256, reverting on
     * overflow (when the input is less than smallest int104 or
     * greater than largest int104).
     *
     * Counterpart to Solidity's `int104` operator.
     *
     * Requirements:
     *
     * - input must fit into 104 bits
     *
     * _Available since v4.7._
     */
    function toInt104(int256 value) internal pure returns (int104) {
        require(value >= type(int104).min && value <= type(int104).max, "SafeCast: value doesn't fit in 104 bits");
        return int104(value);
    }

    /**
     * @dev Returns the downcasted int96 from int256, reverting on
     * overflow (when the input is less than smallest int96 or
     * greater than largest int96).
     *
     * Counterpart to Solidity's `int96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     *
     * _Available since v4.7._
     */
    function toInt96(int256 value) internal pure returns (int96) {
        require(value >= type(int96).min && value <= type(int96).max, "SafeCast: value doesn't fit in 96 bits");
        return int96(value);
    }

    /**
     * @dev Returns the downcasted int88 from int256, reverting on
     * overflow (when the input is less than smallest int88 or
     * greater than largest int88).
     *
     * Counterpart to Solidity's `int88` operator.
     *
     * Requirements:
     *
     * - input must fit into 88 bits
     *
     * _Available since v4.7._
     */
    function toInt88(int256 value) internal pure returns (int88) {
        require(value >= type(int88).min && value <= type(int88).max, "SafeCast: value doesn't fit in 88 bits");
        return int88(value);
    }

    /**
     * @dev Returns the downcasted int80 from int256, reverting on
     * overflow (when the input is less than smallest int80 or
     * greater than largest int80).
     *
     * Counterpart to Solidity's `int80` operator.
     *
     * Requirements:
     *
     * - input must fit into 80 bits
     *
     * _Available since v4.7._
     */
    function toInt80(int256 value) internal pure returns (int80) {
        require(value >= type(int80).min && value <= type(int80).max, "SafeCast: value doesn't fit in 80 bits");
        return int80(value);
    }

    /**
     * @dev Returns the downcasted int72 from int256, reverting on
     * overflow (when the input is less than smallest int72 or
     * greater than largest int72).
     *
     * Counterpart to Solidity's `int72` operator.
     *
     * Requirements:
     *
     * - input must fit into 72 bits
     *
     * _Available since v4.7._
     */
    function toInt72(int256 value) internal pure returns (int72) {
        require(value >= type(int72).min && value <= type(int72).max, "SafeCast: value doesn't fit in 72 bits");
        return int72(value);
    }

    /**
     * @dev Returns the downcasted int64 from int256, reverting on
     * overflow (when the input is less than smallest int64 or
     * greater than largest int64).
     *
     * Counterpart to Solidity's `int64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v3.1._
     */
    function toInt64(int256 value) internal pure returns (int64) {
        require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits");
        return int64(value);
    }

    /**
     * @dev Returns the downcasted int56 from int256, reverting on
     * overflow (when the input is less than smallest int56 or
     * greater than largest int56).
     *
     * Counterpart to Solidity's `int56` operator.
     *
     * Requirements:
     *
     * - input must fit into 56 bits
     *
     * _Available since v4.7._
     */
    function toInt56(int256 value) internal pure returns (int56) {
        require(value >= type(int56).min && value <= type(int56).max, "SafeCast: value doesn't fit in 56 bits");
        return int56(value);
    }

    /**
     * @dev Returns the downcasted int48 from int256, reverting on
     * overflow (when the input is less than smallest int48 or
     * greater than largest int48).
     *
     * Counterpart to Solidity's `int48` operator.
     *
     * Requirements:
     *
     * - input must fit into 48 bits
     *
     * _Available since v4.7._
     */
    function toInt48(int256 value) internal pure returns (int48) {
        require(value >= type(int48).min && value <= type(int48).max, "SafeCast: value doesn't fit in 48 bits");
        return int48(value);
    }

    /**
     * @dev Returns the downcasted int40 from int256, reverting on
     * overflow (when the input is less than smallest int40 or
     * greater than largest int40).
     *
     * Counterpart to Solidity's `int40` operator.
     *
     * Requirements:
     *
     * - input must fit into 40 bits
     *
     * _Available since v4.7._
     */
    function toInt40(int256 value) internal pure returns (int40) {
        require(value >= type(int40).min && value <= type(int40).max, "SafeCast: value doesn't fit in 40 bits");
        return int40(value);
    }

    /**
     * @dev Returns the downcasted int32 from int256, reverting on
     * overflow (when the input is less than smallest int32 or
     * greater than largest int32).
     *
     * Counterpart to Solidity's `int32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v3.1._
     */
    function toInt32(int256 value) internal pure returns (int32) {
        require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits");
        return int32(value);
    }

    /**
     * @dev Returns the downcasted int24 from int256, reverting on
     * overflow (when the input is less than smallest int24 or
     * greater than largest int24).
     *
     * Counterpart to Solidity's `int24` operator.
     *
     * Requirements:
     *
     * - input must fit into 24 bits
     *
     * _Available since v4.7._
     */
    function toInt24(int256 value) internal pure returns (int24) {
        require(value >= type(int24).min && value <= type(int24).max, "SafeCast: value doesn't fit in 24 bits");
        return int24(value);
    }

    /**
     * @dev Returns the downcasted int16 from int256, reverting on
     * overflow (when the input is less than smallest int16 or
     * greater than largest int16).
     *
     * Counterpart to Solidity's `int16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v3.1._
     */
    function toInt16(int256 value) internal pure returns (int16) {
        require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits");
        return int16(value);
    }

    /**
     * @dev Returns the downcasted int8 from int256, reverting on
     * overflow (when the input is less than smallest int8 or
     * greater than largest int8).
     *
     * Counterpart to Solidity's `int8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits
     *
     * _Available since v3.1._
     */
    function toInt8(int256 value) internal pure returns (int8) {
        require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits");
        return int8(value);
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     *
     * _Available since v3.0._
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
        require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
        return int256(value);
    }
}

// File: @openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol


// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)
pragma solidity ^0.8.0;

/**
 * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.
 *
 * _Available since v4.5._
 */
interface IVotesUpgradeable {
    /**
     * @dev Emitted when an account changes their delegate.
     */
    event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

    /**
     * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.
     */
    event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);

    /**
     * @dev Returns the current amount of votes that `account` has.
     */
    function getVotes(address account) external view returns (uint256);

    /**
     * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).
     */
    function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);

    /**
     * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).
     *
     * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.
     * Votes that have not been delegated are still part of total supply, even though they would not participate in a
     * vote.
     */
    function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);

    /**
     * @dev Returns the delegate that `account` has chosen.
     */
    function delegates(address account) external view returns (address);

    /**
     * @dev Delegates votes from the sender to `delegatee`.
     */
    function delegate(address delegatee) external;

    /**
     * @dev Delegates votes from signer to `delegatee`.
     */
    function delegateBySig(
        address delegatee,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;
}

// File: @openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol


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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`.
        // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.
        // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.
        // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a
        // good first aproximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1;
        uint256 x = a;
        if (x >> 128 > 0) {
            x >>= 128;
            result <<= 64;
        }
        if (x >> 64 > 0) {
            x >>= 64;
            result <<= 32;
        }
        if (x >> 32 > 0) {
            x >>= 32;
            result <<= 16;
        }
        if (x >> 16 > 0) {
            x >>= 16;
            result <<= 8;
        }
        if (x >> 8 > 0) {
            x >>= 8;
            result <<= 4;
        }
        if (x >> 4 > 0) {
            x >>= 4;
            result <<= 2;
        }
        if (x >> 2 > 0) {
            result <<= 1;
        }

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

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

// File: @openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.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 CountersUpgradeable {
    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-upgradeable/utils/StringsUpgradeable.sol


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

pragma solidity ^0.8.0;

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // 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);
    }

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

// File: @openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;


/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSAUpgradeable {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", StringsUpgradeable.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

// File: @openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20PermitUpgradeable {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

// File: @openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol


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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.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 IERC20MetadataUpgradeable is IERC20Upgradeable {
    /**
     * @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-upgradeable/utils/StorageSlotUpgradeable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)

pragma solidity ^0.8.0;

/**
 * @dev Library for reading and writing primitive types to specific storage slots.
 *
 * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
 * This library helps with reading and writing to such slots without the need for inline assembly.
 *
 * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
 *
 * Example usage to set ERC1967 implementation slot:
 * ```
 * contract ERC1967 {
 *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
 *
 *     function _getImplementation() internal view returns (address) {
 *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
 *     }
 *
 *     function _setImplementation(address newImplementation) internal {
 *         require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
 *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
 *     }
 * }
 * ```
 *
 * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._
 */
library StorageSlotUpgradeable {
    struct AddressSlot {
        address value;
    }

    struct BooleanSlot {
        bool value;
    }

    struct Bytes32Slot {
        bytes32 value;
    }

    struct Uint256Slot {
        uint256 value;
    }

    /**
     * @dev Returns an `AddressSlot` with member `value` located at `slot`.
     */
    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
     */
    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
     */
    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
     */
    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }
}

// File: @openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol


// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)

pragma solidity ^0.8.0;

/**
 * @dev This is the interface that {BeaconProxy} expects of its beacon.
 */
interface IBeaconUpgradeable {
    /**
     * @dev Must return an address that can be used as a delegate call target.
     *
     * {BeaconProxy} will check that this address is a contract.
     */
    function implementation() external view returns (address);
}

// File: @openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol


// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)

pragma solidity ^0.8.0;

/**
 * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
 * proxy whose upgrades are fully controlled by the current implementation.
 */
interface IERC1822ProxiableUpgradeable {
    /**
     * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
     * address.
     *
     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
     * function revert if invoked through a proxy.
     */
    function proxiableUUID() external view returns (bytes32);
}

// File: @openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol


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

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library AddressUpgradeable {
    /**
     * @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 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
                /// @solidity memory-safe-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// File: @openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;




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

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

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

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

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

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

    function safePermit(
        IERC20PermitUpgradeable token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

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

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

// File: @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)

pragma solidity ^0.8.2;


/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
 * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
 * case an upgrade adds a module that needs to be initialized.
 *
 * For example:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * contract MyToken is ERC20Upgradeable {
 *     function initialize() initializer public {
 *         __ERC20_init("MyToken", "MTK");
 *     }
 * }
 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
 *     function initializeV2() reinitializer(2) public {
 *         __ERC20Permit_init("MyToken");
 *     }
 * }
 * ```
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() {
 *     _disableInitializers();
 * }
 * ```
 * ====
 */
abstract contract Initializable {
    /**
     * @dev Indicates that the contract has been initialized.
     * @custom:oz-retyped-from bool
     */
    uint8 private _initialized;

    /**
     * @dev Indicates that the contract is in the process of being initialized.
     */
    bool private _initializing;

    /**
     * @dev Triggered when the contract has been initialized or reinitialized.
     */
    event Initialized(uint8 version);

    /**
     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
     * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.
     */
    modifier initializer() {
        bool isTopLevelCall = !_initializing;
        require(
            (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
            "Initializable: contract is already initialized"
        );
        _initialized = 1;
        if (isTopLevelCall) {
            _initializing = true;
        }
        _;
        if (isTopLevelCall) {
            _initializing = false;
            emit Initialized(1);
        }
    }

    /**
     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
     * used to initialize parent contracts.
     *
     * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original
     * initialization step. This is essential to configure modules that are added through upgrades and that require
     * initialization.
     *
     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
     * a contract, executing them in the right order is up to the developer or operator.
     */
    modifier reinitializer(uint8 version) {
        require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
        _initialized = version;
        _initializing = true;
        _;
        _initializing = false;
        emit Initialized(version);
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} and {reinitializer} modifiers, directly or indirectly.
     */
    modifier onlyInitializing() {
        require(_initializing, "Initializable: contract is not initializing");
        _;
    }

    /**
     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
     * through proxies.
     */
    function _disableInitializers() internal virtual {
        require(!_initializing, "Initializable: contract is initializing");
        if (_initialized < type(uint8).max) {
            _initialized = type(uint8).max;
            emit Initialized(type(uint8).max);
        }
    }
}

// File: @openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol


// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)

pragma solidity ^0.8.0;



/**
 * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
 *
 * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
 * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
 * they need in their contracts using a combination of `abi.encode` and `keccak256`.
 *
 * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
 * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
 * ({_hashTypedDataV4}).
 *
 * The implementation of the domain separator was designed to be as efficient as possible while still properly updating
 * the chain id to protect against replay attacks on an eventual fork of the chain.
 *
 * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
 * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
 *
 * _Available since v3.4._
 *
 * @custom:storage-size 52
 */
abstract contract EIP712Upgradeable is Initializable {
    /* solhint-disable var-name-mixedcase */
    bytes32 private _HASHED_NAME;
    bytes32 private _HASHED_VERSION;
    bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");

    /* solhint-enable var-name-mixedcase */

    /**
     * @dev Initializes the domain separator and parameter caches.
     *
     * The meaning of `name` and `version` is specified in
     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
     *
     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
     * - `version`: the current major version of the signing domain.
     *
     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
     * contract upgrade].
     */
    function __EIP712_init(string memory name, string memory version) internal onlyInitializing {
        __EIP712_init_unchained(name, version);
    }

    function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {
        bytes32 hashedName = keccak256(bytes(name));
        bytes32 hashedVersion = keccak256(bytes(version));
        _HASHED_NAME = hashedName;
        _HASHED_VERSION = hashedVersion;
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());
    }

    function _buildDomainSeparator(
        bytes32 typeHash,
        bytes32 nameHash,
        bytes32 versionHash
    ) private view returns (bytes32) {
        return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));
    }

    /**
     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
     * function returns the hash of the fully encoded EIP712 message for this domain.
     *
     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
     *
     * ```solidity
     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
     *     keccak256("Mail(address to,string contents)"),
     *     mailTo,
     *     keccak256(bytes(mailContents))
     * )));
     * address signer = ECDSA.recover(digest, signature);
     * ```
     */
    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
        return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);
    }

    /**
     * @dev The hash of the name parameter for the EIP712 domain.
     *
     * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs
     * are a concern.
     */
    function _EIP712NameHash() internal virtual view returns (bytes32) {
        return _HASHED_NAME;
    }

    /**
     * @dev The hash of the version parameter for the EIP712 domain.
     *
     * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs
     * are a concern.
     */
    function _EIP712VersionHash() internal virtual view returns (bytes32) {
        return _HASHED_VERSION;
    }

    /**
     * @dev This empty reserved space is put in place to allow future versions to add new
     * variables without shifting down storage in the inheritance chain.
     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
     */
    uint256[50] private __gap;
}

// File: @openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.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 ContextUpgradeable is Initializable {
    function __Context_init() internal onlyInitializing {
    }

    function __Context_init_unchained() internal onlyInitializing {
    }
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

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

    /**
     * @dev This empty reserved space is put in place to allow future versions to add new
     * variables without shifting down storage in the inheritance chain.
     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
     */
    uint256[50] private __gap;
}

// File: @openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;



/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract PausableUpgradeable is Initializable, ContextUpgradeable {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    function __Pausable_init() internal onlyInitializing {
        __Pausable_init_unchained();
    }

    function __Pausable_init_unchained() internal onlyInitializing {
        _paused = false;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        _requireNotPaused();
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        _requirePaused();
        _;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        require(paused(), "Pausable: not paused");
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }

    /**
     * @dev This empty reserved space is put in place to allow future versions to add new
     * variables without shifting down storage in the inheritance chain.
     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
     */
    uint256[49] private __gap;
}

// File: @openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol


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

pragma solidity ^0.8.0;



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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    function __Ownable_init() internal onlyInitializing {
        __Ownable_init_unchained();
    }

    function __Ownable_init_unchained() internal onlyInitializing {
        _transferOwnership(_msgSender());
    }

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

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

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

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

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

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

    /**
     * @dev This empty reserved space is put in place to allow future versions to add new
     * variables without shifting down storage in the inheritance chain.
     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
     */
    uint256[49] private __gap;
}

// File: @openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol


// OpenZeppelin Contracts (last updated v4.7.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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {
    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.
     */
    function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {
        __ERC20_init_unchained(name_, symbol_);
    }

    function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {
        _name = name_;
        _symbol = symbol_;
    }

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

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

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

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

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

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

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

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

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

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

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

        return true;
    }

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

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _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 Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

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

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

    /**
     * @dev This empty reserved space is put in place to allow future versions to add new
     * variables without shifting down storage in the inheritance chain.
     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
     */
    uint256[45] private __gap;
}

// File: @openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)

pragma solidity ^0.8.0;







/**
 * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 *
 * _Available since v3.4._
 *
 * @custom:storage-size 51
 */
abstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {
    using CountersUpgradeable for CountersUpgradeable.Counter;

    mapping(address => CountersUpgradeable.Counter) private _nonces;

    // solhint-disable-next-line var-name-mixedcase
    bytes32 private constant _PERMIT_TYPEHASH =
        keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
    /**
     * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.
     * However, to ensure consistency with the upgradeable transpiler, we will continue
     * to reserve a slot.
     * @custom:oz-renamed-from _PERMIT_TYPEHASH
     */
    // solhint-disable-next-line var-name-mixedcase
    bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;

    /**
     * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
     *
     * It's a good idea to use the same `name` that is defined as the ERC20 token name.
     */
    function __ERC20Permit_init(string memory name) internal onlyInitializing {
        __EIP712_init_unchained(name, "1");
    }

    function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}

    /**
     * @dev See {IERC20Permit-permit}.
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual override {
        require(block.timestamp <= deadline, "ERC20Permit: expired deadline");

        bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));

        bytes32 hash = _hashTypedDataV4(structHash);

        address signer = ECDSAUpgradeable.recover(hash, v, r, s);
        require(signer == owner, "ERC20Permit: invalid signature");

        _approve(owner, spender, value);
    }

    /**
     * @dev See {IERC20Permit-nonces}.
     */
    function nonces(address owner) public view virtual override returns (uint256) {
        return _nonces[owner].current();
    }

    /**
     * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view override returns (bytes32) {
        return _domainSeparatorV4();
    }

    /**
     * @dev "Consume a nonce": return the current value and increment.
     *
     * _Available since v4.1._
     */
    function _useNonce(address owner) internal virtual returns (uint256 current) {
        CountersUpgradeable.Counter storage nonce = _nonces[owner];
        current = nonce.current();
        nonce.increment();
    }

    /**
     * @dev This empty reserved space is put in place to allow future versions to add new
     * variables without shifting down storage in the inheritance chain.
     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
     */
    uint256[49] private __gap;
}

// File: @openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol


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

pragma solidity ^0.8.0;







/**
 * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,
 * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.
 *
 * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.
 *
 * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either
 * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting
 * power can be queried through the public accessors {getVotes} and {getPastVotes}.
 *
 * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it
 * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.
 *
 * _Available since v4.2._
 */
abstract contract ERC20VotesUpgradeable is Initializable, IVotesUpgradeable, ERC20PermitUpgradeable {
    function __ERC20Votes_init() internal onlyInitializing {
    }

    function __ERC20Votes_init_unchained() internal onlyInitializing {
    }
    struct Checkpoint {
        uint32 fromBlock;
        uint224 votes;
    }

    bytes32 private constant _DELEGATION_TYPEHASH =
        keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");

    mapping(address => address) private _delegates;
    mapping(address => Checkpoint[]) private _checkpoints;
    Checkpoint[] private _totalSupplyCheckpoints;

    /**
     * @dev Get the `pos`-th checkpoint for `account`.
     */
    function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {
        return _checkpoints[account][pos];
    }

    /**
     * @dev Get number of checkpoints for `account`.
     */
    function numCheckpoints(address account) public view virtual returns (uint32) {
        return SafeCastUpgradeable.toUint32(_checkpoints[account].length);
    }

    /**
     * @dev Get the address `account` is currently delegating to.
     */
    function delegates(address account) public view virtual override returns (address) {
        return _delegates[account];
    }

    /**
     * @dev Gets the current votes balance for `account`
     */
    function getVotes(address account) public view virtual override returns (uint256) {
        uint256 pos = _checkpoints[account].length;
        return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;
    }

    /**
     * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.
     *
     * Requirements:
     *
     * - `blockNumber` must have been already mined
     */
    function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {
        require(blockNumber < block.number, "ERC20Votes: block not yet mined");
        return _checkpointsLookup(_checkpoints[account], blockNumber);
    }

    /**
     * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.
     * It is but NOT the sum of all the delegated votes!
     *
     * Requirements:
     *
     * - `blockNumber` must have been already mined
     */
    function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {
        require(blockNumber < block.number, "ERC20Votes: block not yet mined");
        return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);
    }

    /**
     * @dev Lookup a value in a list of (sorted) checkpoints.
     */
    function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {
        // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.
        //
        // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).
        // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.
        // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)
        // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)
        // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not
        // out of bounds (in which case we're looking too far in the past and the result is 0).
        // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is
        // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out
        // the same.
        uint256 high = ckpts.length;
        uint256 low = 0;
        while (low < high) {
            uint256 mid = MathUpgradeable.average(low, high);
            if (ckpts[mid].fromBlock > blockNumber) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        return high == 0 ? 0 : ckpts[high - 1].votes;
    }

    /**
     * @dev Delegate votes from the sender to `delegatee`.
     */
    function delegate(address delegatee) public virtual override {
        _delegate(_msgSender(), delegatee);
    }

    /**
     * @dev Delegates votes from signer to `delegatee`
     */
    function delegateBySig(
        address delegatee,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual override {
        require(block.timestamp <= expiry, "ERC20Votes: signature expired");
        address signer = ECDSAUpgradeable.recover(
            _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),
            v,
            r,
            s
        );
        require(nonce == _useNonce(signer), "ERC20Votes: invalid nonce");
        _delegate(signer, delegatee);
    }

    /**
     * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).
     */
    function _maxSupply() internal view virtual returns (uint224) {
        return type(uint224).max;
    }

    /**
     * @dev Snapshots the totalSupply after it has been increased.
     */
    function _mint(address account, uint256 amount) internal virtual override {
        super._mint(account, amount);
        require(totalSupply() <= _maxSupply(), "ERC20Votes: total supply risks overflowing votes");

        _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);
    }

    /**
     * @dev Snapshots the totalSupply after it has been decreased.
     */
    function _burn(address account, uint256 amount) internal virtual override {
        super._burn(account, amount);

        _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);
    }

    /**
     * @dev Move voting power when tokens are transferred.
     *
     * Emits a {DelegateVotesChanged} event.
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override {
        super._afterTokenTransfer(from, to, amount);

        _moveVotingPower(delegates(from), delegates(to), amount);
    }

    /**
     * @dev Change delegation for `delegator` to `delegatee`.
     *
     * Emits events {DelegateChanged} and {DelegateVotesChanged}.
     */
    function _delegate(address delegator, address delegatee) internal virtual {
        address currentDelegate = delegates(delegator);
        uint256 delegatorBalance = balanceOf(delegator);
        _delegates[delegator] = delegatee;

        emit DelegateChanged(delegator, currentDelegate, delegatee);

        _moveVotingPower(currentDelegate, delegatee, delegatorBalance);
    }

    function _moveVotingPower(
        address src,
        address dst,
        uint256 amount
    ) private {
        if (src != dst && amount > 0) {
            if (src != address(0)) {
                (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);
                emit DelegateVotesChanged(src, oldWeight, newWeight);
            }

            if (dst != address(0)) {
                (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);
                emit DelegateVotesChanged(dst, oldWeight, newWeight);
            }
        }
    }

    function _writeCheckpoint(
        Checkpoint[] storage ckpts,
        function(uint256, uint256) view returns (uint256) op,
        uint256 delta
    ) private returns (uint256 oldWeight, uint256 newWeight) {
        uint256 pos = ckpts.length;
        oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;
        newWeight = op(oldWeight, delta);

        if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {
            ckpts[pos - 1].votes = SafeCastUpgradeable.toUint224(newWeight);
        } else {
            ckpts.push(Checkpoint({fromBlock: SafeCastUpgradeable.toUint32(block.number), votes: SafeCastUpgradeable.toUint224(newWeight)}));
        }
    }

    function _add(uint256 a, uint256 b) private pure returns (uint256) {
        return a + b;
    }

    function _subtract(uint256 a, uint256 b) private pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev This empty reserved space is put in place to allow future versions to add new
     * variables without shifting down storage in the inheritance chain.
     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
     */
    uint256[47] private __gap;
}

// File: @openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol


// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)

pragma solidity ^0.8.2;






/**
 * @dev This abstract contract provides getters and event emitting update functions for
 * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
 *
 * _Available since v4.1._
 *
 * @custom:oz-upgrades-unsafe-allow delegatecall
 */
abstract contract ERC1967UpgradeUpgradeable is Initializable {
    function __ERC1967Upgrade_init() internal onlyInitializing {
    }

    function __ERC1967Upgrade_init_unchained() internal onlyInitializing {
    }
    // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
    bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;

    /**
     * @dev Storage slot with the address of the current implementation.
     * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
     * validated in the constructor.
     */
    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;

    /**
     * @dev Emitted when the implementation is upgraded.
     */
    event Upgraded(address indexed implementation);

    /**
     * @dev Returns the current implementation address.
     */
    function _getImplementation() internal view returns (address) {
        return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;
    }

    /**
     * @dev Stores a new address in the EIP1967 implementation slot.
     */
    function _setImplementation(address newImplementation) private {
        require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract");
        StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
    }

    /**
     * @dev Perform implementation upgrade
     *
     * Emits an {Upgraded} event.
     */
    function _upgradeTo(address newImplementation) internal {
        _setImplementation(newImplementation);
        emit Upgraded(newImplementation);
    }

    /**
     * @dev Perform implementation upgrade with additional setup call.
     *
     * Emits an {Upgraded} event.
     */
    function _upgradeToAndCall(
        address newImplementation,
        bytes memory data,
        bool forceCall
    ) internal {
        _upgradeTo(newImplementation);
        if (data.length > 0 || forceCall) {
            _functionDelegateCall(newImplementation, data);
        }
    }

    /**
     * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
     *
     * Emits an {Upgraded} event.
     */
    function _upgradeToAndCallUUPS(
        address newImplementation,
        bytes memory data,
        bool forceCall
    ) internal {
        // Upgrades from old implementations will perform a rollback test. This test requires the new
        // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing
        // this special case will break upgrade paths from old UUPS implementation to new ones.
        if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {
            _setImplementation(newImplementation);
        } else {
            try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {
                require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID");
            } catch {
                revert("ERC1967Upgrade: new implementation is not UUPS");
            }
            _upgradeToAndCall(newImplementation, data, forceCall);
        }
    }

    /**
     * @dev Storage slot with the admin of the contract.
     * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
     * validated in the constructor.
     */
    bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;

    /**
     * @dev Emitted when the admin account has changed.
     */
    event AdminChanged(address previousAdmin, address newAdmin);

    /**
     * @dev Returns the current admin.
     */
    function _getAdmin() internal view returns (address) {
        return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;
    }

    /**
     * @dev Stores a new address in the EIP1967 admin slot.
     */
    function _setAdmin(address newAdmin) private {
        require(newAdmin != address(0), "ERC1967: new admin is the zero address");
        StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
    }

    /**
     * @dev Changes the admin of the proxy.
     *
     * Emits an {AdminChanged} event.
     */
    function _changeAdmin(address newAdmin) internal {
        emit AdminChanged(_getAdmin(), newAdmin);
        _setAdmin(newAdmin);
    }

    /**
     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
     * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
     */
    bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;

    /**
     * @dev Emitted when the beacon is upgraded.
     */
    event BeaconUpgraded(address indexed beacon);

    /**
     * @dev Returns the current beacon.
     */
    function _getBeacon() internal view returns (address) {
        return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;
    }

    /**
     * @dev Stores a new beacon in the EIP1967 beacon slot.
     */
    function _setBeacon(address newBeacon) private {
        require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract");
        require(
            AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),
            "ERC1967: beacon implementation is not a contract"
        );
        StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;
    }

    /**
     * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
     * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
     *
     * Emits a {BeaconUpgraded} event.
     */
    function _upgradeBeaconToAndCall(
        address newBeacon,
        bytes memory data,
        bool forceCall
    ) internal {
        _setBeacon(newBeacon);
        emit BeaconUpgraded(newBeacon);
        if (data.length > 0 || forceCall) {
            _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);
        }
    }

    /**
     * @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) private returns (bytes memory) {
        require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed");
    }

    /**
     * @dev This empty reserved space is put in place to allow future versions to add new
     * variables without shifting down storage in the inheritance chain.
     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
     */
    uint256[50] private __gap;
}

// File: @openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol


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

pragma solidity ^0.8.0;




/**
 * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
 * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
 *
 * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
 * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
 * `UUPSUpgradeable` with a custom implementation of upgrades.
 *
 * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
 *
 * _Available since v4.1._
 */
abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {
    function __UUPSUpgradeable_init() internal onlyInitializing {
    }

    function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
    }
    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
    address private immutable __self = address(this);

    /**
     * @dev Check that the execution is being performed through a delegatecall call and that the execution context is
     * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
     * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
     * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
     * fail.
     */
    modifier onlyProxy() {
        require(address(this) != __self, "Function must be called through delegatecall");
        require(_getImplementation() == __self, "Function must be called through active proxy");
        _;
    }

    /**
     * @dev Check that the execution is not being performed through a delegate call. This allows a function to be
     * callable on the implementing contract but not through proxies.
     */
    modifier notDelegated() {
        require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall");
        _;
    }

    /**
     * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
     * implementation. It is used to validate that the this implementation remains valid after an upgrade.
     *
     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
     * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
     */
    function proxiableUUID() external view virtual override notDelegated returns (bytes32) {
        return _IMPLEMENTATION_SLOT;
    }

    /**
     * @dev Upgrade the implementation of the proxy to `newImplementation`.
     *
     * Calls {_authorizeUpgrade}.
     *
     * Emits an {Upgraded} event.
     */
    function upgradeTo(address newImplementation) external virtual onlyProxy {
        _authorizeUpgrade(newImplementation);
        _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);
    }

    /**
     * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
     * encoded in `data`.
     *
     * Calls {_authorizeUpgrade}.
     *
     * Emits an {Upgraded} event.
     */
    function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {
        _authorizeUpgrade(newImplementation);
        _upgradeToAndCallUUPS(newImplementation, data, true);
    }

    /**
     * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
     * {upgradeTo} and {upgradeToAndCall}.
     *
     * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
     *
     * ```solidity
     * function _authorizeUpgrade(address) internal override onlyOwner {}
     * ```
     */
    function _authorizeUpgrade(address newImplementation) internal virtual;

    /**
     * @dev This empty reserved space is put in place to allow future versions to add new
     * variables without shifting down storage in the inheritance chain.
     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
     */
    uint256[50] private __gap;
}

// File: Maia.sol


pragma solidity 0.8.2;













contract Maia is Initializable, UUPSUpgradeable, ERC20Upgradeable, ERC20PermitUpgradeable, ERC20VotesUpgradeable, OwnableUpgradeable, PausableUpgradeable {
    using SafeMathUpgradeable for uint256;

    // Info of each user.
    struct UserInfo {
        uint256 amount;     // How many LP tokens the user has provided.
        uint256 rewardDebt; // Reward debt. See explanation below.
        uint256 rewargoldDebt; // Reward debt in GOLD.
        uint256 stakeEnd;
        //
        // We do some fancy math here. Basically, any point in time, the amount of GOLD
        // entitled to a user but is pending to be distributed is:
        //
        //   pending reward = (user.amount * pool.accGOLDPerShare) - user.rewardDebt
        //
        // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens:
        //   1. The pool's `accGOLDPerShare` (and `lastRewardBlock`) gets updated.
        //   2. User receives the pending reward sent to his/her address.
        //   3. User's `amount` gets updated.
        //   4. User's `rewardDebt` gets updated.
    }

    struct ValarUserInfo {
        uint256 rewardDebt;
    }

    // Info of each pool.
    struct PoolInfo {
        IERC20 lpToken;           // Address of LP token contract.
        uint256 allocPoint;       // How many allocation points assigned to this pool. GOLDs to distribute per block.
        uint256 lastRewardBlock;  // Last block number that GOLDs distribution occurs.
        uint256 accGOLDPerShare; // Accumulated GOLDs per share, times 1e12. See below.
        uint256 lastTotalGOLDReward; // last total rewards
        uint256 lastGOLDRewardBalance; // last GOLD rewards tokens
        uint256 totalGOLDReward; // total GOLD rewards tokens
    }

    struct ValarPoolInfo {
        uint256 lastGOLDRewardBalance;
        uint256 totalGOLDReward;
        uint256 totalValar;
    }

    // The GOLD TOKEN!
    IERC20 public GOLD;
    IERC20 public Valar;
    // admin address.
    address public adminAddress;
    // Bonus muliplier for early GOLD makers.
    uint256 public constant BONUS_MULTIPLIER = 1;

    // Number of top staker stored

    uint256 public topStakerNumber;

    // Info of each pool.
    PoolInfo[] public poolInfo;
    ValarPoolInfo[] public valarPoolInfo;
    // Info of each user that stakes LP tokens.
    mapping (uint256 => mapping (address => UserInfo)) public userInfo;
    mapping (uint256 => mapping (address => ValarUserInfo)) public valarUserInfo;


    // Total allocation points. Must be the sum of all allocation points in all pools.
    uint256 public totalAllocPoint;
    // The block number when reward distribution start.
    uint256 public startBlock;
    // total GOLD staked
    uint256 public totalGOLDStaked;
    // total GOLD used for purchase land
    uint256 public totalGOLDUsedForPurchase;
    // withdrawal delay
    uint256 public withdrawDelay;

    event Deposit(address indexed user, uint256 indexed pid, uint256 amount);
    event Withdraw(address indexed user, uint256 indexed pid, uint256 amount);
    event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount);
    event AdminUpdated(address newAdmin);

    function initialize(        
        address _GOLD,
        address _Valar,
        address _adminAddress,
        uint256 _startBlock
        ) public initializer {
        require(_adminAddress != address(0), "initialize: Zero address");
        OwnableUpgradeable.__Ownable_init();
        __ERC20_init_unchained("Maia", "Maia");
        __Pausable_init_unchained();
        ERC20PermitUpgradeable.__ERC20Permit_init("Maia");
        ERC20VotesUpgradeable.__ERC20Votes_init_unchained();
        GOLD = IERC20(_GOLD);
        Valar = IERC20(_Valar);
        adminAddress = _adminAddress;
        startBlock = _startBlock;
        withdrawDelay = 0;
    }

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

    function poolLength() external view returns (uint256) {
        return poolInfo.length;
    }

    // Add a new lp to the pool. Can only be called by the owner.
    // XXX DO NOT add the same LP token more than once. Rewards will be messed up if you do.
    function add(uint256 _allocPoint, IERC20 _lpToken, bool _withUpdate) public onlyOwner {
        if (_withUpdate) {
            massUpdatePools();
        }
        uint256 lastRewardBlock = block.number > startBlock ? block.number : startBlock;
        totalAllocPoint = totalAllocPoint.add(_allocPoint);
        poolInfo.push(PoolInfo({
            lpToken: _lpToken,
            allocPoint: _allocPoint,
            lastRewardBlock: lastRewardBlock,
            accGOLDPerShare: 0,
            lastTotalGOLDReward: 0,
            lastGOLDRewardBalance: 0,
            totalGOLDReward: 0
        }));
         valarPoolInfo.push(ValarPoolInfo({
             lastGOLDRewardBalance: 0,
             totalGOLDReward: 0,
             totalValar: 0
         }));

    }

    function setWithdrawDelay(uint256 _delay) external onlyOwner {
        withdrawDelay = _delay;
    }

    // Update the given pool's GOLD allocation point. Can only be called by the owner.
    function set(uint256 _pid, uint256 _allocPoint, bool _withUpdate) public onlyOwner {
        if (_withUpdate) {
            massUpdatePools();
        }
        totalAllocPoint = totalAllocPoint.sub(poolInfo[_pid].allocPoint).add(_allocPoint);
        poolInfo[_pid].allocPoint = _allocPoint;
    }
    
    // Return reward multiplier over the given _from to _to block.
    function getMultiplier(uint256 _from, uint256 _to) public pure returns (uint256) {
        if (_to >= _from) {
            return _to.sub(_from).mul(BONUS_MULTIPLIER);
        } else {
            return _from.sub(_to);
        }
    }
    
    // View function to see pending GOLDs on frontend.
    function pendingGOLD(uint256 _pid, address _user) external view returns (uint256) {
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][_user];

        uint256 accGOLDPerShare = pool.accGOLDPerShare;
        uint256 lpSupply = totalGOLDStaked;
        if (block.number > pool.lastRewardBlock && lpSupply != 0) {
            uint256 rewardBalance = pool.lpToken.balanceOf(address(this)).sub(totalGOLDStaked.sub(totalGOLDUsedForPurchase));
            uint256 _totalReward = rewardBalance.sub(pool.lastGOLDRewardBalance);
            accGOLDPerShare = accGOLDPerShare.add(_totalReward.mul(1e12).div(lpSupply));
        }
        uint256 reward = user.amount.mul(accGOLDPerShare).div(1e12).sub(user.rewargoldDebt);

        if (Valar.balanceOf(_user) == 1) {
            return reward;
        }
        else {
            return reward.mul(90).div(100);
        }
    }

    // Update reward variables for all pools. Be careful of gas spending!
    function massUpdatePools() public {
        uint256 length = poolInfo.length;
        for (uint256 pid = 0; pid < length; ++pid) {
            updatePool(pid);
        }
    }

    function updatePoolHelper(uint _pid) external view returns (uint) {
        PoolInfo storage pool = poolInfo[_pid];
        
        if (block.number <= pool.lastRewardBlock) {
            return 0;
        }
        uint256 rewardBalance = pool.lpToken.balanceOf(address(this)).sub(totalGOLDStaked.sub(totalGOLDUsedForPurchase));

        return rewardBalance;
    }

    // Update reward variables of the given pool to be up-to-date.
    function updatePool(uint256 _pid) public {
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][msg.sender];

        
        if (block.number <= pool.lastRewardBlock) {
            return;
        }
        uint256 rewardBalance = pool.lpToken.balanceOf(address(this)).sub(totalGOLDStaked.sub(totalGOLDUsedForPurchase));
        uint256 _totalReward = pool.totalGOLDReward.add(rewardBalance.sub(pool.lastGOLDRewardBalance));
        pool.lastGOLDRewardBalance = rewardBalance;
        pool.totalGOLDReward = _totalReward;
        
        uint256 lpSupply = totalGOLDStaked;
        if (lpSupply == 0) {
            pool.lastRewardBlock = block.number;
            pool.accGOLDPerShare = 0;
            pool.lastTotalGOLDReward = 0;
            user.rewargoldDebt = 0;
            pool.lastGOLDRewardBalance = 0;
            pool.totalGOLDReward = 0;
            return;
        }
        
        uint256 reward = _totalReward.sub(pool.lastTotalGOLDReward);
        pool.accGOLDPerShare = pool.accGOLDPerShare.add(reward.mul(1e12).div(lpSupply));
        pool.lastTotalGOLDReward = _totalReward;
    }

    // Deposit GOLD tokens to MasterChef.
    function deposit(uint256 _pid, uint256 _amount) public {
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][msg.sender];

        updatePool(_pid);
        if (user.amount > 0) {
            uint256 GOLDReward = user.amount.mul(pool.accGOLDPerShare).div(1e12).sub(user.rewargoldDebt);
            if (GOLDReward > 0) {
                pool.lpToken.transfer(msg.sender, GOLDReward);
            }
            pool.lastGOLDRewardBalance = pool.lpToken.balanceOf(address(this)).sub(totalGOLDStaked.sub(totalGOLDUsedForPurchase));
        }
        
        uint256 taxAdjustedAmount = _amount.sub(_amount.mul(4).div(100));

        pool.lpToken.transferFrom(address(msg.sender), address(this), _amount);
        totalGOLDStaked = totalGOLDStaked.add(taxAdjustedAmount);
        user.amount = user.amount.add(taxAdjustedAmount);
        user.rewargoldDebt = user.amount.mul(pool.accGOLDPerShare).div(1e12);
        user.stakeEnd = block.timestamp + withdrawDelay;
        _mint(msg.sender,taxAdjustedAmount);
        emit Deposit(msg.sender, _pid, taxAdjustedAmount);
    }

    function getVPool(uint _pid) external view returns(ValarPoolInfo memory) {
        return valarPoolInfo[_pid];
    }

    function withdraw(uint256 _pid, uint256 _amount) public {
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][msg.sender];

        require(block.timestamp >= user.stakeEnd, "withdraw: too soon");
        require(user.amount >= _amount, "withdraw: too little");
        updatePool(_pid);

        uint256 GOLDReward = user.amount.mul(pool.accGOLDPerShare).div(1e12).sub(user.rewargoldDebt);
        if (GOLDReward > 0) pool.lpToken.transfer(msg.sender, GOLDReward);
        pool.lastGOLDRewardBalance = pool.lpToken.balanceOf(address(this)).sub(totalGOLDStaked.sub(totalGOLDUsedForPurchase));

        user.amount = user.amount.sub(_amount);
        totalGOLDStaked = totalGOLDStaked.sub(_amount);
        user.rewargoldDebt = user.amount.mul(pool.accGOLDPerShare).div(1e12);
        pool.lpToken.transfer(address(msg.sender), _amount);
        _burn(msg.sender,_amount);
        emit Withdraw(msg.sender, _pid, _amount);
    }

    function getPool(uint256 _pid) external view returns (PoolInfo memory) {
        return poolInfo[_pid]; 
    }

    function getUser(uint256 _pid, address _user) external view returns (UserInfo memory) {
        return userInfo[_pid][_user]; 
    }
    
    // Earn GOLD tokens to MasterChef.
    function claimGOLD(uint256 _pid) public {
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][msg.sender];

        updatePool(_pid);
        
        uint256 GOLDReward = user.amount.mul(pool.accGOLDPerShare).div(1e12).sub(user.rewargoldDebt);
        if (GOLDReward > 0) {
            if (Valar.balanceOf(msg.sender) == 1) {
                pool.lpToken.transfer(msg.sender, GOLDReward);
            } else {
                pool.lpToken.transfer(msg.sender, GOLDReward.mul(90).div(100));
            }
        }
        pool.lastGOLDRewardBalance = pool.lpToken.balanceOf(address(this)).sub(totalGOLDStaked.sub(totalGOLDUsedForPurchase));

        user.rewargoldDebt = user.amount.mul(pool.accGOLDPerShare).div(1e12);   
    }
    
    // Safe GOLD transfer function to admin.
    function accessGOLDTokens(uint256 _pid, address _to, uint256 _amount) public {
        require(msg.sender == adminAddress, "sender must be admin address");
        require(totalGOLDStaked.sub(totalGOLDUsedForPurchase) >= _amount, "Amount must be less than staked GOLD amount");
        PoolInfo storage pool = poolInfo[_pid];
        uint256 GOLDBal = pool.lpToken.balanceOf(address(this));
        if (_amount > GOLDBal) {
            pool.lpToken.transfer(_to, GOLDBal);
            totalGOLDUsedForPurchase = totalGOLDUsedForPurchase.add(GOLDBal);
            emit EmergencyWithdraw(_to, _pid, GOLDBal);
        } else {
            pool.lpToken.transfer(_to, _amount);
            totalGOLDUsedForPurchase = totalGOLDUsedForPurchase.add(_amount);
            emit EmergencyWithdraw(_to, _pid, _amount);
        }
    }
    // Update admin address by the previous admin.
    function admin(address _adminAddress) public {
        require(_adminAddress != address(0), "admin: Zero address");
        require(msg.sender == adminAddress, "admin: wut?");
        adminAddress = _adminAddress;
        emit AdminUpdated(_adminAddress);
    }

    function _mint(address to, uint256 amount)
        internal
        override(ERC20Upgradeable, ERC20VotesUpgradeable)
    {
        super._mint(to, amount);
    }

    function _burn(address account, uint256 amount)
        internal
        override(ERC20Upgradeable, ERC20VotesUpgradeable)
    {
        super._burn(account, amount);
    }

    function _afterTokenTransfer(address from, address to, uint256 amount)
        internal
        override(ERC20Upgradeable, ERC20VotesUpgradeable)
    {
        ERC20VotesUpgradeable._afterTokenTransfer(from, to, amount);
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override {
        
        if(from == address(0) || to == address(0)){
            super._beforeTokenTransfer(from, to, amount);
        }else{
            revert("Non transferable token");
        }
    }

    function _delegate(address delegator, address delegatee) internal virtual override {
        super._delegate(delegator,delegatee);
    }

    function _authorizeUpgrade(address) internal view override {
        require(owner() == msg.sender, "Only owner can upgrade implementation");
    }

}

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminUpdated","type":"event"},{"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":"beacon","type":"address"}],"name":"BeaconUpgraded","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":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"BONUS_MULTIPLIER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GOLD","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"Valar","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"accessGOLDTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"contract IERC20","name":"_lpToken","type":"address"},{"internalType":"bool","name":"_withUpdate","type":"bool"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_adminAddress","type":"address"}],"name":"admin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"adminAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":"account","type":"address"},{"internalType":"uint32","name":"pos","type":"uint32"}],"name":"checkpoints","outputs":[{"components":[{"internalType":"uint32","name":"fromBlock","type":"uint32"},{"internalType":"uint224","name":"votes","type":"uint224"}],"internalType":"struct ERC20VotesUpgradeable.Checkpoint","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"claimGOLD","outputs":[],"stateMutability":"nonpayable","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":"account","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_from","type":"uint256"},{"internalType":"uint256","name":"_to","type":"uint256"}],"name":"getMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"getPool","outputs":[{"components":[{"internalType":"contract IERC20","name":"lpToken","type":"address"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardBlock","type":"uint256"},{"internalType":"uint256","name":"accGOLDPerShare","type":"uint256"},{"internalType":"uint256","name":"lastTotalGOLDReward","type":"uint256"},{"internalType":"uint256","name":"lastGOLDRewardBalance","type":"uint256"},{"internalType":"uint256","name":"totalGOLDReward","type":"uint256"}],"internalType":"struct Maia.PoolInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"getUser","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"},{"internalType":"uint256","name":"rewargoldDebt","type":"uint256"},{"internalType":"uint256","name":"stakeEnd","type":"uint256"}],"internalType":"struct Maia.UserInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"getVPool","outputs":[{"components":[{"internalType":"uint256","name":"lastGOLDRewardBalance","type":"uint256"},{"internalType":"uint256","name":"totalGOLDReward","type":"uint256"},{"internalType":"uint256","name":"totalValar","type":"uint256"}],"internalType":"struct Maia.ValarPoolInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_GOLD","type":"address"},{"internalType":"address","name":"_Valar","type":"address"},{"internalType":"address","name":"_adminAddress","type":"address"},{"internalType":"uint256","name":"_startBlock","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","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":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingGOLD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"contract IERC20","name":"lpToken","type":"address"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardBlock","type":"uint256"},{"internalType":"uint256","name":"accGOLDPerShare","type":"uint256"},{"internalType":"uint256","name":"lastTotalGOLDReward","type":"uint256"},{"internalType":"uint256","name":"lastGOLDRewardBalance","type":"uint256"},{"internalType":"uint256","name":"totalGOLDReward","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"bool","name":"_withUpdate","type":"bool"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_delay","type":"uint256"}],"name":"setWithdrawDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"topStakerNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAllocPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalGOLDStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalGOLDUsedForPurchase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","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":"uint256","name":"_pid","type":"uint256"}],"name":"updatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updatePoolHelper","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"},{"internalType":"uint256","name":"rewargoldDebt","type":"uint256"},{"internalType":"uint256","name":"stakeEnd","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"valarPoolInfo","outputs":[{"internalType":"uint256","name":"lastGOLDRewardBalance","type":"uint256"},{"internalType":"uint256","name":"totalGOLDReward","type":"uint256"},{"internalType":"uint256","name":"totalValar","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"valarUserInfo","outputs":[{"internalType":"uint256","name":"rewardDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

60a06040523060601b60805234801561001757600080fd5b5060805160601c614d34610052600039600081816117ce0152818161180e01528181611c3801528181611c780152611e520152614d346000f3fe6080604052600436106103a25760003560e01c80635c975abb116101e757806393f1a40b1161010d578063d2371d50116100a0578063f1127ed81161006f578063f1127ed814610c20578063f2fde38b14610c6a578063f8b535ac14610c8a578063fc6f946814610ca1576103a2565b8063d2371d5014610b87578063d505accf14610bc0578063dd62ed3e14610be0578063e2bbb15814610c00576103a2565b8063a87492c8116100dc578063a87492c814610b07578063a9059cbb14610b27578063c3cda52014610b47578063cf756fdf14610b67576103a2565b806393f1a40b14610a4457806395d89b4114610ab25780639ab24eb014610ac7578063a457c2d714610ae7576103a2565b8063715018a6116101855780638aa28550116101545780638aa28550146109d05780638da5cb5b146109e55780638dbb1e3a14610a045780638e539e8c14610a24576103a2565b8063715018a61461094057806372f0cb30146109555780637ecebe001461097557806381fbc5a714610995576103a2565b806364482f79116101c157806364482f791461089e5780636f10947c146108be5780636fcfff45146108d557806370a082311461090a576103a2565b80635c975abb14610850578063630b5ba11461086957806363a846f81461087e576103a2565b8063313ce567116102cc578063477901661161026a57806352d1902d1161023957806352d1902d146107c1578063587cde1e146107d65780635b3c25ce146108105780635c19a95c14610830576103a2565b8063477901661461075657806348cd4cb1146107775780634f1ef2861461078e57806351eb05a6146107a1576103a2565b806339509351116102a657806339509351146106bd5780633a46b1a8146106dd5780633e4bee38146106fd578063441a3e7014610736576103a2565b8063313ce5671461066c5780633644e515146106885780633659cfe61461069d576103a2565b80630d3c5df01161034457806318160ddd1161031357806318160ddd146105c45780631eaaa045146105d957806323b872dd146105f9578063257664a414610619576103a2565b80630d3c5df0146104ea578063101afee41461050c5780631526fe271461054e57806317caf6f1146105ad576103a2565b806306fdde031161038057806306fdde0314610462578063081e3eda14610484578063095ea7b31461049a5780630bc1a005146104ca576103a2565b8063017e58ca146103a75780630288a39c146103d1578063068bcd8d146103e8575b600080fd5b3480156103b357600080fd5b506103be6101d05481565b6040519081526020015b60405180910390f35b3480156103dd57600080fd5b506103be6101d25481565b3480156103f457600080fd5b5061040861040336600461495b565b610cc2565b6040516103c8919081516001600160a01b031681526020808301519082015260408083015190820152606080830151908201526080808301519082015260a0828101519082015260c0918201519181019190915260e00190565b34801561046e57600080fd5b50610477610d9d565b6040516103c89190614a68565b34801561049057600080fd5b506101ca546103be565b3480156104a657600080fd5b506104ba6104b536600461486e565b610e2f565b60405190151581526020016103c8565b3480156104d657600080fd5b506103be6104e5366004614973565b610e49565b3480156104f657600080fd5b5061050a610505366004614997565b611082565b005b34801561051857600080fd5b5061052c61052736600461495b565b6113d5565b60408051825181526020808401519082015291810151908201526060016103c8565b34801561055a57600080fd5b5061056e61056936600461495b565b611459565b604080516001600160a01b0390981688526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016103c8565b3480156105b957600080fd5b506103be6101ce5481565b3480156105d057600080fd5b506099546103be565b3480156105e557600080fd5b5061050a6105f43660046149bd565b6114b3565b34801561060557600080fd5b506104ba610614366004614702565b61170b565b34801561062557600080fd5b50610639610634366004614973565b611731565b6040516103c891908151815260208083015190820152604080830151908201526060918201519181019190915260800190565b34801561067857600080fd5b50604051600981526020016103c8565b34801561069457600080fd5b506103be6117b4565b3480156106a957600080fd5b5061050a6106b836600461465e565b6117c3565b3480156106c957600080fd5b506104ba6106d836600461486e565b6118a3565b3480156106e957600080fd5b506103be6106f836600461486e565b6118c5565b34801561070957600080fd5b506101c65461071e906001600160a01b031681565b6040516001600160a01b0390911681526020016103c8565b34801561074257600080fd5b5061050a6107513660046149fe565b611939565b34801561076257600080fd5b506101c75461071e906001600160a01b031681565b34801561078357600080fd5b506103be6101cf5481565b61050a61079c3660046147af565b611c2d565b3480156107ad57600080fd5b5061050a6107bc36600461495b565b611cfe565b3480156107cd57600080fd5b506103be611e45565b3480156107e257600080fd5b5061071e6107f136600461465e565b6001600160a01b03908116600090815261013060205260409020541690565b34801561081c57600080fd5b5061050a61082b36600461495b565b611ef8565b34801561083c57600080fd5b5061050a61084b36600461465e565b61217c565b34801561085c57600080fd5b506101945460ff166104ba565b34801561087557600080fd5b5061050a612186565b34801561088a57600080fd5b5061050a61089936600461465e565b6121ae565b3480156108aa57600080fd5b5061050a6108b9366004614a1f565b612298565b3480156108ca57600080fd5b506103be6101c95481565b3480156108e157600080fd5b506108f56108f036600461465e565b612345565b60405163ffffffff90911681526020016103c8565b34801561091657600080fd5b506103be61092536600461465e565b6001600160a01b031660009081526097602052604090205490565b34801561094c57600080fd5b5061050a612368565b34801561096157600080fd5b5061050a61097036600461495b565b61237c565b34801561098157600080fd5b506103be61099036600461465e565b61238a565b3480156109a157600080fd5b506109b56109b036600461495b565b6123a8565b604080519384526020840192909252908201526060016103c8565b3480156109dc57600080fd5b506103be600181565b3480156109f157600080fd5b50610162546001600160a01b031661071e565b348015610a1057600080fd5b506103be610a1f3660046149fe565b6123dc565b348015610a3057600080fd5b506103be610a3f36600461495b565b61240b565b348015610a5057600080fd5b50610a92610a5f366004614973565b6101cc60209081526000928352604080842090915290825290208054600182015460028301546003909301549192909184565b6040805194855260208501939093529183015260608201526080016103c8565b348015610abe57600080fd5b50610477612468565b348015610ad357600080fd5b506103be610ae236600461465e565b612477565b348015610af357600080fd5b506104ba610b0236600461486e565b61250e565b348015610b1357600080fd5b506103be610b2236600461495b565b612594565b348015610b3357600080fd5b506104ba610b4236600461486e565b612633565b348015610b5357600080fd5b5061050a610b62366004614899565b612641565b348015610b7357600080fd5b5061050a610b823660046146b2565b612777565b348015610b9357600080fd5b506103be610ba2366004614973565b6101cd60209081526000928352604080842090915290825290205481565b348015610bcc57600080fd5b5061050a610bdb366004614742565b6129a4565b348015610bec57600080fd5b506103be610bfb36600461467a565b612b08565b348015610c0c57600080fd5b5061050a610c1b3660046149fe565b612b33565b348015610c2c57600080fd5b50610c40610c3b3660046148f2565b612da6565b60408051825163ffffffff1681526020928301516001600160e01b031692810192909252016103c8565b348015610c7657600080fd5b5061050a610c8536600461465e565b612e39565b348015610c9657600080fd5b506103be6101d15481565b348015610cad57600080fd5b506101c85461071e906001600160a01b031681565b610d0b6040518060e0016040528060006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6101ca8281548110610d2d57634e487b7160e01b600052603260045260246000fd5b60009182526020918290206040805160e081018252600790930290910180546001600160a01b031683526001810154938301939093526002830154908201526003820154606082015260048201546080820152600582015460a082015260069091015460c082015290505b919050565b6060609a8054610dac90614c18565b80601f0160208091040260200160405190810160405280929190818152602001828054610dd890614c18565b8015610e255780601f10610dfa57610100808354040283529160200191610e25565b820191906000526020600020905b815481529060010190602001808311610e0857829003601f168201915b5050505050905090565b600033610e3d818585612eaf565b60019150505b92915050565b6000806101ca8481548110610e6e57634e487b7160e01b600052603260045260246000fd5b600091825260208083208784526101cc825260408085206001600160a01b0389168652909252922060036007909202909201908101546101d0546002830154929450909143118015610ebf57508015155b15610fa8576000610f63610ee26101d1546101d054612fd390919063ffffffff16565b86546040516370a0823160e01b81523060048201526001600160a01b03909116906370a08231906024015b60206040518083038186803b158015610f2557600080fd5b505afa158015610f39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5d9190614943565b90612fd3565b90506000610f7e866005015483612fd390919063ffffffff16565b9050610fa3610f9c84610f968464e8d4a51000612fdf565b90612feb565b8590612ff7565b935050505b6000610fd28460020154610f5d64e8d4a51000610f96878960000154612fdf90919063ffffffff16565b6101c7546040516370a0823160e01b81526001600160a01b038a811660048301529293509116906370a082319060240160206040518083038186803b15801561101a57600080fd5b505afa15801561102e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110529190614943565b60011415611066579450610e439350505050565b6110766064610f9683605a612fdf565b95505050505050610e43565b6101c8546001600160a01b031633146110e25760405162461bcd60e51b815260206004820152601c60248201527f73656e646572206d7573742062652061646d696e20616464726573730000000060448201526064015b60405180910390fd5b806110fc6101d1546101d054612fd390919063ffffffff16565b101561115e5760405162461bcd60e51b815260206004820152602b60248201527f416d6f756e74206d757374206265206c657373207468616e207374616b65642060448201526a11d3d31108185b5bdd5b9d60aa1b60648201526084016110d9565b60006101ca848154811061118257634e487b7160e01b600052603260045260246000fd5b6000918252602082206007919091020180546040516370a0823160e01b81523060048201529193506001600160a01b0316906370a082319060240160206040518083038186803b1580156111d557600080fd5b505afa1580156111e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061120d9190614943565b9050808311156112f457815460405163a9059cbb60e01b81526001600160a01b038681166004830152602482018490529091169063a9059cbb90604401602060405180830381600087803b15801561126457600080fd5b505af1158015611278573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061129c9190614927565b506101d1546112ab9082612ff7565b6101d15560405181815285906001600160a01b038616907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959060200160405180910390a36113ce565b815460405163a9059cbb60e01b81526001600160a01b038681166004830152602482018690529091169063a9059cbb90604401602060405180830381600087803b15801561134157600080fd5b505af1158015611355573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113799190614927565b506101d1546113889084612ff7565b6101d15560405183815285906001600160a01b038616907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae0595906020015b60405180910390a35b5050505050565b6113f960405180606001604052806000815260200160008152602001600081525090565b6101cb828154811061141b57634e487b7160e01b600052603260045260246000fd5b906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820154815250509050919050565b6101ca818154811061146a57600080fd5b600091825260209091206007909102018054600182015460028301546003840154600485015460058601546006909601546001600160a01b039095169650929491939092919087565b6114bb613003565b80156114c9576114c9612186565b60006101cf5443116114de576101cf546114e0565b435b6101ce549091506114f19085612ff7565b6101ce556040805160e0810182526001600160a01b0394851681526020808201968752818301938452600060608084018281526080850183815260a0860184815260c087018581526101ca80546001808201835591885298517f0faeda9012b7f59bd2a84ac2a33ead5fc9f720c38d8bbf90db1ac3c1518386eb6007909a02998a0180546001600160a01b03191691909e1617909c559b517f0faeda9012b7f59bd2a84ac2a33ead5fc9f720c38d8bbf90db1ac3c1518386ec88015597517f0faeda9012b7f59bd2a84ac2a33ead5fc9f720c38d8bbf90db1ac3c1518386ed87015590517f0faeda9012b7f59bd2a84ac2a33ead5fc9f720c38d8bbf90db1ac3c1518386ee860155517f0faeda9012b7f59bd2a84ac2a33ead5fc9f720c38d8bbf90db1ac3c1518386ef85015594517f0faeda9012b7f59bd2a84ac2a33ead5fc9f720c38d8bbf90db1ac3c1518386f084015596517f0faeda9012b7f59bd2a84ac2a33ead5fc9f720c38d8bbf90db1ac3c1518386f1909201919091558151928301825285835282018581529082018581526101cb8054958601815590955290517fe8bbfecd380c4167d6a1f763a233ec73e73f534b1970c4e1683f437ec23c1f44600390940293840155517fe8bbfecd380c4167d6a1f763a233ec73e73f534b1970c4e1683f437ec23c1f458301555090517fe8bbfecd380c4167d6a1f763a233ec73e73f534b1970c4e1683f437ec23c1f4690910155565b60003361171985828561305e565b6117248585856130d8565b60019150505b9392505050565b61175c6040518060800160405280600081526020016000815260200160008152602001600081525090565b5060009182526101cc602090815260408084206001600160a01b039390931684529181529181902081516080810183528154815260018201549381019390935260028101549183019190915260030154606082015290565b60006117be6132b7565b905090565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016141561180c5760405162461bcd60e51b81526004016110d990614a9b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611855600080516020614cb8833981519152546001600160a01b031690565b6001600160a01b03161461187b5760405162461bcd60e51b81526004016110d990614ae7565b61188481613332565b604080516000808252602082019092526118a0918391906133aa565b50565b600033610e3d8185856118b68383612b08565b6118c09190614b7e565b612eaf565b60004382106119165760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e65640060448201526064016110d9565b6001600160a01b03831660009081526101316020526040902061172a908361352e565b60006101ca838154811061195d57634e487b7160e01b600052603260045260246000fd5b600091825260208083208684526101cc8252604080852033865290925292206003810154600790920290920192504210156119cf5760405162461bcd60e51b81526020600482015260126024820152713bb4ba34323930bb9d103a37b79039b7b7b760711b60448201526064016110d9565b8054831115611a175760405162461bcd60e51b815260206004820152601460248201527377697468647261773a20746f6f206c6974746c6560601b60448201526064016110d9565b611a2084611cfe565b6000611a4e8260020154610f5d64e8d4a51000610f9687600301548760000154612fdf90919063ffffffff16565b90508015611adb57825460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b158015611aa157600080fd5b505af1158015611ab5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ad99190614927565b505b611b26611af76101d1546101d054612fd390919063ffffffff16565b84546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401610f0d565b60058401558154611b379085612fd3565b82556101d054611b479085612fd3565b6101d05560038301548254611b669164e8d4a5100091610f9691612fdf565b6002830155825460405163a9059cbb60e01b8152336004820152602481018690526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b158015611bb657600080fd5b505af1158015611bca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bee9190614927565b50611bf93385613607565b604051848152859033907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568906020016113c5565b306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161415611c765760405162461bcd60e51b81526004016110d990614a9b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611cbf600080516020614cb8833981519152546001600160a01b031690565b6001600160a01b031614611ce55760405162461bcd60e51b81526004016110d990614ae7565b611cee82613332565b611cfa828260016133aa565b5050565b60006101ca8281548110611d2257634e487b7160e01b600052603260045260246000fd5b600091825260208083208584526101cc82526040808520338652909252922060026007909202909201908101549092504311611d5f5750506118a0565b6000611d7d611af76101d1546101d054612fd390919063ffffffff16565b90506000611da6611d9b856005015484612fd390919063ffffffff16565b600686015490612ff7565b60058501839055600685018190556101d05490915080611df45750504360028085019190915560006003850181905560048501819055920182905550600582018190556006909101556118a0565b6000611e0d866004015484612fd390919063ffffffff16565b9050611e30611e2583610f968464e8d4a51000612fdf565b600388015490612ff7565b60038701555050600490930192909255505050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611ee55760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016110d9565b50600080516020614cb883398151915290565b60006101ca8281548110611f1c57634e487b7160e01b600052603260045260246000fd5b600091825260208083208584526101cc82526040808520338652909252922060079091029091019150611f4e83611cfe565b6000611f7c8260020154610f5d64e8d4a51000610f9687600301548760000154612fdf90919063ffffffff16565b90508015612132576101c7546040516370a0823160e01b81523360048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015611fc857600080fd5b505afa158015611fdc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120009190614943565b6001141561209157825460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b15801561205357600080fd5b505af1158015612067573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061208b9190614927565b50612132565b82546001600160a01b031663a9059cbb336120b26064610f9686605a612fdf565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b1580156120f857600080fd5b505af115801561210c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121309190614927565b505b61214e611af76101d1546101d054612fd390919063ffffffff16565b60058401556003830154825461216e9164e8d4a5100091610f9691612fdf565b826002018190555050505050565b6118a03382613611565b6101ca5460005b81811015611cfa5761219e81611cfe565b6121a781614c4d565b905061218d565b6001600160a01b0381166121fa5760405162461bcd60e51b815260206004820152601360248201527261646d696e3a205a65726f206164647265737360681b60448201526064016110d9565b6101c8546001600160a01b031633146122435760405162461bcd60e51b815260206004820152600b60248201526a61646d696e3a207775743f60a81b60448201526064016110d9565b6101c880546001600160a01b0319166001600160a01b0383169081179091556040519081527f54e4612788f90384e6843298d7854436f3a585b2c3831ab66abf1de63bfa6c2d9060200160405180910390a150565b6122a0613003565b80156122ae576122ae612186565b612301826122fb6101ca86815481106122d757634e487b7160e01b600052603260045260246000fd5b9060005260206000209060070201600101546101ce54612fd390919063ffffffff16565b90612ff7565b6101ce81905550816101ca848154811061232b57634e487b7160e01b600052603260045260246000fd5b906000526020600020906007020160010181905550505050565b6001600160a01b03811660009081526101316020526040812054610e439061361b565b612370613003565b61237a6000613684565b565b612384613003565b6101d255565b6001600160a01b038116600090815260fd6020526040812054610e43565b6101cb81815481106123b957600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b6000828210612401576123fa60016123f48486612fd3565b90612fdf565b9050610e43565b6123fa8383612fd3565b600043821061245c5760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e65640060448201526064016110d9565b610e436101328361352e565b6060609b8054610dac90614c18565b6001600160a01b0381166000908152610131602052604081205480156124fb576001600160a01b0383166000908152610131602052604090206124bb600183614bd5565b815481106124d957634e487b7160e01b600052603260045260246000fd5b60009182526020909120015464010000000090046001600160e01b03166124fe565b60005b6001600160e01b03169392505050565b6000338161251c8286612b08565b90508381101561257c5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016110d9565b6125898286868403612eaf565b506001949350505050565b6000806101ca83815481106125b957634e487b7160e01b600052603260045260246000fd5b90600052602060002090600702019050806002015443116125de576000915050610d98565b600061262b6125fc6101d1546101d054612fd390919063ffffffff16565b83546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401610f0d565b949350505050565b600033610e3d8185856130d8565b834211156126915760405162461bcd60e51b815260206004820152601d60248201527f4552433230566f7465733a207369676e6174757265206578706972656400000060448201526064016110d9565b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60208201526001600160a01b03881691810191909152606081018690526080810185905260009061270b906127039060a001604051602081830303815290604052805190602001206136d7565b858585613725565b90506127168161374d565b86146127645760405162461bcd60e51b815260206004820152601960248201527f4552433230566f7465733a20696e76616c6964206e6f6e63650000000000000060448201526064016110d9565b61276e8188613611565b50505050505050565b600054610100900460ff16158080156127975750600054600160ff909116105b806127b15750303b1580156127b1575060005460ff166001145b6128145760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016110d9565b6000805460ff191660011790558015612837576000805461ff0019166101001790555b6001600160a01b03831661288d5760405162461bcd60e51b815260206004820152601860248201527f696e697469616c697a653a205a65726f2061646472657373000000000000000060448201526064016110d9565b612895613775565b6128d7604051806040016040528060048152602001634d61696160e01b815250604051806040016040528060048152602001634d61696160e01b8152506137a4565b6128df6137f2565b612904604051806040016040528060048152602001634d61696160e01b815250613826565b61290c613870565b6101c680546001600160a01b038088166001600160a01b0319928316179092556101c780548784169083161790556101c88054928616929091169190911790556101cf82905560006101d25580156113ce576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b834211156129f45760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e6500000060448201526064016110d9565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888612a238c61374d565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000612a7e826136d7565b90506000612a8e82878787613725565b9050896001600160a01b0316816001600160a01b031614612af15760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e6174757265000060448201526064016110d9565b612afc8a8a8a612eaf565b50505050505050505050565b6001600160a01b03918216600090815260986020908152604080832093909416825291909152205490565b60006101ca8381548110612b5757634e487b7160e01b600052603260045260246000fd5b600091825260208083208684526101cc82526040808520338652909252922060079091029091019150612b8984611cfe565b805415612c6e576000612bbe8260020154610f5d64e8d4a51000610f9687600301548760000154612fdf90919063ffffffff16565b90508015612c4b57825460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b158015612c1157600080fd5b505af1158015612c25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c499190614927565b505b612c67611af76101d1546101d054612fd390919063ffffffff16565b6005840155505b6000612c8a612c836064610f96876004612fdf565b8590612fd3565b83546040516323b872dd60e01b8152336004820152306024820152604481018790529192506001600160a01b0316906323b872dd90606401602060405180830381600087803b158015612cdc57600080fd5b505af1158015612cf0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d149190614927565b506101d054612d239082612ff7565b6101d0558154612d339082612ff7565b8083556003840154612d509164e8d4a5100091610f969190612fdf565b60028301556101d254612d639042614b7e565b6003830155612d723382613897565b604051818152859033907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15906020016113c5565b60408051808201909152600080825260208201526001600160a01b038316600090815261013160205260409020805463ffffffff8416908110612df957634e487b7160e01b600052603260045260246000fd5b60009182526020918290206040805180820190915291015463ffffffff8116825264010000000090046001600160e01b0316918101919091529392505050565b612e41613003565b6001600160a01b038116612ea65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016110d9565b6118a081613684565b6001600160a01b038316612f115760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016110d9565b6001600160a01b038216612f725760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016110d9565b6001600160a01b0383811660008181526098602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600061172a8284614bd5565b600061172a8284614bb6565b600061172a8284614b96565b600061172a8284614b7e565b610162546001600160a01b0316331461237a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016110d9565b600061306a8484612b08565b905060001981146130d257818110156130c55760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016110d9565b6130d28484848403612eaf565b50505050565b6001600160a01b03831661313c5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016110d9565b6001600160a01b03821661319e5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016110d9565b6131a98383836138a1565b6001600160a01b038316600090815260976020526040902054818110156132215760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016110d9565b6001600160a01b03808516600090815260976020526040808220858503905591851681529081208054849290613258908490614b7e565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516132a491815260200190565b60405180910390a36130d2848484613909565b60006117be7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6132e660c95490565b60ca546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b33613346610162546001600160a01b031690565b6001600160a01b0316146118a05760405162461bcd60e51b815260206004820152602560248201527f4f6e6c79206f776e65722063616e207570677261646520696d706c656d656e7460448201526430ba34b7b760d91b60648201526084016110d9565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156133e2576133dd83613914565b613529565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561341b57600080fd5b505afa92505050801561344b575060408051601f3d908101601f1916820190925261344891810190614943565b60015b6134ae5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016110d9565b600080516020614cb8833981519152811461351d5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016110d9565b506135298383836139b0565b505050565b8154600090815b818110156135a057600061354982846139d5565b90508486828154811061356c57634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff16111561358c5780925061359a565b613597816001614b7e565b91505b50613535565b81156135f257846135b2600184614bd5565b815481106135d057634e487b7160e01b600052603260045260246000fd5b60009182526020909120015464010000000090046001600160e01b03166135f5565b60005b6001600160e01b031695945050505050565b611cfa82826139f0565b611cfa8282613a09565b600063ffffffff8211156136805760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b60648201526084016110d9565b5090565b61016280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610e436136e46132b7565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b600080600061373687878787613a84565b9150915061374381613b71565b5095945050505050565b6001600160a01b038116600090815260fd602052604090208054600181018255905b50919050565b600054610100900460ff1661379c5760405162461bcd60e51b81526004016110d990614b33565b61237a613d74565b600054610100900460ff166137cb5760405162461bcd60e51b81526004016110d990614b33565b81516137de90609a9060208501906145bd565b50805161352990609b9060208401906145bd565b600054610100900460ff166138195760405162461bcd60e51b81526004016110d990614b33565b610194805460ff19169055565b600054610100900460ff1661384d5760405162461bcd60e51b81526004016110d990614b33565b6118a081604051806040016040528060018152602001603160f81b815250613da4565b600054610100900460ff1661237a5760405162461bcd60e51b81526004016110d990614b33565b611cfa8282613de5565b6001600160a01b03831615806138be57506001600160a01b038216155b156138c8576133dd565b60405162461bcd60e51b81526020600482015260166024820152752737b7103a3930b739b332b930b13632903a37b5b2b760511b60448201526064016110d9565b613529838383613e70565b6001600160a01b0381163b6139815760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016110d9565b600080516020614cb883398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6139b983613ea3565b6000825111806139c65750805b15613529576130d28383613ee3565b60006139e46002848418614b96565b61172a90848416614b7e565b6139fa8282613fd7565b6130d2610132612fd383614138565b6001600160a01b0382811660008181526101306020818152604080842080546097845282862054949093528787166001600160a01b03198416811790915590519190951694919391928592917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a46130d28284836142e9565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613abb5750600090506003613b68565b8460ff16601b14158015613ad357508460ff16601c14155b15613ae45750600090506004613b68565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613b38573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116613b6157600060019250925050613b68565b9150600090505b94509492505050565b6000816004811115613b9357634e487b7160e01b600052602160045260246000fd5b1415613b9e576118a0565b6001816004811115613bc057634e487b7160e01b600052602160045260246000fd5b1415613c0e5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016110d9565b6002816004811115613c3057634e487b7160e01b600052602160045260246000fd5b1415613c7e5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016110d9565b6003816004811115613ca057634e487b7160e01b600052602160045260246000fd5b1415613cf95760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016110d9565b6004816004811115613d1b57634e487b7160e01b600052602160045260246000fd5b14156118a05760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016110d9565b600054610100900460ff16613d9b5760405162461bcd60e51b81526004016110d990614b33565b61237a33613684565b600054610100900460ff16613dcb5760405162461bcd60e51b81526004016110d990614b33565b81516020928301208151919092012060c99190915560ca55565b613def8282614428565b6099546001600160e01b031015613e615760405162461bcd60e51b815260206004820152603060248201527f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60448201526f766572666c6f77696e6720766f74657360801b60648201526084016110d9565b6130d2610132612ff783614138565b6001600160a01b0383811660009081526101306020526040808220548584168352912054613529929182169116836142e9565b613eac81613914565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b613f4b5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016110d9565b600080846001600160a01b031684604051613f669190614a4c565b600060405180830381855af49150503d8060008114613fa1576040519150601f19603f3d011682016040523d82523d6000602084013e613fa6565b606091505b5091509150613fce8282604051806060016040528060278152602001614cd86027913961451b565b95945050505050565b6001600160a01b0382166140375760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016110d9565b614043826000836138a1565b6001600160a01b038216600090815260976020526040902054818110156140b75760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016110d9565b6001600160a01b03831660009081526097602052604081208383039055609980548492906140e6908490614bd5565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a361352983600084613909565b8254600090819080156141915785614151600183614bd5565b8154811061416f57634e487b7160e01b600052603260045260246000fd5b60009182526020909120015464010000000090046001600160e01b0316614194565b60005b6001600160e01b031692506141ad83858763ffffffff16565b91506000811180156141f9575043866141c7600184614bd5565b815481106141e557634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff16145b156142675761420782614554565b86614213600184614bd5565b8154811061423157634e487b7160e01b600052603260045260246000fd5b9060005260206000200160000160046101000a8154816001600160e01b0302191690836001600160e01b031602179055506142e0565b85604051806040016040528061427c4361361b565b63ffffffff16815260200161429085614554565b6001600160e01b039081169091528254600181018455600093845260209384902083519101805493909401519091166401000000000263ffffffff91821663ffffffff1990931692909217161790555b50935093915050565b816001600160a01b0316836001600160a01b03161415801561430b5750600081115b15613529576001600160a01b0383161561439a576001600160a01b038316600090815261013160205260408120819061434790612fd385614138565b91509150846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724838360405161438f929190918252602082015260400190565b60405180910390a250505b6001600160a01b03821615613529576001600160a01b03821660009081526101316020526040812081906143d190612ff785614138565b91509150836001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051614419929190918252602082015260400190565b60405180910390a25050505050565b6001600160a01b03821661447e5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016110d9565b61448a600083836138a1565b806099600082825461449c9190614b7e565b90915550506001600160a01b038216600090815260976020526040812080548392906144c9908490614b7e565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3611cfa60008383613909565b6060831561452a57508161172a565b82511561453a5782518084602001fd5b8160405162461bcd60e51b81526004016110d99190614a68565b60006001600160e01b038211156136805760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b60648201526084016110d9565b8280546145c990614c18565b90600052602060002090601f0160209004810192826145eb5760008555614631565b82601f1061460457805160ff1916838001178555614631565b82800160010185558215614631579182015b82811115614631578251825591602001919060010190614616565b506136809291505b808211156136805760008155600101614639565b803560ff81168114610d9857600080fd5b60006020828403121561466f578081fd5b813561172a81614c94565b6000806040838503121561468c578081fd5b823561469781614c94565b915060208301356146a781614c94565b809150509250929050565b600080600080608085870312156146c7578182fd5b84356146d281614c94565b935060208501356146e281614c94565b925060408501356146f281614c94565b9396929550929360600135925050565b600080600060608486031215614716578283fd5b833561472181614c94565b9250602084013561473181614c94565b929592945050506040919091013590565b600080600080600080600060e0888a03121561475c578283fd5b873561476781614c94565b9650602088013561477781614c94565b955060408801359450606088013593506147936080890161464d565b925060a0880135915060c0880135905092959891949750929550565b600080604083850312156147c1578182fd5b82356147cc81614c94565b9150602083013567ffffffffffffffff808211156147e8578283fd5b818501915085601f8301126147fb578283fd5b81358181111561480d5761480d614c7e565b604051601f8201601f19908116603f0116810190838211818310171561483557614835614c7e565b8160405282815288602084870101111561484d578586fd5b82602086016020830137856020848301015280955050505050509250929050565b60008060408385031215614880578182fd5b823561488b81614c94565b946020939093013593505050565b60008060008060008060c087890312156148b1578182fd5b86356148bc81614c94565b955060208701359450604087013593506148d86060880161464d565b92506080870135915060a087013590509295509295509295565b60008060408385031215614904578182fd5b823561490f81614c94565b9150602083013563ffffffff811681146146a7578182fd5b600060208284031215614938578081fd5b815161172a81614ca9565b600060208284031215614954578081fd5b5051919050565b60006020828403121561496c578081fd5b5035919050565b60008060408385031215614985578182fd5b8235915060208301356146a781614c94565b6000806000606084860312156149ab578081fd5b83359250602084013561473181614c94565b6000806000606084860312156149d1578081fd5b8335925060208401356149e381614c94565b915060408401356149f381614ca9565b809150509250925092565b60008060408385031215614a10578182fd5b50508035926020909101359150565b600080600060608486031215614a33578081fd5b833592506020840135915060408401356149f381614ca9565b60008251614a5e818460208701614bec565b9190910192915050565b6000602082528251806020840152614a87816040850160208701614bec565b601f01601f19169190910160400192915050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60008219821115614b9157614b91614c68565b500190565b600082614bb157634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615614bd057614bd0614c68565b500290565b600082821015614be757614be7614c68565b500390565b60005b83811015614c07578181015183820152602001614bef565b838111156130d25750506000910152565b600281046001821680614c2c57607f821691505b6020821081141561376f57634e487b7160e01b600052602260045260246000fd5b6000600019821415614c6157614c61614c68565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146118a057600080fd5b80151581146118a057600080fdfe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212204818f7eefa1f3d5f2d1805bfcffa1a9b932dd98859e15958dee130ec9f26e0ed64736f6c63430008020033

Deployed Bytecode

0x6080604052600436106103a25760003560e01c80635c975abb116101e757806393f1a40b1161010d578063d2371d50116100a0578063f1127ed81161006f578063f1127ed814610c20578063f2fde38b14610c6a578063f8b535ac14610c8a578063fc6f946814610ca1576103a2565b8063d2371d5014610b87578063d505accf14610bc0578063dd62ed3e14610be0578063e2bbb15814610c00576103a2565b8063a87492c8116100dc578063a87492c814610b07578063a9059cbb14610b27578063c3cda52014610b47578063cf756fdf14610b67576103a2565b806393f1a40b14610a4457806395d89b4114610ab25780639ab24eb014610ac7578063a457c2d714610ae7576103a2565b8063715018a6116101855780638aa28550116101545780638aa28550146109d05780638da5cb5b146109e55780638dbb1e3a14610a045780638e539e8c14610a24576103a2565b8063715018a61461094057806372f0cb30146109555780637ecebe001461097557806381fbc5a714610995576103a2565b806364482f79116101c157806364482f791461089e5780636f10947c146108be5780636fcfff45146108d557806370a082311461090a576103a2565b80635c975abb14610850578063630b5ba11461086957806363a846f81461087e576103a2565b8063313ce567116102cc578063477901661161026a57806352d1902d1161023957806352d1902d146107c1578063587cde1e146107d65780635b3c25ce146108105780635c19a95c14610830576103a2565b8063477901661461075657806348cd4cb1146107775780634f1ef2861461078e57806351eb05a6146107a1576103a2565b806339509351116102a657806339509351146106bd5780633a46b1a8146106dd5780633e4bee38146106fd578063441a3e7014610736576103a2565b8063313ce5671461066c5780633644e515146106885780633659cfe61461069d576103a2565b80630d3c5df01161034457806318160ddd1161031357806318160ddd146105c45780631eaaa045146105d957806323b872dd146105f9578063257664a414610619576103a2565b80630d3c5df0146104ea578063101afee41461050c5780631526fe271461054e57806317caf6f1146105ad576103a2565b806306fdde031161038057806306fdde0314610462578063081e3eda14610484578063095ea7b31461049a5780630bc1a005146104ca576103a2565b8063017e58ca146103a75780630288a39c146103d1578063068bcd8d146103e8575b600080fd5b3480156103b357600080fd5b506103be6101d05481565b6040519081526020015b60405180910390f35b3480156103dd57600080fd5b506103be6101d25481565b3480156103f457600080fd5b5061040861040336600461495b565b610cc2565b6040516103c8919081516001600160a01b031681526020808301519082015260408083015190820152606080830151908201526080808301519082015260a0828101519082015260c0918201519181019190915260e00190565b34801561046e57600080fd5b50610477610d9d565b6040516103c89190614a68565b34801561049057600080fd5b506101ca546103be565b3480156104a657600080fd5b506104ba6104b536600461486e565b610e2f565b60405190151581526020016103c8565b3480156104d657600080fd5b506103be6104e5366004614973565b610e49565b3480156104f657600080fd5b5061050a610505366004614997565b611082565b005b34801561051857600080fd5b5061052c61052736600461495b565b6113d5565b60408051825181526020808401519082015291810151908201526060016103c8565b34801561055a57600080fd5b5061056e61056936600461495b565b611459565b604080516001600160a01b0390981688526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016103c8565b3480156105b957600080fd5b506103be6101ce5481565b3480156105d057600080fd5b506099546103be565b3480156105e557600080fd5b5061050a6105f43660046149bd565b6114b3565b34801561060557600080fd5b506104ba610614366004614702565b61170b565b34801561062557600080fd5b50610639610634366004614973565b611731565b6040516103c891908151815260208083015190820152604080830151908201526060918201519181019190915260800190565b34801561067857600080fd5b50604051600981526020016103c8565b34801561069457600080fd5b506103be6117b4565b3480156106a957600080fd5b5061050a6106b836600461465e565b6117c3565b3480156106c957600080fd5b506104ba6106d836600461486e565b6118a3565b3480156106e957600080fd5b506103be6106f836600461486e565b6118c5565b34801561070957600080fd5b506101c65461071e906001600160a01b031681565b6040516001600160a01b0390911681526020016103c8565b34801561074257600080fd5b5061050a6107513660046149fe565b611939565b34801561076257600080fd5b506101c75461071e906001600160a01b031681565b34801561078357600080fd5b506103be6101cf5481565b61050a61079c3660046147af565b611c2d565b3480156107ad57600080fd5b5061050a6107bc36600461495b565b611cfe565b3480156107cd57600080fd5b506103be611e45565b3480156107e257600080fd5b5061071e6107f136600461465e565b6001600160a01b03908116600090815261013060205260409020541690565b34801561081c57600080fd5b5061050a61082b36600461495b565b611ef8565b34801561083c57600080fd5b5061050a61084b36600461465e565b61217c565b34801561085c57600080fd5b506101945460ff166104ba565b34801561087557600080fd5b5061050a612186565b34801561088a57600080fd5b5061050a61089936600461465e565b6121ae565b3480156108aa57600080fd5b5061050a6108b9366004614a1f565b612298565b3480156108ca57600080fd5b506103be6101c95481565b3480156108e157600080fd5b506108f56108f036600461465e565b612345565b60405163ffffffff90911681526020016103c8565b34801561091657600080fd5b506103be61092536600461465e565b6001600160a01b031660009081526097602052604090205490565b34801561094c57600080fd5b5061050a612368565b34801561096157600080fd5b5061050a61097036600461495b565b61237c565b34801561098157600080fd5b506103be61099036600461465e565b61238a565b3480156109a157600080fd5b506109b56109b036600461495b565b6123a8565b604080519384526020840192909252908201526060016103c8565b3480156109dc57600080fd5b506103be600181565b3480156109f157600080fd5b50610162546001600160a01b031661071e565b348015610a1057600080fd5b506103be610a1f3660046149fe565b6123dc565b348015610a3057600080fd5b506103be610a3f36600461495b565b61240b565b348015610a5057600080fd5b50610a92610a5f366004614973565b6101cc60209081526000928352604080842090915290825290208054600182015460028301546003909301549192909184565b6040805194855260208501939093529183015260608201526080016103c8565b348015610abe57600080fd5b50610477612468565b348015610ad357600080fd5b506103be610ae236600461465e565b612477565b348015610af357600080fd5b506104ba610b0236600461486e565b61250e565b348015610b1357600080fd5b506103be610b2236600461495b565b612594565b348015610b3357600080fd5b506104ba610b4236600461486e565b612633565b348015610b5357600080fd5b5061050a610b62366004614899565b612641565b348015610b7357600080fd5b5061050a610b823660046146b2565b612777565b348015610b9357600080fd5b506103be610ba2366004614973565b6101cd60209081526000928352604080842090915290825290205481565b348015610bcc57600080fd5b5061050a610bdb366004614742565b6129a4565b348015610bec57600080fd5b506103be610bfb36600461467a565b612b08565b348015610c0c57600080fd5b5061050a610c1b3660046149fe565b612b33565b348015610c2c57600080fd5b50610c40610c3b3660046148f2565b612da6565b60408051825163ffffffff1681526020928301516001600160e01b031692810192909252016103c8565b348015610c7657600080fd5b5061050a610c8536600461465e565b612e39565b348015610c9657600080fd5b506103be6101d15481565b348015610cad57600080fd5b506101c85461071e906001600160a01b031681565b610d0b6040518060e0016040528060006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6101ca8281548110610d2d57634e487b7160e01b600052603260045260246000fd5b60009182526020918290206040805160e081018252600790930290910180546001600160a01b031683526001810154938301939093526002830154908201526003820154606082015260048201546080820152600582015460a082015260069091015460c082015290505b919050565b6060609a8054610dac90614c18565b80601f0160208091040260200160405190810160405280929190818152602001828054610dd890614c18565b8015610e255780601f10610dfa57610100808354040283529160200191610e25565b820191906000526020600020905b815481529060010190602001808311610e0857829003601f168201915b5050505050905090565b600033610e3d818585612eaf565b60019150505b92915050565b6000806101ca8481548110610e6e57634e487b7160e01b600052603260045260246000fd5b600091825260208083208784526101cc825260408085206001600160a01b0389168652909252922060036007909202909201908101546101d0546002830154929450909143118015610ebf57508015155b15610fa8576000610f63610ee26101d1546101d054612fd390919063ffffffff16565b86546040516370a0823160e01b81523060048201526001600160a01b03909116906370a08231906024015b60206040518083038186803b158015610f2557600080fd5b505afa158015610f39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5d9190614943565b90612fd3565b90506000610f7e866005015483612fd390919063ffffffff16565b9050610fa3610f9c84610f968464e8d4a51000612fdf565b90612feb565b8590612ff7565b935050505b6000610fd28460020154610f5d64e8d4a51000610f96878960000154612fdf90919063ffffffff16565b6101c7546040516370a0823160e01b81526001600160a01b038a811660048301529293509116906370a082319060240160206040518083038186803b15801561101a57600080fd5b505afa15801561102e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110529190614943565b60011415611066579450610e439350505050565b6110766064610f9683605a612fdf565b95505050505050610e43565b6101c8546001600160a01b031633146110e25760405162461bcd60e51b815260206004820152601c60248201527f73656e646572206d7573742062652061646d696e20616464726573730000000060448201526064015b60405180910390fd5b806110fc6101d1546101d054612fd390919063ffffffff16565b101561115e5760405162461bcd60e51b815260206004820152602b60248201527f416d6f756e74206d757374206265206c657373207468616e207374616b65642060448201526a11d3d31108185b5bdd5b9d60aa1b60648201526084016110d9565b60006101ca848154811061118257634e487b7160e01b600052603260045260246000fd5b6000918252602082206007919091020180546040516370a0823160e01b81523060048201529193506001600160a01b0316906370a082319060240160206040518083038186803b1580156111d557600080fd5b505afa1580156111e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061120d9190614943565b9050808311156112f457815460405163a9059cbb60e01b81526001600160a01b038681166004830152602482018490529091169063a9059cbb90604401602060405180830381600087803b15801561126457600080fd5b505af1158015611278573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061129c9190614927565b506101d1546112ab9082612ff7565b6101d15560405181815285906001600160a01b038616907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959060200160405180910390a36113ce565b815460405163a9059cbb60e01b81526001600160a01b038681166004830152602482018690529091169063a9059cbb90604401602060405180830381600087803b15801561134157600080fd5b505af1158015611355573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113799190614927565b506101d1546113889084612ff7565b6101d15560405183815285906001600160a01b038616907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae0595906020015b60405180910390a35b5050505050565b6113f960405180606001604052806000815260200160008152602001600081525090565b6101cb828154811061141b57634e487b7160e01b600052603260045260246000fd5b906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820154815250509050919050565b6101ca818154811061146a57600080fd5b600091825260209091206007909102018054600182015460028301546003840154600485015460058601546006909601546001600160a01b039095169650929491939092919087565b6114bb613003565b80156114c9576114c9612186565b60006101cf5443116114de576101cf546114e0565b435b6101ce549091506114f19085612ff7565b6101ce556040805160e0810182526001600160a01b0394851681526020808201968752818301938452600060608084018281526080850183815260a0860184815260c087018581526101ca80546001808201835591885298517f0faeda9012b7f59bd2a84ac2a33ead5fc9f720c38d8bbf90db1ac3c1518386eb6007909a02998a0180546001600160a01b03191691909e1617909c559b517f0faeda9012b7f59bd2a84ac2a33ead5fc9f720c38d8bbf90db1ac3c1518386ec88015597517f0faeda9012b7f59bd2a84ac2a33ead5fc9f720c38d8bbf90db1ac3c1518386ed87015590517f0faeda9012b7f59bd2a84ac2a33ead5fc9f720c38d8bbf90db1ac3c1518386ee860155517f0faeda9012b7f59bd2a84ac2a33ead5fc9f720c38d8bbf90db1ac3c1518386ef85015594517f0faeda9012b7f59bd2a84ac2a33ead5fc9f720c38d8bbf90db1ac3c1518386f084015596517f0faeda9012b7f59bd2a84ac2a33ead5fc9f720c38d8bbf90db1ac3c1518386f1909201919091558151928301825285835282018581529082018581526101cb8054958601815590955290517fe8bbfecd380c4167d6a1f763a233ec73e73f534b1970c4e1683f437ec23c1f44600390940293840155517fe8bbfecd380c4167d6a1f763a233ec73e73f534b1970c4e1683f437ec23c1f458301555090517fe8bbfecd380c4167d6a1f763a233ec73e73f534b1970c4e1683f437ec23c1f4690910155565b60003361171985828561305e565b6117248585856130d8565b60019150505b9392505050565b61175c6040518060800160405280600081526020016000815260200160008152602001600081525090565b5060009182526101cc602090815260408084206001600160a01b039390931684529181529181902081516080810183528154815260018201549381019390935260028101549183019190915260030154606082015290565b60006117be6132b7565b905090565b306001600160a01b037f00000000000000000000000098b60038edadad66f6b44065851182b597e0c22e16141561180c5760405162461bcd60e51b81526004016110d990614a9b565b7f00000000000000000000000098b60038edadad66f6b44065851182b597e0c22e6001600160a01b0316611855600080516020614cb8833981519152546001600160a01b031690565b6001600160a01b03161461187b5760405162461bcd60e51b81526004016110d990614ae7565b61188481613332565b604080516000808252602082019092526118a0918391906133aa565b50565b600033610e3d8185856118b68383612b08565b6118c09190614b7e565b612eaf565b60004382106119165760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e65640060448201526064016110d9565b6001600160a01b03831660009081526101316020526040902061172a908361352e565b60006101ca838154811061195d57634e487b7160e01b600052603260045260246000fd5b600091825260208083208684526101cc8252604080852033865290925292206003810154600790920290920192504210156119cf5760405162461bcd60e51b81526020600482015260126024820152713bb4ba34323930bb9d103a37b79039b7b7b760711b60448201526064016110d9565b8054831115611a175760405162461bcd60e51b815260206004820152601460248201527377697468647261773a20746f6f206c6974746c6560601b60448201526064016110d9565b611a2084611cfe565b6000611a4e8260020154610f5d64e8d4a51000610f9687600301548760000154612fdf90919063ffffffff16565b90508015611adb57825460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b158015611aa157600080fd5b505af1158015611ab5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ad99190614927565b505b611b26611af76101d1546101d054612fd390919063ffffffff16565b84546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401610f0d565b60058401558154611b379085612fd3565b82556101d054611b479085612fd3565b6101d05560038301548254611b669164e8d4a5100091610f9691612fdf565b6002830155825460405163a9059cbb60e01b8152336004820152602481018690526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b158015611bb657600080fd5b505af1158015611bca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bee9190614927565b50611bf93385613607565b604051848152859033907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568906020016113c5565b306001600160a01b037f00000000000000000000000098b60038edadad66f6b44065851182b597e0c22e161415611c765760405162461bcd60e51b81526004016110d990614a9b565b7f00000000000000000000000098b60038edadad66f6b44065851182b597e0c22e6001600160a01b0316611cbf600080516020614cb8833981519152546001600160a01b031690565b6001600160a01b031614611ce55760405162461bcd60e51b81526004016110d990614ae7565b611cee82613332565b611cfa828260016133aa565b5050565b60006101ca8281548110611d2257634e487b7160e01b600052603260045260246000fd5b600091825260208083208584526101cc82526040808520338652909252922060026007909202909201908101549092504311611d5f5750506118a0565b6000611d7d611af76101d1546101d054612fd390919063ffffffff16565b90506000611da6611d9b856005015484612fd390919063ffffffff16565b600686015490612ff7565b60058501839055600685018190556101d05490915080611df45750504360028085019190915560006003850181905560048501819055920182905550600582018190556006909101556118a0565b6000611e0d866004015484612fd390919063ffffffff16565b9050611e30611e2583610f968464e8d4a51000612fdf565b600388015490612ff7565b60038701555050600490930192909255505050565b6000306001600160a01b037f00000000000000000000000098b60038edadad66f6b44065851182b597e0c22e1614611ee55760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016110d9565b50600080516020614cb883398151915290565b60006101ca8281548110611f1c57634e487b7160e01b600052603260045260246000fd5b600091825260208083208584526101cc82526040808520338652909252922060079091029091019150611f4e83611cfe565b6000611f7c8260020154610f5d64e8d4a51000610f9687600301548760000154612fdf90919063ffffffff16565b90508015612132576101c7546040516370a0823160e01b81523360048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015611fc857600080fd5b505afa158015611fdc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120009190614943565b6001141561209157825460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b15801561205357600080fd5b505af1158015612067573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061208b9190614927565b50612132565b82546001600160a01b031663a9059cbb336120b26064610f9686605a612fdf565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b1580156120f857600080fd5b505af115801561210c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121309190614927565b505b61214e611af76101d1546101d054612fd390919063ffffffff16565b60058401556003830154825461216e9164e8d4a5100091610f9691612fdf565b826002018190555050505050565b6118a03382613611565b6101ca5460005b81811015611cfa5761219e81611cfe565b6121a781614c4d565b905061218d565b6001600160a01b0381166121fa5760405162461bcd60e51b815260206004820152601360248201527261646d696e3a205a65726f206164647265737360681b60448201526064016110d9565b6101c8546001600160a01b031633146122435760405162461bcd60e51b815260206004820152600b60248201526a61646d696e3a207775743f60a81b60448201526064016110d9565b6101c880546001600160a01b0319166001600160a01b0383169081179091556040519081527f54e4612788f90384e6843298d7854436f3a585b2c3831ab66abf1de63bfa6c2d9060200160405180910390a150565b6122a0613003565b80156122ae576122ae612186565b612301826122fb6101ca86815481106122d757634e487b7160e01b600052603260045260246000fd5b9060005260206000209060070201600101546101ce54612fd390919063ffffffff16565b90612ff7565b6101ce81905550816101ca848154811061232b57634e487b7160e01b600052603260045260246000fd5b906000526020600020906007020160010181905550505050565b6001600160a01b03811660009081526101316020526040812054610e439061361b565b612370613003565b61237a6000613684565b565b612384613003565b6101d255565b6001600160a01b038116600090815260fd6020526040812054610e43565b6101cb81815481106123b957600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b6000828210612401576123fa60016123f48486612fd3565b90612fdf565b9050610e43565b6123fa8383612fd3565b600043821061245c5760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e65640060448201526064016110d9565b610e436101328361352e565b6060609b8054610dac90614c18565b6001600160a01b0381166000908152610131602052604081205480156124fb576001600160a01b0383166000908152610131602052604090206124bb600183614bd5565b815481106124d957634e487b7160e01b600052603260045260246000fd5b60009182526020909120015464010000000090046001600160e01b03166124fe565b60005b6001600160e01b03169392505050565b6000338161251c8286612b08565b90508381101561257c5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016110d9565b6125898286868403612eaf565b506001949350505050565b6000806101ca83815481106125b957634e487b7160e01b600052603260045260246000fd5b90600052602060002090600702019050806002015443116125de576000915050610d98565b600061262b6125fc6101d1546101d054612fd390919063ffffffff16565b83546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401610f0d565b949350505050565b600033610e3d8185856130d8565b834211156126915760405162461bcd60e51b815260206004820152601d60248201527f4552433230566f7465733a207369676e6174757265206578706972656400000060448201526064016110d9565b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60208201526001600160a01b03881691810191909152606081018690526080810185905260009061270b906127039060a001604051602081830303815290604052805190602001206136d7565b858585613725565b90506127168161374d565b86146127645760405162461bcd60e51b815260206004820152601960248201527f4552433230566f7465733a20696e76616c6964206e6f6e63650000000000000060448201526064016110d9565b61276e8188613611565b50505050505050565b600054610100900460ff16158080156127975750600054600160ff909116105b806127b15750303b1580156127b1575060005460ff166001145b6128145760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016110d9565b6000805460ff191660011790558015612837576000805461ff0019166101001790555b6001600160a01b03831661288d5760405162461bcd60e51b815260206004820152601860248201527f696e697469616c697a653a205a65726f2061646472657373000000000000000060448201526064016110d9565b612895613775565b6128d7604051806040016040528060048152602001634d61696160e01b815250604051806040016040528060048152602001634d61696160e01b8152506137a4565b6128df6137f2565b612904604051806040016040528060048152602001634d61696160e01b815250613826565b61290c613870565b6101c680546001600160a01b038088166001600160a01b0319928316179092556101c780548784169083161790556101c88054928616929091169190911790556101cf82905560006101d25580156113ce576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b834211156129f45760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e6500000060448201526064016110d9565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888612a238c61374d565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000612a7e826136d7565b90506000612a8e82878787613725565b9050896001600160a01b0316816001600160a01b031614612af15760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e6174757265000060448201526064016110d9565b612afc8a8a8a612eaf565b50505050505050505050565b6001600160a01b03918216600090815260986020908152604080832093909416825291909152205490565b60006101ca8381548110612b5757634e487b7160e01b600052603260045260246000fd5b600091825260208083208684526101cc82526040808520338652909252922060079091029091019150612b8984611cfe565b805415612c6e576000612bbe8260020154610f5d64e8d4a51000610f9687600301548760000154612fdf90919063ffffffff16565b90508015612c4b57825460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b158015612c1157600080fd5b505af1158015612c25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c499190614927565b505b612c67611af76101d1546101d054612fd390919063ffffffff16565b6005840155505b6000612c8a612c836064610f96876004612fdf565b8590612fd3565b83546040516323b872dd60e01b8152336004820152306024820152604481018790529192506001600160a01b0316906323b872dd90606401602060405180830381600087803b158015612cdc57600080fd5b505af1158015612cf0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d149190614927565b506101d054612d239082612ff7565b6101d0558154612d339082612ff7565b8083556003840154612d509164e8d4a5100091610f969190612fdf565b60028301556101d254612d639042614b7e565b6003830155612d723382613897565b604051818152859033907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15906020016113c5565b60408051808201909152600080825260208201526001600160a01b038316600090815261013160205260409020805463ffffffff8416908110612df957634e487b7160e01b600052603260045260246000fd5b60009182526020918290206040805180820190915291015463ffffffff8116825264010000000090046001600160e01b0316918101919091529392505050565b612e41613003565b6001600160a01b038116612ea65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016110d9565b6118a081613684565b6001600160a01b038316612f115760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016110d9565b6001600160a01b038216612f725760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016110d9565b6001600160a01b0383811660008181526098602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600061172a8284614bd5565b600061172a8284614bb6565b600061172a8284614b96565b600061172a8284614b7e565b610162546001600160a01b0316331461237a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016110d9565b600061306a8484612b08565b905060001981146130d257818110156130c55760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016110d9565b6130d28484848403612eaf565b50505050565b6001600160a01b03831661313c5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016110d9565b6001600160a01b03821661319e5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016110d9565b6131a98383836138a1565b6001600160a01b038316600090815260976020526040902054818110156132215760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016110d9565b6001600160a01b03808516600090815260976020526040808220858503905591851681529081208054849290613258908490614b7e565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516132a491815260200190565b60405180910390a36130d2848484613909565b60006117be7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6132e660c95490565b60ca546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b33613346610162546001600160a01b031690565b6001600160a01b0316146118a05760405162461bcd60e51b815260206004820152602560248201527f4f6e6c79206f776e65722063616e207570677261646520696d706c656d656e7460448201526430ba34b7b760d91b60648201526084016110d9565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156133e2576133dd83613914565b613529565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561341b57600080fd5b505afa92505050801561344b575060408051601f3d908101601f1916820190925261344891810190614943565b60015b6134ae5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016110d9565b600080516020614cb8833981519152811461351d5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016110d9565b506135298383836139b0565b505050565b8154600090815b818110156135a057600061354982846139d5565b90508486828154811061356c57634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff16111561358c5780925061359a565b613597816001614b7e565b91505b50613535565b81156135f257846135b2600184614bd5565b815481106135d057634e487b7160e01b600052603260045260246000fd5b60009182526020909120015464010000000090046001600160e01b03166135f5565b60005b6001600160e01b031695945050505050565b611cfa82826139f0565b611cfa8282613a09565b600063ffffffff8211156136805760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b60648201526084016110d9565b5090565b61016280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610e436136e46132b7565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b600080600061373687878787613a84565b9150915061374381613b71565b5095945050505050565b6001600160a01b038116600090815260fd602052604090208054600181018255905b50919050565b600054610100900460ff1661379c5760405162461bcd60e51b81526004016110d990614b33565b61237a613d74565b600054610100900460ff166137cb5760405162461bcd60e51b81526004016110d990614b33565b81516137de90609a9060208501906145bd565b50805161352990609b9060208401906145bd565b600054610100900460ff166138195760405162461bcd60e51b81526004016110d990614b33565b610194805460ff19169055565b600054610100900460ff1661384d5760405162461bcd60e51b81526004016110d990614b33565b6118a081604051806040016040528060018152602001603160f81b815250613da4565b600054610100900460ff1661237a5760405162461bcd60e51b81526004016110d990614b33565b611cfa8282613de5565b6001600160a01b03831615806138be57506001600160a01b038216155b156138c8576133dd565b60405162461bcd60e51b81526020600482015260166024820152752737b7103a3930b739b332b930b13632903a37b5b2b760511b60448201526064016110d9565b613529838383613e70565b6001600160a01b0381163b6139815760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016110d9565b600080516020614cb883398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6139b983613ea3565b6000825111806139c65750805b15613529576130d28383613ee3565b60006139e46002848418614b96565b61172a90848416614b7e565b6139fa8282613fd7565b6130d2610132612fd383614138565b6001600160a01b0382811660008181526101306020818152604080842080546097845282862054949093528787166001600160a01b03198416811790915590519190951694919391928592917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a46130d28284836142e9565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613abb5750600090506003613b68565b8460ff16601b14158015613ad357508460ff16601c14155b15613ae45750600090506004613b68565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613b38573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116613b6157600060019250925050613b68565b9150600090505b94509492505050565b6000816004811115613b9357634e487b7160e01b600052602160045260246000fd5b1415613b9e576118a0565b6001816004811115613bc057634e487b7160e01b600052602160045260246000fd5b1415613c0e5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016110d9565b6002816004811115613c3057634e487b7160e01b600052602160045260246000fd5b1415613c7e5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016110d9565b6003816004811115613ca057634e487b7160e01b600052602160045260246000fd5b1415613cf95760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016110d9565b6004816004811115613d1b57634e487b7160e01b600052602160045260246000fd5b14156118a05760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016110d9565b600054610100900460ff16613d9b5760405162461bcd60e51b81526004016110d990614b33565b61237a33613684565b600054610100900460ff16613dcb5760405162461bcd60e51b81526004016110d990614b33565b81516020928301208151919092012060c99190915560ca55565b613def8282614428565b6099546001600160e01b031015613e615760405162461bcd60e51b815260206004820152603060248201527f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60448201526f766572666c6f77696e6720766f74657360801b60648201526084016110d9565b6130d2610132612ff783614138565b6001600160a01b0383811660009081526101306020526040808220548584168352912054613529929182169116836142e9565b613eac81613914565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b613f4b5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016110d9565b600080846001600160a01b031684604051613f669190614a4c565b600060405180830381855af49150503d8060008114613fa1576040519150601f19603f3d011682016040523d82523d6000602084013e613fa6565b606091505b5091509150613fce8282604051806060016040528060278152602001614cd86027913961451b565b95945050505050565b6001600160a01b0382166140375760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016110d9565b614043826000836138a1565b6001600160a01b038216600090815260976020526040902054818110156140b75760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016110d9565b6001600160a01b03831660009081526097602052604081208383039055609980548492906140e6908490614bd5565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a361352983600084613909565b8254600090819080156141915785614151600183614bd5565b8154811061416f57634e487b7160e01b600052603260045260246000fd5b60009182526020909120015464010000000090046001600160e01b0316614194565b60005b6001600160e01b031692506141ad83858763ffffffff16565b91506000811180156141f9575043866141c7600184614bd5565b815481106141e557634e487b7160e01b600052603260045260246000fd5b60009182526020909120015463ffffffff16145b156142675761420782614554565b86614213600184614bd5565b8154811061423157634e487b7160e01b600052603260045260246000fd5b9060005260206000200160000160046101000a8154816001600160e01b0302191690836001600160e01b031602179055506142e0565b85604051806040016040528061427c4361361b565b63ffffffff16815260200161429085614554565b6001600160e01b039081169091528254600181018455600093845260209384902083519101805493909401519091166401000000000263ffffffff91821663ffffffff1990931692909217161790555b50935093915050565b816001600160a01b0316836001600160a01b03161415801561430b5750600081115b15613529576001600160a01b0383161561439a576001600160a01b038316600090815261013160205260408120819061434790612fd385614138565b91509150846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724838360405161438f929190918252602082015260400190565b60405180910390a250505b6001600160a01b03821615613529576001600160a01b03821660009081526101316020526040812081906143d190612ff785614138565b91509150836001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051614419929190918252602082015260400190565b60405180910390a25050505050565b6001600160a01b03821661447e5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016110d9565b61448a600083836138a1565b806099600082825461449c9190614b7e565b90915550506001600160a01b038216600090815260976020526040812080548392906144c9908490614b7e565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3611cfa60008383613909565b6060831561452a57508161172a565b82511561453a5782518084602001fd5b8160405162461bcd60e51b81526004016110d99190614a68565b60006001600160e01b038211156136805760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b60648201526084016110d9565b8280546145c990614c18565b90600052602060002090601f0160209004810192826145eb5760008555614631565b82601f1061460457805160ff1916838001178555614631565b82800160010185558215614631579182015b82811115614631578251825591602001919060010190614616565b506136809291505b808211156136805760008155600101614639565b803560ff81168114610d9857600080fd5b60006020828403121561466f578081fd5b813561172a81614c94565b6000806040838503121561468c578081fd5b823561469781614c94565b915060208301356146a781614c94565b809150509250929050565b600080600080608085870312156146c7578182fd5b84356146d281614c94565b935060208501356146e281614c94565b925060408501356146f281614c94565b9396929550929360600135925050565b600080600060608486031215614716578283fd5b833561472181614c94565b9250602084013561473181614c94565b929592945050506040919091013590565b600080600080600080600060e0888a03121561475c578283fd5b873561476781614c94565b9650602088013561477781614c94565b955060408801359450606088013593506147936080890161464d565b925060a0880135915060c0880135905092959891949750929550565b600080604083850312156147c1578182fd5b82356147cc81614c94565b9150602083013567ffffffffffffffff808211156147e8578283fd5b818501915085601f8301126147fb578283fd5b81358181111561480d5761480d614c7e565b604051601f8201601f19908116603f0116810190838211818310171561483557614835614c7e565b8160405282815288602084870101111561484d578586fd5b82602086016020830137856020848301015280955050505050509250929050565b60008060408385031215614880578182fd5b823561488b81614c94565b946020939093013593505050565b60008060008060008060c087890312156148b1578182fd5b86356148bc81614c94565b955060208701359450604087013593506148d86060880161464d565b92506080870135915060a087013590509295509295509295565b60008060408385031215614904578182fd5b823561490f81614c94565b9150602083013563ffffffff811681146146a7578182fd5b600060208284031215614938578081fd5b815161172a81614ca9565b600060208284031215614954578081fd5b5051919050565b60006020828403121561496c578081fd5b5035919050565b60008060408385031215614985578182fd5b8235915060208301356146a781614c94565b6000806000606084860312156149ab578081fd5b83359250602084013561473181614c94565b6000806000606084860312156149d1578081fd5b8335925060208401356149e381614c94565b915060408401356149f381614ca9565b809150509250925092565b60008060408385031215614a10578182fd5b50508035926020909101359150565b600080600060608486031215614a33578081fd5b833592506020840135915060408401356149f381614ca9565b60008251614a5e818460208701614bec565b9190910192915050565b6000602082528251806020840152614a87816040850160208701614bec565b601f01601f19169190910160400192915050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60008219821115614b9157614b91614c68565b500190565b600082614bb157634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615614bd057614bd0614c68565b500290565b600082821015614be757614be7614c68565b500390565b60005b83811015614c07578181015183820152602001614bef565b838111156130d25750506000910152565b600281046001821680614c2c57607f821691505b6020821081141561376f57634e487b7160e01b600052602260045260246000fd5b6000600019821415614c6157614c61614c68565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146118a057600080fd5b80151581146118a057600080fdfe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212204818f7eefa1f3d5f2d1805bfcffa1a9b932dd98859e15958dee130ec9f26e0ed64736f6c63430008020033

Deployed Bytecode Sourcemap

153204:14696:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;156004:30;;;;;;;;;;;;;;;;;;;9755:25:1;;;9743:2;9728:18;156004:30:0;;;;;;;;156154:28;;;;;;;;;;;;;;;;164336:112;;;;;;;;;;-1:-1:-1;164336:112:0;;;;;:::i;:::-;;:::i;:::-;;;;;;29986:13:1;;-1:-1:-1;;;;;29982:39:1;29964:58;;30078:4;30066:17;;;30060:24;30038:20;;;30031:54;30141:4;30129:17;;;30123:24;30101:20;;;30094:54;30204:4;30192:17;;;30186:24;30164:20;;;30157:54;30267:4;30255:17;;;30249:24;30227:20;;;30220:54;30009:3;30318:17;;;30312:24;30290:20;;;30283:54;30393:4;30381:17;;;30375:24;30353:20;;;30346:54;;;;29951:3;29936:19;;29918:488;115518:100:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;157245:95::-;;;;;;;;;;-1:-1:-1;157317:8:0;:15;157245:95;;117869:201;;;;;;;;;;-1:-1:-1;117869:201:0;;;;;:::i;:::-;;:::i;:::-;;;9582:14:1;;9575:22;9557:41;;9545:2;9530:18;117869:201:0;9512:92:1;159194:930:0;;;;;;;;;;-1:-1:-1;159194:930:0;;;;;:::i;:::-;;:::i;165489:836::-;;;;;;;;;;-1:-1:-1;165489:836:0;;;;;:::i;:::-;;:::i;:::-;;163214:118;;;;;;;;;;-1:-1:-1;163214:118:0;;;;;:::i;:::-;;:::i;:::-;;;;31068:13:1;;31050:32;;31138:4;31126:17;;;31120:24;31098:20;;;31091:54;31189:17;;;31183:24;31161:20;;;31154:54;31038:2;31023:18;163214:118:0;31005:209:1;155479:26:0;;;;;;;;;;-1:-1:-1;155479:26:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;12273:32:1;;;12255:51;;12337:2;12322:18;;12315:34;;;;12365:18;;;12358:34;;;;12423:2;12408:18;;12401:34;;;;12466:3;12451:19;;12444:35;12293:3;12495:19;;12488:35;12554:3;12539:19;;12532:35;12242:3;12227:19;155479:26:0;12209:364:1;155852:30:0;;;;;;;;;;;;;;;;116638:108;;;;;;;;;;-1:-1:-1;116726:12:0;;116638:108;;157509:786;;;;;;;;;;-1:-1:-1;157509:786:0;;;;;:::i;:::-;;:::i;118650:295::-;;;;;;;;;;-1:-1:-1;118650:295:0;;;;;:::i;:::-;;:::i;164456:134::-;;;;;;;;;;-1:-1:-1;164456:134:0;;;;;:::i;:::-;;:::i;:::-;;;;;;30628:13:1;;30610:32;;30698:4;30686:17;;;30680:24;30658:20;;;30651:54;30761:4;30749:17;;;30743:24;30721:20;;;30714:54;30824:4;30812:17;;;30806:24;30784:20;;;30777:54;;;;30597:3;30582:19;;30564:273;157162:75:0;;;;;;;;;;-1:-1:-1;157162:75:0;;157231:1;12730:36:1;;12718:2;12703:18;157162:75:0;12685:87:1;129745:115:0;;;;;;;;;;;;;:::i;151651:200::-;;;;;;;;;;-1:-1:-1;151651:200:0;;;;;:::i;:::-;;:::i;119354:238::-;;;;;;;;;;-1:-1:-1;119354:238:0;;;;;:::i;:::-;;:::i;133490:268::-;;;;;;;;;;-1:-1:-1;133490:268:0;;;;;:::i;:::-;;:::i;155167:18::-;;;;;;;;;;-1:-1:-1;155167:18:0;;;;-1:-1:-1;;;;;155167:18:0;;;;;;-1:-1:-1;;;;;8714:32:1;;;8696:51;;8684:2;8669:18;155167::0;8651:102:1;163340:988:0;;;;;;;;;;-1:-1:-1;163340:988:0;;;;;:::i;:::-;;:::i;155192:19::-;;;;;;;;;;-1:-1:-1;155192:19:0;;;;-1:-1:-1;;;;;155192:19:0;;;155946:25;;;;;;;;;;;;;;;;152110:225;;;;;;:::i;:::-;;:::i;160847:1173::-;;;;;;;;;;-1:-1:-1;160847:1173:0;;;;;:::i;:::-;;:::i;151329:133::-;;;;;;;;;;;;;:::i;132864:128::-;;;;;;;;;;-1:-1:-1;132864:128:0;;;;;:::i;:::-;-1:-1:-1;;;;;132965:19:0;;;132938:7;132965:19;;;:10;:19;;;;;;;;132864:128;164642:789;;;;;;;;;;-1:-1:-1;164642:789:0;;;;;:::i;:::-;;:::i;135974:114::-;;;;;;;;;;-1:-1:-1;135974:114:0;;;;;:::i;:::-;;:::i;108592:86::-;;;;;;;;;;-1:-1:-1;108663:7:0;;;;108592:86;;160207:180;;;;;;;;;;;;;:::i;166383:266::-;;;;;;;;;;-1:-1:-1;166383:266:0;;;;;:::i;:::-;;:::i;158501:304::-;;;;;;;;;;-1:-1:-1;158501:304:0;;;;;:::i;:::-;;:::i;155413:30::-;;;;;;;;;;;;;;;;132609:162;;;;;;;;;;-1:-1:-1;132609:162:0;;;;;:::i;:::-;;:::i;:::-;;;32548:10:1;32536:23;;;32518:42;;32506:2;32491:18;132609:162:0;32473:93:1;116809:127:0;;;;;;;;;;-1:-1:-1;116809:127:0;;;;;:::i;:::-;-1:-1:-1;;;;;116910:18:0;116883:7;116910:18;;;:9;:18;;;;;;;116809:127;111970:103;;;;;;;;;;;;;:::i;158303:102::-;;;;;;;;;;-1:-1:-1;158303:102:0;;;;;:::i;:::-;;:::i;129487:128::-;;;;;;;;;;-1:-1:-1;129487:128:0;;;;;:::i;:::-;;:::i;155512:36::-;;;;;;;;;;-1:-1:-1;155512:36:0;;;;;:::i;:::-;;:::i;:::-;;;;31856:25:1;;;31912:2;31897:18;;31890:34;;;;31940:18;;;31933:34;31844:2;31829:18;155512:36:0;31811:162:1;155322:44:0;;;;;;;;;;;;155365:1;155322:44;;111322:87;;;;;;;;;;-1:-1:-1;111395:6:0;;-1:-1:-1;;;;;111395:6:0;111322:87;;158885:241;;;;;;;;;;-1:-1:-1;158885:241:0;;;;;:::i;:::-;;:::i;134047:259::-;;;;;;;;;;-1:-1:-1;134047:259:0;;;;;:::i;:::-;;:::i;155604:66::-;;;;;;;;;;-1:-1:-1;155604:66:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32209:25:1;;;32265:2;32250:18;;32243:34;;;;32293:18;;;32286:34;32351:2;32336:18;;32329:34;32196:3;32181:19;155604:66:0;32163:206:1;115737:104:0;;;;;;;;;;;;;:::i;133076:212::-;;;;;;;;;;-1:-1:-1;133076:212:0;;;;;:::i;:::-;;:::i;120095:436::-;;;;;;;;;;-1:-1:-1;120095:436:0;;;;;:::i;:::-;;:::i;160395:376::-;;;;;;;;;;-1:-1:-1;160395:376:0;;;;;:::i;:::-;;:::i;117142:193::-;;;;;;;;;;-1:-1:-1;117142:193:0;;;;;:::i;:::-;;:::i;136170:602::-;;;;;;;;;;-1:-1:-1;136170:602:0;;;;;:::i;:::-;;:::i;156484:673::-;;;;;;;;;;-1:-1:-1;156484:673:0;;;;;:::i;:::-;;:::i;155677:76::-;;;;;;;;;;-1:-1:-1;155677:76:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;128765:656;;;;;;;;;;-1:-1:-1;128765:656:0;;;;;:::i;:::-;;:::i;117398:151::-;;;;;;;;;;-1:-1:-1;117398:151:0;;;;;:::i;:::-;;:::i;162071:1135::-;;;;;;;;;;-1:-1:-1;162071:1135:0;;;;;:::i;:::-;;:::i;132379:150::-;;;;;;;;;;-1:-1:-1;132379:150:0;;;;;:::i;:::-;;:::i;:::-;;;;29638:13:1;;29653:10;29634:30;29616:49;;29725:4;29713:17;;;29707:24;-1:-1:-1;;;;;29703:50:1;29681:20;;;29674:80;;;;29589:18;132379:150:0;29571:189:1;112228:201:0;;;;;;;;;;-1:-1:-1;112228:201:0;;;;;:::i;:::-;;:::i;156083:39::-;;;;;;;;;;;;;;;;155241:27;;;;;;;;;;-1:-1:-1;155241:27:0;;;;-1:-1:-1;;;;;155241:27:0;;;164336:112;164390:15;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;164390:15:0;164425:8;164434:4;164425:14;;;;;;-1:-1:-1;;;164425:14:0;;;;;;;;;;;;;;;;;;164418:21;;;;;;;;164425:14;;;;;;;164418:21;;-1:-1:-1;;;;;164418:21:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;164336:112:0;;;;:::o;115518:100::-;115572:13;115605:5;115598:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;115518:100;:::o;117869:201::-;117952:4;106269:10;118008:32;106269:10;118024:7;118033:6;118008:8;:32::i;:::-;118058:4;118051:11;;;117869:201;;;;;:::o;159194:930::-;159267:7;159287:21;159311:8;159320:4;159311:14;;;;;;-1:-1:-1;;;159311:14:0;;;;;;;;;;;;;;;;;159360;;;:8;:14;;;;;;-1:-1:-1;;;;;159360:21:0;;;;;;;;;159420:20;159311:14;;;;;;;159420:20;;;;159470:15;;159515:20;;;;159311:14;;-1:-1:-1;159420:20:0;;159500:12;:35;:52;;;;-1:-1:-1;159539:13:0;;;159500:52;159496:370;;;159569:21;159593:88;159635:45;159655:24;;159635:15;;:19;;:45;;;;:::i;:::-;159593:12;;:37;;-1:-1:-1;;;159593:37:0;;159624:4;159593:37;;;8696:51:1;-1:-1:-1;;;;;159593:12:0;;;;:22;;8669:18:1;;159593:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;:88::i;:::-;159569:112;;159696:20;159719:45;159737:4;:26;;;159719:13;:17;;:45;;;;:::i;:::-;159696:68;-1:-1:-1;159797:57:0;159817:36;159844:8;159817:22;159696:68;159834:4;159817:16;:22::i;:::-;:26;;:36::i;:::-;159797:15;;:19;:57::i;:::-;159779:75;;159496:370;;;159876:14;159893:66;159940:4;:18;;;159893:42;159930:4;159893:32;159909:15;159893:4;:11;;;:15;;:32;;;;:::i;:66::-;159976:5;;:22;;-1:-1:-1;;;159976:22:0;;-1:-1:-1;;;;;8714:32:1;;;159976:22:0;;;8696:51:1;159876:83:0;;-1:-1:-1;159976:5:0;;;:15;;8669:18:1;;159976:22:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;160002:1;159976:27;159972:145;;;160027:6;-1:-1:-1;160020:13:0;;-1:-1:-1;;;;160020:13:0;159972:145;160082:23;160101:3;160082:14;:6;160093:2;160082:10;:14::i;:23::-;160075:30;;;;;;;;;165489:836;165599:12;;-1:-1:-1;;;;;165599:12:0;165585:10;:26;165577:67;;;;-1:-1:-1;;;165577:67:0;;22235:2:1;165577:67:0;;;22217:21:1;22274:2;22254:18;;;22247:30;22313;22293:18;;;22286:58;22361:18;;165577:67:0;;;;;;;;;165712:7;165663:45;165683:24;;165663:15;;:19;;:45;;;;:::i;:::-;:56;;165655:112;;;;-1:-1:-1;;;165655:112:0;;14126:2:1;165655:112:0;;;14108:21:1;14165:2;14145:18;;;14138:30;14204:34;14184:18;;;14177:62;-1:-1:-1;;;14255:18:1;;;14248:41;14306:19;;165655:112:0;14098:233:1;165655:112:0;165778:21;165802:8;165811:4;165802:14;;;;;;-1:-1:-1;;;165802:14:0;;;;;;;;;;;;;;;;;;;;;;165845:12;;:37;;-1:-1:-1;;;165845:37:0;;165876:4;165845:37;;;8696:51:1;165802:14:0;;-1:-1:-1;;;;;;165845:12:0;;:22;;8669:18:1;;165845:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;165827:55;;165907:7;165897;:17;165893:425;;;165931:12;;:35;;-1:-1:-1;;;165931:35:0;;-1:-1:-1;;;;;9330:32:1;;;165931:35:0;;;9312:51:1;9379:18;;;9372:34;;;165931:12:0;;;;:21;;9285:18:1;;165931:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;166008:24:0;;:37;;166037:7;166008:28;:37::i;:::-;165981:24;:64;166065:37;;9755:25:1;;;166088:4:0;;-1:-1:-1;;;;;166065:37:0;;;;;9743:2:1;9728:18;166065:37:0;;;;;;;165893:425;;;166135:12;;:35;;-1:-1:-1;;;166135:35:0;;-1:-1:-1;;;;;9330:32:1;;;166135:35:0;;;9312:51:1;9379:18;;;9372:34;;;166135:12:0;;;;:21;;9285:18:1;;166135:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;166212:24:0;;:37;;166241:7;166212:28;:37::i;:::-;166185:24;:64;166269:37;;9755:25:1;;;166292:4:0;;-1:-1:-1;;;;;166269:37:0;;;;;9743:2:1;9728:18;166269:37:0;;;;;;;;165893:425;165489:836;;;;;:::o;163214:118::-;163265:20;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;163265:20:0;163305:13;163319:4;163305:19;;;;;;-1:-1:-1;;;163305:19:0;;;;;;;;;;;;;;;;;;;163298:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;163214:118;;;:::o;155479:26::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;155479:26:0;;;;-1:-1:-1;155479:26:0;;;;;;;;;:::o;157509:786::-;111208:13;:11;:13::i;:::-;157610:11:::1;157606:61;;;157638:17;:15;:17::i;:::-;157677:23;157718:10;;157703:12;:25;:53;;157746:10;;157703:53;;;157731:12;157703:53;157785:15;::::0;157677:79;;-1:-1:-1;157785:32:0::1;::::0;157805:11;157785:19:::1;:32::i;:::-;157767:15;:50:::0;157842:280:::1;::::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;;;;;157842:280:0;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;;;-1:-1:-1;157842:280:0;;;;;;;;;;;;;;;;;;;;;;;;;157828:8:::1;:295:::0;;::::1;::::0;;::::1;::::0;;;;;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;-1:-1:-1;;;;;;157828:295:0::1;::::0;;;::::1;;::::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;158154:130;;;;::::1;::::0;;;;;;::::1;::::0;;;;;;;;;158135:13:::1;:150:::0;;;;::::1;::::0;;;;;;;;157828:295:::1;158135:150:::0;;::::1;::::0;;::::1;::::0;;;;;;-1:-1:-1;158135:150:0;;;;;;;157509:786::o;118650:295::-;118781:4;106269:10;118839:38;118855:4;106269:10;118870:6;118839:15;:38::i;:::-;118888:27;118898:4;118904:2;118908:6;118888:9;:27::i;:::-;118933:4;118926:11;;;118650:295;;;;;;:::o;164456:134::-;164525:15;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;164525:15:0;-1:-1:-1;164560:14:0;;;;:8;:14;;;;;;;;-1:-1:-1;;;;;164560:21:0;;;;;;;;;;;;;164553:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;164456:134::o;129745:115::-;129805:7;129832:20;:18;:20::i;:::-;129825:27;;129745:115;:::o;151651:200::-;150192:4;-1:-1:-1;;;;;150201:6:0;150184:23;;;150176:80;;;;-1:-1:-1;;;150176:80:0;;;;;;;:::i;:::-;150299:6;-1:-1:-1;;;;;150275:30:0;:20;-1:-1:-1;;;;;;;;;;;141988:65:0;-1:-1:-1;;;;;141988:65:0;;141908:153;150275:20;-1:-1:-1;;;;;150275:30:0;;150267:87;;;;-1:-1:-1;;;150267:87:0;;;;;;;:::i;:::-;151735:36:::1;151753:17;151735;:36::i;:::-;151823:12;::::0;;151833:1:::1;151823:12:::0;;;::::1;::::0;::::1;::::0;;;151782:61:::1;::::0;151804:17;;151823:12;151782:21:::1;:61::i;:::-;151651:200:::0;:::o;119354:238::-;119442:4;106269:10;119498:64;106269:10;119514:7;119551:10;119523:25;106269:10;119514:7;119523:9;:25::i;:::-;:38;;;;:::i;:::-;119498:8;:64::i;133490:268::-;133588:7;133630:12;133616:11;:26;133608:70;;;;-1:-1:-1;;;133608:70:0;;14942:2:1;133608:70:0;;;14924:21:1;14981:2;14961:18;;;14954:30;15020:33;15000:18;;;14993:61;15071:18;;133608:70:0;14914:181:1;133608:70:0;-1:-1:-1;;;;;133715:21:0;;;;;;:12;:21;;;;;133696:54;;133738:11;133696:18;:54::i;163340:988::-;163407:21;163431:8;163440:4;163431:14;;;;;;-1:-1:-1;;;163431:14:0;;;;;;;;;;;;;;;;;163480;;;:8;:14;;;;;;163495:10;163480:26;;;;;;;163546:13;;;;163431:14;;;;;;;;-1:-1:-1;163527:15:0;:32;;163519:63;;;;-1:-1:-1;;;163519:63:0;;18286:2:1;163519:63:0;;;18268:21:1;18325:2;18305:18;;;18298:30;-1:-1:-1;;;18344:18:1;;;18337:48;18402:18;;163519:63:0;18258:168:1;163519:63:0;163601:11;;:22;-1:-1:-1;163601:22:0;163593:55;;;;-1:-1:-1;;;163593:55:0;;28907:2:1;163593:55:0;;;28889:21:1;28946:2;28926:18;;;28919:30;-1:-1:-1;;;28965:18:1;;;28958:50;29025:18;;163593:55:0;28879:170:1;163593:55:0;163659:16;163670:4;163659:10;:16::i;:::-;163688:18;163709:71;163761:4;:18;;;163709:47;163751:4;163709:37;163725:4;:20;;;163709:4;:11;;;:15;;:37;;;;:::i;:71::-;163688:92;-1:-1:-1;163795:14:0;;163791:65;;163811:12;;:45;;-1:-1:-1;;;163811:45:0;;163833:10;163811:45;;;9312:51:1;9379:18;;;9372:34;;;-1:-1:-1;;;;;163811:12:0;;;;:21;;9285:18:1;;163811:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;163791:65;163896:88;163938:45;163958:24;;163938:15;;:19;;:45;;;;:::i;:::-;163896:12;;:37;;-1:-1:-1;;;163896:37:0;;163927:4;163896:37;;;8696:51:1;-1:-1:-1;;;;;163896:12:0;;;;:22;;8669:18:1;;163896:37:0;8651:102:1;163896:88:0;163867:26;;;:117;164011:11;;:24;;164027:7;164011:15;:24::i;:::-;163997:38;;164064:15;;:28;;164084:7;164064:19;:28::i;:::-;164046:15;:46;164140:20;;;;164124:11;;:47;;164166:4;;164124:37;;:15;:37::i;:47::-;164103:18;;;:68;164182:12;;:51;;-1:-1:-1;;;164182:51:0;;164212:10;164182:51;;;9312::1;9379:18;;;9372:34;;;-1:-1:-1;;;;;164182:12:0;;;;:21;;9285:18:1;;164182:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;164244:25;164250:10;164261:7;164244:5;:25::i;:::-;164285:35;;9755:25:1;;;164306:4:0;;164294:10;;164285:35;;9743:2:1;9728:18;164285:35:0;9710:76:1;152110:225:0;150192:4;-1:-1:-1;;;;;150201:6:0;150184:23;;;150176:80;;;;-1:-1:-1;;;150176:80:0;;;;;;;:::i;:::-;150299:6;-1:-1:-1;;;;;150275:30:0;:20;-1:-1:-1;;;;;;;;;;;141988:65:0;-1:-1:-1;;;;;141988:65:0;;141908:153;150275:20;-1:-1:-1;;;;;150275:30:0;;150267:87;;;;-1:-1:-1;;;150267:87:0;;;;;;;:::i;:::-;152228:36:::1;152246:17;152228;:36::i;:::-;152275:52;152297:17;152316:4;152322;152275:21;:52::i;:::-;152110:225:::0;;:::o;160847:1173::-;160899:21;160923:8;160932:4;160923:14;;;;;;-1:-1:-1;;;160923:14:0;;;;;;;;;;;;;;;;;160972;;;:8;:14;;;;;;160987:10;160972:26;;;;;;;161041:20;160923:14;;;;;;;161041:20;;;;160923:14;;-1:-1:-1;161025:12:0;:36;161021:75;;161078:7;;;;161021:75;161106:21;161130:88;161172:45;161192:24;;161172:15;;:19;;:45;;;;:::i;161130:88::-;161106:112;;161229:20;161252:71;161277:45;161295:4;:26;;;161277:13;:17;;:45;;;;:::i;:::-;161252:20;;;;;:24;:71::i;:::-;161334:26;;;:42;;;161387:20;;;:35;;;161462:15;;161229:94;;-1:-1:-1;161492:13:0;161488:305;;-1:-1:-1;;161545:12:0;161522:20;;;;:35;;;;161595:1;161572:20;;;:24;;;161611;;;:28;;;161654:18;;:22;;;-1:-1:-1;161691:26:0;;;:30;;;161736:20;;;;:24;161775:7;;161488:305;161813:14;161830:42;161847:4;:24;;;161830:12;:16;;:42;;;;:::i;:::-;161813:59;-1:-1:-1;161906:56:0;161931:30;161952:8;161931:16;161813:59;161942:4;161931:10;:16::i;:30::-;161906:20;;;;;:24;:56::i;:::-;161883:20;;;:79;-1:-1:-1;;161973:24:0;;;;:39;;;;-1:-1:-1;;160847:1173:0;:::o;151329:133::-;151407:7;150637:4;-1:-1:-1;;;;;150646:6:0;150629:23;;150621:92;;;;-1:-1:-1;;;150621:92:0;;20985:2:1;150621:92:0;;;20967:21:1;21024:2;21004:18;;;20997:30;21063:34;21043:18;;;21036:62;21134:26;21114:18;;;21107:54;21178:19;;150621:92:0;20957:246:1;150621:92:0;-1:-1:-1;;;;;;;;;;;;151329:133:0;:::o;164642:789::-;164693:21;164717:8;164726:4;164717:14;;;;;;-1:-1:-1;;;164717:14:0;;;;;;;;;;;;;;;;;164766;;;:8;:14;;;;;;164781:10;164766:26;;;;;;;164717:14;;;;;;;;-1:-1:-1;164805:16:0;164775:4;164805:10;:16::i;:::-;164842:18;164863:71;164915:4;:18;;;164863:47;164905:4;164863:37;164879:4;:20;;;164863:4;:11;;;:15;;:37;;;;:::i;:71::-;164842:92;-1:-1:-1;164949:14:0;;164945:267;;164984:5;;:27;;-1:-1:-1;;;164984:27:0;;165000:10;164984:27;;;8696:51:1;-1:-1:-1;;;;;164984:5:0;;;;:15;;8669:18:1;;164984:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;165015:1;164984:32;164980:221;;;165037:12;;:45;;-1:-1:-1;;;165037:45:0;;165059:10;165037:45;;;9312:51:1;9379:18;;;9372:34;;;-1:-1:-1;;;;;165037:12:0;;;;:21;;9285:18:1;;165037:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;164980:221;;;165123:12;;-1:-1:-1;;;;;165123:12:0;:21;165145:10;165157:27;165180:3;165157:18;:10;165172:2;165157:14;:18::i;:27::-;165123:62;;-1:-1:-1;;;;;;165123:62:0;;;;;;;-1:-1:-1;;;;;9330:32:1;;;165123:62:0;;;9312:51:1;9379:18;;;9372:34;9285:18;;165123:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;164980:221;165251:88;165293:45;165313:24;;165293:15;;:19;;:45;;;;:::i;165251:88::-;165222:26;;;:117;165389:20;;;;165373:11;;:47;;165415:4;;165373:37;;:15;:37::i;:47::-;165352:4;:18;;:68;;;;164642:789;;;;:::o;135974:114::-;136046:34;106269:10;136070:9;136046;:34::i;160207:180::-;160269:8;:15;160252:14;160295:85;160323:6;160317:3;:12;160295:85;;;160353:15;160364:3;160353:10;:15::i;:::-;160331:5;;;:::i;:::-;;;160295:85;;166383:266;-1:-1:-1;;;;;166447:27:0;;166439:59;;;;-1:-1:-1;;;166439:59:0;;17938:2:1;166439:59:0;;;17920:21:1;17977:2;17957:18;;;17950:30;-1:-1:-1;;;17996:18:1;;;17989:49;18055:18;;166439:59:0;17910:169:1;166439:59:0;166531:12;;-1:-1:-1;;;;;166531:12:0;166517:10;:26;166509:50;;;;-1:-1:-1;;;166509:50:0;;25722:2:1;166509:50:0;;;25704:21:1;25761:2;25741:18;;;25734:30;-1:-1:-1;;;25780:18:1;;;25773:41;25831:18;;166509:50:0;25694:161:1;166509:50:0;166570:12;:28;;-1:-1:-1;;;;;;166570:28:0;-1:-1:-1;;;;;166570:28:0;;;;;;;;166614:27;;8696:51:1;;;166614:27:0;;8684:2:1;8669:18;166614:27:0;;;;;;;166383:266;:::o;158501:304::-;111208:13;:11;:13::i;:::-;158599:11:::1;158595:61;;;158627:17;:15;:17::i;:::-;158684:63;158735:11;158684:46;158704:8;158713:4;158704:14;;;;;;-1:-1:-1::0;;;158704:14:0::1;;;;;;;;;;;;;;;;;;;:25;;;158684:15;;:19;;:46;;;;:::i;:::-;:50:::0;::::1;:63::i;:::-;158666:15;:81;;;;158786:11;158758:8;158767:4;158758:14;;;;;;-1:-1:-1::0;;;158758:14:0::1;;;;;;;;;;;;;;;;;;;:25;;:39;;;;158501:304:::0;;;:::o;132609:162::-;-1:-1:-1;;;;;132734:21:0;;132679:6;132734:21;;;:12;:21;;;;;:28;132705:58;;:28;:58::i;111970:103::-;111208:13;:11;:13::i;:::-;112035:30:::1;112062:1;112035:18;:30::i;:::-;111970:103::o:0;158303:102::-;111208:13;:11;:13::i;:::-;158375::::1;:22:::0;158303:102::o;129487:128::-;-1:-1:-1;;;;;129583:14:0;;129556:7;129583:14;;;:7;:14;;;;;58988;129583:24;58896:114;155512:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;155512:36:0;:::o;158885:241::-;158957:7;158988:5;158981:3;:12;158977:142;;159017:36;155365:1;159017:14;:3;159025:5;159017:7;:14::i;:::-;:18;;:36::i;:::-;159010:43;;;;158977:142;159093:14;:5;159103:3;159093:9;:14::i;134047:259::-;134134:7;134176:12;134162:11;:26;134154:70;;;;-1:-1:-1;;;134154:70:0;;14942:2:1;134154:70:0;;;14924:21:1;14981:2;14961:18;;;14954:30;15020:33;15000:18;;;14993:61;15071:18;;134154:70:0;14914:181:1;134154:70:0;134242:56;134261:23;134286:11;134242:18;:56::i;115737:104::-;115793:13;115826:7;115819:14;;;;;:::i;133076:212::-;-1:-1:-1;;;;;133183:21:0;;133149:7;133183:21;;;:12;:21;;;;;:28;133229:8;;:51;;-1:-1:-1;;;;;133244:21:0;;;;;;:12;:21;;;;;133266:7;133272:1;133266:3;:7;:::i;:::-;133244:30;;;;;;-1:-1:-1;;;133244:30:0;;;;;;;;;;;;;;;;;;:36;;;;-1:-1:-1;;;;;133244:36:0;133229:51;;;133240:1;133229:51;-1:-1:-1;;;;;133222:58:0;;133076:212;-1:-1:-1;;;133076:212:0:o;120095:436::-;120188:4;106269:10;120188:4;120271:25;106269:10;120288:7;120271:9;:25::i;:::-;120244:52;;120335:15;120315:16;:35;;120307:85;;;;-1:-1:-1;;;120307:85:0;;28501:2:1;120307:85:0;;;28483:21:1;28540:2;28520:18;;;28513:30;28579:34;28559:18;;;28552:62;-1:-1:-1;;;28630:18:1;;;28623:35;28675:19;;120307:85:0;28473:227:1;120307:85:0;120428:60;120437:5;120444:7;120472:15;120453:16;:34;120428:8;:60::i;:::-;-1:-1:-1;120519:4:0;;120095:436;-1:-1:-1;;;;120095:436:0:o;160395:376::-;160455:4;160472:21;160496:8;160505:4;160496:14;;;;;;-1:-1:-1;;;160496:14:0;;;;;;;;;;;;;;;;;;;160472:38;;160551:4;:20;;;160535:12;:36;160531:77;;160595:1;160588:8;;;;;160531:77;160618:21;160642:88;160684:45;160704:24;;160684:15;;:19;;:45;;;;:::i;:::-;160642:12;;:37;;-1:-1:-1;;;160642:37:0;;160673:4;160642:37;;;8696:51:1;-1:-1:-1;;;;;160642:12:0;;;;:22;;8669:18:1;;160642:37:0;8651:102:1;160642:88:0;160618:112;160395:376;-1:-1:-1;;;;160395:376:0:o;117142:193::-;117221:4;106269:10;117277:28;106269:10;117294:2;117298:6;117277:9;:28::i;136170:602::-;136397:6;136378:15;:25;;136370:67;;;;-1:-1:-1;;;136370:67:0;;15653:2:1;136370:67:0;;;15635:21:1;15692:2;15672:18;;;15665:30;15731:31;15711:18;;;15704:59;15780:18;;136370:67:0;15625:179:1;136370:67:0;136531:58;;;132059:71;136531:58;;;10618:25:1;-1:-1:-1;;;;;10679:32:1;;10659:18;;;10652:60;;;;10728:18;;;10721:34;;;10771:18;;;10764:34;;;136448:14:0;;136465:185;;136504:87;;10590:19:1;;136531:58:0;;;;;;;;;;;;136521:69;;;;;;136504:16;:87::i;:::-;136606:1;136622;136638;136465:24;:185::i;:::-;136448:202;;136678:17;136688:6;136678:9;:17::i;:::-;136669:5;:26;136661:64;;;;-1:-1:-1;;;136661:64:0;;16774:2:1;136661:64:0;;;16756:21:1;16813:2;16793:18;;;16786:30;16852:27;16832:18;;;16825:55;16897:18;;136661:64:0;16746:175:1;136661:64:0;136736:28;136746:6;136754:9;136736;:28::i;:::-;136170:602;;;;;;;:::o;156484:673::-;97537:19;97560:13;;;;;;97559:14;;97607:34;;;;-1:-1:-1;97625:12:0;;97640:1;97625:12;;;;:16;97607:34;97606:108;;;-1:-1:-1;97686:4:0;83673:19;:23;;;97647:66;;-1:-1:-1;97696:12:0;;;;;:17;97647:66;97584:204;;;;-1:-1:-1;;;97584:204:0;;21820:2:1;97584:204:0;;;21802:21:1;21859:2;21839:18;;;21832:30;21898:34;21878:18;;;21871:62;-1:-1:-1;;;21949:18:1;;;21942:44;22003:19;;97584:204:0;21792:236:1;97584:204:0;97799:12;:16;;-1:-1:-1;;97799:16:0;97814:1;97799:16;;;97826:67;;;;97861:13;:20;;-1:-1:-1;;97861:20:0;;;;;97826:67;-1:-1:-1;;;;;156672:27:0;::::1;156664:64;;;::::0;-1:-1:-1;;;156664:64:0;;22995:2:1;156664:64:0::1;::::0;::::1;22977:21:1::0;23034:2;23014:18;;;23007:30;23073:26;23053:18;;;23046:54;23117:18;;156664:64:0::1;22967:174:1::0;156664:64:0::1;156739:35;:33;:35::i;:::-;156785:38;;;;;;;;;;;;;;-1:-1:-1::0;;;156785:38:0::1;;::::0;::::1;;;;;;;;;;;;;-1:-1:-1::0;;;156785:38:0::1;;::::0;:22:::1;:38::i;:::-;156834:27;:25;:27::i;:::-;156872:49;;;;;;;;;;;;;;-1:-1:-1::0;;;156872:49:0::1;;::::0;:41:::1;:49::i;:::-;156932:51;:49;:51::i;:::-;156994:4;:20:::0;;-1:-1:-1;;;;;156994:20:0;;::::1;-1:-1:-1::0;;;;;;156994:20:0;;::::1;;::::0;;;157025:5:::1;:22:::0;;;;::::1;::::0;;::::1;;::::0;;157058:12:::1;:28:::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;157097:10:::1;:24:::0;;;156994:4:::1;157132:13;:17:::0;97915:102;;;;97966:5;97950:21;;-1:-1:-1;;97950:21:0;;;97991:14;;-1:-1:-1;12730:36:1;;97991:14:0;;12718:2:1;12703:18;97991:14:0;;;;;;;156484:673;;;;;:::o;128765:656::-;129009:8;128990:15;:27;;128982:69;;;;-1:-1:-1;;;128982:69:0;;19404:2:1;128982:69:0;;;19386:21:1;19443:2;19423:18;;;19416:30;19482:31;19462:18;;;19455:59;19531:18;;128982:69:0;19376:179:1;128982:69:0;129064:18;127776:95;129124:5;129131:7;129140:5;129147:16;129157:5;129147:9;:16::i;:::-;129095:79;;;;;;10078:25:1;;;;-1:-1:-1;;;;;10177:15:1;;;10157:18;;;10150:43;10229:15;;;;10209:18;;;10202:43;10261:18;;;10254:34;10304:19;;;10297:35;10348:19;;;10341:35;;;10050:19;;129095:79:0;;;;;;;;;;;;129085:90;;;;;;129064:111;;129188:12;129203:28;129220:10;129203:16;:28::i;:::-;129188:43;;129244:14;129261:39;129286:4;129292:1;129295;129298;129261:24;:39::i;:::-;129244:56;;129329:5;-1:-1:-1;;;;;129319:15:0;:6;-1:-1:-1;;;;;129319:15:0;;129311:58;;;;-1:-1:-1;;;129311:58:0;;23763:2:1;129311:58:0;;;23745:21:1;23802:2;23782:18;;;23775:30;23841:32;23821:18;;;23814:60;23891:18;;129311:58:0;23735:180:1;129311:58:0;129382:31;129391:5;129398:7;129407:5;129382:8;:31::i;:::-;128765:656;;;;;;;;;;:::o;117398:151::-;-1:-1:-1;;;;;117514:18:0;;;117487:7;117514:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;117398:151::o;162071:1135::-;162137:21;162161:8;162170:4;162161:14;;;;;;-1:-1:-1;;;162161:14:0;;;;;;;;;;;;;;;;;162210;;;:8;:14;;;;;;162225:10;162210:26;;;;;;;162161:14;;;;;;;;-1:-1:-1;162249:16:0;162219:4;162249:10;:16::i;:::-;162280:11;;:15;162276:386;;162312:18;162333:71;162385:4;:18;;;162333:47;162375:4;162333:37;162349:4;:20;;;162333:4;:11;;;:15;;:37;;;;:::i;:71::-;162312:92;-1:-1:-1;162423:14:0;;162419:100;;162458:12;;:45;;-1:-1:-1;;;162458:45:0;;162480:10;162458:45;;;9312:51:1;9379:18;;;9372:34;;;-1:-1:-1;;;;;162458:12:0;;;;:21;;9285:18:1;;162458:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;162419:100;162562:88;162604:45;162624:24;;162604:15;;:19;;:45;;;;:::i;162562:88::-;162533:26;;;:117;-1:-1:-1;162276:386:0;162682:25;162710:36;162722:23;162741:3;162722:14;:7;162734:1;162722:11;:14::i;:23::-;162710:7;;:11;:36::i;:::-;162759:12;;:70;;-1:-1:-1;;;162759:70:0;;162793:10;162759:70;;;8998:34:1;162814:4:0;9048:18:1;;;9041:43;9100:18;;;9093:34;;;162682:64:0;;-1:-1:-1;;;;;;162759:12:0;;:25;;8933:18:1;;162759:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;162858:15:0;;:38;;162878:17;162858:19;:38::i;:::-;162840:15;:56;162921:11;;:34;;162937:17;162921:15;:34::i;:::-;162907:48;;;163003:20;;;;162987:47;;163029:4;;162987:37;;162907:48;162987:15;:37::i;:47::-;162966:18;;;:68;163079:13;;163061:31;;:15;:31;:::i;:::-;163045:13;;;:47;163103:35;163109:10;163120:17;163103:5;:35::i;:::-;163154:44;;9755:25:1;;;163174:4:0;;163162:10;;163154:44;;9743:2:1;9728:18;163154:44:0;9710:76:1;132379:150:0;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;132495:21:0;;;;;;:12;:21;;;;;:26;;;;;;;;;;-1:-1:-1;;;132495:26:0;;;;;;;;;;;;;;;;;;132488:33;;;;;;;;;132495:26;;132488:33;;;;;;;;;-1:-1:-1;;;;;132488:33:0;;;;;;;;;132379:150;-1:-1:-1;;;132379:150:0:o;112228:201::-;111208:13;:11;:13::i;:::-;-1:-1:-1;;;;;112317:22:0;::::1;112309:73;;;::::0;-1:-1:-1;;;112309:73:0;;17128:2:1;112309:73:0::1;::::0;::::1;17110:21:1::0;17167:2;17147:18;;;17140:30;17206:34;17186:18;;;17179:62;-1:-1:-1;;;17257:18:1;;;17250:36;17303:19;;112309:73:0::1;17100:228:1::0;112309:73:0::1;112393:28;112412:8;112393:18;:28::i;123720:380::-:0;-1:-1:-1;;;;;123856:19:0;;123848:68;;;;-1:-1:-1;;;123848:68:0;;27684:2:1;123848:68:0;;;27666:21:1;27723:2;27703:18;;;27696:30;27762:34;27742:18;;;27735:62;-1:-1:-1;;;27813:18:1;;;27806:34;27857:19;;123848:68:0;27656:226:1;123848:68:0;-1:-1:-1;;;;;123935:21:0;;123927:68;;;;-1:-1:-1;;;123927:68:0;;17535:2:1;123927:68:0;;;17517:21:1;17574:2;17554:18;;;17547:30;17613:34;17593:18;;;17586:62;-1:-1:-1;;;17664:18:1;;;17657:32;17706:19;;123927:68:0;17507:224:1;123927:68:0;-1:-1:-1;;;;;124008:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;124060:32;;9755:25:1;;;124060:32:0;;9728:18:1;124060:32:0;;;;;;;123720:380;;;:::o;6170:98::-;6228:7;6255:5;6259:1;6255;:5;:::i;6527:98::-;6585:7;6612:5;6616:1;6612;:5;:::i;6926:98::-;6984:7;7011:5;7015:1;7011;:5;:::i;5789:98::-;5847:7;5874:5;5878:1;5874;:5;:::i;111487:132::-;111395:6;;-1:-1:-1;;;;;111395:6:0;106269:10;111551:23;111543:68;;;;-1:-1:-1;;;111543:68:0;;24953:2:1;111543:68:0;;;24935:21:1;;;24972:18;;;24965:30;25031:34;25011:18;;;25004:62;25083:18;;111543:68:0;24925:182:1;124391:453:0;124526:24;124553:25;124563:5;124570:7;124553:9;:25::i;:::-;124526:52;;-1:-1:-1;;124593:16:0;:37;124589:248;;124675:6;124655:16;:26;;124647:68;;;;-1:-1:-1;;;124647:68:0;;19046:2:1;124647:68:0;;;19028:21:1;19085:2;19065:18;;;19058:30;19124:31;19104:18;;;19097:59;19173:18;;124647:68:0;19018:179:1;124647:68:0;124759:51;124768:5;124775:7;124803:6;124784:16;:25;124759:8;:51::i;:::-;124391:453;;;;:::o;121001:671::-;-1:-1:-1;;;;;121132:18:0;;121124:68;;;;-1:-1:-1;;;121124:68:0;;26871:2:1;121124:68:0;;;26853:21:1;26910:2;26890:18;;;26883:30;26949:34;26929:18;;;26922:62;-1:-1:-1;;;27000:18:1;;;26993:35;27045:19;;121124:68:0;26843:227:1;121124:68:0;-1:-1:-1;;;;;121211:16:0;;121203:64;;;;-1:-1:-1;;;121203:64:0;;14538:2:1;121203:64:0;;;14520:21:1;14577:2;14557:18;;;14550:30;14616:34;14596:18;;;14589:62;-1:-1:-1;;;14667:18:1;;;14660:33;14710:19;;121203:64:0;14510:225:1;121203:64:0;121280:38;121301:4;121307:2;121311:6;121280:20;:38::i;:::-;-1:-1:-1;;;;;121353:15:0;;121331:19;121353:15;;;:9;:15;;;;;;121387:21;;;;121379:72;;;;-1:-1:-1;;;121379:72:0;;19762:2:1;121379:72:0;;;19744:21:1;19801:2;19781:18;;;19774:30;19840:34;19820:18;;;19813:62;-1:-1:-1;;;19891:18:1;;;19884:36;19937:19;;121379:72:0;19734:228:1;121379:72:0;-1:-1:-1;;;;;121487:15:0;;;;;;;:9;:15;;;;;;121505:20;;;121487:38;;121547:13;;;;;;;;:23;;121519:6;;121487:15;121547:23;;121519:6;;121547:23;:::i;:::-;;;;;;;;121603:2;-1:-1:-1;;;;;121588:26:0;121597:4;-1:-1:-1;;;;;121588:26:0;;121607:6;121588:26;;;;9755:25:1;;9743:2;9728:18;;9710:76;121588:26:0;;;;;;;;121627:37;121647:4;121653:2;121657:6;121627:19;:37::i;103048:162::-;103101:7;103128:74;101771:95;103162:17;104630:12;;104545:105;;103162:17;104985:15;;103399:73;;;;;;11068:25:1;;;11109:18;;;11102:34;;;11152:18;;;11145:34;;;103443:13:0;11195:18:1;;;11188:34;103466:4:0;11238:19:1;;;11231:61;103362:7:0;;11040:19:1;;103399:73:0;;;;;;;;;;;;103389:84;;;;;;103382:91;;103218:263;;;;;;167746:149;167835:10;167824:7;111395:6;;-1:-1:-1;;;;;111395:6:0;111322:87;;167824:7;-1:-1:-1;;;;;167824:21:0;;167816:71;;;;-1:-1:-1;;;167816:71:0;;13720:2:1;167816:71:0;;;13702:21:1;13759:2;13739:18;;;13732:30;13798:34;13778:18;;;13771:62;-1:-1:-1;;;13849:18:1;;;13842:35;13894:19;;167816:71:0;13692:227:1;143326:992:0;141279:66;143780:59;;;143776:535;;;143856:37;143875:17;143856:18;:37::i;:::-;143776:535;;;143959:17;-1:-1:-1;;;;;143930:61:0;;:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;143930:63:0;;;;;;;;-1:-1:-1;;143930:63:0;;;;;;;;;;;;:::i;:::-;;;143926:306;;144160:56;;-1:-1:-1;;;144160:56:0;;23348:2:1;144160:56:0;;;23330:21:1;23387:2;23367:18;;;23360:30;23426:34;23406:18;;;23399:62;-1:-1:-1;;;23477:18:1;;;23470:44;23531:19;;144160:56:0;23320:236:1;143926:306:0;-1:-1:-1;;;;;;;;;;;144044:28:0;;144036:82;;;;-1:-1:-1;;;144036:82:0;;21410:2:1;144036:82:0;;;21392:21:1;21449:2;21429:18;;;21422:30;21488:34;21468:18;;;21461:62;-1:-1:-1;;;21539:18:1;;;21532:39;21588:19;;144036:82:0;21382:231:1;144036:82:0;143994:140;144246:53;144264:17;144283:4;144289:9;144246:17;:53::i;:::-;143326:992;;;:::o;134395:1493::-;135528:12;;134494:7;;;135577:247;135590:4;135584:3;:10;135577:247;;;135611:11;135625:34;135649:3;135654:4;135625:23;:34::i;:::-;135611:48;;135701:11;135678:5;135684:3;135678:10;;;;;;-1:-1:-1;;;135678:10:0;;;;;;;;;;;;;;;;;;:20;;;:34;135674:139;;;135740:3;135733:10;;135674:139;;;135790:7;:3;135796:1;135790:7;:::i;:::-;135784:13;;135674:139;135577:247;;;;135843:9;;:37;;135859:5;135865:8;135872:1;135865:4;:8;:::i;:::-;135859:15;;;;;;-1:-1:-1;;;135859:15:0;;;;;;;;;;;;;;;;;;:21;;;;-1:-1:-1;;;;;135859:21:0;135843:37;;;135855:1;135843:37;-1:-1:-1;;;;;135836:44:0;;134395:1493;-1:-1:-1;;;;;134395:1493:0:o;166832:177::-;166973:28;166985:7;166994:6;166973:11;:28::i;167600:138::-;167694:36;167710:9;167720;167694:15;:36::i;25688:190::-;25744:6;25780:16;25771:25;;;25763:76;;;;-1:-1:-1;;;25763:76:0;;27277:2:1;25763:76:0;;;27259:21:1;27316:2;27296:18;;;27289:30;27355:34;27335:18;;;27328:62;-1:-1:-1;;;27406:18:1;;;27399:36;27452:19;;25763:76:0;27249:228:1;25763:76:0;-1:-1:-1;25864:5:0;25688:190::o;112589:191::-;112682:6;;;-1:-1:-1;;;;;112699:17:0;;;-1:-1:-1;;;;;;112699:17:0;;;;;;;112732:40;;112682:6;;;112699:17;112682:6;;112732:40;;112663:16;;112732:40;112589:191;;:::o;104123:178::-;104200:7;104227:66;104260:20;:18;:20::i;:::-;104282:10;71622:57;;-1:-1:-1;;;71622:57:0;;;8411:27:1;8454:11;;;8447:27;;;8490:12;;;8483:28;;;71585:7:0;;8527:12:1;;71622:57:0;;;;;;;;;;;;71612:68;;;;;;71605:75;;71492:196;;;;;69790:279;69918:7;69939:17;69958:18;69980:25;69991:4;69997:1;70000;70003;69980:10;:25::i;:::-;69938:67;;;;70016:18;70028:5;70016:11;:18::i;:::-;-1:-1:-1;70052:9:0;69790:279;-1:-1:-1;;;;;69790:279:0:o;129998:218::-;-1:-1:-1;;;;;130130:14:0;;130058:15;130130:14;;;:7;:14;;;;;58988;;59125:1;59107:19;;;;58988:14;130191:17;129998:218;;;;:::o;110865:97::-;99378:13;;;;;;;99370:69;;;;-1:-1:-1;;;99370:69:0;;;;;;;:::i;:::-;110928:26:::1;:24;:26::i;115286:162::-:0;99378:13;;;;;;;99370:69;;;;-1:-1:-1;;;99370:69:0;;;;;;;:::i;:::-;115399:13;;::::1;::::0;:5:::1;::::0;:13:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;115423:17:0;;::::1;::::0;:7:::1;::::0;:17:::1;::::0;::::1;::::0;::::1;:::i;107869:97::-:0;99378:13;;;;;;;99370:69;;;;-1:-1:-1;;;99370:69:0;;;;;;;:::i;:::-;107943:7:::1;:15:::0;;-1:-1:-1;;107943:15:0::1;::::0;;107869:97::o;128483:127::-;99378:13;;;;;;;99370:69;;;;-1:-1:-1;;;99370:69:0;;;;;;;:::i;:::-;128568:34:::1;128592:4;128568:34;;;;;;;;;;;;;-1:-1:-1::0;;;128568:34:0::1;;::::0;:23:::1;:34::i;131838:73::-:0;99378:13;;;;;;;99370:69;;;;-1:-1:-1;;;99370:69:0;;;;;;;:::i;166657:167::-;166793:23;166805:2;166809:6;166793:11;:23::i;167256:336::-;-1:-1:-1;;;;;167412:18:0;;;;:38;;-1:-1:-1;;;;;;167434:16:0;;;167412:38;167409:176;;;167466:44;143326:992;167409:176;167541:32;;-1:-1:-1;;;167541:32:0;;15302:2:1;167541:32:0;;;15284:21:1;15341:2;15321:18;;;15314:30;-1:-1:-1;;;15360:18:1;;;15353:52;15422:18;;167541:32:0;15274:172:1;167017:231:0;167181:59;167223:4;167229:2;167233:6;167181:41;:59::i;142157:284::-;-1:-1:-1;;;;;83673:19:0;;;142231:106;;;;-1:-1:-1;;;142231:106:0;;24122:2:1;142231:106:0;;;24104:21:1;24161:2;24141:18;;;24134:30;24200:34;24180:18;;;24173:62;-1:-1:-1;;;24251:18:1;;;24244:43;24304:19;;142231:106:0;24094:235:1;142231:106:0;-1:-1:-1;;;;;;;;;;;142348:85:0;;-1:-1:-1;;;;;;142348:85:0;-1:-1:-1;;;;;142348:85:0;;;;;;;;;;142157:284::o;142850:297::-;142993:29;143004:17;142993:10;:29::i;:::-;143051:1;143037:4;:11;:15;:28;;;;143056:9;143037:28;143033:107;;;143082:46;143104:17;143123:4;143082:21;:46::i;49774:156::-;49836:7;49911:11;49921:1;49912:5;;;49911:11;:::i;:::-;49901:21;;49902:5;;;49901:21;:::i;137462:194::-;137547:28;137559:7;137568:6;137547:11;:28::i;:::-;137588:60;137605:23;137630:9;137641:6;137588:16;:60::i;138222:388::-;-1:-1:-1;;;;;132965:19:0;;;138307:23;132965:19;;;:10;:19;;;;;;;;;;116910:9;:18;;;;;;138422:21;;;;:33;;;-1:-1:-1;;;;;;138422:33:0;;;;;;;138473:54;;132965:19;;;;;116910:18;;138422:33;;132965:19;;;138473:54;;138307:23;138473:54;138540:62;138557:15;138574:9;138585:16;138540;:62::i;68019:1632::-;68150:7;;69084:66;69071:79;;69067:163;;;-1:-1:-1;69183:1:0;;-1:-1:-1;69187:30:0;69167:51;;69067:163;69244:1;:7;;69249:2;69244:7;;:18;;;;;69255:1;:7;;69260:2;69255:7;;69244:18;69240:102;;;-1:-1:-1;69295:1:0;;-1:-1:-1;69299:30:0;69279:51;;69240:102;69456:24;;;69439:14;69456:24;;;;;;;;;11530:25:1;;;11603:4;11591:17;;11571:18;;;11564:45;;;;11625:18;;;11618:34;;;11668:18;;;11661:34;;;69456:24:0;;11502:19:1;;69456:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;69456:24:0;;-1:-1:-1;;69456:24:0;;;-1:-1:-1;;;;;;;69495:20:0;;69491:103;;69548:1;69552:29;69532:50;;;;;;;69491:103;69614:6;-1:-1:-1;69622:20:0;;-1:-1:-1;68019:1632:0;;;;;;;;:::o;62632:643::-;62710:20;62701:5;:29;;;;;;-1:-1:-1;;;62701:29:0;;;;;;;;;;62697:571;;;62747:7;;62697:571;62808:29;62799:5;:38;;;;;;-1:-1:-1;;;62799:38:0;;;;;;;;;;62795:473;;;62854:34;;-1:-1:-1;;;62854:34:0;;13367:2:1;62854:34:0;;;13349:21:1;13406:2;13386:18;;;13379:30;13445:26;13425:18;;;13418:54;13489:18;;62854:34:0;13339:174:1;62795:473:0;62919:35;62910:5;:44;;;;;;-1:-1:-1;;;62910:44:0;;;;;;;;;;62906:362;;;62971:41;;-1:-1:-1;;;62971:41:0;;16414:2:1;62971:41:0;;;16396:21:1;16453:2;16433:18;;;16426:30;16492:33;16472:18;;;16465:61;16543:18;;62971:41:0;16386:181:1;62906:362:0;63043:30;63034:5;:39;;;;;;-1:-1:-1;;;63034:39:0;;;;;;;;;;63030:238;;;63090:44;;-1:-1:-1;;;63090:44:0;;20169:2:1;63090:44:0;;;20151:21:1;20208:2;20188:18;;;20181:30;20247:34;20227:18;;;20220:62;-1:-1:-1;;;20298:18:1;;;20291:32;20340:19;;63090:44:0;20141:224:1;63030:238:0;63165:30;63156:5;:39;;;;;;-1:-1:-1;;;63156:39:0;;;;;;;;;;63152:116;;;63212:44;;-1:-1:-1;;;63212:44:0;;22592:2:1;63212:44:0;;;22574:21:1;22631:2;22611:18;;;22604:30;22670:34;22650:18;;;22643:62;-1:-1:-1;;;22721:18:1;;;22714:32;22763:19;;63212:44:0;22564:224:1;110970:113:0;99378:13;;;;;;;99370:69;;;;-1:-1:-1;;;99370:69:0;;;;;;;:::i;:::-;111043:32:::1;106269:10:::0;111043:18:::1;:32::i;102655:302::-:0;99378:13;;;;;;;99370:69;;;;-1:-1:-1;;;99370:69:0;;;;;;;:::i;:::-;102789:22;;::::1;::::0;;::::1;::::0;102846:25;;;;;::::1;::::0;102882:12:::1;:25:::0;;;;102918:15:::1;:31:::0;102655:302::o;137078:290::-;137163:28;137175:7;137184:6;137163:11;:28::i;:::-;116726:12;;-1:-1:-1;;;;;;137210:29:0;137202:90;;;;-1:-1:-1;;;137202:90:0;;24536:2:1;137202:90:0;;;24518:21:1;24575:2;24555:18;;;24548:30;24614:34;24594:18;;;24587:62;-1:-1:-1;;;24665:18:1;;;24658:46;24721:19;;137202:90:0;24508:238:1;137202:90:0;137305:55;137322:23;137347:4;137353:6;137305:16;:55::i;137796:262::-;-1:-1:-1;;;;;132965:19:0;;;132938:7;132965:19;;;:10;:19;;;;;;;;;;;;;;;137994:56;;132965:19;;;;;138043:6;137994:16;:56::i;142554:155::-;142621:37;142640:17;142621:18;:37::i;:::-;142674:27;;-1:-1:-1;;;;;142674:27:0;;;;;;;;142554:155;:::o;147587:461::-;147670:12;-1:-1:-1;;;;;83673:19:0;;;147695:88;;;;-1:-1:-1;;;147695:88:0;;26464:2:1;147695:88:0;;;26446:21:1;26503:2;26483:18;;;26476:30;26542:34;26522:18;;;26515:62;-1:-1:-1;;;26593:18:1;;;26586:36;26639:19;;147695:88:0;26436:228:1;147695:88:0;147857:12;147871:23;147898:6;-1:-1:-1;;;;;147898:19:0;147918:4;147898:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;147856:67;;;;147941:99;147977:7;147986:10;147941:99;;;;;;;;;;;;;;;;;:35;:99::i;:::-;147934:106;147587:461;-1:-1:-1;;;;;147587:461:0:o;122691:591::-;-1:-1:-1;;;;;122775:21:0;;122767:67;;;;-1:-1:-1;;;122767:67:0;;26062:2:1;122767:67:0;;;26044:21:1;26101:2;26081:18;;;26074:30;26140:34;26120:18;;;26113:62;-1:-1:-1;;;26191:18:1;;;26184:31;26232:19;;122767:67:0;26034:223:1;122767:67:0;122847:49;122868:7;122885:1;122889:6;122847:20;:49::i;:::-;-1:-1:-1;;;;;122934:18:0;;122909:22;122934:18;;;:9;:18;;;;;;122971:24;;;;122963:71;;;;-1:-1:-1;;;122963:71:0;;16011:2:1;122963:71:0;;;15993:21:1;16050:2;16030:18;;;16023:30;16089:34;16069:18;;;16062:62;-1:-1:-1;;;16140:18:1;;;16133:32;16182:19;;122963:71:0;15983:224:1;122963:71:0;-1:-1:-1;;;;;123070:18:0;;;;;;:9;:18;;;;;123091:23;;;123070:44;;123136:12;:22;;123108:6;;123070:18;123136:22;;123108:6;;123136:22;:::i;:::-;;;;-1:-1:-1;;123176:37:0;;9755:25:1;;;123202:1:0;;-1:-1:-1;;;;;123176:37:0;;;;;9743:2:1;9728:18;123176:37:0;;;;;;;123226:48;123246:7;123263:1;123267:6;123226:19;:48::i;139269:678::-;139506:12;;139443:17;;;;139541:8;;:35;;139556:5;139562:7;139568:1;139562:3;:7;:::i;:::-;139556:14;;;;;;-1:-1:-1;;;139556:14:0;;;;;;;;;;;;;;;;;;:20;;;;-1:-1:-1;;;;;139556:20:0;139541:35;;;139552:1;139541:35;-1:-1:-1;;;;;139529:47:0;;;139599:20;139602:9;139613:5;139599:2;:20;;:::i;:::-;139587:32;;139642:1;139636:3;:7;:51;;;;-1:-1:-1;139675:12:0;139647:5;139653:7;139659:1;139653:3;:7;:::i;:::-;139647:14;;;;;;-1:-1:-1;;;139647:14:0;;;;;;;;;;;;;;;;;;:24;;;:40;139636:51;139632:308;;;139727:40;139757:9;139727:29;:40::i;:::-;139704:5;139710:7;139716:1;139710:3;:7;:::i;:::-;139704:14;;;;;;-1:-1:-1;;;139704:14:0;;;;;;;;;;;;;;;;:20;;;:63;;;;;-1:-1:-1;;;;;139704:63:0;;;;;-1:-1:-1;;;;;139704:63:0;;;;;;139632:308;;;139800:5;139811:116;;;;;;;;139834:42;139863:12;139834:28;:42::i;:::-;139811:116;;;;;;139885:40;139915:9;139885:29;:40::i;:::-;-1:-1:-1;;;;;139811:116:0;;;;;;139800:128;;;;;;;-1:-1:-1;139800:128:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;139800:128:0;;;;;;;;;;;139632:308;139269:678;;;;;;;:::o;138618:643::-;138750:3;-1:-1:-1;;;;;138743:10:0;:3;-1:-1:-1;;;;;138743:10:0;;;:24;;;;;138766:1;138757:6;:10;138743:24;138739:515;;;-1:-1:-1;;;;;138788:17:0;;;138784:224;;-1:-1:-1;;;;;138884:17:0;;138827;138884;;;:12;:17;;;;;138827;;138867:54;;138903:9;138914:6;138867:16;:54::i;:::-;138826:95;;;;138966:3;-1:-1:-1;;;;;138945:47:0;;138971:9;138982;138945:47;;;;;;31575:25:1;;;31631:2;31616:18;;31609:34;31563:2;31548:18;;31530:119;138945:47:0;;;;;;;;138784:224;;;-1:-1:-1;;;;;139028:17:0;;;139024:219;;-1:-1:-1;;;;;139124:17:0;;139067;139124;;;:12;:17;;;;;139067;;139107:49;;139143:4;139149:6;139107:16;:49::i;:::-;139066:90;;;;139201:3;-1:-1:-1;;;;;139180:47:0;;139206:9;139217;139180:47;;;;;;31575:25:1;;;31631:2;31616:18;;31609:34;31563:2;31548:18;;31530:119;139180:47:0;;;;;;;;139024:219;;138618:643;;;:::o;121959:399::-;-1:-1:-1;;;;;122043:21:0;;122035:65;;;;-1:-1:-1;;;122035:65:0;;29256:2:1;122035:65:0;;;29238:21:1;29295:2;29275:18;;;29268:30;29334:33;29314:18;;;29307:61;29385:18;;122035:65:0;29228:181:1;122035:65:0;122113:49;122142:1;122146:7;122155:6;122113:20;:49::i;:::-;122191:6;122175:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;122208:18:0;;;;;;:9;:18;;;;;:28;;122230:6;;122208:18;:28;;122230:6;;122208:28;:::i;:::-;;;;-1:-1:-1;;122252:37:0;;9755:25:1;;;-1:-1:-1;;;;;122252:37:0;;;122269:1;;122252:37;;9743:2:1;9728:18;122252:37:0;;;;;;;122302:48;122330:1;122334:7;122343:6;122302:19;:48::i;88952:762::-;89102:12;89131:7;89127:580;;;-1:-1:-1;89162:10:0;89155:17;;89127:580;89276:17;;:21;89272:424;;89524:10;89518:17;89585:15;89572:10;89568:2;89564:19;89557:44;89472:148;89667:12;89660:20;;-1:-1:-1;;;89660:20:0;;;;;;;;:::i;12852:195::-;12909:7;-1:-1:-1;;;;;12937:26:0;;;12929:78;;;;-1:-1:-1;;;12929:78:0;;25314:2:1;12929:78:0;;;25296:21:1;25353:2;25333:18;;;25326:30;25392:34;25372:18;;;25365:62;-1:-1:-1;;;25443:18:1;;;25436:37;25490:19;;12929:78:0;25286:229:1;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:156:1;80:20;;140:4;129:16;;119:27;;109:2;;160:1;157;150:12;175:257;;287:2;275:9;266:7;262:23;258:32;255:2;;;308:6;300;293:22;255:2;352:9;339:23;371:31;396:5;371:31;:::i;437:398::-;;;566:2;554:9;545:7;541:23;537:32;534:2;;;587:6;579;572:22;534:2;631:9;618:23;650:31;675:5;650:31;:::i;:::-;700:5;-1:-1:-1;757:2:1;742:18;;729:32;770:33;729:32;770:33;:::i;:::-;822:7;812:17;;;524:311;;;;;:::o;840:608::-;;;;;1003:3;991:9;982:7;978:23;974:33;971:2;;;1025:6;1017;1010:22;971:2;1069:9;1056:23;1088:31;1113:5;1088:31;:::i;:::-;1138:5;-1:-1:-1;1195:2:1;1180:18;;1167:32;1208:33;1167:32;1208:33;:::i;:::-;1260:7;-1:-1:-1;1319:2:1;1304:18;;1291:32;1332:33;1291:32;1332:33;:::i;:::-;961:487;;;;-1:-1:-1;1384:7:1;;1438:2;1423:18;1410:32;;-1:-1:-1;;961:487:1:o;1453:466::-;;;;1599:2;1587:9;1578:7;1574:23;1570:32;1567:2;;;1620:6;1612;1605:22;1567:2;1664:9;1651:23;1683:31;1708:5;1683:31;:::i;:::-;1733:5;-1:-1:-1;1790:2:1;1775:18;;1762:32;1803:33;1762:32;1803:33;:::i;:::-;1557:362;;1855:7;;-1:-1:-1;;;1909:2:1;1894:18;;;;1881:32;;1557:362::o;1924:744::-;;;;;;;;2136:3;2124:9;2115:7;2111:23;2107:33;2104:2;;;2158:6;2150;2143:22;2104:2;2202:9;2189:23;2221:31;2246:5;2221:31;:::i;:::-;2271:5;-1:-1:-1;2328:2:1;2313:18;;2300:32;2341:33;2300:32;2341:33;:::i;:::-;2393:7;-1:-1:-1;2447:2:1;2432:18;;2419:32;;-1:-1:-1;2498:2:1;2483:18;;2470:32;;-1:-1:-1;2521:37:1;2553:3;2538:19;;2521:37;:::i;:::-;2511:47;;2605:3;2594:9;2590:19;2577:33;2567:43;;2657:3;2646:9;2642:19;2629:33;2619:43;;2094:574;;;;;;;;;;:::o;2673:1101::-;;;2811:2;2799:9;2790:7;2786:23;2782:32;2779:2;;;2832:6;2824;2817:22;2779:2;2876:9;2863:23;2895:31;2920:5;2895:31;:::i;:::-;2945:5;-1:-1:-1;3001:2:1;2986:18;;2973:32;3024:18;3054:14;;;3051:2;;;3086:6;3078;3071:22;3051:2;3129:6;3118:9;3114:22;3104:32;;3174:7;3167:4;3163:2;3159:13;3155:27;3145:2;;3201:6;3193;3186:22;3145:2;3242;3229:16;3264:2;3260;3257:10;3254:2;;;3270:18;;:::i;:::-;3345:2;3339:9;3313:2;3399:13;;-1:-1:-1;;3395:22:1;;;3419:2;3391:31;3387:40;3375:53;;;3443:18;;;3463:22;;;3440:46;3437:2;;;3489:18;;:::i;:::-;3529:10;3525:2;3518:22;3564:2;3556:6;3549:18;3604:7;3599:2;3594;3590;3586:11;3582:20;3579:33;3576:2;;;3630:6;3622;3615:22;3576:2;3691;3686;3682;3678:11;3673:2;3665:6;3661:15;3648:46;3736:6;3731:2;3726;3718:6;3714:15;3710:24;3703:40;3762:6;3752:16;;;;;;;2769:1005;;;;;:::o;3779:325::-;;;3908:2;3896:9;3887:7;3883:23;3879:32;3876:2;;;3929:6;3921;3914:22;3876:2;3973:9;3960:23;3992:31;4017:5;3992:31;:::i;:::-;4042:5;4094:2;4079:18;;;;4066:32;;-1:-1:-1;;;3866:238:1:o;4109:602::-;;;;;;;4304:3;4292:9;4283:7;4279:23;4275:33;4272:2;;;4326:6;4318;4311:22;4272:2;4370:9;4357:23;4389:31;4414:5;4389:31;:::i;:::-;4439:5;-1:-1:-1;4491:2:1;4476:18;;4463:32;;-1:-1:-1;4542:2:1;4527:18;;4514:32;;-1:-1:-1;4565:36:1;4597:2;4582:18;;4565:36;:::i;:::-;4555:46;;4648:3;4637:9;4633:19;4620:33;4610:43;;4700:3;4689:9;4685:19;4672:33;4662:43;;4262:449;;;;;;;;:::o;4716:439::-;;;4844:2;4832:9;4823:7;4819:23;4815:32;4812:2;;;4865:6;4857;4850:22;4812:2;4909:9;4896:23;4928:31;4953:5;4928:31;:::i;:::-;4978:5;-1:-1:-1;5035:2:1;5020:18;;5007:32;5083:10;5070:24;;5058:37;;5048:2;;5114:6;5106;5099:22;5160:255;;5280:2;5268:9;5259:7;5255:23;5251:32;5248:2;;;5301:6;5293;5286:22;5248:2;5338:9;5332:16;5357:28;5379:5;5357:28;:::i;5420:194::-;;5543:2;5531:9;5522:7;5518:23;5514:32;5511:2;;;5564:6;5556;5549:22;5511:2;-1:-1:-1;5592:16:1;;5501:113;-1:-1:-1;5501:113:1:o;5619:190::-;;5731:2;5719:9;5710:7;5706:23;5702:32;5699:2;;;5752:6;5744;5737:22;5699:2;-1:-1:-1;5780:23:1;;5689:120;-1:-1:-1;5689:120:1:o;6013:325::-;;;6142:2;6130:9;6121:7;6117:23;6113:32;6110:2;;;6163:6;6155;6148:22;6110:2;6204:9;6191:23;6181:33;;6264:2;6253:9;6249:18;6236:32;6277:31;6302:5;6277:31;:::i;6343:393::-;;;;6489:2;6477:9;6468:7;6464:23;6460:32;6457:2;;;6510:6;6502;6495:22;6457:2;6551:9;6538:23;6528:33;;6611:2;6600:9;6596:18;6583:32;6624:31;6649:5;6624:31;:::i;6741:473::-;;;;6897:2;6885:9;6876:7;6872:23;6868:32;6865:2;;;6918:6;6910;6903:22;6865:2;6959:9;6946:23;6936:33;;7019:2;7008:9;7004:18;6991:32;7032:31;7057:5;7032:31;:::i;:::-;7082:5;-1:-1:-1;7139:2:1;7124:18;;7111:32;7152:30;7111:32;7152:30;:::i;:::-;7201:7;7191:17;;;6855:359;;;;;:::o;7219:258::-;;;7348:2;7336:9;7327:7;7323:23;7319:32;7316:2;;;7369:6;7361;7354:22;7316:2;-1:-1:-1;;7397:23:1;;;7467:2;7452:18;;;7439:32;;-1:-1:-1;7306:171:1:o;7482:387::-;;;;7625:2;7613:9;7604:7;7600:23;7596:32;7593:2;;;7646:6;7638;7631:22;7593:2;7687:9;7674:23;7664:33;;7744:2;7733:9;7729:18;7716:32;7706:42;;7798:2;7787:9;7783:18;7770:32;7811:28;7833:5;7811:28;:::i;7874:274::-;;8041:6;8035:13;8057:53;8103:6;8098:3;8091:4;8083:6;8079:17;8057:53;:::i;:::-;8126:16;;;;;8011:137;-1:-1:-1;;8011:137:1:o;12777:383::-;;12926:2;12915:9;12908:21;12958:6;12952:13;13001:6;12996:2;12985:9;12981:18;12974:34;13017:66;13076:6;13071:2;13060:9;13056:18;13051:2;13043:6;13039:15;13017:66;:::i;:::-;13144:2;13123:15;-1:-1:-1;;13119:29:1;13104:45;;;;13151:2;13100:54;;12898:262;-1:-1:-1;;12898:262:1:o;18431:408::-;18633:2;18615:21;;;18672:2;18652:18;;;18645:30;18711:34;18706:2;18691:18;;18684:62;-1:-1:-1;;;18777:2:1;18762:18;;18755:42;18829:3;18814:19;;18605:234::o;20370:408::-;20572:2;20554:21;;;20611:2;20591:18;;;20584:30;20650:34;20645:2;20630:18;;20623:62;-1:-1:-1;;;20716:2:1;20701:18;;20694:42;20768:3;20753:19;;20544:234::o;27887:407::-;28089:2;28071:21;;;28128:2;28108:18;;;28101:30;28167:34;28162:2;28147:18;;28140:62;-1:-1:-1;;;28233:2:1;28218:18;;28211:41;28284:3;28269:19;;28061:233::o;32760:128::-;;32831:1;32827:6;32824:1;32821:13;32818:2;;;32837:18;;:::i;:::-;-1:-1:-1;32873:9:1;;32808:80::o;32893:217::-;;32959:1;32949:2;;-1:-1:-1;;;32984:31:1;;33038:4;33035:1;33028:15;33066:4;32991:1;33056:15;32949:2;-1:-1:-1;33095:9:1;;32939:171::o;33115:168::-;;33221:1;33217;33213:6;33209:14;33206:1;33203:21;33198:1;33191:9;33184:17;33180:45;33177:2;;;33228:18;;:::i;:::-;-1:-1:-1;33268:9:1;;33167:116::o;33288:125::-;;33356:1;33353;33350:8;33347:2;;;33361:18;;:::i;:::-;-1:-1:-1;33398:9:1;;33337:76::o;33418:258::-;33490:1;33500:113;33514:6;33511:1;33508:13;33500:113;;;33590:11;;;33584:18;33571:11;;;33564:39;33536:2;33529:10;33500:113;;;33631:6;33628:1;33625:13;33622:2;;;-1:-1:-1;;33666:1:1;33648:16;;33641:27;33471:205::o;33681:380::-;33766:1;33756:12;;33813:1;33803:12;;;33824:2;;33878:4;33870:6;33866:17;33856:27;;33824:2;33931;33923:6;33920:14;33900:18;33897:38;33894:2;;;33977:10;33972:3;33968:20;33965:1;33958:31;34012:4;34009:1;34002:15;34040:4;34037:1;34030:15;34066:135;;-1:-1:-1;;34126:17:1;;34123:2;;;34146:18;;:::i;:::-;-1:-1:-1;34193:1:1;34182:13;;34113:88::o;34206:127::-;34267:10;34262:3;34258:20;34255:1;34248:31;34298:4;34295:1;34288:15;34322:4;34319:1;34312:15;34338:127;34399:10;34394:3;34390:20;34387:1;34380:31;34430:4;34427:1;34420:15;34454:4;34451:1;34444:15;34470:131;-1:-1:-1;;;;;34545:31:1;;34535:42;;34525:2;;34591:1;34588;34581:12;34606:118;34692:5;34685:13;34678:21;34671:5;34668:32;34658:2;;34714:1;34711;34704:12

Swarm Source

ipfs://4818f7eefa1f3d5f2d1805bfcffa1a9b932dd98859e15958dee130ec9f26e0ed
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.