ETH Price: $2,583.31 (-2.80%)

Token

HeartX Utility Token (HNX)
 

Overview

Max Total Supply

5,699,387.681031 HNX

Holders

69 (0.00%)

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
90,956.054544658134073539 HNX

Value
$0.00
0x9327fe4d065d01c412ebb93acc413f495db50000
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

A global Web3 artwork community powered by artists and collectors. HeartX strives to redefine the value of art by the community consensus.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
HNXCoin

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-04-03
*/

// Sources flattened with hardhat v2.12.7 https://hardhat.org

// File @openzeppelin/contracts/access/[email protected]

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.9;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

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

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

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

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

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

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

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

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

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

        _revokeRole(role, account);
    }

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

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

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

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

/**
 * @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 Pausable is Context {
    /**
     * @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.
     */
    constructor() {
        _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 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);
}

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

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

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

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

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

        return true;
    }

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

        _beforeTokenTransfer(from, to, amount);

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

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/**
 * @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 ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV // Deprecated in v4.8
    }

    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");
        }
    }

    /**
     * @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) {
        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 {
            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 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",
                    Strings.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 contracts/IBaseCoin.sol

interface IBaseCoin {
    // 1.[Basic Types]
    // 1.1 record structure
    struct coinRecord {
        uint256 nonce;
        uint256[] amount;
        uint256[] tag;
    }

    // 2.[Setting Functions, Owner Privilege]
    function setSigner(address signer) external; // 2.1 Signer

    function setTreasury(address treasury) external; // 2.2 Treasury

    function setOpExecutorRole(address executor, bool bEnable) external; // 2.3 Executor (Enable or Disable)

    // 3.[Events]
    event evCoinConsumed(address from, uint256 amount); // 3.1

    event evCoinClaimed(
        address indexed to,
        uint256 nonce,
        uint256 amount,
        uint256 tag
    ); // 3.2 Claimed

    event evCoinMinted(
        address indexed to,
        uint256 nonce,
        uint256 amount,
        uint256 tag
    ); // 3.3 Minted

    event evCoinStake(
        address indexed staker,
        uint256 nonce,
        uint256[] aryTime,
        uint256[] aryAmount
    ); // 3.4 Staked

    event evAddrSetted(
        address indexed old,
        address indexed current,
        uint256 tag,
        bool bEnable
    ); // Configured
}

// File contracts/IBaseStake.sol

interface IBaseStake {
    // 1.[Basic Types]
    // 1.1 staking record
    struct stakeUnit {
        uint256 nonce;
        uint256[] lockTime;
        uint256[] lockAmount;
        uint256[] lockTag;
    }

    // 2.[Functions]
    function newStake(
        address staker,
        uint256 nonce,
        uint256[] memory aryTime,
        uint256[] memory aryAmount
    ) external;

    function claimStake() external;

    // 3. [Events]
    event evNewStake(
        address staker,
        uint256 nonce,
        uint256[] time,
        uint256[] amount
    );

    event evClaimStake(
        address staker,
        uint256 total,
        uint256[] aryTime,
        uint256[] aryAmount
    );
}

// File contracts/BaseCoin.sol

/// @custom:security-contact [email protected]

contract BaseCoin is ERC20, ERC20Burnable, Pausable, AccessControl, IBaseCoin {
    // 1. State Variables & Constructor
    // 1.1 Executor Role, Constant Tags
    bytes32 internal constant ROLE_OP_EXECUTOR =
        keccak256("OPERATION EXECUTOR");

    uint256 internal constant TAG_SIGNER = 0;
    uint256 internal constant TAG_TREASURY = 1;
    uint256 internal constant TAG_EXECUTOR = 2;

    // 1.2 Record of claiming, minting & consuming
    mapping(address => coinRecord) internal m_recdClaim;
    mapping(address => coinRecord) internal m_recdMint;

    // 1.3 Address of Signer & Treasury
    address internal m_opSigner;
    address internal m_opTreasury;

    constructor(
        string memory strTokenName,
        string memory strTokenAbbr
    ) ERC20(strTokenName, strTokenAbbr) {
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(ROLE_OP_EXECUTOR, msg.sender);
        m_opSigner = msg.sender;
        m_opTreasury = msg.sender;
    }

    // 2. Internal Funtions
    // 2.1 Verify signature for minting & claiming:
    function verifySingleData(
        address addrUser,
        uint256 nonce,
        uint256 amount,
        uint256 tag,
        bytes4 selector,
        bytes memory signature
    ) internal view returns (bool) {
        bytes32 orderHash = ECDSA.toEthSignedMessageHash(
            keccak256(abi.encodePacked(tag, amount, nonce, addrUser, selector))
        );
        address signer = ECDSA.recover(orderHash, signature);
        return (signer == m_opSigner);
    }

    // 2.2 Verify signature for staking:
    function verifyArrayData(
        address addrUser,
        uint256 nonce,
        uint256[] memory aryTime,
        uint256[] memory aryAmount,
        bytes memory signature
    ) internal view returns (bool) {
        require(
            aryTime.length == aryAmount.length,
            "timestamp and amount array length should be equal"
        );
        require(aryTime.length <= 10, "no more 10 arrays");

        // check signature
        bytes32 orderHash = ECDSA.toEthSignedMessageHash(
            keccak256(abi.encodePacked(addrUser, nonce, aryTime, aryAmount))
        );
        address signer = ECDSA.recover(orderHash, signature);
        return (signer == m_opSigner);
    }

    // 2.3 claiming
    function _claimCoin(
        uint256 nonce,
        uint256 amount,
        uint256 tag,
        bytes4 selt,
        bytes memory signature
    ) internal {
        // step 1. check the nonce
        require(m_recdClaim[msg.sender].nonce == nonce - 1, "wrong nonce");
        // step 2. check the claim order's content and signer officer
        require(
            verifySingleData(msg.sender, nonce, amount, tag, selt, signature),
            "invalid signature"
        );

        // step 3. minting to msg.sender
        _mint(msg.sender, amount);

        // step 4. update state & emit claimed event
        m_recdClaim[msg.sender].nonce = nonce;
        m_recdClaim[msg.sender].amount.push(amount);
        m_recdClaim[msg.sender].tag.push(tag);

        emit evCoinClaimed(msg.sender, nonce, amount, tag);
    }

    // 2.4 minting
    function _mintCoin(
        address acceptor,
        uint256 nonce,
        uint256 amount,
        uint256 tag,
        bytes4 selt,
        bytes memory signature
    ) internal onlyRole(ROLE_OP_EXECUTOR) {
        require(acceptor != address(0), "couldn't be Zero address");
        require(m_recdMint[acceptor].nonce == nonce - 1, "wrong nonce");
        require(
            verifySingleData(acceptor, nonce, amount, tag, selt, signature),
            "invalid signature"
        );

        _mint(acceptor, amount);

        m_recdMint[acceptor].nonce = nonce;
        m_recdMint[acceptor].amount.push(amount);
        m_recdMint[acceptor].tag.push(tag);

        emit evCoinMinted(acceptor, nonce, amount, tag);
    }

    // 2.5 consuming
    function _consumeCoin(uint256 amount) internal {
        require(m_opTreasury != address(0), "income address not set");
        require(balanceOf(msg.sender) >= amount, "insufficient balance");

        transfer(m_opTreasury, amount);

        emit evCoinConsumed(msg.sender, amount);
    }

    // 2.6 staking
    function _stakeCoin(
        IBaseStake conBaseStake,
        address staker,
        uint256 nonce,
        uint256[] memory aryTime,
        uint256[] memory aryAmount,
        bytes memory signature
    ) internal onlyRole(ROLE_OP_EXECUTOR) {
        // check stake contract address is set
        require(
            conBaseStake != IBaseStake(address(0)),
            "stake contract not set"
        );
        // timestamp & amount array should be paired
        require(
            verifyArrayData(staker, nonce, aryTime, aryAmount, signature),
            "invalid signature"
        );

        // for testing convience
        uint256 deltaT = 300; // 5 minutes, just for debugging
        uint256 sum = 0;

        for (uint256 i = 0; i < aryTime.length; i++) {
            // block timestamp must smaller than the locked time
            assert(block.timestamp < (aryTime[i] + deltaT));
        }
        for (uint256 i = 0; i < aryAmount.length; i++) {
            sum += aryAmount[i];
        }

        _mint(address(conBaseStake), sum);

        conBaseStake.newStake(staker, nonce, aryTime, aryAmount);
        emit evCoinStake(staker, nonce, aryTime, aryAmount);
    }

    // 3. Interface Implementing
    // Part 3.3 [Setting Functions]
    // 3.3.1 Set Signer
    function setSigner(address signer) external onlyRole(DEFAULT_ADMIN_ROLE) {
        require(signer != address(0), "couldn't asign to Zero address");
        require(signer != m_opSigner, "need to use a new address");

        address addrOld = m_opSigner;
        m_opSigner = signer;

        emit evAddrSetted(addrOld, m_opSigner, TAG_SIGNER, true);
    }

    // 3.3.2 Set Treasury
    function setTreasury(
        address treasury
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        require(treasury != address(0), "couldn't asign to Zero address");
        require(treasury != m_opTreasury, "need to use a new address");

        address addrOld = m_opTreasury;
        m_opTreasury = treasury;
        emit evAddrSetted(addrOld, m_opTreasury, TAG_TREASURY, true);
    }

    // 3.3.3 Set Executor
    function setOpExecutorRole(
        address executor,
        bool bEnable
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        require(executor != address(0), "executor couldn't be Zero address");
        bEnable == true
            ? _grantRole(ROLE_OP_EXECUTOR, executor)
            : _revokeRole(ROLE_OP_EXECUTOR, executor);

        emit evAddrSetted(address(0), executor, TAG_EXECUTOR, bEnable);
    }

    // 4. Internal Data Views
    // 4.2 Minting Record for specific address
    function viewMintRecd(
        address acceptor
    ) external view returns (coinRecord memory) {
        return m_recdMint[acceptor];
    }

    // 4.3 Claim Record for specific address
    function viewClaimRecd(
        address acceptor
    ) external view returns (coinRecord memory) {
        return m_recdClaim[acceptor];
    }

    // 5. Pausable Funtions
    // 5.1 Pause the Contract
    function pause() public onlyRole(DEFAULT_ADMIN_ROLE) {
        _pause();
    }

    // 5.2 Unpause the Contract
    function unpause() public onlyRole(DEFAULT_ADMIN_ROLE) {
        _unpause();
    }

    // 5.2 Hook
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal override whenNotPaused {
        super._beforeTokenTransfer(from, to, amount);
    }
}

// File contracts/HNXCoin.sol
/// @custom:security-contact [email protected]

contract HNXCoin is BaseCoin {
    // 1. State Variables & Constructor
    constructor(
        string memory strTokenName,
        string memory strTokenAbbr
    ) BaseCoin(strTokenName, strTokenAbbr) {}

    // 3.2.1 claiming
    function claimHNX(
        uint256 nonce,
        uint256 amount,
        uint256 tag,
        bytes memory signature
    ) external {
        _claimCoin(nonce, amount, tag, this.claimHNX.selector, signature);
    }

    // 3.2.2 consuming
    function consumeHNX(uint256 amount) external {
        _consumeCoin(amount);
    }

    // 3.2.3 mingting
    function mintHNX(
        address acceptor,
        uint256 nonce,
        uint256 amount,
        uint256 tag,
        bytes memory signature
    ) external {
        _mintCoin(
            acceptor,
            nonce,
            amount,
            tag,
            this.mintHNX.selector,
            signature
        );
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"strTokenName","type":"string"},{"internalType":"string","name":"strTokenAbbr","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"old","type":"address"},{"indexed":true,"internalType":"address","name":"current","type":"address"},{"indexed":false,"internalType":"uint256","name":"tag","type":"uint256"},{"indexed":false,"internalType":"bool","name":"bEnable","type":"bool"}],"name":"evAddrSetted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tag","type":"uint256"}],"name":"evCoinClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"evCoinConsumed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tag","type":"uint256"}],"name":"evCoinMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"aryTime","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"aryAmount","type":"uint256[]"}],"name":"evCoinStake","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"tag","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"claimHNX","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"consumeHNX","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"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":"acceptor","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"tag","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"mintHNX","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"executor","type":"address"},{"internalType":"bool","name":"bEnable","type":"bool"}],"name":"setOpExecutorRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"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":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"acceptor","type":"address"}],"name":"viewClaimRecd","outputs":[{"components":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256[]","name":"amount","type":"uint256[]"},{"internalType":"uint256[]","name":"tag","type":"uint256[]"}],"internalType":"struct IBaseCoin.coinRecord","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"acceptor","type":"address"}],"name":"viewMintRecd","outputs":[{"components":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256[]","name":"amount","type":"uint256[]"},{"internalType":"uint256[]","name":"tag","type":"uint256[]"}],"internalType":"struct IBaseCoin.coinRecord","name":"","type":"tuple"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b5060405162004cb338038062004cb383398181016040528101906200003791906200050f565b81818181816003908051906020019062000053929190620002c2565b5080600490805190602001906200006c929190620002c2565b5050506000600560006101000a81548160ff0219169083151502179055506200009f6000801b336200015d60201b60201c565b620000d17f8dc3bffbc9ab2ce2601dfda7970ef84557839e84e1938e7efc03e3ed7b0d6e9f336200015d60201b60201c565b33600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555033600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050620005f9565b6200016f82826200024f60201b60201c565b6200024b5760016006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550620001f0620002ba60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b60006006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b828054620002d090620005c3565b90600052602060002090601f016020900481019282620002f4576000855562000340565b82601f106200030f57805160ff191683800117855562000340565b8280016001018555821562000340579182015b828111156200033f57825182559160200191906001019062000322565b5b5090506200034f919062000353565b5090565b5b808211156200036e57600081600090555060010162000354565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620003db8262000390565b810181811067ffffffffffffffff82111715620003fd57620003fc620003a1565b5b80604052505050565b60006200041262000372565b9050620004208282620003d0565b919050565b600067ffffffffffffffff821115620004435762000442620003a1565b5b6200044e8262000390565b9050602081019050919050565b60005b838110156200047b5780820151818401526020810190506200045e565b838111156200048b576000848401525b50505050565b6000620004a8620004a28462000425565b62000406565b905082815260208101848484011115620004c757620004c66200038b565b5b620004d48482856200045b565b509392505050565b600082601f830112620004f457620004f362000386565b5b81516200050684826020860162000491565b91505092915050565b600080604083850312156200052957620005286200037c565b5b600083015167ffffffffffffffff8111156200054a576200054962000381565b5b6200055885828601620004dc565b925050602083015167ffffffffffffffff8111156200057c576200057b62000381565b5b6200058a85828601620004dc565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620005dc57607f821691505b60208210811415620005f357620005f262000594565b5b50919050565b6146aa80620006096000396000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c80636c19e7831161010f578063a9059cbb116100a2578063dd62ed3e11610071578063dd62ed3e1461058e578063e1595f6d146105be578063ec22ab38146105ee578063f0f442601461060a576101e5565b8063a9059cbb1461050a578063b259b53f1461053a578063c6f6c85f14610556578063d547741f14610572576101e5565b806391d14854116100de57806391d148541461046e57806395d89b411461049e578063a217fddf146104bc578063a457c2d7146104da576101e5565b80636c19e783146103fc57806370a082311461041857806379cc6790146104485780638456cb5914610464576101e5565b80632f2ff15d116101875780633f4ba83a116101565780633f4ba83a1461039c57806342966c68146103a65780635c975abb146103c25780635f6a598d146103e0576101e5565b80632f2ff15d14610316578063313ce5671461033257806336568abe14610350578063395093511461036c576101e5565b806318160ddd116101c357806318160ddd14610268578063221933921461028657806323b872dd146102b6578063248a9ca3146102e6576101e5565b806301ffc9a7146101ea57806306fdde031461021a578063095ea7b314610238575b600080fd5b61020460048036038101906101ff9190612cc9565b610626565b6040516102119190612d11565b60405180910390f35b6102226106a0565b60405161022f9190612dc5565b60405180910390f35b610252600480360381019061024d9190612e7b565b610732565b60405161025f9190612d11565b60405180910390f35b610270610755565b60405161027d9190612eca565b60405180910390f35b6102a0600480360381019061029b9190612ee5565b61075f565b6040516102ad9190613027565b60405180910390f35b6102d060048036038101906102cb9190613049565b610872565b6040516102dd9190612d11565b60405180910390f35b61030060048036038101906102fb91906130d2565b6108a1565b60405161030d919061310e565b60405180910390f35b610330600480360381019061032b9190613129565b6108c1565b005b61033a6108e2565b6040516103479190613185565b60405180910390f35b61036a60048036038101906103659190613129565b6108eb565b005b61038660048036038101906103819190612e7b565b61096e565b6040516103939190612d11565b60405180910390f35b6103a46109a5565b005b6103c060048036038101906103bb91906131a0565b6109bd565b005b6103ca6109d1565b6040516103d79190612d11565b60405180910390f35b6103fa60048036038101906103f59190613302565b6109e8565b005b61041660048036038101906104119190612ee5565b610a02565b005b610432600480360381019061042d9190612ee5565b610c08565b60405161043f9190612eca565b60405180910390f35b610462600480360381019061045d9190612e7b565b610c50565b005b61046c610c70565b005b61048860048036038101906104839190613129565b610c88565b6040516104959190612d11565b60405180910390f35b6104a6610cf3565b6040516104b39190612dc5565b60405180910390f35b6104c4610d85565b6040516104d1919061310e565b60405180910390f35b6104f460048036038101906104ef9190612e7b565b610d8c565b6040516105019190612d11565b60405180910390f35b610524600480360381019061051f9190612e7b565b610e03565b6040516105319190612d11565b60405180910390f35b610554600480360381019061054f91906131a0565b610e26565b005b610570600480360381019061056b9190613385565b610e32565b005b61058c60048036038101906105879190613129565b610e4e565b005b6105a860048036038101906105a3919061341c565b610e6f565b6040516105b59190612eca565b60405180910390f35b6105d860048036038101906105d39190612ee5565b610ef6565b6040516105e59190613027565b60405180910390f35b61060860048036038101906106039190613488565b611009565b005b610624600480360381019061061f9190612ee5565b61115a565b005b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061069957506106988261135f565b5b9050919050565b6060600380546106af906134f7565b80601f01602080910402602001604051908101604052809291908181526020018280546106db906134f7565b80156107285780601f106106fd57610100808354040283529160200191610728565b820191906000526020600020905b81548152906001019060200180831161070b57829003601f168201915b5050505050905090565b60008061073d6113c9565b905061074a8185856113d1565b600191505092915050565b6000600254905090565b610767612c3c565b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806060016040529081600082015481526020016001820180548060200260200160405190810160405280929190818152602001828054801561080a57602002820191906000526020600020905b8154815260200190600101908083116107f6575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561086257602002820191906000526020600020905b81548152602001906001019080831161084e575b5050505050815250509050919050565b60008061087d6113c9565b905061088a85828561159c565b610895858585611628565b60019150509392505050565b600060066000838152602001908152602001600020600101549050919050565b6108ca826108a1565b6108d3816118a0565b6108dd83836118b4565b505050565b60006012905090565b6108f36113c9565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610960576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109579061359b565b60405180910390fd5b61096a8282611995565b5050565b6000806109796113c9565b905061099a81858561098b8589610e6f565b61099591906135ea565b6113d1565b600191505092915050565b6000801b6109b2816118a0565b6109ba611a77565b50565b6109ce6109c86113c9565b82611ada565b50565b6000600560009054906101000a900460ff16905090565b6109fc848484635f6a598d60e01b85611ca8565b50505050565b6000801b610a0f816118a0565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610a7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a769061368c565b60405180910390fd5b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610b10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b07906136f8565b60405180910390fd5b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f856682daf819c2dd305489298086e4f93ff2b82bcc19f6f5942008078d8288d160006001604051610bfb929190613718565b60405180910390a3505050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610c6282610c5c6113c9565b8361159c565b610c6c8282611ada565b5050565b6000801b610c7d816118a0565b610c85611f01565b50565b60006006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060048054610d02906134f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610d2e906134f7565b8015610d7b5780601f10610d5057610100808354040283529160200191610d7b565b820191906000526020600020905b815481529060010190602001808311610d5e57829003601f168201915b5050505050905090565b6000801b81565b600080610d976113c9565b90506000610da58286610e6f565b905083811015610dea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de1906137b3565b60405180910390fd5b610df782868684036113d1565b60019250505092915050565b600080610e0e6113c9565b9050610e1b818585611628565b600191505092915050565b610e2f81611f64565b50565b610e478585858563c6f6c85f60e01b866120aa565b5050505050565b610e57826108a1565b610e60816118a0565b610e6a8383611995565b505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b610efe612c3c565b600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060600160405290816000820154815260200160018201805480602002602001604051908101604052809291908181526020018280548015610fa157602002820191906000526020600020905b815481526020019060010190808311610f8d575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015610ff957602002820191906000526020600020905b815481526020019060010190808311610fe5575b5050505050815250509050919050565b6000801b611016816118a0565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611086576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107d90613845565b60405180910390fd5b60011515821515146110c1576110bc7f8dc3bffbc9ab2ce2601dfda7970ef84557839e84e1938e7efc03e3ed7b0d6e9f84611995565b6110ec565b6110eb7f8dc3bffbc9ab2ce2601dfda7970ef84557839e84e1938e7efc03e3ed7b0d6e9f846118b4565b5b8273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f856682daf819c2dd305489298086e4f93ff2b82bcc19f6f5942008078d8288d160028560405161114d929190613718565b60405180910390a3505050565b6000801b611167816118a0565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156111d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ce9061368c565b60405180910390fd5b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611268576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125f906136f8565b60405180910390fd5b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f856682daf819c2dd305489298086e4f93ff2b82bcc19f6f5942008078d8288d1600180604051611352929190613718565b60405180910390a3505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611441576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611438906138d7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156114b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a890613969565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258360405161158f9190612eca565b60405180910390a3505050565b60006115a88484610e6f565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146116225781811015611614576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161160b906139d5565b60405180910390fd5b61162184848484036113d1565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611698576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168f90613a67565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611708576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ff90613af9565b60405180910390fd5b61171383838361239f565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611799576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161179090613b8b565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516118879190612eca565b60405180910390a361189a8484846123b7565b50505050565b6118b1816118ac6113c9565b6123bc565b50565b6118be8282610c88565b6119915760016006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506119366113c9565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b61199f8282610c88565b15611a735760006006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611a186113c9565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b611a7f612441565b6000600560006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa611ac36113c9565b604051611ad09190613bba565b60405180910390a1565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611b4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4190613c47565b60405180910390fd5b611b568260008361239f565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611bdc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bd390613cd9565b60405180910390fd5b8181036000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600260008282540392505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611c8f9190612eca565b60405180910390a3611ca3836000846123b7565b505050565b600185611cb59190613cf9565b600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015414611d38576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d2f90613d79565b60405180910390fd5b611d4633868686868661248a565b611d85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7c90613de5565b60405180910390fd5b611d8f3385612533565b84600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101849080600181540180825580915050600190039060005260206000200160009091909190915055600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002018390806001815401808255809150506001900390600052602060002001600090919091909150553373ffffffffffffffffffffffffffffffffffffffff167fae67c1aea2c7e3a6f98ee6c7e9d54ed35520fb872d69e733e2e4e50fe1efbad2868686604051611ef293929190613e05565b60405180910390a25050505050565b611f0961268a565b6001600560006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611f4d6113c9565b604051611f5a9190613bba565b60405180910390a1565b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611ff6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fed90613e88565b60405180910390fd5b8061200033610c08565b1015612041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161203890613ef4565b60405180910390fd5b61206d600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682610e03565b507f2328a8bd2f323cab97debab732f548ffe9a5ae1edd618949df5408a34e5889e7338260405161209f929190613f14565b60405180910390a150565b7f8dc3bffbc9ab2ce2601dfda7970ef84557839e84e1938e7efc03e3ed7b0d6e9f6120d4816118a0565b600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161415612144576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213b90613f89565b60405180910390fd5b6001866121519190613cf9565b600860008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154146121d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121cb90613d79565b60405180910390fd5b6121e287878787878761248a565b612221576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161221890613de5565b60405180910390fd5b61222b8786612533565b85600860008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550600860008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101859080600181540180825580915050600190039060005260206000200160009091909190915055600860008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002018490806001815401808255809150506001900390600052602060002001600090919091909150558673ffffffffffffffffffffffffffffffffffffffff167f73e65bdcb5f50cf54b66ffd274d956456a3162963144d41bb9d1c8fdfdc95b6587878760405161238e93929190613e05565b60405180910390a250505050505050565b6123a761268a565b6123b28383836126d4565b505050565b505050565b6123c68282610c88565b61243d576123d3816126d9565b6123e18360001c6020612706565b6040516020016123f292919061407d565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124349190612dc5565b60405180910390fd5b5050565b6124496109d1565b612488576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247f90614103565b60405180910390fd5b565b6000806124c48587898b886040516020016124a99594939291906141ad565b60405160208183030381529060405280519060200120612942565b905060006124d28285612972565b9050600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614925050509695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156125a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161259a90614258565b60405180910390fd5b6125af6000838361239f565b80600260008282546125c191906135ea565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516126729190612eca565b60405180910390a3612686600083836123b7565b5050565b6126926109d1565b156126d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c9906142c4565b60405180910390fd5b565b505050565b60606126ff8273ffffffffffffffffffffffffffffffffffffffff16601460ff16612706565b9050919050565b60606000600283600261271991906142e4565b61272391906135ea565b67ffffffffffffffff81111561273c5761273b6131d7565b5b6040519080825280601f01601f19166020018201604052801561276e5781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106127a6576127a561433e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061280a5761280961433e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261284a91906142e4565b61285491906135ea565b90505b60018111156128f4577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106128965761289561433e565b5b1a60f81b8282815181106128ad576128ac61433e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806128ed9061436d565b9050612857565b5060008414612938576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161292f906143e3565b60405180910390fd5b8091505092915050565b6000816040516020016129559190614470565b604051602081830303815290604052805190602001209050919050565b60008060006129818585612999565b9150915061298e816129eb565b819250505092915050565b6000806041835114156129db5760008060006020860151925060408601519150606086015160001a90506129cf87828585612b59565b945094505050506129e4565b60006002915091505b9250929050565b600060048111156129ff576129fe614496565b5b816004811115612a1257612a11614496565b5b1415612a1d57612b56565b60016004811115612a3157612a30614496565b5b816004811115612a4457612a43614496565b5b1415612a85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a7c90614511565b60405180910390fd5b60026004811115612a9957612a98614496565b5b816004811115612aac57612aab614496565b5b1415612aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae49061457d565b60405180910390fd5b60036004811115612b0157612b00614496565b5b816004811115612b1457612b13614496565b5b1415612b55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b4c9061460f565b60405180910390fd5b5b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c1115612b94576000600391509150612c33565b600060018787878760405160008152602001604052604051612bb9949392919061462f565b6020604051602081039080840390855afa158015612bdb573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612c2a57600060019250925050612c33565b80600092509250505b94509492505050565b60405180606001604052806000815260200160608152602001606081525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612ca681612c71565b8114612cb157600080fd5b50565b600081359050612cc381612c9d565b92915050565b600060208284031215612cdf57612cde612c67565b5b6000612ced84828501612cb4565b91505092915050565b60008115159050919050565b612d0b81612cf6565b82525050565b6000602082019050612d266000830184612d02565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612d66578082015181840152602081019050612d4b565b83811115612d75576000848401525b50505050565b6000601f19601f8301169050919050565b6000612d9782612d2c565b612da18185612d37565b9350612db1818560208601612d48565b612dba81612d7b565b840191505092915050565b60006020820190508181036000830152612ddf8184612d8c565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612e1282612de7565b9050919050565b612e2281612e07565b8114612e2d57600080fd5b50565b600081359050612e3f81612e19565b92915050565b6000819050919050565b612e5881612e45565b8114612e6357600080fd5b50565b600081359050612e7581612e4f565b92915050565b60008060408385031215612e9257612e91612c67565b5b6000612ea085828601612e30565b9250506020612eb185828601612e66565b9150509250929050565b612ec481612e45565b82525050565b6000602082019050612edf6000830184612ebb565b92915050565b600060208284031215612efb57612efa612c67565b5b6000612f0984828501612e30565b91505092915050565b612f1b81612e45565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000612f598383612f12565b60208301905092915050565b6000602082019050919050565b6000612f7d82612f21565b612f878185612f2c565b9350612f9283612f3d565b8060005b83811015612fc3578151612faa8882612f4d565b9750612fb583612f65565b925050600181019050612f96565b5085935050505092915050565b6000606083016000830151612fe86000860182612f12565b50602083015184820360208601526130008282612f72565b9150506040830151848203604086015261301a8282612f72565b9150508091505092915050565b600060208201905081810360008301526130418184612fd0565b905092915050565b60008060006060848603121561306257613061612c67565b5b600061307086828701612e30565b935050602061308186828701612e30565b925050604061309286828701612e66565b9150509250925092565b6000819050919050565b6130af8161309c565b81146130ba57600080fd5b50565b6000813590506130cc816130a6565b92915050565b6000602082840312156130e8576130e7612c67565b5b60006130f6848285016130bd565b91505092915050565b6131088161309c565b82525050565b600060208201905061312360008301846130ff565b92915050565b600080604083850312156131405761313f612c67565b5b600061314e858286016130bd565b925050602061315f85828601612e30565b9150509250929050565b600060ff82169050919050565b61317f81613169565b82525050565b600060208201905061319a6000830184613176565b92915050565b6000602082840312156131b6576131b5612c67565b5b60006131c484828501612e66565b91505092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61320f82612d7b565b810181811067ffffffffffffffff8211171561322e5761322d6131d7565b5b80604052505050565b6000613241612c5d565b905061324d8282613206565b919050565b600067ffffffffffffffff82111561326d5761326c6131d7565b5b61327682612d7b565b9050602081019050919050565b82818337600083830152505050565b60006132a56132a084613252565b613237565b9050828152602081018484840111156132c1576132c06131d2565b5b6132cc848285613283565b509392505050565b600082601f8301126132e9576132e86131cd565b5b81356132f9848260208601613292565b91505092915050565b6000806000806080858703121561331c5761331b612c67565b5b600061332a87828801612e66565b945050602061333b87828801612e66565b935050604061334c87828801612e66565b925050606085013567ffffffffffffffff81111561336d5761336c612c6c565b5b613379878288016132d4565b91505092959194509250565b600080600080600060a086880312156133a1576133a0612c67565b5b60006133af88828901612e30565b95505060206133c088828901612e66565b94505060406133d188828901612e66565b93505060606133e288828901612e66565b925050608086013567ffffffffffffffff81111561340357613402612c6c565b5b61340f888289016132d4565b9150509295509295909350565b6000806040838503121561343357613432612c67565b5b600061344185828601612e30565b925050602061345285828601612e30565b9150509250929050565b61346581612cf6565b811461347057600080fd5b50565b6000813590506134828161345c565b92915050565b6000806040838503121561349f5761349e612c67565b5b60006134ad85828601612e30565b92505060206134be85828601613473565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061350f57607f821691505b60208210811415613523576135226134c8565b5b50919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b6000613585602f83612d37565b915061359082613529565b604082019050919050565b600060208201905081810360008301526135b481613578565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006135f582612e45565b915061360083612e45565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613635576136346135bb565b5b828201905092915050565b7f636f756c646e277420617369676e20746f205a65726f20616464726573730000600082015250565b6000613676601e83612d37565b915061368182613640565b602082019050919050565b600060208201905081810360008301526136a581613669565b9050919050565b7f6e65656420746f207573652061206e6577206164647265737300000000000000600082015250565b60006136e2601983612d37565b91506136ed826136ac565b602082019050919050565b60006020820190508181036000830152613711816136d5565b9050919050565b600060408201905061372d6000830185612ebb565b61373a6020830184612d02565b9392505050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b600061379d602583612d37565b91506137a882613741565b604082019050919050565b600060208201905081810360008301526137cc81613790565b9050919050565b7f6578656375746f7220636f756c646e2774206265205a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b600061382f602183612d37565b915061383a826137d3565b604082019050919050565b6000602082019050818103600083015261385e81613822565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006138c1602483612d37565b91506138cc82613865565b604082019050919050565b600060208201905081810360008301526138f0816138b4565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b6000613953602283612d37565b915061395e826138f7565b604082019050919050565b6000602082019050818103600083015261398281613946565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b60006139bf601d83612d37565b91506139ca82613989565b602082019050919050565b600060208201905081810360008301526139ee816139b2565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000613a51602583612d37565b9150613a5c826139f5565b604082019050919050565b60006020820190508181036000830152613a8081613a44565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b6000613ae3602383612d37565b9150613aee82613a87565b604082019050919050565b60006020820190508181036000830152613b1281613ad6565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b6000613b75602683612d37565b9150613b8082613b19565b604082019050919050565b60006020820190508181036000830152613ba481613b68565b9050919050565b613bb481612e07565b82525050565b6000602082019050613bcf6000830184613bab565b92915050565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b6000613c31602183612d37565b9150613c3c82613bd5565b604082019050919050565b60006020820190508181036000830152613c6081613c24565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b6000613cc3602283612d37565b9150613cce82613c67565b604082019050919050565b60006020820190508181036000830152613cf281613cb6565b9050919050565b6000613d0482612e45565b9150613d0f83612e45565b925082821015613d2257613d216135bb565b5b828203905092915050565b7f77726f6e67206e6f6e6365000000000000000000000000000000000000000000600082015250565b6000613d63600b83612d37565b9150613d6e82613d2d565b602082019050919050565b60006020820190508181036000830152613d9281613d56565b9050919050565b7f696e76616c6964207369676e6174757265000000000000000000000000000000600082015250565b6000613dcf601183612d37565b9150613dda82613d99565b602082019050919050565b60006020820190508181036000830152613dfe81613dc2565b9050919050565b6000606082019050613e1a6000830186612ebb565b613e276020830185612ebb565b613e346040830184612ebb565b949350505050565b7f696e636f6d652061646472657373206e6f742073657400000000000000000000600082015250565b6000613e72601683612d37565b9150613e7d82613e3c565b602082019050919050565b60006020820190508181036000830152613ea181613e65565b9050919050565b7f696e73756666696369656e742062616c616e6365000000000000000000000000600082015250565b6000613ede601483612d37565b9150613ee982613ea8565b602082019050919050565b60006020820190508181036000830152613f0d81613ed1565b9050919050565b6000604082019050613f296000830185613bab565b613f366020830184612ebb565b9392505050565b7f636f756c646e2774206265205a65726f20616464726573730000000000000000600082015250565b6000613f73601883612d37565b9150613f7e82613f3d565b602082019050919050565b60006020820190508181036000830152613fa281613f66565b9050919050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b6000613fea601783613fa9565b9150613ff582613fb4565b601782019050919050565b600061400b82612d2c565b6140158185613fa9565b9350614025818560208601612d48565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b6000614067601183613fa9565b915061407282614031565b601182019050919050565b600061408882613fdd565b91506140948285614000565b915061409f8261405a565b91506140ab8284614000565b91508190509392505050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b60006140ed601483612d37565b91506140f8826140b7565b602082019050919050565b6000602082019050818103600083015261411c816140e0565b9050919050565b6000819050919050565b61413e61413982612e45565b614123565b82525050565b60008160601b9050919050565b600061415c82614144565b9050919050565b600061416e82614151565b9050919050565b61418661418182612e07565b614163565b82525050565b6000819050919050565b6141a76141a282612c71565b61418c565b82525050565b60006141b9828861412d565b6020820191506141c9828761412d565b6020820191506141d9828661412d565b6020820191506141e98285614175565b6014820191506141f98284614196565b6004820191508190509695505050505050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000614242601f83612d37565b915061424d8261420c565b602082019050919050565b6000602082019050818103600083015261427181614235565b9050919050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b60006142ae601083612d37565b91506142b982614278565b602082019050919050565b600060208201905081810360008301526142dd816142a1565b9050919050565b60006142ef82612e45565b91506142fa83612e45565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614333576143326135bb565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061437882612e45565b9150600082141561438c5761438b6135bb565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006143cd602083612d37565b91506143d882614397565b602082019050919050565b600060208201905081810360008301526143fc816143c0565b9050919050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000614439601c83613fa9565b915061444482614403565b601c82019050919050565b6000819050919050565b61446a6144658261309c565b61444f565b82525050565b600061447b8261442c565b91506144878284614459565b60208201915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b60006144fb601883612d37565b9150614506826144c5565b602082019050919050565b6000602082019050818103600083015261452a816144ee565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000614567601f83612d37565b915061457282614531565b602082019050919050565b600060208201905081810360008301526145968161455a565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b60006145f9602283612d37565b91506146048261459d565b604082019050919050565b60006020820190508181036000830152614628816145ec565b9050919050565b600060808201905061464460008301876130ff565b6146516020830186613176565b61465e60408301856130ff565b61466b60608301846130ff565b9594505050505056fea2646970667358221220fdb39637c0c1b3ec9d721b78e9c92103efa0b8fc4c8422b64787c5a6442b47da64736f6c63430008090033000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000014486561727458205574696c69747920546f6b656e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000003484e580000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101e55760003560e01c80636c19e7831161010f578063a9059cbb116100a2578063dd62ed3e11610071578063dd62ed3e1461058e578063e1595f6d146105be578063ec22ab38146105ee578063f0f442601461060a576101e5565b8063a9059cbb1461050a578063b259b53f1461053a578063c6f6c85f14610556578063d547741f14610572576101e5565b806391d14854116100de57806391d148541461046e57806395d89b411461049e578063a217fddf146104bc578063a457c2d7146104da576101e5565b80636c19e783146103fc57806370a082311461041857806379cc6790146104485780638456cb5914610464576101e5565b80632f2ff15d116101875780633f4ba83a116101565780633f4ba83a1461039c57806342966c68146103a65780635c975abb146103c25780635f6a598d146103e0576101e5565b80632f2ff15d14610316578063313ce5671461033257806336568abe14610350578063395093511461036c576101e5565b806318160ddd116101c357806318160ddd14610268578063221933921461028657806323b872dd146102b6578063248a9ca3146102e6576101e5565b806301ffc9a7146101ea57806306fdde031461021a578063095ea7b314610238575b600080fd5b61020460048036038101906101ff9190612cc9565b610626565b6040516102119190612d11565b60405180910390f35b6102226106a0565b60405161022f9190612dc5565b60405180910390f35b610252600480360381019061024d9190612e7b565b610732565b60405161025f9190612d11565b60405180910390f35b610270610755565b60405161027d9190612eca565b60405180910390f35b6102a0600480360381019061029b9190612ee5565b61075f565b6040516102ad9190613027565b60405180910390f35b6102d060048036038101906102cb9190613049565b610872565b6040516102dd9190612d11565b60405180910390f35b61030060048036038101906102fb91906130d2565b6108a1565b60405161030d919061310e565b60405180910390f35b610330600480360381019061032b9190613129565b6108c1565b005b61033a6108e2565b6040516103479190613185565b60405180910390f35b61036a60048036038101906103659190613129565b6108eb565b005b61038660048036038101906103819190612e7b565b61096e565b6040516103939190612d11565b60405180910390f35b6103a46109a5565b005b6103c060048036038101906103bb91906131a0565b6109bd565b005b6103ca6109d1565b6040516103d79190612d11565b60405180910390f35b6103fa60048036038101906103f59190613302565b6109e8565b005b61041660048036038101906104119190612ee5565b610a02565b005b610432600480360381019061042d9190612ee5565b610c08565b60405161043f9190612eca565b60405180910390f35b610462600480360381019061045d9190612e7b565b610c50565b005b61046c610c70565b005b61048860048036038101906104839190613129565b610c88565b6040516104959190612d11565b60405180910390f35b6104a6610cf3565b6040516104b39190612dc5565b60405180910390f35b6104c4610d85565b6040516104d1919061310e565b60405180910390f35b6104f460048036038101906104ef9190612e7b565b610d8c565b6040516105019190612d11565b60405180910390f35b610524600480360381019061051f9190612e7b565b610e03565b6040516105319190612d11565b60405180910390f35b610554600480360381019061054f91906131a0565b610e26565b005b610570600480360381019061056b9190613385565b610e32565b005b61058c60048036038101906105879190613129565b610e4e565b005b6105a860048036038101906105a3919061341c565b610e6f565b6040516105b59190612eca565b60405180910390f35b6105d860048036038101906105d39190612ee5565b610ef6565b6040516105e59190613027565b60405180910390f35b61060860048036038101906106039190613488565b611009565b005b610624600480360381019061061f9190612ee5565b61115a565b005b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061069957506106988261135f565b5b9050919050565b6060600380546106af906134f7565b80601f01602080910402602001604051908101604052809291908181526020018280546106db906134f7565b80156107285780601f106106fd57610100808354040283529160200191610728565b820191906000526020600020905b81548152906001019060200180831161070b57829003601f168201915b5050505050905090565b60008061073d6113c9565b905061074a8185856113d1565b600191505092915050565b6000600254905090565b610767612c3c565b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051806060016040529081600082015481526020016001820180548060200260200160405190810160405280929190818152602001828054801561080a57602002820191906000526020600020905b8154815260200190600101908083116107f6575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561086257602002820191906000526020600020905b81548152602001906001019080831161084e575b5050505050815250509050919050565b60008061087d6113c9565b905061088a85828561159c565b610895858585611628565b60019150509392505050565b600060066000838152602001908152602001600020600101549050919050565b6108ca826108a1565b6108d3816118a0565b6108dd83836118b4565b505050565b60006012905090565b6108f36113c9565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610960576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109579061359b565b60405180910390fd5b61096a8282611995565b5050565b6000806109796113c9565b905061099a81858561098b8589610e6f565b61099591906135ea565b6113d1565b600191505092915050565b6000801b6109b2816118a0565b6109ba611a77565b50565b6109ce6109c86113c9565b82611ada565b50565b6000600560009054906101000a900460ff16905090565b6109fc848484635f6a598d60e01b85611ca8565b50505050565b6000801b610a0f816118a0565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610a7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a769061368c565b60405180910390fd5b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610b10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b07906136f8565b60405180910390fd5b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f856682daf819c2dd305489298086e4f93ff2b82bcc19f6f5942008078d8288d160006001604051610bfb929190613718565b60405180910390a3505050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610c6282610c5c6113c9565b8361159c565b610c6c8282611ada565b5050565b6000801b610c7d816118a0565b610c85611f01565b50565b60006006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060048054610d02906134f7565b80601f0160208091040260200160405190810160405280929190818152602001828054610d2e906134f7565b8015610d7b5780601f10610d5057610100808354040283529160200191610d7b565b820191906000526020600020905b815481529060010190602001808311610d5e57829003601f168201915b5050505050905090565b6000801b81565b600080610d976113c9565b90506000610da58286610e6f565b905083811015610dea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de1906137b3565b60405180910390fd5b610df782868684036113d1565b60019250505092915050565b600080610e0e6113c9565b9050610e1b818585611628565b600191505092915050565b610e2f81611f64565b50565b610e478585858563c6f6c85f60e01b866120aa565b5050505050565b610e57826108a1565b610e60816118a0565b610e6a8383611995565b505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b610efe612c3c565b600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060600160405290816000820154815260200160018201805480602002602001604051908101604052809291908181526020018280548015610fa157602002820191906000526020600020905b815481526020019060010190808311610f8d575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015610ff957602002820191906000526020600020905b815481526020019060010190808311610fe5575b5050505050815250509050919050565b6000801b611016816118a0565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611086576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107d90613845565b60405180910390fd5b60011515821515146110c1576110bc7f8dc3bffbc9ab2ce2601dfda7970ef84557839e84e1938e7efc03e3ed7b0d6e9f84611995565b6110ec565b6110eb7f8dc3bffbc9ab2ce2601dfda7970ef84557839e84e1938e7efc03e3ed7b0d6e9f846118b4565b5b8273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f856682daf819c2dd305489298086e4f93ff2b82bcc19f6f5942008078d8288d160028560405161114d929190613718565b60405180910390a3505050565b6000801b611167816118a0565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156111d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ce9061368c565b60405180910390fd5b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611268576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125f906136f8565b60405180910390fd5b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f856682daf819c2dd305489298086e4f93ff2b82bcc19f6f5942008078d8288d1600180604051611352929190613718565b60405180910390a3505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611441576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611438906138d7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156114b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a890613969565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258360405161158f9190612eca565b60405180910390a3505050565b60006115a88484610e6f565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146116225781811015611614576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161160b906139d5565b60405180910390fd5b61162184848484036113d1565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611698576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168f90613a67565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611708576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ff90613af9565b60405180910390fd5b61171383838361239f565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611799576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161179090613b8b565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516118879190612eca565b60405180910390a361189a8484846123b7565b50505050565b6118b1816118ac6113c9565b6123bc565b50565b6118be8282610c88565b6119915760016006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506119366113c9565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b61199f8282610c88565b15611a735760006006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611a186113c9565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b611a7f612441565b6000600560006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa611ac36113c9565b604051611ad09190613bba565b60405180910390a1565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611b4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4190613c47565b60405180910390fd5b611b568260008361239f565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611bdc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bd390613cd9565b60405180910390fd5b8181036000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600260008282540392505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611c8f9190612eca565b60405180910390a3611ca3836000846123b7565b505050565b600185611cb59190613cf9565b600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015414611d38576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d2f90613d79565b60405180910390fd5b611d4633868686868661248a565b611d85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7c90613de5565b60405180910390fd5b611d8f3385612533565b84600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101849080600181540180825580915050600190039060005260206000200160009091909190915055600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002018390806001815401808255809150506001900390600052602060002001600090919091909150553373ffffffffffffffffffffffffffffffffffffffff167fae67c1aea2c7e3a6f98ee6c7e9d54ed35520fb872d69e733e2e4e50fe1efbad2868686604051611ef293929190613e05565b60405180910390a25050505050565b611f0961268a565b6001600560006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611f4d6113c9565b604051611f5a9190613bba565b60405180910390a1565b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611ff6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fed90613e88565b60405180910390fd5b8061200033610c08565b1015612041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161203890613ef4565b60405180910390fd5b61206d600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682610e03565b507f2328a8bd2f323cab97debab732f548ffe9a5ae1edd618949df5408a34e5889e7338260405161209f929190613f14565b60405180910390a150565b7f8dc3bffbc9ab2ce2601dfda7970ef84557839e84e1938e7efc03e3ed7b0d6e9f6120d4816118a0565b600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161415612144576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213b90613f89565b60405180910390fd5b6001866121519190613cf9565b600860008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154146121d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121cb90613d79565b60405180910390fd5b6121e287878787878761248a565b612221576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161221890613de5565b60405180910390fd5b61222b8786612533565b85600860008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550600860008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101859080600181540180825580915050600190039060005260206000200160009091909190915055600860008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002018490806001815401808255809150506001900390600052602060002001600090919091909150558673ffffffffffffffffffffffffffffffffffffffff167f73e65bdcb5f50cf54b66ffd274d956456a3162963144d41bb9d1c8fdfdc95b6587878760405161238e93929190613e05565b60405180910390a250505050505050565b6123a761268a565b6123b28383836126d4565b505050565b505050565b6123c68282610c88565b61243d576123d3816126d9565b6123e18360001c6020612706565b6040516020016123f292919061407d565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124349190612dc5565b60405180910390fd5b5050565b6124496109d1565b612488576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247f90614103565b60405180910390fd5b565b6000806124c48587898b886040516020016124a99594939291906141ad565b60405160208183030381529060405280519060200120612942565b905060006124d28285612972565b9050600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614925050509695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156125a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161259a90614258565b60405180910390fd5b6125af6000838361239f565b80600260008282546125c191906135ea565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516126729190612eca565b60405180910390a3612686600083836123b7565b5050565b6126926109d1565b156126d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c9906142c4565b60405180910390fd5b565b505050565b60606126ff8273ffffffffffffffffffffffffffffffffffffffff16601460ff16612706565b9050919050565b60606000600283600261271991906142e4565b61272391906135ea565b67ffffffffffffffff81111561273c5761273b6131d7565b5b6040519080825280601f01601f19166020018201604052801561276e5781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106127a6576127a561433e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061280a5761280961433e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261284a91906142e4565b61285491906135ea565b90505b60018111156128f4577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106128965761289561433e565b5b1a60f81b8282815181106128ad576128ac61433e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806128ed9061436d565b9050612857565b5060008414612938576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161292f906143e3565b60405180910390fd5b8091505092915050565b6000816040516020016129559190614470565b604051602081830303815290604052805190602001209050919050565b60008060006129818585612999565b9150915061298e816129eb565b819250505092915050565b6000806041835114156129db5760008060006020860151925060408601519150606086015160001a90506129cf87828585612b59565b945094505050506129e4565b60006002915091505b9250929050565b600060048111156129ff576129fe614496565b5b816004811115612a1257612a11614496565b5b1415612a1d57612b56565b60016004811115612a3157612a30614496565b5b816004811115612a4457612a43614496565b5b1415612a85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a7c90614511565b60405180910390fd5b60026004811115612a9957612a98614496565b5b816004811115612aac57612aab614496565b5b1415612aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae49061457d565b60405180910390fd5b60036004811115612b0157612b00614496565b5b816004811115612b1457612b13614496565b5b1415612b55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b4c9061460f565b60405180910390fd5b5b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c1115612b94576000600391509150612c33565b600060018787878760405160008152602001604052604051612bb9949392919061462f565b6020604051602081039080840390855afa158015612bdb573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612c2a57600060019250925050612c33565b80600092509250505b94509492505050565b60405180606001604052806000815260200160608152602001606081525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612ca681612c71565b8114612cb157600080fd5b50565b600081359050612cc381612c9d565b92915050565b600060208284031215612cdf57612cde612c67565b5b6000612ced84828501612cb4565b91505092915050565b60008115159050919050565b612d0b81612cf6565b82525050565b6000602082019050612d266000830184612d02565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612d66578082015181840152602081019050612d4b565b83811115612d75576000848401525b50505050565b6000601f19601f8301169050919050565b6000612d9782612d2c565b612da18185612d37565b9350612db1818560208601612d48565b612dba81612d7b565b840191505092915050565b60006020820190508181036000830152612ddf8184612d8c565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612e1282612de7565b9050919050565b612e2281612e07565b8114612e2d57600080fd5b50565b600081359050612e3f81612e19565b92915050565b6000819050919050565b612e5881612e45565b8114612e6357600080fd5b50565b600081359050612e7581612e4f565b92915050565b60008060408385031215612e9257612e91612c67565b5b6000612ea085828601612e30565b9250506020612eb185828601612e66565b9150509250929050565b612ec481612e45565b82525050565b6000602082019050612edf6000830184612ebb565b92915050565b600060208284031215612efb57612efa612c67565b5b6000612f0984828501612e30565b91505092915050565b612f1b81612e45565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000612f598383612f12565b60208301905092915050565b6000602082019050919050565b6000612f7d82612f21565b612f878185612f2c565b9350612f9283612f3d565b8060005b83811015612fc3578151612faa8882612f4d565b9750612fb583612f65565b925050600181019050612f96565b5085935050505092915050565b6000606083016000830151612fe86000860182612f12565b50602083015184820360208601526130008282612f72565b9150506040830151848203604086015261301a8282612f72565b9150508091505092915050565b600060208201905081810360008301526130418184612fd0565b905092915050565b60008060006060848603121561306257613061612c67565b5b600061307086828701612e30565b935050602061308186828701612e30565b925050604061309286828701612e66565b9150509250925092565b6000819050919050565b6130af8161309c565b81146130ba57600080fd5b50565b6000813590506130cc816130a6565b92915050565b6000602082840312156130e8576130e7612c67565b5b60006130f6848285016130bd565b91505092915050565b6131088161309c565b82525050565b600060208201905061312360008301846130ff565b92915050565b600080604083850312156131405761313f612c67565b5b600061314e858286016130bd565b925050602061315f85828601612e30565b9150509250929050565b600060ff82169050919050565b61317f81613169565b82525050565b600060208201905061319a6000830184613176565b92915050565b6000602082840312156131b6576131b5612c67565b5b60006131c484828501612e66565b91505092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61320f82612d7b565b810181811067ffffffffffffffff8211171561322e5761322d6131d7565b5b80604052505050565b6000613241612c5d565b905061324d8282613206565b919050565b600067ffffffffffffffff82111561326d5761326c6131d7565b5b61327682612d7b565b9050602081019050919050565b82818337600083830152505050565b60006132a56132a084613252565b613237565b9050828152602081018484840111156132c1576132c06131d2565b5b6132cc848285613283565b509392505050565b600082601f8301126132e9576132e86131cd565b5b81356132f9848260208601613292565b91505092915050565b6000806000806080858703121561331c5761331b612c67565b5b600061332a87828801612e66565b945050602061333b87828801612e66565b935050604061334c87828801612e66565b925050606085013567ffffffffffffffff81111561336d5761336c612c6c565b5b613379878288016132d4565b91505092959194509250565b600080600080600060a086880312156133a1576133a0612c67565b5b60006133af88828901612e30565b95505060206133c088828901612e66565b94505060406133d188828901612e66565b93505060606133e288828901612e66565b925050608086013567ffffffffffffffff81111561340357613402612c6c565b5b61340f888289016132d4565b9150509295509295909350565b6000806040838503121561343357613432612c67565b5b600061344185828601612e30565b925050602061345285828601612e30565b9150509250929050565b61346581612cf6565b811461347057600080fd5b50565b6000813590506134828161345c565b92915050565b6000806040838503121561349f5761349e612c67565b5b60006134ad85828601612e30565b92505060206134be85828601613473565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061350f57607f821691505b60208210811415613523576135226134c8565b5b50919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b6000613585602f83612d37565b915061359082613529565b604082019050919050565b600060208201905081810360008301526135b481613578565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006135f582612e45565b915061360083612e45565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613635576136346135bb565b5b828201905092915050565b7f636f756c646e277420617369676e20746f205a65726f20616464726573730000600082015250565b6000613676601e83612d37565b915061368182613640565b602082019050919050565b600060208201905081810360008301526136a581613669565b9050919050565b7f6e65656420746f207573652061206e6577206164647265737300000000000000600082015250565b60006136e2601983612d37565b91506136ed826136ac565b602082019050919050565b60006020820190508181036000830152613711816136d5565b9050919050565b600060408201905061372d6000830185612ebb565b61373a6020830184612d02565b9392505050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b600061379d602583612d37565b91506137a882613741565b604082019050919050565b600060208201905081810360008301526137cc81613790565b9050919050565b7f6578656375746f7220636f756c646e2774206265205a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b600061382f602183612d37565b915061383a826137d3565b604082019050919050565b6000602082019050818103600083015261385e81613822565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006138c1602483612d37565b91506138cc82613865565b604082019050919050565b600060208201905081810360008301526138f0816138b4565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b6000613953602283612d37565b915061395e826138f7565b604082019050919050565b6000602082019050818103600083015261398281613946565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b60006139bf601d83612d37565b91506139ca82613989565b602082019050919050565b600060208201905081810360008301526139ee816139b2565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000613a51602583612d37565b9150613a5c826139f5565b604082019050919050565b60006020820190508181036000830152613a8081613a44565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b6000613ae3602383612d37565b9150613aee82613a87565b604082019050919050565b60006020820190508181036000830152613b1281613ad6565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b6000613b75602683612d37565b9150613b8082613b19565b604082019050919050565b60006020820190508181036000830152613ba481613b68565b9050919050565b613bb481612e07565b82525050565b6000602082019050613bcf6000830184613bab565b92915050565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b6000613c31602183612d37565b9150613c3c82613bd5565b604082019050919050565b60006020820190508181036000830152613c6081613c24565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b6000613cc3602283612d37565b9150613cce82613c67565b604082019050919050565b60006020820190508181036000830152613cf281613cb6565b9050919050565b6000613d0482612e45565b9150613d0f83612e45565b925082821015613d2257613d216135bb565b5b828203905092915050565b7f77726f6e67206e6f6e6365000000000000000000000000000000000000000000600082015250565b6000613d63600b83612d37565b9150613d6e82613d2d565b602082019050919050565b60006020820190508181036000830152613d9281613d56565b9050919050565b7f696e76616c6964207369676e6174757265000000000000000000000000000000600082015250565b6000613dcf601183612d37565b9150613dda82613d99565b602082019050919050565b60006020820190508181036000830152613dfe81613dc2565b9050919050565b6000606082019050613e1a6000830186612ebb565b613e276020830185612ebb565b613e346040830184612ebb565b949350505050565b7f696e636f6d652061646472657373206e6f742073657400000000000000000000600082015250565b6000613e72601683612d37565b9150613e7d82613e3c565b602082019050919050565b60006020820190508181036000830152613ea181613e65565b9050919050565b7f696e73756666696369656e742062616c616e6365000000000000000000000000600082015250565b6000613ede601483612d37565b9150613ee982613ea8565b602082019050919050565b60006020820190508181036000830152613f0d81613ed1565b9050919050565b6000604082019050613f296000830185613bab565b613f366020830184612ebb565b9392505050565b7f636f756c646e2774206265205a65726f20616464726573730000000000000000600082015250565b6000613f73601883612d37565b9150613f7e82613f3d565b602082019050919050565b60006020820190508181036000830152613fa281613f66565b9050919050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b6000613fea601783613fa9565b9150613ff582613fb4565b601782019050919050565b600061400b82612d2c565b6140158185613fa9565b9350614025818560208601612d48565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b6000614067601183613fa9565b915061407282614031565b601182019050919050565b600061408882613fdd565b91506140948285614000565b915061409f8261405a565b91506140ab8284614000565b91508190509392505050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b60006140ed601483612d37565b91506140f8826140b7565b602082019050919050565b6000602082019050818103600083015261411c816140e0565b9050919050565b6000819050919050565b61413e61413982612e45565b614123565b82525050565b60008160601b9050919050565b600061415c82614144565b9050919050565b600061416e82614151565b9050919050565b61418661418182612e07565b614163565b82525050565b6000819050919050565b6141a76141a282612c71565b61418c565b82525050565b60006141b9828861412d565b6020820191506141c9828761412d565b6020820191506141d9828661412d565b6020820191506141e98285614175565b6014820191506141f98284614196565b6004820191508190509695505050505050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000614242601f83612d37565b915061424d8261420c565b602082019050919050565b6000602082019050818103600083015261427181614235565b9050919050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b60006142ae601083612d37565b91506142b982614278565b602082019050919050565b600060208201905081810360008301526142dd816142a1565b9050919050565b60006142ef82612e45565b91506142fa83612e45565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614333576143326135bb565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061437882612e45565b9150600082141561438c5761438b6135bb565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006143cd602083612d37565b91506143d882614397565b602082019050919050565b600060208201905081810360008301526143fc816143c0565b9050919050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000614439601c83613fa9565b915061444482614403565b601c82019050919050565b6000819050919050565b61446a6144658261309c565b61444f565b82525050565b600061447b8261442c565b91506144878284614459565b60208201915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b60006144fb601883612d37565b9150614506826144c5565b602082019050919050565b6000602082019050818103600083015261452a816144ee565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000614567601f83612d37565b915061457282614531565b602082019050919050565b600060208201905081810360008301526145968161455a565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b60006145f9602283612d37565b91506146048261459d565b604082019050919050565b60006020820190508181036000830152614628816145ec565b9050919050565b600060808201905061464460008301876130ff565b6146516020830186613176565b61465e60408301856130ff565b61466b60608301846130ff565b9594505050505056fea2646970667358221220fdb39637c0c1b3ec9d721b78e9c92103efa0b8fc4c8422b64787c5a6442b47da64736f6c63430008090033

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

000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000014486561727458205574696c69747920546f6b656e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000003484e580000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : strTokenName (string): HeartX Utility Token
Arg [1] : strTokenAbbr (string): HNX

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [3] : 486561727458205574696c69747920546f6b656e000000000000000000000000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [5] : 484e580000000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

68301:957:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23227:246;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36878:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39295:226;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37998:108;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67368:144;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40101:295;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25117:147;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25574:172;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;37840:93;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26768:280;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;40805:263;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67901:84;;;:::i;:::-;;48709:91;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;30600:86;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68541:222;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;66030:364;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;38169:143;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49119:164;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67780:80;;;:::i;:::-;;23565:172;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37097:104;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22628:49;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41571:498;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38518:218;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68795:84;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68910:345;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;26039:174;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;38799:176;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67566:146;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66862:419;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;66429:398;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;23227:246;23328:4;23380:32;23365:47;;;:11;:47;;;;:100;;;;23429:36;23453:11;23429:23;:36::i;:::-;23365:100;23345:120;;23227:246;;;:::o;36878:100::-;36932:13;36965:5;36958:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36878:100;:::o;39295:226::-;39403:4;39420:13;39436:12;:10;:12::i;:::-;39420:28;;39459:32;39468:5;39475:7;39484:6;39459:8;:32::i;:::-;39509:4;39502:11;;;39295:226;;;;:::o;37998:108::-;38059:7;38086:12;;38079:19;;37998:108;:::o;67368:144::-;67447:17;;:::i;:::-;67484:10;:20;67495:8;67484:20;;;;;;;;;;;;;;;67477:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67368:144;;;:::o;40101:295::-;40232:4;40249:15;40267:12;:10;:12::i;:::-;40249:30;;40290:38;40306:4;40312:7;40321:6;40290:15;:38::i;:::-;40339:27;40349:4;40355:2;40359:6;40339:9;:27::i;:::-;40384:4;40377:11;;;40101:295;;;;;:::o;25117:147::-;25207:7;25234:6;:12;25241:4;25234:12;;;;;;;;;;;:22;;;25227:29;;25117:147;;;:::o;25574:172::-;25682:18;25695:4;25682:12;:18::i;:::-;23119:16;23130:4;23119:10;:16::i;:::-;25713:25:::1;25724:4;25730:7;25713:10;:25::i;:::-;25574:172:::0;;;:::o;37840:93::-;37898:5;37923:2;37916:9;;37840:93;:::o;26768:280::-;26914:12;:10;:12::i;:::-;26903:23;;:7;:23;;;26881:120;;;;;;;;;;;;:::i;:::-;;;;;;;;;27014:26;27026:4;27032:7;27014:11;:26::i;:::-;26768:280;;:::o;40805:263::-;40918:4;40935:13;40951:12;:10;:12::i;:::-;40935:28;;40974:64;40983:5;40990:7;41027:10;40999:25;41009:5;41016:7;40999:9;:25::i;:::-;:38;;;;:::i;:::-;40974:8;:64::i;:::-;41056:4;41049:11;;;40805:263;;;;:::o;67901:84::-;22673:4;67936:18;;23119:16;23130:4;23119:10;:16::i;:::-;67967:10:::1;:8;:10::i;:::-;67901:84:::0;:::o;48709:91::-;48765:27;48771:12;:10;:12::i;:::-;48785:6;48765:5;:27::i;:::-;48709:91;:::o;30600:86::-;30647:4;30671:7;;;;;;;;;;;30664:14;;30600:86;:::o;68541:222::-;68690:65;68701:5;68708:6;68716:3;68721:22;;;68745:9;68690:10;:65::i;:::-;68541:222;;;;:::o;66030:364::-;22673:4;66083:18;;23119:16;23130:4;23119:10;:16::i;:::-;66140:1:::1;66122:20;;:6;:20;;;;66114:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;66206:10;;;;;;;;;;;66196:20;;:6;:20;;;;66188:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;66259:15;66277:10;;;;;;;;;;;66259:28;;66311:6;66298:10;;:19;;;;;;;;;;;;;;;;;;66357:10;;;;;;;;;;;66335:51;;66348:7;66335:51;;;60664:1;66381:4;66335:51;;;;;;;:::i;:::-;;;;;;;;66103:291;66030:364:::0;;:::o;38169:143::-;38259:7;38286:9;:18;38296:7;38286:18;;;;;;;;;;;;;;;;38279:25;;38169:143;;;:::o;49119:164::-;49196:46;49212:7;49221:12;:10;:12::i;:::-;49235:6;49196:15;:46::i;:::-;49253:22;49259:7;49268:6;49253:5;:22::i;:::-;49119:164;;:::o;67780:80::-;22673:4;67813:18;;23119:16;23130:4;23119:10;:16::i;:::-;67844:8:::1;:6;:8::i;:::-;67780:80:::0;:::o;23565:172::-;23676:4;23700:6;:12;23707:4;23700:12;;;;;;;;;;;:20;;:29;23721:7;23700:29;;;;;;;;;;;;;;;;;;;;;;;;;23693:36;;23565:172;;;;:::o;37097:104::-;37153:13;37186:7;37179:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37097:104;:::o;22628:49::-;22673:4;22628:49;;;:::o;41571:498::-;41689:4;41706:13;41722:12;:10;:12::i;:::-;41706:28;;41745:24;41772:25;41782:5;41789:7;41772:9;:25::i;:::-;41745:52;;41850:15;41830:16;:35;;41808:122;;;;;;;;;;;;:::i;:::-;;;;;;;;;41966:60;41975:5;41982:7;42010:15;41991:16;:34;41966:8;:60::i;:::-;42057:4;42050:11;;;;41571:498;;;;:::o;38518:218::-;38622:4;38639:13;38655:12;:10;:12::i;:::-;38639:28;;38678;38688:5;38695:2;38699:6;38678:9;:28::i;:::-;38724:4;38717:11;;;38518:218;;;;:::o;68795:84::-;68851:20;68864:6;68851:12;:20::i;:::-;68795:84;:::o;68910:345::-;69085:162;69109:8;69132:5;69152:6;69173:3;69191:21;;;69227:9;69085;:162::i;:::-;68910:345;;;;;:::o;26039:174::-;26148:18;26161:4;26148:12;:18::i;:::-;23119:16;23130:4;23119:10;:16::i;:::-;26179:26:::1;26191:4;26197:7;26179:11;:26::i;:::-;26039:174:::0;;;:::o;38799:176::-;38913:7;38940:11;:18;38952:5;38940:18;;;;;;;;;;;;;;;:27;38959:7;38940:27;;;;;;;;;;;;;;;;38933:34;;38799:176;;;;:::o;67566:146::-;67646:17;;:::i;:::-;67683:11;:21;67695:8;67683:21;;;;;;;;;;;;;;;67676:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67566:146;;;:::o;66862:419::-;22673:4;66964:18;;23119:16;23130:4;23119:10;:16::i;:::-;67023:1:::1;67003:22;;:8;:22;;;;66995:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;67085:4;67074:15;;:7;:15;;;:124;;67159:39;60585:31;67189:8;67159:11;:39::i;:::-;67074:124;;;67105:38;60585:31;67134:8;67105:10;:38::i;:::-;67074:124;67241:8;67216:57;;67237:1;67216:57;;;60762:1;67265:7;67216:57;;;;;;;:::i;:::-;;;;;;;;66862:419:::0;;;:::o;66429:398::-;22673:4;66502:18;;23119:16;23130:4;23119:10;:16::i;:::-;66561:1:::1;66541:22;;:8;:22;;;;66533:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;66629:12;;;;;;;;;;;66617:24;;:8;:24;;;;66609:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;66684:15;66702:12;;;;;;;;;;;66684:30;;66740:8;66725:12;;:23;;;;;;;;;;;;;;;;;;66786:12;;;;;;;;;;;66764:55;;66777:7;66764:55;;;60713:1;66814:4:::0;66764:55:::1;;;;;;;:::i;:::-;;;;;;;;66522:305;66429:398:::0;;:::o;5472:173::-;5573:4;5612:25;5597:40;;;:11;:40;;;;5590:47;;5472:173;;;:::o;3810:98::-;3863:7;3890:10;3883:17;;3810:98;:::o;45697:380::-;45850:1;45833:19;;:5;:19;;;;45825:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;45931:1;45912:21;;:7;:21;;;;45904:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;46015:6;45985:11;:18;45997:5;45985:18;;;;;;;;;;;;;;;:27;46004:7;45985:27;;;;;;;;;;;;;;;:36;;;;46053:7;46037:32;;46046:5;46037:32;;;46062:6;46037:32;;;;;;:::i;:::-;;;;;;;;45697:380;;;:::o;46368:502::-;46503:24;46530:25;46540:5;46547:7;46530:9;:25::i;:::-;46503:52;;46590:17;46570:16;:37;46566:297;;46670:6;46650:16;:26;;46624:117;;;;;;;;;;;;:::i;:::-;;;;;;;;;46785:51;46794:5;46801:7;46829:6;46810:16;:25;46785:8;:51::i;:::-;46566:297;46492:378;46368:502;;;:::o;42539:877::-;42686:1;42670:18;;:4;:18;;;;42662:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;42763:1;42749:16;;:2;:16;;;;42741:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;42818:38;42839:4;42845:2;42849:6;42818:20;:38::i;:::-;42869:19;42891:9;:15;42901:4;42891:15;;;;;;;;;;;;;;;;42869:37;;42954:6;42939:11;:21;;42917:109;;;;;;;;;;;;:::i;:::-;;;;;;;;;43094:6;43080:11;:20;43062:9;:15;43072:4;43062:15;;;;;;;;;;;;;;;:38;;;;43297:6;43280:9;:13;43290:2;43280:13;;;;;;;;;;;;;;;;:23;;;;;;;;;;;43347:2;43332:26;;43341:4;43332:26;;;43351:6;43332:26;;;;;;:::i;:::-;;;;;;;;43371:37;43391:4;43397:2;43401:6;43371:19;:37::i;:::-;42651:765;42539:877;;;:::o;24041:105::-;24108:30;24119:4;24125:12;:10;:12::i;:::-;24108:10;:30::i;:::-;24041:105;:::o;28427:238::-;28511:22;28519:4;28525:7;28511;:22::i;:::-;28506:152;;28582:4;28550:6;:12;28557:4;28550:12;;;;;;;;;;;:20;;:29;28571:7;28550:29;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;28633:12;:10;:12::i;:::-;28606:40;;28624:7;28606:40;;28618:4;28606:40;;;;;;;;;;28506:152;28427:238;;:::o;28845:239::-;28929:22;28937:4;28943:7;28929;:22::i;:::-;28925:152;;;29000:5;28968:6;:12;28975:4;28968:12;;;;;;;;;;;:20;;:29;28989:7;28968:29;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;29052:12;:10;:12::i;:::-;29025:40;;29043:7;29025:40;;29037:4;29025:40;;;;;;;;;;28925:152;28845:239;;:::o;31455:120::-;30464:16;:14;:16::i;:::-;31524:5:::1;31514:7;;:15;;;;;;;;;;;;;;;;;;31545:22;31554:12;:10;:12::i;:::-;31545:22;;;;;;:::i;:::-;;;;;;;;31455:120::o:0;44584:675::-;44687:1;44668:21;;:7;:21;;;;44660:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;44740:49;44761:7;44778:1;44782:6;44740:20;:49::i;:::-;44802:22;44827:9;:18;44837:7;44827:18;;;;;;;;;;;;;;;;44802:43;;44882:6;44864:14;:24;;44856:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;45001:6;44984:14;:23;44963:9;:18;44973:7;44963:18;;;;;;;;;;;;;;;:44;;;;45118:6;45102:12;;:22;;;;;;;;;;;45179:1;45153:37;;45162:7;45153:37;;;45183:6;45153:37;;;;;;:::i;:::-;;;;;;;;45203:48;45223:7;45240:1;45244:6;45203:19;:48::i;:::-;44649:610;44584:675;;:::o;62726:846::-;62984:1;62976:5;:9;;;;:::i;:::-;62943:11;:23;62955:10;62943:23;;;;;;;;;;;;;;;:29;;;:42;62935:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;63105:65;63122:10;63134:5;63141:6;63149:3;63154:4;63160:9;63105:16;:65::i;:::-;63083:132;;;;;;;;;;;;:::i;:::-;;;;;;;;;63270:25;63276:10;63288:6;63270:5;:25::i;:::-;63394:5;63362:11;:23;63374:10;63362:23;;;;;;;;;;;;;;;:29;;:37;;;;63410:11;:23;63422:10;63410:23;;;;;;;;;;;;;;;:30;;63446:6;63410:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63464:11;:23;63476:10;63464:23;;;;;;;;;;;;;;;:27;;63497:3;63464:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63533:10;63519:45;;;63545:5;63552:6;63560:3;63519:45;;;;;;;;:::i;:::-;;;;;;;;62726:846;;;;;:::o;31196:118::-;30205:19;:17;:19::i;:::-;31266:4:::1;31256:7;;:14;;;;;;;;;;;;;;;;;;31286:20;31293:12;:10;:12::i;:::-;31286:20;;;;;;:::i;:::-;;;;;;;;31196:118::o:0;64377:297::-;64467:1;64443:26;;:12;;;;;;;;;;;:26;;;;64435:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;64540:6;64515:21;64525:10;64515:9;:21::i;:::-;:31;;64507:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;64584:30;64593:12;;;;;;;;;;;64607:6;64584:8;:30::i;:::-;;64632:34;64647:10;64659:6;64632:34;;;;;;;:::i;:::-;;;;;;;;64377:297;:::o;63600:747::-;60585:31;23119:16;23130:4;23119:10;:16::i;:::-;63854:1:::1;63834:22;;:8;:22;;;;63826:59;;;;;;;;;;;;:::i;:::-;;;;;;;;;63942:1;63934:5;:9;;;;:::i;:::-;63904:10;:20;63915:8;63904:20;;;;;;;;;;;;;;;:26;;;:39;63896:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;63992;64009:8;64019:5;64026:6;64034:3;64039:4;64045:9;63992:16;:63::i;:::-;63970:130;;;;;;;;;;;;:::i;:::-;;;;;;;;;64113:23;64119:8;64129:6;64113:5;:23::i;:::-;64178:5;64149:10;:20;64160:8;64149:20;;;;;;;;;;;;;;;:26;;:34;;;;64194:10;:20;64205:8;64194:20;;;;;;;;;;;;;;;:27;;64227:6;64194:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64245:10;:20;64256:8;64245:20;;;;;;;;;;;;;;;:24;;64275:3;64245:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64310:8;64297:42;;;64320:5;64327:6;64335:3;64297:42;;;;;;;;:::i;:::-;;;;;;;;63600:747:::0;;;;;;;:::o;68010:201::-;30205:19;:17;:19::i;:::-;68159:44:::1;68186:4;68192:2;68196:6;68159:26;:44::i;:::-;68010:201:::0;;;:::o;48199:124::-;;;;:::o;24436:492::-;24525:22;24533:4;24539:7;24525;:22::i;:::-;24520:401;;24713:28;24733:7;24713:19;:28::i;:::-;24814:38;24842:4;24834:13;;24849:2;24814:19;:38::i;:::-;24618:257;;;;;;;;;:::i;:::-;;;;;;;;;;;;;24564:345;;;;;;;;;;;:::i;:::-;;;;;;;;24520:401;24436:492;;:::o;30944:108::-;31011:8;:6;:8::i;:::-;31003:41;;;;;;;;;;;;:::i;:::-;;;;;;;;;30944:108::o;61453:482::-;61666:4;61683:17;61703:121;61773:3;61778:6;61786:5;61793:8;61803;61756:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;61746:67;;;;;;61703:28;:121::i;:::-;61683:141;;61835:14;61852:35;61866:9;61877;61852:13;:35::i;:::-;61835:52;;61916:10;;;;;;;;;;;61906:20;;:6;:20;;;61898:29;;;;61453:482;;;;;;;;:::o;43703:548::-;43806:1;43787:21;;:7;:21;;;;43779:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;43857:49;43886:1;43890:7;43899:6;43857:20;:49::i;:::-;43935:6;43919:12;;:22;;;;;;;:::i;:::-;;;;;;;;44112:6;44090:9;:18;44100:7;44090:18;;;;;;;;;;;;;;;;:28;;;;;;;;;;;44166:7;44145:37;;44162:1;44145:37;;;44175:6;44145:37;;;;;;:::i;:::-;;;;;;;;44195:48;44223:1;44227:7;44236:6;44195:19;:48::i;:::-;43703:548;;:::o;30759:108::-;30830:8;:6;:8::i;:::-;30829:9;30821:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;30759:108::o;47470:125::-;;;;:::o;20668:151::-;20726:13;20759:52;20787:4;20771:22;;18798:2;20759:52;;:11;:52::i;:::-;20752:59;;20668:151;;;:::o;20039:472::-;20139:13;20165:19;20210:1;20201:6;20197:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;20187:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20165:47;;20223:15;:6;20230:1;20223:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;20249;:6;20256:1;20249:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;20280:9;20305:1;20296:6;20292:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;20280:26;;20275:131;20312:1;20308;:5;20275:131;;;20347:8;20364:3;20356:5;:11;20347:21;;;;;;;:::i;:::-;;;;;20335:6;20342:1;20335:9;;;;;;;;:::i;:::-;;;;;:33;;;;;;;;;;;20393:1;20383:11;;;;;20315:3;;;;:::i;:::-;;;20275:131;;;;20433:1;20424:5;:10;20416:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;20496:6;20482:21;;;20039:472;;;;:::o;56690:330::-;56775:7;56992:4;56939:58;;;;;;;;:::i;:::-;;;;;;;;;;;;;56911:101;;;;;;56891:121;;56690:330;;;:::o;52893:256::-;52996:7;53017:17;53036:18;53058:27;53069:4;53075:9;53058:10;:27::i;:::-;53016:69;;;;53096:18;53108:5;53096:11;:18::i;:::-;53132:9;53125:16;;;;52893:256;;;;:::o;51319:772::-;51425:7;51434:12;51483:2;51463:9;:16;:22;51459:625;;;51502:9;51526;51550:7;51807:4;51796:9;51792:20;51786:27;51781:32;;51857:4;51846:9;51842:20;51836:27;51831:32;;51915:4;51904:9;51900:20;51894:27;51891:1;51886:36;51881:41;;51958:25;51969:4;51975:1;51978;51981;51958:10;:25::i;:::-;51951:32;;;;;;;;;51459:625;52032:1;52036:35;52016:56;;;;51319:772;;;;;;:::o;49712:521::-;49790:20;49781:29;;;;;;;;:::i;:::-;;:5;:29;;;;;;;;:::i;:::-;;;49777:449;;;49827:7;;49777:449;49888:29;49879:38;;;;;;;;:::i;:::-;;:5;:38;;;;;;;;:::i;:::-;;;49875:351;;;49934:34;;;;;;;;;;:::i;:::-;;;;;;;;49875:351;49999:35;49990:44;;;;;;;;:::i;:::-;;:5;:44;;;;;;;;:::i;:::-;;;49986:240;;;50051:41;;;;;;;;;;:::i;:::-;;;;;;;;49986:240;50123:30;50114:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;50110:116;;;50170:44;;;;;;;;;;:::i;:::-;;;;;;;;50110:116;49712:521;;:::o;54415:1557::-;54546:7;54555:12;55507:66;55489:1;55481:10;;:92;55463:200;;;55616:1;55620:30;55600:51;;;;;;55463:200;55760:14;55777:24;55787:4;55793:1;55796;55799;55777:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55760:41;;55834:1;55816:20;;:6;:20;;;55812:103;;;55869:1;55873:29;55853:50;;;;;;;55812:103;55935:6;55943:20;55927:37;;;;;54415:1557;;;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:307::-;1866:1;1876:113;1890:6;1887:1;1884:13;1876:113;;;1975:1;1970:3;1966:11;1960:18;1956:1;1951:3;1947:11;1940:39;1912:2;1909:1;1905:10;1900:15;;1876:113;;;2007:6;2004:1;2001:13;1998:101;;;2087:1;2078:6;2073:3;2069:16;2062:27;1998:101;1847:258;1798:307;;;:::o;2111:102::-;2152:6;2203:2;2199:7;2194:2;2187:5;2183:14;2179:28;2169:38;;2111:102;;;:::o;2219:364::-;2307:3;2335:39;2368:5;2335:39;:::i;:::-;2390:71;2454:6;2449:3;2390:71;:::i;:::-;2383:78;;2470:52;2515:6;2510:3;2503:4;2496:5;2492:16;2470:52;:::i;:::-;2547:29;2569:6;2547:29;:::i;:::-;2542:3;2538:39;2531:46;;2311:272;2219:364;;;;:::o;2589:313::-;2702:4;2740:2;2729:9;2725:18;2717:26;;2789:9;2783:4;2779:20;2775:1;2764:9;2760:17;2753:47;2817:78;2890:4;2881:6;2817:78;:::i;:::-;2809:86;;2589:313;;;;:::o;2908:126::-;2945:7;2985:42;2978:5;2974:54;2963:65;;2908:126;;;:::o;3040:96::-;3077:7;3106:24;3124:5;3106:24;:::i;:::-;3095:35;;3040:96;;;:::o;3142:122::-;3215:24;3233:5;3215:24;:::i;:::-;3208:5;3205:35;3195:63;;3254:1;3251;3244:12;3195:63;3142:122;:::o;3270:139::-;3316:5;3354:6;3341:20;3332:29;;3370:33;3397:5;3370:33;:::i;:::-;3270:139;;;;:::o;3415:77::-;3452:7;3481:5;3470:16;;3415:77;;;:::o;3498:122::-;3571:24;3589:5;3571:24;:::i;:::-;3564:5;3561:35;3551:63;;3610:1;3607;3600:12;3551:63;3498:122;:::o;3626:139::-;3672:5;3710:6;3697:20;3688:29;;3726:33;3753:5;3726:33;:::i;:::-;3626:139;;;;:::o;3771:474::-;3839:6;3847;3896:2;3884:9;3875:7;3871:23;3867:32;3864:119;;;3902:79;;:::i;:::-;3864:119;4022:1;4047:53;4092:7;4083:6;4072:9;4068:22;4047:53;:::i;:::-;4037:63;;3993:117;4149:2;4175:53;4220:7;4211:6;4200:9;4196:22;4175:53;:::i;:::-;4165:63;;4120:118;3771:474;;;;;:::o;4251:118::-;4338:24;4356:5;4338:24;:::i;:::-;4333:3;4326:37;4251:118;;:::o;4375:222::-;4468:4;4506:2;4495:9;4491:18;4483:26;;4519:71;4587:1;4576:9;4572:17;4563:6;4519:71;:::i;:::-;4375:222;;;;:::o;4603:329::-;4662:6;4711:2;4699:9;4690:7;4686:23;4682:32;4679:119;;;4717:79;;:::i;:::-;4679:119;4837:1;4862:53;4907:7;4898:6;4887:9;4883:22;4862:53;:::i;:::-;4852:63;;4808:117;4603:329;;;;:::o;4938:108::-;5015:24;5033:5;5015:24;:::i;:::-;5010:3;5003:37;4938:108;;:::o;5052:114::-;5119:6;5153:5;5147:12;5137:22;;5052:114;;;:::o;5172:174::-;5261:11;5295:6;5290:3;5283:19;5335:4;5330:3;5326:14;5311:29;;5172:174;;;;:::o;5352:132::-;5419:4;5442:3;5434:11;;5472:4;5467:3;5463:14;5455:22;;5352:132;;;:::o;5490:179::-;5559:10;5580:46;5622:3;5614:6;5580:46;:::i;:::-;5658:4;5653:3;5649:14;5635:28;;5490:179;;;;:::o;5675:113::-;5745:4;5777;5772:3;5768:14;5760:22;;5675:113;;;:::o;5824:712::-;5933:3;5962:54;6010:5;5962:54;:::i;:::-;6032:76;6101:6;6096:3;6032:76;:::i;:::-;6025:83;;6132:56;6182:5;6132:56;:::i;:::-;6211:7;6242:1;6227:284;6252:6;6249:1;6246:13;6227:284;;;6328:6;6322:13;6355:63;6414:3;6399:13;6355:63;:::i;:::-;6348:70;;6441:60;6494:6;6441:60;:::i;:::-;6431:70;;6287:224;6274:1;6271;6267:9;6262:14;;6227:284;;;6231:14;6527:3;6520:10;;5938:598;;;5824:712;;;;:::o;6608:919::-;6733:3;6769:4;6764:3;6760:14;6857:4;6850:5;6846:16;6840:23;6876:63;6933:4;6928:3;6924:14;6910:12;6876:63;:::i;:::-;6784:165;7033:4;7026:5;7022:16;7016:23;7086:3;7080:4;7076:14;7069:4;7064:3;7060:14;7053:38;7112:103;7210:4;7196:12;7112:103;:::i;:::-;7104:111;;6959:267;7307:4;7300:5;7296:16;7290:23;7360:3;7354:4;7350:14;7343:4;7338:3;7334:14;7327:38;7386:103;7484:4;7470:12;7386:103;:::i;:::-;7378:111;;7236:264;7517:4;7510:11;;6738:789;6608:919;;;;:::o;7533:385::-;7682:4;7720:2;7709:9;7705:18;7697:26;;7769:9;7763:4;7759:20;7755:1;7744:9;7740:17;7733:47;7797:114;7906:4;7897:6;7797:114;:::i;:::-;7789:122;;7533:385;;;;:::o;7924:619::-;8001:6;8009;8017;8066:2;8054:9;8045:7;8041:23;8037:32;8034:119;;;8072:79;;:::i;:::-;8034:119;8192:1;8217:53;8262:7;8253:6;8242:9;8238:22;8217:53;:::i;:::-;8207:63;;8163:117;8319:2;8345:53;8390:7;8381:6;8370:9;8366:22;8345:53;:::i;:::-;8335:63;;8290:118;8447:2;8473:53;8518:7;8509:6;8498:9;8494:22;8473:53;:::i;:::-;8463:63;;8418:118;7924:619;;;;;:::o;8549:77::-;8586:7;8615:5;8604:16;;8549:77;;;:::o;8632:122::-;8705:24;8723:5;8705:24;:::i;:::-;8698:5;8695:35;8685:63;;8744:1;8741;8734:12;8685:63;8632:122;:::o;8760:139::-;8806:5;8844:6;8831:20;8822:29;;8860:33;8887:5;8860:33;:::i;:::-;8760:139;;;;:::o;8905:329::-;8964:6;9013:2;9001:9;8992:7;8988:23;8984:32;8981:119;;;9019:79;;:::i;:::-;8981:119;9139:1;9164:53;9209:7;9200:6;9189:9;9185:22;9164:53;:::i;:::-;9154:63;;9110:117;8905:329;;;;:::o;9240:118::-;9327:24;9345:5;9327:24;:::i;:::-;9322:3;9315:37;9240:118;;:::o;9364:222::-;9457:4;9495:2;9484:9;9480:18;9472:26;;9508:71;9576:1;9565:9;9561:17;9552:6;9508:71;:::i;:::-;9364:222;;;;:::o;9592:474::-;9660:6;9668;9717:2;9705:9;9696:7;9692:23;9688:32;9685:119;;;9723:79;;:::i;:::-;9685:119;9843:1;9868:53;9913:7;9904:6;9893:9;9889:22;9868:53;:::i;:::-;9858:63;;9814:117;9970:2;9996:53;10041:7;10032:6;10021:9;10017:22;9996:53;:::i;:::-;9986:63;;9941:118;9592:474;;;;;:::o;10072:86::-;10107:7;10147:4;10140:5;10136:16;10125:27;;10072:86;;;:::o;10164:112::-;10247:22;10263:5;10247:22;:::i;:::-;10242:3;10235:35;10164:112;;:::o;10282:214::-;10371:4;10409:2;10398:9;10394:18;10386:26;;10422:67;10486:1;10475:9;10471:17;10462:6;10422:67;:::i;:::-;10282:214;;;;:::o;10502:329::-;10561:6;10610:2;10598:9;10589:7;10585:23;10581:32;10578:119;;;10616:79;;:::i;:::-;10578:119;10736:1;10761:53;10806:7;10797:6;10786:9;10782:22;10761:53;:::i;:::-;10751:63;;10707:117;10502:329;;;;:::o;10837:117::-;10946:1;10943;10936:12;10960:117;11069:1;11066;11059:12;11083:180;11131:77;11128:1;11121:88;11228:4;11225:1;11218:15;11252:4;11249:1;11242:15;11269:281;11352:27;11374:4;11352:27;:::i;:::-;11344:6;11340:40;11482:6;11470:10;11467:22;11446:18;11434:10;11431:34;11428:62;11425:88;;;11493:18;;:::i;:::-;11425:88;11533:10;11529:2;11522:22;11312:238;11269:281;;:::o;11556:129::-;11590:6;11617:20;;:::i;:::-;11607:30;;11646:33;11674:4;11666:6;11646:33;:::i;:::-;11556:129;;;:::o;11691:307::-;11752:4;11842:18;11834:6;11831:30;11828:56;;;11864:18;;:::i;:::-;11828:56;11902:29;11924:6;11902:29;:::i;:::-;11894:37;;11986:4;11980;11976:15;11968:23;;11691:307;;;:::o;12004:154::-;12088:6;12083:3;12078;12065:30;12150:1;12141:6;12136:3;12132:16;12125:27;12004:154;;;:::o;12164:410::-;12241:5;12266:65;12282:48;12323:6;12282:48;:::i;:::-;12266:65;:::i;:::-;12257:74;;12354:6;12347:5;12340:21;12392:4;12385:5;12381:16;12430:3;12421:6;12416:3;12412:16;12409:25;12406:112;;;12437:79;;:::i;:::-;12406:112;12527:41;12561:6;12556:3;12551;12527:41;:::i;:::-;12247:327;12164:410;;;;;:::o;12593:338::-;12648:5;12697:3;12690:4;12682:6;12678:17;12674:27;12664:122;;12705:79;;:::i;:::-;12664:122;12822:6;12809:20;12847:78;12921:3;12913:6;12906:4;12898:6;12894:17;12847:78;:::i;:::-;12838:87;;12654:277;12593:338;;;;:::o;12937:943::-;13032:6;13040;13048;13056;13105:3;13093:9;13084:7;13080:23;13076:33;13073:120;;;13112:79;;:::i;:::-;13073:120;13232:1;13257:53;13302:7;13293:6;13282:9;13278:22;13257:53;:::i;:::-;13247:63;;13203:117;13359:2;13385:53;13430:7;13421:6;13410:9;13406:22;13385:53;:::i;:::-;13375:63;;13330:118;13487:2;13513:53;13558:7;13549:6;13538:9;13534:22;13513:53;:::i;:::-;13503:63;;13458:118;13643:2;13632:9;13628:18;13615:32;13674:18;13666:6;13663:30;13660:117;;;13696:79;;:::i;:::-;13660:117;13801:62;13855:7;13846:6;13835:9;13831:22;13801:62;:::i;:::-;13791:72;;13586:287;12937:943;;;;;;;:::o;13886:1089::-;13990:6;13998;14006;14014;14022;14071:3;14059:9;14050:7;14046:23;14042:33;14039:120;;;14078:79;;:::i;:::-;14039:120;14198:1;14223:53;14268:7;14259:6;14248:9;14244:22;14223:53;:::i;:::-;14213:63;;14169:117;14325:2;14351:53;14396:7;14387:6;14376:9;14372:22;14351:53;:::i;:::-;14341:63;;14296:118;14453:2;14479:53;14524:7;14515:6;14504:9;14500:22;14479:53;:::i;:::-;14469:63;;14424:118;14581:2;14607:53;14652:7;14643:6;14632:9;14628:22;14607:53;:::i;:::-;14597:63;;14552:118;14737:3;14726:9;14722:19;14709:33;14769:18;14761:6;14758:30;14755:117;;;14791:79;;:::i;:::-;14755:117;14896:62;14950:7;14941:6;14930:9;14926:22;14896:62;:::i;:::-;14886:72;;14680:288;13886:1089;;;;;;;;:::o;14981:474::-;15049:6;15057;15106:2;15094:9;15085:7;15081:23;15077:32;15074:119;;;15112:79;;:::i;:::-;15074:119;15232:1;15257:53;15302:7;15293:6;15282:9;15278:22;15257:53;:::i;:::-;15247:63;;15203:117;15359:2;15385:53;15430:7;15421:6;15410:9;15406:22;15385:53;:::i;:::-;15375:63;;15330:118;14981:474;;;;;:::o;15461:116::-;15531:21;15546:5;15531:21;:::i;:::-;15524:5;15521:32;15511:60;;15567:1;15564;15557:12;15511:60;15461:116;:::o;15583:133::-;15626:5;15664:6;15651:20;15642:29;;15680:30;15704:5;15680:30;:::i;:::-;15583:133;;;;:::o;15722:468::-;15787:6;15795;15844:2;15832:9;15823:7;15819:23;15815:32;15812:119;;;15850:79;;:::i;:::-;15812:119;15970:1;15995:53;16040:7;16031:6;16020:9;16016:22;15995:53;:::i;:::-;15985:63;;15941:117;16097:2;16123:50;16165:7;16156:6;16145:9;16141:22;16123:50;:::i;:::-;16113:60;;16068:115;15722:468;;;;;:::o;16196:180::-;16244:77;16241:1;16234:88;16341:4;16338:1;16331:15;16365:4;16362:1;16355:15;16382:320;16426:6;16463:1;16457:4;16453:12;16443:22;;16510:1;16504:4;16500:12;16531:18;16521:81;;16587:4;16579:6;16575:17;16565:27;;16521:81;16649:2;16641:6;16638:14;16618:18;16615:38;16612:84;;;16668:18;;:::i;:::-;16612:84;16433:269;16382:320;;;:::o;16708:234::-;16848:34;16844:1;16836:6;16832:14;16825:58;16917:17;16912:2;16904:6;16900:15;16893:42;16708:234;:::o;16948:366::-;17090:3;17111:67;17175:2;17170:3;17111:67;:::i;:::-;17104:74;;17187:93;17276:3;17187:93;:::i;:::-;17305:2;17300:3;17296:12;17289:19;;16948:366;;;:::o;17320:419::-;17486:4;17524:2;17513:9;17509:18;17501:26;;17573:9;17567:4;17563:20;17559:1;17548:9;17544:17;17537:47;17601:131;17727:4;17601:131;:::i;:::-;17593:139;;17320:419;;;:::o;17745:180::-;17793:77;17790:1;17783:88;17890:4;17887:1;17880:15;17914:4;17911:1;17904:15;17931:305;17971:3;17990:20;18008:1;17990:20;:::i;:::-;17985:25;;18024:20;18042:1;18024:20;:::i;:::-;18019:25;;18178:1;18110:66;18106:74;18103:1;18100:81;18097:107;;;18184:18;;:::i;:::-;18097:107;18228:1;18225;18221:9;18214:16;;17931:305;;;;:::o;18242:180::-;18382:32;18378:1;18370:6;18366:14;18359:56;18242:180;:::o;18428:366::-;18570:3;18591:67;18655:2;18650:3;18591:67;:::i;:::-;18584:74;;18667:93;18756:3;18667:93;:::i;:::-;18785:2;18780:3;18776:12;18769:19;;18428:366;;;:::o;18800:419::-;18966:4;19004:2;18993:9;18989:18;18981:26;;19053:9;19047:4;19043:20;19039:1;19028:9;19024:17;19017:47;19081:131;19207:4;19081:131;:::i;:::-;19073:139;;18800:419;;;:::o;19225:175::-;19365:27;19361:1;19353:6;19349:14;19342:51;19225:175;:::o;19406:366::-;19548:3;19569:67;19633:2;19628:3;19569:67;:::i;:::-;19562:74;;19645:93;19734:3;19645:93;:::i;:::-;19763:2;19758:3;19754:12;19747:19;;19406:366;;;:::o;19778:419::-;19944:4;19982:2;19971:9;19967:18;19959:26;;20031:9;20025:4;20021:20;20017:1;20006:9;20002:17;19995:47;20059:131;20185:4;20059:131;:::i;:::-;20051:139;;19778:419;;;:::o;20203:320::-;20318:4;20356:2;20345:9;20341:18;20333:26;;20369:71;20437:1;20426:9;20422:17;20413:6;20369:71;:::i;:::-;20450:66;20512:2;20501:9;20497:18;20488:6;20450:66;:::i;:::-;20203:320;;;;;:::o;20529:224::-;20669:34;20665:1;20657:6;20653:14;20646:58;20738:7;20733:2;20725:6;20721:15;20714:32;20529:224;:::o;20759:366::-;20901:3;20922:67;20986:2;20981:3;20922:67;:::i;:::-;20915:74;;20998:93;21087:3;20998:93;:::i;:::-;21116:2;21111:3;21107:12;21100:19;;20759:366;;;:::o;21131:419::-;21297:4;21335:2;21324:9;21320:18;21312:26;;21384:9;21378:4;21374:20;21370:1;21359:9;21355:17;21348:47;21412:131;21538:4;21412:131;:::i;:::-;21404:139;;21131:419;;;:::o;21556:220::-;21696:34;21692:1;21684:6;21680:14;21673:58;21765:3;21760:2;21752:6;21748:15;21741:28;21556:220;:::o;21782:366::-;21924:3;21945:67;22009:2;22004:3;21945:67;:::i;:::-;21938:74;;22021:93;22110:3;22021:93;:::i;:::-;22139:2;22134:3;22130:12;22123:19;;21782:366;;;:::o;22154:419::-;22320:4;22358:2;22347:9;22343:18;22335:26;;22407:9;22401:4;22397:20;22393:1;22382:9;22378:17;22371:47;22435:131;22561:4;22435:131;:::i;:::-;22427:139;;22154:419;;;:::o;22579:223::-;22719:34;22715:1;22707:6;22703:14;22696:58;22788:6;22783:2;22775:6;22771:15;22764:31;22579:223;:::o;22808:366::-;22950:3;22971:67;23035:2;23030:3;22971:67;:::i;:::-;22964:74;;23047:93;23136:3;23047:93;:::i;:::-;23165:2;23160:3;23156:12;23149:19;;22808:366;;;:::o;23180:419::-;23346:4;23384:2;23373:9;23369:18;23361:26;;23433:9;23427:4;23423:20;23419:1;23408:9;23404:17;23397:47;23461:131;23587:4;23461:131;:::i;:::-;23453:139;;23180:419;;;:::o;23605:221::-;23745:34;23741:1;23733:6;23729:14;23722:58;23814:4;23809:2;23801:6;23797:15;23790:29;23605:221;:::o;23832:366::-;23974:3;23995:67;24059:2;24054:3;23995:67;:::i;:::-;23988:74;;24071:93;24160:3;24071:93;:::i;:::-;24189:2;24184:3;24180:12;24173:19;;23832:366;;;:::o;24204:419::-;24370:4;24408:2;24397:9;24393:18;24385:26;;24457:9;24451:4;24447:20;24443:1;24432:9;24428:17;24421:47;24485:131;24611:4;24485:131;:::i;:::-;24477:139;;24204:419;;;:::o;24629:179::-;24769:31;24765:1;24757:6;24753:14;24746:55;24629:179;:::o;24814:366::-;24956:3;24977:67;25041:2;25036:3;24977:67;:::i;:::-;24970:74;;25053:93;25142:3;25053:93;:::i;:::-;25171:2;25166:3;25162:12;25155:19;;24814:366;;;:::o;25186:419::-;25352:4;25390:2;25379:9;25375:18;25367:26;;25439:9;25433:4;25429:20;25425:1;25414:9;25410:17;25403:47;25467:131;25593:4;25467:131;:::i;:::-;25459:139;;25186:419;;;:::o;25611:224::-;25751:34;25747:1;25739:6;25735:14;25728:58;25820:7;25815:2;25807:6;25803:15;25796:32;25611:224;:::o;25841:366::-;25983:3;26004:67;26068:2;26063:3;26004:67;:::i;:::-;25997:74;;26080:93;26169:3;26080:93;:::i;:::-;26198:2;26193:3;26189:12;26182:19;;25841:366;;;:::o;26213:419::-;26379:4;26417:2;26406:9;26402:18;26394:26;;26466:9;26460:4;26456:20;26452:1;26441:9;26437:17;26430:47;26494:131;26620:4;26494:131;:::i;:::-;26486:139;;26213:419;;;:::o;26638:222::-;26778:34;26774:1;26766:6;26762:14;26755:58;26847:5;26842:2;26834:6;26830:15;26823:30;26638:222;:::o;26866:366::-;27008:3;27029:67;27093:2;27088:3;27029:67;:::i;:::-;27022:74;;27105:93;27194:3;27105:93;:::i;:::-;27223:2;27218:3;27214:12;27207:19;;26866:366;;;:::o;27238:419::-;27404:4;27442:2;27431:9;27427:18;27419:26;;27491:9;27485:4;27481:20;27477:1;27466:9;27462:17;27455:47;27519:131;27645:4;27519:131;:::i;:::-;27511:139;;27238:419;;;:::o;27663:225::-;27803:34;27799:1;27791:6;27787:14;27780:58;27872:8;27867:2;27859:6;27855:15;27848:33;27663:225;:::o;27894:366::-;28036:3;28057:67;28121:2;28116:3;28057:67;:::i;:::-;28050:74;;28133:93;28222:3;28133:93;:::i;:::-;28251:2;28246:3;28242:12;28235:19;;27894:366;;;:::o;28266:419::-;28432:4;28470:2;28459:9;28455:18;28447:26;;28519:9;28513:4;28509:20;28505:1;28494:9;28490:17;28483:47;28547:131;28673:4;28547:131;:::i;:::-;28539:139;;28266:419;;;:::o;28691:118::-;28778:24;28796:5;28778:24;:::i;:::-;28773:3;28766:37;28691:118;;:::o;28815:222::-;28908:4;28946:2;28935:9;28931:18;28923:26;;28959:71;29027:1;29016:9;29012:17;29003:6;28959:71;:::i;:::-;28815:222;;;;:::o;29043:220::-;29183:34;29179:1;29171:6;29167:14;29160:58;29252:3;29247:2;29239:6;29235:15;29228:28;29043:220;:::o;29269:366::-;29411:3;29432:67;29496:2;29491:3;29432:67;:::i;:::-;29425:74;;29508:93;29597:3;29508:93;:::i;:::-;29626:2;29621:3;29617:12;29610:19;;29269:366;;;:::o;29641:419::-;29807:4;29845:2;29834:9;29830:18;29822:26;;29894:9;29888:4;29884:20;29880:1;29869:9;29865:17;29858:47;29922:131;30048:4;29922:131;:::i;:::-;29914:139;;29641:419;;;:::o;30066:221::-;30206:34;30202:1;30194:6;30190:14;30183:58;30275:4;30270:2;30262:6;30258:15;30251:29;30066:221;:::o;30293:366::-;30435:3;30456:67;30520:2;30515:3;30456:67;:::i;:::-;30449:74;;30532:93;30621:3;30532:93;:::i;:::-;30650:2;30645:3;30641:12;30634:19;;30293:366;;;:::o;30665:419::-;30831:4;30869:2;30858:9;30854:18;30846:26;;30918:9;30912:4;30908:20;30904:1;30893:9;30889:17;30882:47;30946:131;31072:4;30946:131;:::i;:::-;30938:139;;30665:419;;;:::o;31090:191::-;31130:4;31150:20;31168:1;31150:20;:::i;:::-;31145:25;;31184:20;31202:1;31184:20;:::i;:::-;31179:25;;31223:1;31220;31217:8;31214:34;;;31228:18;;:::i;:::-;31214:34;31273:1;31270;31266:9;31258:17;;31090:191;;;;:::o;31287:161::-;31427:13;31423:1;31415:6;31411:14;31404:37;31287:161;:::o;31454:366::-;31596:3;31617:67;31681:2;31676:3;31617:67;:::i;:::-;31610:74;;31693:93;31782:3;31693:93;:::i;:::-;31811:2;31806:3;31802:12;31795:19;;31454:366;;;:::o;31826:419::-;31992:4;32030:2;32019:9;32015:18;32007:26;;32079:9;32073:4;32069:20;32065:1;32054:9;32050:17;32043:47;32107:131;32233:4;32107:131;:::i;:::-;32099:139;;31826:419;;;:::o;32251:167::-;32391:19;32387:1;32379:6;32375:14;32368:43;32251:167;:::o;32424:366::-;32566:3;32587:67;32651:2;32646:3;32587:67;:::i;:::-;32580:74;;32663:93;32752:3;32663:93;:::i;:::-;32781:2;32776:3;32772:12;32765:19;;32424:366;;;:::o;32796:419::-;32962:4;33000:2;32989:9;32985:18;32977:26;;33049:9;33043:4;33039:20;33035:1;33024:9;33020:17;33013:47;33077:131;33203:4;33077:131;:::i;:::-;33069:139;;32796:419;;;:::o;33221:442::-;33370:4;33408:2;33397:9;33393:18;33385:26;;33421:71;33489:1;33478:9;33474:17;33465:6;33421:71;:::i;:::-;33502:72;33570:2;33559:9;33555:18;33546:6;33502:72;:::i;:::-;33584;33652:2;33641:9;33637:18;33628:6;33584:72;:::i;:::-;33221:442;;;;;;:::o;33669:172::-;33809:24;33805:1;33797:6;33793:14;33786:48;33669:172;:::o;33847:366::-;33989:3;34010:67;34074:2;34069:3;34010:67;:::i;:::-;34003:74;;34086:93;34175:3;34086:93;:::i;:::-;34204:2;34199:3;34195:12;34188:19;;33847:366;;;:::o;34219:419::-;34385:4;34423:2;34412:9;34408:18;34400:26;;34472:9;34466:4;34462:20;34458:1;34447:9;34443:17;34436:47;34500:131;34626:4;34500:131;:::i;:::-;34492:139;;34219:419;;;:::o;34644:170::-;34784:22;34780:1;34772:6;34768:14;34761:46;34644:170;:::o;34820:366::-;34962:3;34983:67;35047:2;35042:3;34983:67;:::i;:::-;34976:74;;35059:93;35148:3;35059:93;:::i;:::-;35177:2;35172:3;35168:12;35161:19;;34820:366;;;:::o;35192:419::-;35358:4;35396:2;35385:9;35381:18;35373:26;;35445:9;35439:4;35435:20;35431:1;35420:9;35416:17;35409:47;35473:131;35599:4;35473:131;:::i;:::-;35465:139;;35192:419;;;:::o;35617:332::-;35738:4;35776:2;35765:9;35761:18;35753:26;;35789:71;35857:1;35846:9;35842:17;35833:6;35789:71;:::i;:::-;35870:72;35938:2;35927:9;35923:18;35914:6;35870:72;:::i;:::-;35617:332;;;;;:::o;35955:174::-;36095:26;36091:1;36083:6;36079:14;36072:50;35955:174;:::o;36135:366::-;36277:3;36298:67;36362:2;36357:3;36298:67;:::i;:::-;36291:74;;36374:93;36463:3;36374:93;:::i;:::-;36492:2;36487:3;36483:12;36476:19;;36135:366;;;:::o;36507:419::-;36673:4;36711:2;36700:9;36696:18;36688:26;;36760:9;36754:4;36750:20;36746:1;36735:9;36731:17;36724:47;36788:131;36914:4;36788:131;:::i;:::-;36780:139;;36507:419;;;:::o;36932:148::-;37034:11;37071:3;37056:18;;36932:148;;;;:::o;37086:173::-;37226:25;37222:1;37214:6;37210:14;37203:49;37086:173;:::o;37265:402::-;37425:3;37446:85;37528:2;37523:3;37446:85;:::i;:::-;37439:92;;37540:93;37629:3;37540:93;:::i;:::-;37658:2;37653:3;37649:12;37642:19;;37265:402;;;:::o;37673:377::-;37779:3;37807:39;37840:5;37807:39;:::i;:::-;37862:89;37944:6;37939:3;37862:89;:::i;:::-;37855:96;;37960:52;38005:6;38000:3;37993:4;37986:5;37982:16;37960:52;:::i;:::-;38037:6;38032:3;38028:16;38021:23;;37783:267;37673:377;;;;:::o;38056:167::-;38196:19;38192:1;38184:6;38180:14;38173:43;38056:167;:::o;38229:402::-;38389:3;38410:85;38492:2;38487:3;38410:85;:::i;:::-;38403:92;;38504:93;38593:3;38504:93;:::i;:::-;38622:2;38617:3;38613:12;38606:19;;38229:402;;;:::o;38637:967::-;39019:3;39041:148;39185:3;39041:148;:::i;:::-;39034:155;;39206:95;39297:3;39288:6;39206:95;:::i;:::-;39199:102;;39318:148;39462:3;39318:148;:::i;:::-;39311:155;;39483:95;39574:3;39565:6;39483:95;:::i;:::-;39476:102;;39595:3;39588:10;;38637:967;;;;;:::o;39610:170::-;39750:22;39746:1;39738:6;39734:14;39727:46;39610:170;:::o;39786:366::-;39928:3;39949:67;40013:2;40008:3;39949:67;:::i;:::-;39942:74;;40025:93;40114:3;40025:93;:::i;:::-;40143:2;40138:3;40134:12;40127:19;;39786:366;;;:::o;40158:419::-;40324:4;40362:2;40351:9;40347:18;40339:26;;40411:9;40405:4;40401:20;40397:1;40386:9;40382:17;40375:47;40439:131;40565:4;40439:131;:::i;:::-;40431:139;;40158:419;;;:::o;40583:79::-;40622:7;40651:5;40640:16;;40583:79;;;:::o;40668:157::-;40773:45;40793:24;40811:5;40793:24;:::i;:::-;40773:45;:::i;:::-;40768:3;40761:58;40668:157;;:::o;40831:94::-;40864:8;40912:5;40908:2;40904:14;40883:35;;40831:94;;;:::o;40931:::-;40970:7;40999:20;41013:5;40999:20;:::i;:::-;40988:31;;40931:94;;;:::o;41031:100::-;41070:7;41099:26;41119:5;41099:26;:::i;:::-;41088:37;;41031:100;;;:::o;41137:157::-;41242:45;41262:24;41280:5;41262:24;:::i;:::-;41242:45;:::i;:::-;41237:3;41230:58;41137:157;;:::o;41300:78::-;41338:7;41367:5;41356:16;;41300:78;;;:::o;41384:153::-;41487:43;41506:23;41523:5;41506:23;:::i;:::-;41487:43;:::i;:::-;41482:3;41475:56;41384:153;;:::o;41543:815::-;41765:3;41780:75;41851:3;41842:6;41780:75;:::i;:::-;41880:2;41875:3;41871:12;41864:19;;41893:75;41964:3;41955:6;41893:75;:::i;:::-;41993:2;41988:3;41984:12;41977:19;;42006:75;42077:3;42068:6;42006:75;:::i;:::-;42106:2;42101:3;42097:12;42090:19;;42119:75;42190:3;42181:6;42119:75;:::i;:::-;42219:2;42214:3;42210:12;42203:19;;42232:73;42301:3;42292:6;42232:73;:::i;:::-;42330:1;42325:3;42321:11;42314:18;;42349:3;42342:10;;41543:815;;;;;;;;:::o;42364:181::-;42504:33;42500:1;42492:6;42488:14;42481:57;42364:181;:::o;42551:366::-;42693:3;42714:67;42778:2;42773:3;42714:67;:::i;:::-;42707:74;;42790:93;42879:3;42790:93;:::i;:::-;42908:2;42903:3;42899:12;42892:19;;42551:366;;;:::o;42923:419::-;43089:4;43127:2;43116:9;43112:18;43104:26;;43176:9;43170:4;43166:20;43162:1;43151:9;43147:17;43140:47;43204:131;43330:4;43204:131;:::i;:::-;43196:139;;42923:419;;;:::o;43348:166::-;43488:18;43484:1;43476:6;43472:14;43465:42;43348:166;:::o;43520:366::-;43662:3;43683:67;43747:2;43742:3;43683:67;:::i;:::-;43676:74;;43759:93;43848:3;43759:93;:::i;:::-;43877:2;43872:3;43868:12;43861:19;;43520:366;;;:::o;43892:419::-;44058:4;44096:2;44085:9;44081:18;44073:26;;44145:9;44139:4;44135:20;44131:1;44120:9;44116:17;44109:47;44173:131;44299:4;44173:131;:::i;:::-;44165:139;;43892:419;;;:::o;44317:348::-;44357:7;44380:20;44398:1;44380:20;:::i;:::-;44375:25;;44414:20;44432:1;44414:20;:::i;:::-;44409:25;;44602:1;44534:66;44530:74;44527:1;44524:81;44519:1;44512:9;44505:17;44501:105;44498:131;;;44609:18;;:::i;:::-;44498:131;44657:1;44654;44650:9;44639:20;;44317:348;;;;:::o;44671:180::-;44719:77;44716:1;44709:88;44816:4;44813:1;44806:15;44840:4;44837:1;44830:15;44857:171;44896:3;44919:24;44937:5;44919:24;:::i;:::-;44910:33;;44965:4;44958:5;44955:15;44952:41;;;44973:18;;:::i;:::-;44952:41;45020:1;45013:5;45009:13;45002:20;;44857:171;;;:::o;45034:182::-;45174:34;45170:1;45162:6;45158:14;45151:58;45034:182;:::o;45222:366::-;45364:3;45385:67;45449:2;45444:3;45385:67;:::i;:::-;45378:74;;45461:93;45550:3;45461:93;:::i;:::-;45579:2;45574:3;45570:12;45563:19;;45222:366;;;:::o;45594:419::-;45760:4;45798:2;45787:9;45783:18;45775:26;;45847:9;45841:4;45837:20;45833:1;45822:9;45818:17;45811:47;45875:131;46001:4;45875:131;:::i;:::-;45867:139;;45594:419;;;:::o;46019:214::-;46159:66;46155:1;46147:6;46143:14;46136:90;46019:214;:::o;46239:402::-;46399:3;46420:85;46502:2;46497:3;46420:85;:::i;:::-;46413:92;;46514:93;46603:3;46514:93;:::i;:::-;46632:2;46627:3;46623:12;46616:19;;46239:402;;;:::o;46647:79::-;46686:7;46715:5;46704:16;;46647:79;;;:::o;46732:157::-;46837:45;46857:24;46875:5;46857:24;:::i;:::-;46837:45;:::i;:::-;46832:3;46825:58;46732:157;;:::o;46895:522::-;47108:3;47130:148;47274:3;47130:148;:::i;:::-;47123:155;;47288:75;47359:3;47350:6;47288:75;:::i;:::-;47388:2;47383:3;47379:12;47372:19;;47408:3;47401:10;;46895:522;;;;:::o;47423:180::-;47471:77;47468:1;47461:88;47568:4;47565:1;47558:15;47592:4;47589:1;47582:15;47609:174;47749:26;47745:1;47737:6;47733:14;47726:50;47609:174;:::o;47789:366::-;47931:3;47952:67;48016:2;48011:3;47952:67;:::i;:::-;47945:74;;48028:93;48117:3;48028:93;:::i;:::-;48146:2;48141:3;48137:12;48130:19;;47789:366;;;:::o;48161:419::-;48327:4;48365:2;48354:9;48350:18;48342:26;;48414:9;48408:4;48404:20;48400:1;48389:9;48385:17;48378:47;48442:131;48568:4;48442:131;:::i;:::-;48434:139;;48161:419;;;:::o;48586:181::-;48726:33;48722:1;48714:6;48710:14;48703:57;48586:181;:::o;48773:366::-;48915:3;48936:67;49000:2;48995:3;48936:67;:::i;:::-;48929:74;;49012:93;49101:3;49012:93;:::i;:::-;49130:2;49125:3;49121:12;49114:19;;48773:366;;;:::o;49145:419::-;49311:4;49349:2;49338:9;49334:18;49326:26;;49398:9;49392:4;49388:20;49384:1;49373:9;49369:17;49362:47;49426:131;49552:4;49426:131;:::i;:::-;49418:139;;49145:419;;;:::o;49570:221::-;49710:34;49706:1;49698:6;49694:14;49687:58;49779:4;49774:2;49766:6;49762:15;49755:29;49570:221;:::o;49797:366::-;49939:3;49960:67;50024:2;50019:3;49960:67;:::i;:::-;49953:74;;50036:93;50125:3;50036:93;:::i;:::-;50154:2;50149:3;50145:12;50138:19;;49797:366;;;:::o;50169:419::-;50335:4;50373:2;50362:9;50358:18;50350:26;;50422:9;50416:4;50412:20;50408:1;50397:9;50393:17;50386:47;50450:131;50576:4;50450:131;:::i;:::-;50442:139;;50169:419;;;:::o;50594:545::-;50767:4;50805:3;50794:9;50790:19;50782:27;;50819:71;50887:1;50876:9;50872:17;50863:6;50819:71;:::i;:::-;50900:68;50964:2;50953:9;50949:18;50940:6;50900:68;:::i;:::-;50978:72;51046:2;51035:9;51031:18;51022:6;50978:72;:::i;:::-;51060;51128:2;51117:9;51113:18;51104:6;51060:72;:::i;:::-;50594:545;;;;;;;:::o

Swarm Source

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