ERC-20
Overview
Max Total Supply
1,000,000,000 INSP
Holders
8,313 ( -0.024%)
Market
Price
$0.03 @ 0.000007 ETH (+1.74%)
Onchain Market Cap
$25,143,360.00
Circulating Supply Market Cap
$0.00
Other Info
Token Contract (WITH 18 Decimals)
Balance
720,309.0904570591414361 INSPValue
$18,110.99 ( ~5.3914 Eth) [0.0720%]Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Inspect
Compiler Version
v0.8.22+commit.4fc1097e
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-11-24 */ // File: @openzeppelin/[email protected]/utils/introspection/IERC165.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/[email protected]/utils/introspection/ERC165.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; /** * @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); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: @openzeppelin/[email protected]/access/IAccessControl.sol // OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol) pragma solidity ^0.8.20; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev The `account` is missing a role. */ error AccessControlUnauthorizedAccount(address account, bytes32 neededRole); /** * @dev The caller of a function is not the expected one. * * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}. */ error AccessControlBadConfirmation(); /** * @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. */ 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 `callerConfirmation`. */ function renounceRole(bytes32 role, address callerConfirmation) external; } // File: @openzeppelin/[email protected]/utils/math/SafeCast.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.20; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeCast { /** * @dev Value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); /** * @dev An int value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedIntToUint(int256 value); /** * @dev Value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); /** * @dev An uint value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedUintToInt(uint256 value); /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits */ function toUint248(uint256 value) internal pure returns (uint248) { if (value > type(uint248).max) { revert SafeCastOverflowedUintDowncast(248, value); } return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits */ function toUint240(uint256 value) internal pure returns (uint240) { if (value > type(uint240).max) { revert SafeCastOverflowedUintDowncast(240, value); } return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits */ function toUint232(uint256 value) internal pure returns (uint232) { if (value > type(uint232).max) { revert SafeCastOverflowedUintDowncast(232, value); } return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { if (value > type(uint224).max) { revert SafeCastOverflowedUintDowncast(224, value); } return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits */ function toUint216(uint256 value) internal pure returns (uint216) { if (value > type(uint216).max) { revert SafeCastOverflowedUintDowncast(216, value); } return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 value) internal pure returns (uint208) { if (value > type(uint208).max) { revert SafeCastOverflowedUintDowncast(208, value); } return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits */ function toUint200(uint256 value) internal pure returns (uint200) { if (value > type(uint200).max) { revert SafeCastOverflowedUintDowncast(200, value); } return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits */ function toUint192(uint256 value) internal pure returns (uint192) { if (value > type(uint192).max) { revert SafeCastOverflowedUintDowncast(192, value); } return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits */ function toUint184(uint256 value) internal pure returns (uint184) { if (value > type(uint184).max) { revert SafeCastOverflowedUintDowncast(184, value); } return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits */ function toUint176(uint256 value) internal pure returns (uint176) { if (value > type(uint176).max) { revert SafeCastOverflowedUintDowncast(176, value); } return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits */ function toUint168(uint256 value) internal pure returns (uint168) { if (value > type(uint168).max) { revert SafeCastOverflowedUintDowncast(168, value); } return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits */ function toUint160(uint256 value) internal pure returns (uint160) { if (value > type(uint160).max) { revert SafeCastOverflowedUintDowncast(160, value); } return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits */ function toUint152(uint256 value) internal pure returns (uint152) { if (value > type(uint152).max) { revert SafeCastOverflowedUintDowncast(152, value); } return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits */ function toUint144(uint256 value) internal pure returns (uint144) { if (value > type(uint144).max) { revert SafeCastOverflowedUintDowncast(144, value); } return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits */ function toUint136(uint256 value) internal pure returns (uint136) { if (value > type(uint136).max) { revert SafeCastOverflowedUintDowncast(136, value); } return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { if (value > type(uint128).max) { revert SafeCastOverflowedUintDowncast(128, value); } return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits */ function toUint120(uint256 value) internal pure returns (uint120) { if (value > type(uint120).max) { revert SafeCastOverflowedUintDowncast(120, value); } return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits */ function toUint112(uint256 value) internal pure returns (uint112) { if (value > type(uint112).max) { revert SafeCastOverflowedUintDowncast(112, value); } return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 value) internal pure returns (uint104) { if (value > type(uint104).max) { revert SafeCastOverflowedUintDowncast(104, value); } return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { if (value > type(uint96).max) { revert SafeCastOverflowedUintDowncast(96, value); } return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits */ function toUint88(uint256 value) internal pure returns (uint88) { if (value > type(uint88).max) { revert SafeCastOverflowedUintDowncast(88, value); } return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits */ function toUint80(uint256 value) internal pure returns (uint80) { if (value > type(uint80).max) { revert SafeCastOverflowedUintDowncast(80, value); } return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits */ function toUint72(uint256 value) internal pure returns (uint72) { if (value > type(uint72).max) { revert SafeCastOverflowedUintDowncast(72, value); } return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { if (value > type(uint64).max) { revert SafeCastOverflowedUintDowncast(64, value); } return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits */ function toUint56(uint256 value) internal pure returns (uint56) { if (value > type(uint56).max) { revert SafeCastOverflowedUintDowncast(56, value); } return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits */ function toUint48(uint256 value) internal pure returns (uint48) { if (value > type(uint48).max) { revert SafeCastOverflowedUintDowncast(48, value); } return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { if (value > type(uint40).max) { revert SafeCastOverflowedUintDowncast(40, value); } return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { if (value > type(uint32).max) { revert SafeCastOverflowedUintDowncast(32, value); } return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits */ function toUint24(uint256 value) internal pure returns (uint24) { if (value > type(uint24).max) { revert SafeCastOverflowedUintDowncast(24, value); } return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { if (value > type(uint16).max) { revert SafeCastOverflowedUintDowncast(16, value); } return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits */ function toUint8(uint256 value) internal pure returns (uint8) { if (value > type(uint8).max) { revert SafeCastOverflowedUintDowncast(8, value); } return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { if (value < 0) { revert SafeCastOverflowedIntToUint(value); } return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(248, value); } } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(240, value); } } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(232, value); } } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(224, value); } } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(216, value); } } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(208, value); } } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(200, value); } } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(192, value); } } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(184, value); } } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(176, value); } } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(168, value); } } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(160, value); } } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(152, value); } } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(144, value); } } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(136, value); } } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(128, value); } } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(120, value); } } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(112, value); } } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(104, value); } } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(96, value); } } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(88, value); } } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(80, value); } } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(72, value); } } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(64, value); } } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(56, value); } } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(48, value); } } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(40, value); } } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(32, value); } } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(24, value); } } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(16, value); } } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(8, value); } } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive if (value > uint256(type(int256).max)) { revert SafeCastOverflowedUintToInt(value); } return int256(value); } } // File: @openzeppelin/[email protected]/interfaces/IERC6372.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC6372.sol) pragma solidity ^0.8.20; interface IERC6372 { /** * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting). */ function clock() external view returns (uint48); /** * @dev Description of the clock */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() external view returns (string memory); } // File: @openzeppelin/[email protected]/governance/utils/IVotes.sol // OpenZeppelin Contracts (last updated v5.0.0) (governance/utils/IVotes.sol) pragma solidity ^0.8.20; /** * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts. */ interface IVotes { /** * @dev The signature used has expired. */ error VotesExpiredSignature(uint256 expiry); /** * @dev Emitted when an account changes their delegate. */ event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); /** * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of voting units. */ event DelegateVotesChanged(address indexed delegate, uint256 previousVotes, uint256 newVotes); /** * @dev Returns the current amount of votes that `account` has. */ function getVotes(address account) external view returns (uint256); /** * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value at the end of the corresponding block. */ function getPastVotes(address account, uint256 timepoint) external view returns (uint256); /** * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value at the end of the corresponding block. * * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. * Votes that have not been delegated are still part of total supply, even though they would not participate in a * vote. */ function getPastTotalSupply(uint256 timepoint) external view returns (uint256); /** * @dev Returns the delegate that `account` has chosen. */ function delegates(address account) external view returns (address); /** * @dev Delegates votes from the sender to `delegatee`. */ function delegate(address delegatee) external; /** * @dev Delegates votes from signer to `delegatee`. */ function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external; } // File: @openzeppelin/[email protected]/interfaces/IERC5805.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5805.sol) pragma solidity ^0.8.20; interface IERC5805 is IERC6372, IVotes {} // File: @openzeppelin/[email protected]/utils/Nonces.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/Nonces.sol) pragma solidity ^0.8.20; /** * @dev Provides tracking nonces for addresses. Nonces will only increment. */ abstract contract Nonces { /** * @dev The nonce used for an `account` is not the expected current nonce. */ error InvalidAccountNonce(address account, uint256 currentNonce); mapping(address account => uint256) private _nonces; /** * @dev Returns the next unused nonce for an address. */ function nonces(address owner) public view virtual returns (uint256) { return _nonces[owner]; } /** * @dev Consumes a nonce. * * Returns the current value and increments nonce. */ function _useNonce(address owner) internal virtual returns (uint256) { // For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be // decremented or reset. This guarantees that the nonce never overflows. unchecked { // It is important to do x++ and not ++x here. return _nonces[owner]++; } } /** * @dev Same as {_useNonce} but checking that `nonce` is the next valid for `owner`. */ function _useCheckedNonce(address owner, uint256 nonce) internal virtual { uint256 current = _useNonce(owner); if (nonce != current) { revert InvalidAccountNonce(owner, current); } } } // File: @openzeppelin/[email protected]/interfaces/IERC5267.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol) pragma solidity ^0.8.20; interface IERC5267 { /** * @dev MAY be emitted to signal that the domain could have changed. */ event EIP712DomainChanged(); /** * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 * signature. */ function eip712Domain() external view returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ); } // File: @openzeppelin/[email protected]/utils/StorageSlot.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.20; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(newImplementation.code.length > 0); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } } // File: @openzeppelin/[email protected]/utils/ShortStrings.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/ShortStrings.sol) pragma solidity ^0.8.20; // | string | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | // | length | 0x BB | type ShortString is bytes32; /** * @dev This library provides functions to convert short memory strings * into a `ShortString` type that can be used as an immutable variable. * * Strings of arbitrary length can be optimized using this library if * they are short enough (up to 31 bytes) by packing them with their * length (1 byte) in a single EVM word (32 bytes). Additionally, a * fallback mechanism can be used for every other case. * * Usage example: * * ```solidity * contract Named { * using ShortStrings for *; * * ShortString private immutable _name; * string private _nameFallback; * * constructor(string memory contractName) { * _name = contractName.toShortStringWithFallback(_nameFallback); * } * * function name() external view returns (string memory) { * return _name.toStringWithFallback(_nameFallback); * } * } * ``` */ library ShortStrings { // Used as an identifier for strings longer than 31 bytes. bytes32 private constant FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF; error StringTooLong(string str); error InvalidShortString(); /** * @dev Encode a string of at most 31 chars into a `ShortString`. * * This will trigger a `StringTooLong` error is the input string is too long. */ function toShortString(string memory str) internal pure returns (ShortString) { bytes memory bstr = bytes(str); if (bstr.length > 31) { revert StringTooLong(str); } return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length)); } /** * @dev Decode a `ShortString` back to a "normal" string. */ function toString(ShortString sstr) internal pure returns (string memory) { uint256 len = byteLength(sstr); // using `new string(len)` would work locally but is not memory safe. string memory str = new string(32); /// @solidity memory-safe-assembly assembly { mstore(str, len) mstore(add(str, 0x20), sstr) } return str; } /** * @dev Return the length of a `ShortString`. */ function byteLength(ShortString sstr) internal pure returns (uint256) { uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF; if (result > 31) { revert InvalidShortString(); } return result; } /** * @dev Encode a string into a `ShortString`, or write it to storage if it is too long. */ function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) { if (bytes(value).length < 32) { return toShortString(value); } else { StorageSlot.getStringSlot(store).value = value; return ShortString.wrap(FALLBACK_SENTINEL); } } /** * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}. */ function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) { if (ShortString.unwrap(value) != FALLBACK_SENTINEL) { return toString(value); } else { return store; } } /** * @dev Return the length of a string that was encoded to `ShortString` or written to storage using * {setWithFallback}. * * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of * actual characters as the UTF-8 encoding of a single character can span over multiple bytes. */ function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) { if (ShortString.unwrap(value) != FALLBACK_SENTINEL) { return byteLength(value); } else { return bytes(store).length; } } } // File: @openzeppelin/[email protected]/utils/math/SignedMath.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } } // File: @openzeppelin/[email protected]/utils/math/Math.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol) pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Muldiv operation overflow. */ error MathOverflowedMulDiv(); enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an overflow flag. */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the 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 towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. return a / b; } // (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 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. if (denominator <= prod1) { revert MathOverflowedMulDiv(); } /////////////////////////////////////////////// // 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. uint256 twos = denominator & (0 - denominator); 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 (unsignedRoundsUp(rounding) && 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 * towards zero. * * 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 + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * 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 + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * 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 + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * 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 256, 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 + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } } // File: @openzeppelin/[email protected]/utils/types/Time.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/types/Time.sol) pragma solidity ^0.8.20; /** * @dev This library provides helpers for manipulating time-related objects. * * It uses the following types: * - `uint48` for timepoints * - `uint32` for durations * * While the library doesn't provide specific types for timepoints and duration, it does provide: * - a `Delay` type to represent duration that can be programmed to change value automatically at a given point * - additional helper functions */ library Time { using Time for *; /** * @dev Get the block timestamp as a Timepoint. */ function timestamp() internal view returns (uint48) { return SafeCast.toUint48(block.timestamp); } /** * @dev Get the block number as a Timepoint. */ function blockNumber() internal view returns (uint48) { return SafeCast.toUint48(block.number); } // ==================================================== Delay ===================================================== /** * @dev A `Delay` is a uint32 duration that can be programmed to change value automatically at a given point in the * future. The "effect" timepoint describes when the transitions happens from the "old" value to the "new" value. * This allows updating the delay applied to some operation while keeping some guarantees. * * In particular, the {update} function guarantees that if the delay is reduced, the old delay still applies for * some time. For example if the delay is currently 7 days to do an upgrade, the admin should not be able to set * the delay to 0 and upgrade immediately. If the admin wants to reduce the delay, the old delay (7 days) should * still apply for some time. * * * The `Delay` type is 112 bits long, and packs the following: * * ``` * | [uint48]: effect date (timepoint) * | | [uint32]: value before (duration) * ↓ ↓ ↓ [uint32]: value after (duration) * 0xAAAAAAAAAAAABBBBBBBBCCCCCCCC * ``` * * NOTE: The {get} and {withUpdate} functions operate using timestamps. Block number based delays are not currently * supported. */ type Delay is uint112; /** * @dev Wrap a duration into a Delay to add the one-step "update in the future" feature */ function toDelay(uint32 duration) internal pure returns (Delay) { return Delay.wrap(duration); } /** * @dev Get the value at a given timepoint plus the pending value and effect timepoint if there is a scheduled * change after this timepoint. If the effect timepoint is 0, then the pending value should not be considered. */ function _getFullAt(Delay self, uint48 timepoint) private pure returns (uint32, uint32, uint48) { (uint32 valueBefore, uint32 valueAfter, uint48 effect) = self.unpack(); return effect <= timepoint ? (valueAfter, 0, 0) : (valueBefore, valueAfter, effect); } /** * @dev Get the current value plus the pending value and effect timepoint if there is a scheduled change. If the * effect timepoint is 0, then the pending value should not be considered. */ function getFull(Delay self) internal view returns (uint32, uint32, uint48) { return _getFullAt(self, timestamp()); } /** * @dev Get the current value. */ function get(Delay self) internal view returns (uint32) { (uint32 delay, , ) = self.getFull(); return delay; } /** * @dev Update a Delay object so that it takes a new duration after a timepoint that is automatically computed to * enforce the old delay at the moment of the update. Returns the updated Delay object and the timestamp when the * new delay becomes effective. */ function withUpdate( Delay self, uint32 newValue, uint32 minSetback ) internal view returns (Delay updatedDelay, uint48 effect) { uint32 value = self.get(); uint32 setback = uint32(Math.max(minSetback, value > newValue ? value - newValue : 0)); effect = timestamp() + setback; return (pack(value, newValue, effect), effect); } /** * @dev Split a delay into its components: valueBefore, valueAfter and effect (transition timepoint). */ function unpack(Delay self) internal pure returns (uint32 valueBefore, uint32 valueAfter, uint48 effect) { uint112 raw = Delay.unwrap(self); valueAfter = uint32(raw); valueBefore = uint32(raw >> 32); effect = uint48(raw >> 64); return (valueBefore, valueAfter, effect); } /** * @dev pack the components into a Delay object. */ function pack(uint32 valueBefore, uint32 valueAfter, uint48 effect) internal pure returns (Delay) { return Delay.wrap((uint112(effect) << 64) | (uint112(valueBefore) << 32) | uint112(valueAfter)); } } // File: @openzeppelin/[email protected]/utils/structs/Checkpoints.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/Checkpoints.sol) // This file was procedurally generated from scripts/generate/templates/Checkpoints.js. pragma solidity ^0.8.20; /** * @dev This library defines the `Trace*` struct, for checkpointing values as they change at different points in * time, and later looking up past values by block number. See {Votes} as an example. * * To create a history of checkpoints define a variable type `Checkpoints.Trace*` in your contract, and store a new * checkpoint for the current transaction block using the {push} function. */ library Checkpoints { /** * @dev A value was attempted to be inserted on a past checkpoint. */ error CheckpointUnorderedInsertion(); struct Trace224 { Checkpoint224[] _checkpoints; } struct Checkpoint224 { uint32 _key; uint224 _value; } /** * @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint. * * Returns previous value and new value. * * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint32).max` key set will disable the * library. */ function push(Trace224 storage self, uint32 key, uint224 value) internal returns (uint224, uint224) { return _insert(self._checkpoints, key, value); } /** * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if * there is none. */ function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) { uint256 len = self._checkpoints.length; uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len); return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero * if there is none. */ function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) { uint256 len = self._checkpoints.length; uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero * if there is none. * * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high * keys). */ function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) { uint256 len = self._checkpoints.length; uint256 low = 0; uint256 high = len; if (len > 5) { uint256 mid = len - Math.sqrt(len); if (key < _unsafeAccess(self._checkpoints, mid)._key) { high = mid; } else { low = mid + 1; } } uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. */ function latest(Trace224 storage self) internal view returns (uint224) { uint256 pos = self._checkpoints.length; return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value * in the most recent checkpoint. */ function latestCheckpoint(Trace224 storage self) internal view returns (bool exists, uint32 _key, uint224 _value) { uint256 pos = self._checkpoints.length; if (pos == 0) { return (false, 0, 0); } else { Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1); return (true, ckpt._key, ckpt._value); } } /** * @dev Returns the number of checkpoint. */ function length(Trace224 storage self) internal view returns (uint256) { return self._checkpoints.length; } /** * @dev Returns checkpoint at given position. */ function at(Trace224 storage self, uint32 pos) internal view returns (Checkpoint224 memory) { return self._checkpoints[pos]; } /** * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, * or by updating the last one. */ function _insert(Checkpoint224[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) { uint256 pos = self.length; if (pos > 0) { // Copying to memory is important here. Checkpoint224 memory last = _unsafeAccess(self, pos - 1); // Checkpoint keys must be non-decreasing. if (last._key > key) { revert CheckpointUnorderedInsertion(); } // Update or push new checkpoint if (last._key == key) { _unsafeAccess(self, pos - 1)._value = value; } else { self.push(Checkpoint224({_key: key, _value: value})); } return (last._value, value); } else { self.push(Checkpoint224({_key: key, _value: value})); return (0, value); } } /** * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive * `high`. * * WARNING: `high` should not be greater than the array's length. */ function _upperBinaryLookup( Checkpoint224[] storage self, uint32 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key > key) { high = mid; } else { low = mid + 1; } } return high; } /** * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or * `high` if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and * exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _lowerBinaryLookup( Checkpoint224[] storage self, uint32 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key < key) { low = mid + 1; } else { high = mid; } } return high; } /** * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. */ function _unsafeAccess( Checkpoint224[] storage self, uint256 pos ) private pure returns (Checkpoint224 storage result) { assembly { mstore(0, self.slot) result.slot := add(keccak256(0, 0x20), pos) } } struct Trace208 { Checkpoint208[] _checkpoints; } struct Checkpoint208 { uint48 _key; uint208 _value; } /** * @dev Pushes a (`key`, `value`) pair into a Trace208 so that it is stored as the checkpoint. * * Returns previous value and new value. * * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint48).max` key set will disable the * library. */ function push(Trace208 storage self, uint48 key, uint208 value) internal returns (uint208, uint208) { return _insert(self._checkpoints, key, value); } /** * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if * there is none. */ function lowerLookup(Trace208 storage self, uint48 key) internal view returns (uint208) { uint256 len = self._checkpoints.length; uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len); return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero * if there is none. */ function upperLookup(Trace208 storage self, uint48 key) internal view returns (uint208) { uint256 len = self._checkpoints.length; uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero * if there is none. * * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high * keys). */ function upperLookupRecent(Trace208 storage self, uint48 key) internal view returns (uint208) { uint256 len = self._checkpoints.length; uint256 low = 0; uint256 high = len; if (len > 5) { uint256 mid = len - Math.sqrt(len); if (key < _unsafeAccess(self._checkpoints, mid)._key) { high = mid; } else { low = mid + 1; } } uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. */ function latest(Trace208 storage self) internal view returns (uint208) { uint256 pos = self._checkpoints.length; return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value * in the most recent checkpoint. */ function latestCheckpoint(Trace208 storage self) internal view returns (bool exists, uint48 _key, uint208 _value) { uint256 pos = self._checkpoints.length; if (pos == 0) { return (false, 0, 0); } else { Checkpoint208 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1); return (true, ckpt._key, ckpt._value); } } /** * @dev Returns the number of checkpoint. */ function length(Trace208 storage self) internal view returns (uint256) { return self._checkpoints.length; } /** * @dev Returns checkpoint at given position. */ function at(Trace208 storage self, uint32 pos) internal view returns (Checkpoint208 memory) { return self._checkpoints[pos]; } /** * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, * or by updating the last one. */ function _insert(Checkpoint208[] storage self, uint48 key, uint208 value) private returns (uint208, uint208) { uint256 pos = self.length; if (pos > 0) { // Copying to memory is important here. Checkpoint208 memory last = _unsafeAccess(self, pos - 1); // Checkpoint keys must be non-decreasing. if (last._key > key) { revert CheckpointUnorderedInsertion(); } // Update or push new checkpoint if (last._key == key) { _unsafeAccess(self, pos - 1)._value = value; } else { self.push(Checkpoint208({_key: key, _value: value})); } return (last._value, value); } else { self.push(Checkpoint208({_key: key, _value: value})); return (0, value); } } /** * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive * `high`. * * WARNING: `high` should not be greater than the array's length. */ function _upperBinaryLookup( Checkpoint208[] storage self, uint48 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key > key) { high = mid; } else { low = mid + 1; } } return high; } /** * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or * `high` if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and * exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _lowerBinaryLookup( Checkpoint208[] storage self, uint48 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key < key) { low = mid + 1; } else { high = mid; } } return high; } /** * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. */ function _unsafeAccess( Checkpoint208[] storage self, uint256 pos ) private pure returns (Checkpoint208 storage result) { assembly { mstore(0, self.slot) result.slot := add(keccak256(0, 0x20), pos) } } struct Trace160 { Checkpoint160[] _checkpoints; } struct Checkpoint160 { uint96 _key; uint160 _value; } /** * @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint. * * Returns previous value and new value. * * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint96).max` key set will disable the * library. */ function push(Trace160 storage self, uint96 key, uint160 value) internal returns (uint160, uint160) { return _insert(self._checkpoints, key, value); } /** * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if * there is none. */ function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) { uint256 len = self._checkpoints.length; uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len); return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero * if there is none. */ function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) { uint256 len = self._checkpoints.length; uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero * if there is none. * * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high * keys). */ function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) { uint256 len = self._checkpoints.length; uint256 low = 0; uint256 high = len; if (len > 5) { uint256 mid = len - Math.sqrt(len); if (key < _unsafeAccess(self._checkpoints, mid)._key) { high = mid; } else { low = mid + 1; } } uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. */ function latest(Trace160 storage self) internal view returns (uint160) { uint256 pos = self._checkpoints.length; return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value * in the most recent checkpoint. */ function latestCheckpoint(Trace160 storage self) internal view returns (bool exists, uint96 _key, uint160 _value) { uint256 pos = self._checkpoints.length; if (pos == 0) { return (false, 0, 0); } else { Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1); return (true, ckpt._key, ckpt._value); } } /** * @dev Returns the number of checkpoint. */ function length(Trace160 storage self) internal view returns (uint256) { return self._checkpoints.length; } /** * @dev Returns checkpoint at given position. */ function at(Trace160 storage self, uint32 pos) internal view returns (Checkpoint160 memory) { return self._checkpoints[pos]; } /** * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, * or by updating the last one. */ function _insert(Checkpoint160[] storage self, uint96 key, uint160 value) private returns (uint160, uint160) { uint256 pos = self.length; if (pos > 0) { // Copying to memory is important here. Checkpoint160 memory last = _unsafeAccess(self, pos - 1); // Checkpoint keys must be non-decreasing. if (last._key > key) { revert CheckpointUnorderedInsertion(); } // Update or push new checkpoint if (last._key == key) { _unsafeAccess(self, pos - 1)._value = value; } else { self.push(Checkpoint160({_key: key, _value: value})); } return (last._value, value); } else { self.push(Checkpoint160({_key: key, _value: value})); return (0, value); } } /** * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive * `high`. * * WARNING: `high` should not be greater than the array's length. */ function _upperBinaryLookup( Checkpoint160[] storage self, uint96 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key > key) { high = mid; } else { low = mid + 1; } } return high; } /** * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or * `high` if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and * exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _lowerBinaryLookup( Checkpoint160[] storage self, uint96 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key < key) { low = mid + 1; } else { high = mid; } } return high; } /** * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. */ function _unsafeAccess( Checkpoint160[] storage self, uint256 pos ) private pure returns (Checkpoint160 storage result) { assembly { mstore(0, self.slot) result.slot := add(keccak256(0, 0x20), pos) } } } // File: @openzeppelin/[email protected]/utils/Strings.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol) pragma solidity ^0.8.20; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @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), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @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) { uint256 localValue = value; bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } 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 Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } } // File: @openzeppelin/[email protected]/utils/cryptography/MessageHashUtils.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MessageHashUtils.sol) pragma solidity ^0.8.20; /** * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing. * * The library provides methods for generating a hash of a message that conforms to the * https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712] * specifications. */ library MessageHashUtils { /** * @dev Returns the keccak256 digest of an EIP-191 signed data with version * `0x45` (`personal_sign` messages). * * The digest is calculated by prefixing a bytes32 `messageHash` with * `"\x19Ethereum Signed Message:\n32"` and hashing the result. It corresponds with the * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. * * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with * keccak256, although any bytes32 value can be safely used because the final digest will * be re-hashed. * * See {ECDSA-recover}. */ function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) { /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") // 32 is the bytes-length of messageHash mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20) } } /** * @dev Returns the keccak256 digest of an EIP-191 signed data with version * `0x45` (`personal_sign` messages). * * The digest is calculated by prefixing an arbitrary `message` with * `"\x19Ethereum Signed Message:\n" + len(message)` and hashing the result. It corresponds with the * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. * * See {ECDSA-recover}. */ function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) { return keccak256(bytes.concat("\x19Ethereum Signed Message:\n", bytes(Strings.toString(message.length)), message)); } /** * @dev Returns the keccak256 digest of an EIP-191 signed data with version * `0x00` (data with intended validator). * * The digest is calculated by prefixing an arbitrary `data` with `"\x19\x00"` and the intended * `validator` address. Then hashing the result. * * See {ECDSA-recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked(hex"19_00", validator, data)); } /** * @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`). * * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with * `\x19\x01` and hashing the result. It corresponds to the hash signed by the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712. * * See {ECDSA-recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, hex"19_01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) digest := keccak256(ptr, 0x42) } } } // File: @openzeppelin/[email protected]/utils/cryptography/EIP712.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/EIP712.sol) pragma solidity ^0.8.20; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose * encoding is very generic and therefore its implementation in Solidity is not feasible, thus this contract * does not implement the encoding itself. Protocols need to implement the type-specific encoding they need in order to * produce the hash of their typed data using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain * separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. * * @custom:oz-upgrades-unsafe-allow state-variable-immutable */ abstract contract EIP712 is IERC5267 { using ShortStrings for *; bytes32 private constant TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _cachedDomainSeparator; uint256 private immutable _cachedChainId; address private immutable _cachedThis; bytes32 private immutable _hashedName; bytes32 private immutable _hashedVersion; ShortString private immutable _name; ShortString private immutable _version; string private _nameFallback; string private _versionFallback; /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { _name = name.toShortStringWithFallback(_nameFallback); _version = version.toShortStringWithFallback(_versionFallback); _hashedName = keccak256(bytes(name)); _hashedVersion = keccak256(bytes(version)); _cachedChainId = block.chainid; _cachedDomainSeparator = _buildDomainSeparator(); _cachedThis = address(this); } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _cachedThis && block.chainid == _cachedChainId) { return _cachedDomainSeparator; } else { return _buildDomainSeparator(); } } function _buildDomainSeparator() private view returns (bytes32) { return keccak256(abi.encode(TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev See {IERC-5267}. */ function eip712Domain() public view virtual returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { return ( hex"0f", // 01111 _EIP712Name(), _EIP712Version(), block.chainid, address(this), bytes32(0), new uint256[](0) ); } /** * @dev The name parameter for the EIP712 domain. * * NOTE: By default this function reads _name which is an immutable value. * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). */ // solhint-disable-next-line func-name-mixedcase function _EIP712Name() internal view returns (string memory) { return _name.toStringWithFallback(_nameFallback); } /** * @dev The version parameter for the EIP712 domain. * * NOTE: By default this function reads _version which is an immutable value. * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). */ // solhint-disable-next-line func-name-mixedcase function _EIP712Version() internal view returns (string memory) { return _version.toStringWithFallback(_versionFallback); } } // File: @openzeppelin/[email protected]/utils/cryptography/ECDSA.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.20; /** * @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 } /** * @dev The signature derives the `address(0)`. */ error ECDSAInvalidSignature(); /** * @dev The signature has an invalid length. */ error ECDSAInvalidSignatureLength(uint256 length); /** * @dev The signature has an S value that is in the upper half order. */ error ECDSAInvalidSignatureS(bytes32 s); /** * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not * return address(0) without also returning an error description. Errors are documented using an enum (error type) * and a bytes32 providing additional information about the error. * * If no error is returned, then the address can be used for verification purposes. * * The `ecrecover` EVM precompile 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 {MessageHashUtils-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] */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) { 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, bytes32(signature.length)); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM precompile 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 {MessageHashUtils-toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature); _throwError(error, errorArg); 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] */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) { unchecked { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); // We do not check for an overflow here since the shift operation results in 0 or 1. 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. */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs); _throwError(error, errorArg); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError, bytes32) { // 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, s); } // 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, bytes32(0)); } return (signer, RecoverError.NoError, bytes32(0)); } /** * @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, bytes32 errorArg) = tryRecover(hash, v, r, s); _throwError(error, errorArg); return recovered; } /** * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided. */ function _throwError(RecoverError error, bytes32 errorArg) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert ECDSAInvalidSignature(); } else if (error == RecoverError.InvalidSignatureLength) { revert ECDSAInvalidSignatureLength(uint256(errorArg)); } else if (error == RecoverError.InvalidSignatureS) { revert ECDSAInvalidSignatureS(errorArg); } } } // File: @openzeppelin/[email protected]/token/ERC20/extensions/IERC20Permit.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // File: @openzeppelin/[email protected]/interfaces/draft-IERC6093.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); } // File: @openzeppelin/[email protected]/utils/Context.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/[email protected]/access/AccessControl.sol // OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol) pragma solidity ^0.8.20; /** * @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: * * ```solidity * 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}: * * ```solidity * 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. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address account => bool) hasRole; bytes32 adminRole; } mapping(bytes32 role => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with an {AccessControlUnauthorizedAccount} error including the required role. */ 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 returns (bool) { return _roles[role].hasRole[account]; } /** * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()` * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier. */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account` * is missing `role`. */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert AccessControlUnauthorizedAccount(account, role); } } /** * @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 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 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 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 `callerConfirmation`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address callerConfirmation) public virtual { if (callerConfirmation != _msgSender()) { revert AccessControlBadConfirmation(); } _revokeRole(role, callerConfirmation); } /** * @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 Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual returns (bool) { if (!hasRole(role, account)) { _roles[role].hasRole[account] = true; emit RoleGranted(role, account, _msgSender()); return true; } else { return false; } } /** * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual returns (bool) { if (hasRole(role, account)) { _roles[role].hasRole[account] = false; emit RoleRevoked(role, account, _msgSender()); return true; } else { return false; } } } // File: @openzeppelin/[email protected]/governance/utils/Votes.sol // OpenZeppelin Contracts (last updated v5.0.0) (governance/utils/Votes.sol) pragma solidity ^0.8.20; /** * @dev This is a base abstract contract that tracks voting units, which are a measure of voting power that can be * transferred, and provides a system of vote delegation, where an account can delegate its voting units to a sort of * "representative" that will pool delegated voting units from different accounts and can then use it to vote in * decisions. In fact, voting units _must_ be delegated in order to count as actual votes, and an account has to * delegate those votes to itself if it wishes to participate in decisions and does not have a trusted representative. * * This contract is often combined with a token contract such that voting units correspond to token units. For an * example, see {ERC721Votes}. * * The full history of delegate votes is tracked on-chain so that governance protocols can consider votes as distributed * at a particular block number to protect against flash loans and double voting. The opt-in delegate system makes the * cost of this history tracking optional. * * When using this module the derived contract must implement {_getVotingUnits} (for example, make it return * {ERC721-balanceOf}), and can use {_transferVotingUnits} to track a change in the distribution of those units (in the * previous example, it would be included in {ERC721-_update}). */ abstract contract Votes is Context, EIP712, Nonces, IERC5805 { using Checkpoints for Checkpoints.Trace208; bytes32 private constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); mapping(address account => address) private _delegatee; mapping(address delegatee => Checkpoints.Trace208) private _delegateCheckpoints; Checkpoints.Trace208 private _totalCheckpoints; /** * @dev The clock was incorrectly modified. */ error ERC6372InconsistentClock(); /** * @dev Lookup to future votes is not available. */ error ERC5805FutureLookup(uint256 timepoint, uint48 clock); /** * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based * checkpoints (and voting), in which case {CLOCK_MODE} should be overridden as well to match. */ function clock() public view virtual returns (uint48) { return Time.blockNumber(); } /** * @dev Machine-readable description of the clock as specified in EIP-6372. */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() public view virtual returns (string memory) { // Check that the clock was not modified if (clock() != Time.blockNumber()) { revert ERC6372InconsistentClock(); } return "mode=blocknumber&from=default"; } /** * @dev Returns the current amount of votes that `account` has. */ function getVotes(address account) public view virtual returns (uint256) { return _delegateCheckpoints[account].latest(); } /** * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value at the end of the corresponding block. * * Requirements: * * - `timepoint` must be in the past. If operating using block numbers, the block must be already mined. */ function getPastVotes(address account, uint256 timepoint) public view virtual returns (uint256) { uint48 currentTimepoint = clock(); if (timepoint >= currentTimepoint) { revert ERC5805FutureLookup(timepoint, currentTimepoint); } return _delegateCheckpoints[account].upperLookupRecent(SafeCast.toUint48(timepoint)); } /** * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value at the end of the corresponding block. * * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. * Votes that have not been delegated are still part of total supply, even though they would not participate in a * vote. * * Requirements: * * - `timepoint` must be in the past. If operating using block numbers, the block must be already mined. */ function getPastTotalSupply(uint256 timepoint) public view virtual returns (uint256) { uint48 currentTimepoint = clock(); if (timepoint >= currentTimepoint) { revert ERC5805FutureLookup(timepoint, currentTimepoint); } return _totalCheckpoints.upperLookupRecent(SafeCast.toUint48(timepoint)); } /** * @dev Returns the current total supply of votes. */ function _getTotalSupply() internal view virtual returns (uint256) { return _totalCheckpoints.latest(); } /** * @dev Returns the delegate that `account` has chosen. */ function delegates(address account) public view virtual returns (address) { return _delegatee[account]; } /** * @dev Delegates votes from the sender to `delegatee`. */ function delegate(address delegatee) public virtual { address account = _msgSender(); _delegate(account, delegatee); } /** * @dev Delegates votes from signer to `delegatee`. */ function delegateBySig( address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) public virtual { if (block.timestamp > expiry) { revert VotesExpiredSignature(expiry); } address signer = ECDSA.recover( _hashTypedDataV4(keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry))), v, r, s ); _useCheckedNonce(signer, nonce); _delegate(signer, delegatee); } /** * @dev Delegate all of `account`'s voting units to `delegatee`. * * Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}. */ function _delegate(address account, address delegatee) internal virtual { address oldDelegate = delegates(account); _delegatee[account] = delegatee; emit DelegateChanged(account, oldDelegate, delegatee); _moveDelegateVotes(oldDelegate, delegatee, _getVotingUnits(account)); } /** * @dev Transfers, mints, or burns voting units. To register a mint, `from` should be zero. To register a burn, `to` * should be zero. Total supply of voting units will be adjusted with mints and burns. */ function _transferVotingUnits(address from, address to, uint256 amount) internal virtual { if (from == address(0)) { _push(_totalCheckpoints, _add, SafeCast.toUint208(amount)); } if (to == address(0)) { _push(_totalCheckpoints, _subtract, SafeCast.toUint208(amount)); } _moveDelegateVotes(delegates(from), delegates(to), amount); } /** * @dev Moves delegated votes from one delegate to another. */ function _moveDelegateVotes(address from, address to, uint256 amount) private { if (from != to && amount > 0) { if (from != address(0)) { (uint256 oldValue, uint256 newValue) = _push( _delegateCheckpoints[from], _subtract, SafeCast.toUint208(amount) ); emit DelegateVotesChanged(from, oldValue, newValue); } if (to != address(0)) { (uint256 oldValue, uint256 newValue) = _push( _delegateCheckpoints[to], _add, SafeCast.toUint208(amount) ); emit DelegateVotesChanged(to, oldValue, newValue); } } } /** * @dev Get number of checkpoints for `account`. */ function _numCheckpoints(address account) internal view virtual returns (uint32) { return SafeCast.toUint32(_delegateCheckpoints[account].length()); } /** * @dev Get the `pos`-th checkpoint for `account`. */ function _checkpoints( address account, uint32 pos ) internal view virtual returns (Checkpoints.Checkpoint208 memory) { return _delegateCheckpoints[account].at(pos); } function _push( Checkpoints.Trace208 storage store, function(uint208, uint208) view returns (uint208) op, uint208 delta ) private returns (uint208, uint208) { return store.push(clock(), op(store.latest(), delta)); } function _add(uint208 a, uint208 b) private pure returns (uint208) { return a + b; } function _subtract(uint208 a, uint208 b) private pure returns (uint208) { return a - b; } /** * @dev Must return the voting units held by an account. */ function _getVotingUnits(address) internal view virtual returns (uint256); } // File: @openzeppelin/[email protected]/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @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 value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` 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 value) external returns (bool); } // File: @openzeppelin/[email protected]/token/ERC20/extensions/IERC20Metadata.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; /** * @dev Interface for the optional metadata functions from the ERC20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File: @openzeppelin/[email protected]/token/ERC20/ERC20.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.20; /** * @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}. * * 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]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * 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. */ abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors { mapping(address account => uint256) private _balances; mapping(address account => mapping(address spender => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * 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 returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens 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 default value returned by this function, unless * it's 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 returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual 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 `value`. */ function transfer(address to, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _transfer(owner, to, value); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `value` 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 value) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, value); 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 `value`. * - the caller must have allowance for ``from``'s tokens of at least * `value`. */ function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, value); _transfer(from, to, value); return true; } /** * @dev Moves a `value` 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. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _transfer(address from, address to, uint256 value) internal { if (from == address(0)) { revert ERC20InvalidSender(address(0)); } if (to == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(from, to, value); } /** * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding * this function. * * Emits a {Transfer} event. */ function _update(address from, address to, uint256 value) internal virtual { if (from == address(0)) { // Overflow check required: The rest of the code assumes that totalSupply never overflows _totalSupply += value; } else { uint256 fromBalance = _balances[from]; if (fromBalance < value) { revert ERC20InsufficientBalance(from, fromBalance, value); } unchecked { // Overflow not possible: value <= fromBalance <= totalSupply. _balances[from] = fromBalance - value; } } if (to == address(0)) { unchecked { // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply. _totalSupply -= value; } } else { unchecked { // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. _balances[to] += value; } } emit Transfer(from, to, value); } /** * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). * Relies on the `_update` mechanism * * Emits a {Transfer} event with `from` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _mint(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(address(0), account, value); } /** * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. * Relies on the `_update` mechanism. * * Emits a {Transfer} event with `to` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead */ function _burn(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidSender(address(0)); } _update(account, address(0), value); } /** * @dev Sets `value` 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. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address owner, address spender, uint256 value) internal { _approve(owner, spender, value, true); } /** * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event. * * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any * `Approval` event during `transferFrom` operations. * * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to * true using the following override: * ``` * function _approve(address owner, address spender, uint256 value, bool) internal virtual override { * super._approve(owner, spender, value, true); * } * ``` * * Requirements are the same as {_approve}. */ function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual { if (owner == address(0)) { revert ERC20InvalidApprover(address(0)); } if (spender == address(0)) { revert ERC20InvalidSpender(address(0)); } _allowances[owner][spender] = value; if (emitEvent) { emit Approval(owner, spender, value); } } /** * @dev Updates `owner` s allowance for `spender` based on spent `value`. * * Does not update the allowance value in case of infinite allowance. * Revert if not enough allowance is available. * * Does not emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 value) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { if (currentAllowance < value) { revert ERC20InsufficientAllowance(spender, currentAllowance, value); } unchecked { _approve(owner, spender, currentAllowance - value, false); } } } } // File: @openzeppelin/[email protected]/token/ERC20/extensions/ERC20Votes.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Votes.sol) pragma solidity ^0.8.20; /** * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's, * and supports token supply up to 2^208^ - 1, while COMP is limited to 2^96^ - 1. * * NOTE: This contract does not provide interface compatibility with Compound's COMP token. * * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting * power can be queried through the public accessors {getVotes} and {getPastVotes}. * * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked. */ abstract contract ERC20Votes is ERC20, Votes { /** * @dev Total supply cap has been exceeded, introducing a risk of votes overflowing. */ error ERC20ExceededSafeSupply(uint256 increasedSupply, uint256 cap); /** * @dev Maximum token supply. Defaults to `type(uint208).max` (2^208^ - 1). * * This maximum is enforced in {_update}. It limits the total supply of the token, which is otherwise a uint256, * so that checkpoints can be stored in the Trace208 structure used by {{Votes}}. Increasing this value will not * remove the underlying limitation, and will cause {_update} to fail because of a math overflow in * {_transferVotingUnits}. An override could be used to further restrict the total supply (to a lower value) if * additional logic requires it. When resolving override conflicts on this function, the minimum should be * returned. */ function _maxSupply() internal view virtual returns (uint256) { return type(uint208).max; } /** * @dev Move voting power when tokens are transferred. * * Emits a {IVotes-DelegateVotesChanged} event. */ function _update(address from, address to, uint256 value) internal virtual override { super._update(from, to, value); if (from == address(0)) { uint256 supply = totalSupply(); uint256 cap = _maxSupply(); if (supply > cap) { revert ERC20ExceededSafeSupply(supply, cap); } } _transferVotingUnits(from, to, value); } /** * @dev Returns the voting units of an `account`. * * WARNING: Overriding this function may compromise the internal vote accounting. * `ERC20Votes` assumes tokens map to voting units 1:1 and this is not easy to change. */ function _getVotingUnits(address account) internal view virtual override returns (uint256) { return balanceOf(account); } /** * @dev Get number of checkpoints for `account`. */ function numCheckpoints(address account) public view virtual returns (uint32) { return _numCheckpoints(account); } /** * @dev Get the `pos`-th checkpoint for `account`. */ function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoints.Checkpoint208 memory) { return _checkpoints(account, pos); } } // File: @openzeppelin/[email protected]/token/ERC20/extensions/ERC20Permit.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Permit.sol) pragma solidity ^0.8.20; /** * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712, Nonces { bytes32 private constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); /** * @dev Permit deadline has expired. */ error ERC2612ExpiredSignature(uint256 deadline); /** * @dev Mismatched signature. */ error ERC2612InvalidSigner(address signer, address owner); /** * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`. * * It's a good idea to use the same `name` that is defined as the ERC20 token name. */ constructor(string memory name) EIP712(name, "1") {} /** * @inheritdoc IERC20Permit */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { if (block.timestamp > deadline) { revert ERC2612ExpiredSignature(deadline); } bytes32 structHash = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); bytes32 hash = _hashTypedDataV4(structHash); address signer = ECDSA.recover(hash, v, r, s); if (signer != owner) { revert ERC2612InvalidSigner(signer, owner); } _approve(owner, spender, value); } /** * @inheritdoc IERC20Permit */ function nonces(address owner) public view virtual override(IERC20Permit, Nonces) returns (uint256) { return super.nonces(owner); } /** * @inheritdoc IERC20Permit */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view virtual returns (bytes32) { return _domainSeparatorV4(); } } // File: @openzeppelin/[email protected]/token/ERC20/extensions/ERC20Burnable.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Burnable.sol) pragma solidity ^0.8.20; /** * @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 a `value` amount of tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 value) public virtual { _burn(_msgSender(), value); } /** * @dev Destroys a `value` amount of 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 * `value`. */ function burnFrom(address account, uint256 value) public virtual { _spendAllowance(account, _msgSender(), value); _burn(account, value); } } // File: contracts/Inspect.sol pragma solidity ^0.8.20; contract Inspect is ERC20, ERC20Burnable, ERC20Permit, ERC20Votes, AccessControl { constructor() ERC20("Inspect", "INSP") ERC20Permit("Inspect") { address adminOwner = 0xD79c8FD0393237fDF9BE92C839a23415f576E370; _grantRole(DEFAULT_ADMIN_ROLE, adminOwner); uint256 a_1 = 1000000000 * 10 ** uint256(decimals()) * 1250 / 10000; //12.5 uint256 a_2 = 1000000000 * 10 ** uint256(decimals()) * 1200 / 10000; //12 uint256 a_3 = 1000000000 * 10 ** uint256(decimals()) * 20 / 10000; //0.20 uint256 a_4 = 1000000000 * 10 ** uint256(decimals()) * 133 / 10000; //1.33 uint256 a_5 = 1000000000 * 10 ** uint256(decimals()) * 1250 / 10000; //12.5 uint256 a_6 = 1000000000 * 10 ** uint256(decimals()) * 1747 / 10000; //17.47 uint256 a_7 = 1000000000 * 10 ** uint256(decimals()) * 500 / 10000; //5 uint256 a_8 = 1000000000 * 10 ** uint256(decimals()) * 800 / 10000; //8 uint256 a_9 = 1000000000 * 10 ** uint256(decimals()) * 1600 / 10000; //16 uint256 a_10 = 1000000000 * 10 ** uint256(decimals()) * 1500 / 10000; //15 _mint(0x9ccC8541c573964c6253a56e985c0E629e4f4459, a_1); _mint(0x3224d23DDB9c936D1d393014D4c331026B4dDC1C, a_2); _mint(0xb5F70C907EF376BdDCBD57c35Ab2FF188045aD8c, a_3); _mint(0x489E3c5E6d1b0469Bb307C19bCD0c71B4419582e, a_4); _mint(0xa7097330cdA09A76798Cf55420BCeD559b78843a, a_5); _mint(0xc4BE3d5068CBDa558004985529DfDA264837dF8a, a_6); _mint(0xA9Fdb3d6426d490C3c97B74D1Ddf46C41a981784, a_7); _mint(0x1287F0b9231d7958b4526916506AF43DaC591789, a_8); _mint(0x7adf3131C497666a1fF97a81b3f84a3ED1F25968, a_9); _mint(0x929A9C1E4ff1A88fAD071130220D302bE0c4Fc3d, a_10); } function _update(address from, address to, uint256 value) internal override(ERC20, ERC20Votes) { super._update(from, to, value); } function nonces(address owner) public view override(ERC20Permit, Nonces) returns (uint256) { return super.nonces(owner); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[],"name":"CheckpointUnorderedInsertion","type":"error"},{"inputs":[],"name":"ECDSAInvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"ECDSAInvalidSignatureLength","type":"error"},{"inputs":[{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"ECDSAInvalidSignatureS","type":"error"},{"inputs":[{"internalType":"uint256","name":"increasedSupply","type":"uint256"},{"internalType":"uint256","name":"cap","type":"uint256"}],"name":"ERC20ExceededSafeSupply","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"ERC2612ExpiredSignature","type":"error"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC2612InvalidSigner","type":"error"},{"inputs":[{"internalType":"uint256","name":"timepoint","type":"uint256"},{"internalType":"uint48","name":"clock","type":"uint48"}],"name":"ERC5805FutureLookup","type":"error"},{"inputs":[],"name":"ERC6372InconsistentClock","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"currentNonce","type":"uint256"}],"name":"InvalidAccountNonce","type":"error"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[{"internalType":"uint8","name":"bits","type":"uint8"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SafeCastOverflowedUintDowncast","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"inputs":[{"internalType":"uint256","name":"expiry","type":"uint256"}],"name":"VotesExpiredSignature","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousVotes","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newVotes","type":"uint256"}],"name":"DelegateVotesChanged","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","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"},{"inputs":[],"name":"CLOCK_MODE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","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":"value","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":"value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint32","name":"pos","type":"uint32"}],"name":"checkpoints","outputs":[{"components":[{"internalType":"uint48","name":"_key","type":"uint48"},{"internalType":"uint208","name":"_value","type":"uint208"}],"internalType":"struct Checkpoints.Checkpoint208","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"clock","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"getPastTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"getPastVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"numCheckpoints","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","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":"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":"value","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":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
61016060405234801562000011575f80fd5b506040518060400160405280600781526020017f496e737065637400000000000000000000000000000000000000000000000000815250806040518060400160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152506040518060400160405280600781526020017f496e7370656374000000000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f494e5350000000000000000000000000000000000000000000000000000000008152508160039081620000fc919062001920565b5080600490816200010e919062001920565b50505062000127600583620006b860201b90919060201c565b610120818152505062000145600682620006b860201b90919060201c565b6101408181525050818051906020012060e08181525050808051906020012061010081815250504660a08181525050620001846200070d60201b60201c565b608081815250503073ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff16815250505050505f73d79c8fd0393237fdf9be92c839a23415f576e3709050620001ee5f801b826200076960201b60201c565b505f6127106104e2620002066200086560201b60201c565b60ff16600a62000217919062001b81565b633b9aca0062000228919062001bd1565b62000234919062001bd1565b62000240919062001c48565b90505f6127106104b0620002596200086560201b60201c565b60ff16600a6200026a919062001b81565b633b9aca006200027b919062001bd1565b62000287919062001bd1565b62000293919062001c48565b90505f6127106014620002ab6200086560201b60201c565b60ff16600a620002bc919062001b81565b633b9aca00620002cd919062001bd1565b620002d9919062001bd1565b620002e5919062001c48565b90505f6127106085620002fd6200086560201b60201c565b60ff16600a6200030e919062001b81565b633b9aca006200031f919062001bd1565b6200032b919062001bd1565b62000337919062001c48565b90505f6127106104e2620003506200086560201b60201c565b60ff16600a62000361919062001b81565b633b9aca0062000372919062001bd1565b6200037e919062001bd1565b6200038a919062001c48565b90505f6127106106d3620003a36200086560201b60201c565b60ff16600a620003b4919062001b81565b633b9aca00620003c5919062001bd1565b620003d1919062001bd1565b620003dd919062001c48565b90505f6127106101f4620003f66200086560201b60201c565b60ff16600a62000407919062001b81565b633b9aca0062000418919062001bd1565b62000424919062001bd1565b62000430919062001c48565b90505f612710610320620004496200086560201b60201c565b60ff16600a6200045a919062001b81565b633b9aca006200046b919062001bd1565b62000477919062001bd1565b62000483919062001c48565b90505f6127106106406200049c6200086560201b60201c565b60ff16600a620004ad919062001b81565b633b9aca00620004be919062001bd1565b620004ca919062001bd1565b620004d6919062001c48565b90505f6127106105dc620004ef6200086560201b60201c565b60ff16600a62000500919062001b81565b633b9aca0062000511919062001bd1565b6200051d919062001bd1565b62000529919062001c48565b905062000551739ccc8541c573964c6253a56e985c0e629e4f44598b6200086d60201b60201c565b62000577733224d23ddb9c936d1d393014d4c331026b4ddc1c8a6200086d60201b60201c565b6200059d73b5f70c907ef376bddcbd57c35ab2ff188045ad8c896200086d60201b60201c565b620005c373489e3c5e6d1b0469bb307c19bcd0c71b4419582e886200086d60201b60201c565b620005e973a7097330cda09a76798cf55420bced559b78843a876200086d60201b60201c565b6200060f73c4be3d5068cbda558004985529dfda264837df8a866200086d60201b60201c565b6200063573a9fdb3d6426d490c3c97b74d1ddf46c41a981784856200086d60201b60201c565b6200065b731287f0b9231d7958b4526916506af43dac591789846200086d60201b60201c565b62000681737adf3131c497666a1ff97a81b3f84a3ed1f25968836200086d60201b60201c565b620006a773929a9c1e4ff1a88fad071130220d302be0c4fc3d826200086d60201b60201c565b505050505050505050505062002153565b5f602083511015620006dd57620006d583620008f760201b60201c565b905062000707565b82620006ef836200096160201b60201c565b5f019081620006ff919062001920565b5060ff5f1b90505b92915050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60e0516101005146306040516020016200074e95949392919062001ced565b60405160208183030381529060405280519060200120905090565b5f6200077c83836200096a60201b60201c565b6200085b576001600b5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550620007f7620009ce60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4600190506200085f565b5f90505b92915050565b5f6012905090565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603620008e0575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401620008d7919062001d48565b60405180910390fd5b620008f35f8383620009d560201b60201c565b5050565b5f80829050601f815111156200094657826040517f305a27a90000000000000000000000000000000000000000000000000000000081526004016200093d919062001ded565b60405180910390fd5b805181620009549062001e3e565b5f1c175f1b915050919050565b5f819050919050565b5f600b5f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f33905090565b620009e8838383620009ed60201b60201c565b505050565b62000a0083838362000abf60201b60201c565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160362000aa7575f62000a4562000ce360201b60201c565b90505f62000a5862000cec60201b60201c565b90508082111562000aa45781816040517f1cb15d2600000000000000000000000000000000000000000000000000000000815260040162000a9b92919062001ead565b60405180910390fd5b50505b62000aba83838362000d0f60201b60201c565b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160362000b13578060025f82825462000b06919062001ed8565b9250508190555062000be4565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490508181101562000b9f578381836040517fe450d38c00000000000000000000000000000000000000000000000000000000815260040162000b969392919062001f12565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160362000c2d578060025f828254039250508190555062000c77565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405162000cd6919062001f4d565b60405180910390a3505050565b5f600254905090565b5f79ffffffffffffffffffffffffffffffffffffffffffffffffffff8016905090565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160362000d755762000d72600a62000e1360201b620011051762000d668462000e2a60201b60201c565b62000e9a60201b60201c565b50505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160362000ddb5762000dd8600a62000ee960201b6200111a1762000dcc8462000e2a60201b60201c565b62000e9a60201b60201c565b50505b62000e0e62000df08462000f0060201b60201c565b62000e018462000f0060201b60201c565b8362000f6560201b60201c565b505050565b5f818362000e22919062001f8d565b905092915050565b5f79ffffffffffffffffffffffffffffffffffffffffffffffffffff801682111562000e925760d0826040517f6dfcc65000000000000000000000000000000000000000000000000000000000815260040162000e899291906200202e565b60405180910390fd5b819050919050565b5f8062000edd62000eb06200120f60201b60201c565b62000ecc62000ec5886200122560201b60201c565b868860201c565b876200129360201b9092919060201c565b91509150935093915050565b5f818362000ef8919062002059565b905092915050565b5f60085f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801562000fa157505f81115b156200120a575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614620010d8575f806200104760095f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2062000ee960201b6200111a176200103b8662000e2a60201b60201c565b62000e9a60201b60201c565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff16915079ffffffffffffffffffffffffffffffffffffffffffffffffffff1691508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051620010cd92919062001ead565b60405180910390a250505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161462001209575f806200117860095f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2062000e1360201b62001105176200116c8662000e2a60201b60201c565b62000e9a60201b60201c565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff16915079ffffffffffffffffffffffffffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051620011fe92919062001ead565b60405180910390a250505b5b505050565b5f62001220620012b660201b60201c565b905090565b5f80825f018054905090505f811462001289576200125a835f016001836200124e9190620020ad565b620012cd60201b60201c565b5f0160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff166200128b565b5f5b915050919050565b5f80620012aa855f018585620012df60201b60201c565b91509150935093915050565b5f620012c8436200166060201b60201c565b905090565b5f825f528160205f2001905092915050565b5f805f858054905090505f81111562001578575f6200131387600184620013079190620020ad565b620012cd60201b60201c565b6040518060400160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff168152505090508565ffffffffffff16815f015165ffffffffffff161115620013ff576040517f2520601d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8565ffffffffffff16815f015165ffffffffffff16036200148d57846200143b886001856200142f9190620020ad565b620012cd60201b60201c565b5f0160066101000a81548179ffffffffffffffffffffffffffffffffffffffffffffffffffff021916908379ffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555062001566565b8660405180604001604052808865ffffffffffff1681526020018779ffffffffffffffffffffffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003905f5260205f20015f909190919091505f820151815f015f6101000a81548165ffffffffffff021916908365ffffffffffff1602179055506020820151815f0160066101000a81548179ffffffffffffffffffffffffffffffffffffffffffffffffffff021916908379ffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b80602001518593509350505062001658565b8560405180604001604052808765ffffffffffff1681526020018679ffffffffffffffffffffffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003905f5260205f20015f909190919091505f820151815f015f6101000a81548165ffffffffffff021916908365ffffffffffff1602179055506020820151815f0160066101000a81548179ffffffffffffffffffffffffffffffffffffffffffffffffffff021916908379ffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505f8492509250505b935093915050565b5f65ffffffffffff8016821115620016b4576030826040517f6dfcc650000000000000000000000000000000000000000000000000000000008152600401620016ab92919062002128565b60405180910390fd5b819050919050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200173857607f821691505b6020821081036200174e576200174d620016f3565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620017b27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262001775565b620017be868362001775565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6200180862001802620017fc84620017d6565b620017df565b620017d6565b9050919050565b5f819050919050565b6200182383620017e8565b6200183b62001832826200180f565b84845462001781565b825550505050565b5f90565b6200185162001843565b6200185e81848462001818565b505050565b5b818110156200188557620018795f8262001847565b60018101905062001864565b5050565b601f821115620018d4576200189e8162001754565b620018a98462001766565b81016020851015620018b9578190505b620018d1620018c88562001766565b83018262001863565b50505b505050565b5f82821c905092915050565b5f620018f65f1984600802620018d9565b1980831691505092915050565b5f620019108383620018e5565b9150826002028217905092915050565b6200192b82620016bc565b67ffffffffffffffff811115620019475762001946620016c6565b5b62001953825462001720565b6200196082828562001889565b5f60209050601f83116001811462001996575f841562001981578287015190505b6200198d858262001903565b865550620019fc565b601f198416620019a68662001754565b5f5b82811015620019cf57848901518255600182019150602085019450602081019050620019a8565b86831015620019ef5784890151620019eb601f891682620018e5565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f808291508390505b600185111562001a8e5780860481111562001a665762001a6562001a04565b5b600185161562001a765780820291505b808102905062001a868562001a31565b945062001a46565b94509492505050565b5f8262001aa8576001905062001b7a565b8162001ab7575f905062001b7a565b816001811462001ad0576002811462001adb5762001b11565b600191505062001b7a565b60ff84111562001af05762001aef62001a04565b5b8360020a91508482111562001b0a5762001b0962001a04565b5b5062001b7a565b5060208310610133831016604e8410600b841016171562001b4b5782820a90508381111562001b455762001b4462001a04565b5b62001b7a565b62001b5a848484600162001a3d565b9250905081840481111562001b745762001b7362001a04565b5b81810290505b9392505050565b5f62001b8d82620017d6565b915062001b9a83620017d6565b925062001bc97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848462001a97565b905092915050565b5f62001bdd82620017d6565b915062001bea83620017d6565b925082820262001bfa81620017d6565b9150828204841483151762001c145762001c1362001a04565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f62001c5482620017d6565b915062001c6183620017d6565b92508262001c745762001c7362001c1b565b5b828204905092915050565b5f819050919050565b62001c938162001c7f565b82525050565b62001ca481620017d6565b82525050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f62001cd58262001caa565b9050919050565b62001ce78162001cc9565b82525050565b5f60a08201905062001d025f83018862001c88565b62001d11602083018762001c88565b62001d20604083018662001c88565b62001d2f606083018562001c99565b62001d3e608083018462001cdc565b9695505050505050565b5f60208201905062001d5d5f83018462001cdc565b92915050565b5f82825260208201905092915050565b5f5b8381101562001d9257808201518184015260208101905062001d75565b5f8484015250505050565b5f601f19601f8301169050919050565b5f62001db982620016bc565b62001dc5818562001d63565b935062001dd781856020860162001d73565b62001de28162001d9d565b840191505092915050565b5f6020820190508181035f83015262001e07818462001dad565b905092915050565b5f81519050919050565b5f819050602082019050919050565b5f62001e35825162001c7f565b80915050919050565b5f62001e4a8262001e0f565b8262001e568462001e19565b905062001e638162001e28565b9250602082101562001ea65762001ea17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080262001775565b831692505b5050919050565b5f60408201905062001ec25f83018562001c99565b62001ed1602083018462001c99565b9392505050565b5f62001ee482620017d6565b915062001ef183620017d6565b925082820190508082111562001f0c5762001f0b62001a04565b5b92915050565b5f60608201905062001f275f83018662001cdc565b62001f36602083018562001c99565b62001f45604083018462001c99565b949350505050565b5f60208201905062001f625f83018462001c99565b92915050565b5f79ffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b5f62001f998262001f68565b915062001fa68362001f68565b9250828201905079ffffffffffffffffffffffffffffffffffffffffffffffffffff81111562001fdb5762001fda62001a04565b5b92915050565b5f819050919050565b5f60ff82169050919050565b5f62002016620020106200200a8462001fe1565b620017df565b62001fea565b9050919050565b620020288162001ff6565b82525050565b5f604082019050620020435f8301856200201d565b62002052602083018462001c99565b9392505050565b5f620020658262001f68565b9150620020728362001f68565b9250828203905079ffffffffffffffffffffffffffffffffffffffffffffffffffff811115620020a757620020a662001a04565b5b92915050565b5f620020b982620017d6565b9150620020c683620017d6565b9250828203905081811115620020e157620020e062001a04565b5b92915050565b5f819050919050565b5f620021106200210a6200210484620020e7565b620017df565b62001fea565b9050919050565b6200212281620020f0565b82525050565b5f6040820190506200213d5f83018562002117565b6200214c602083018462001c99565b9392505050565b60805160a05160c05160e051610100516101205161014051613f0f620021a55f395f61195f01525f61192401525f611db801525f611d9701525f61143401525f61148a01525f6114b30152613f0f5ff3fe608060405234801561000f575f80fd5b50600436106101ee575f3560e01c806370a082311161010d5780639ab24eb0116100a0578063d505accf1161006f578063d505accf1461061e578063d547741f1461063a578063dd62ed3e14610656578063f1127ed814610686576101ee565b80639ab24eb014610584578063a217fddf146105b4578063a9059cbb146105d2578063c3cda52014610602576101ee565b80638e539e8c116100dc5780638e539e8c146104e857806391d148541461051857806391ddadf41461054857806395d89b4114610566576101ee565b806370a082311461044857806379cc6790146104785780637ecebe001461049457806384b0196e146104c4576101ee565b80633644e515116101855780634bf5d7e9116101545780634bf5d7e9146103ae578063587cde1e146103cc5780635c19a95c146103fc5780636fcfff4514610418576101ee565b80633644e5151461032857806336568abe146103465780633a46b1a81461036257806342966c6814610392576101ee565b806323b872dd116101c157806323b872dd1461028e578063248a9ca3146102be5780632f2ff15d146102ee578063313ce5671461030a576101ee565b806301ffc9a7146101f257806306fdde0314610222578063095ea7b31461024057806318160ddd14610270575b5f80fd5b61020c600480360381019061020791906130f1565b6106b6565b6040516102199190613136565b60405180910390f35b61022a61072f565b60405161023791906131d9565b60405180910390f35b61025a60048036038101906102559190613286565b6107bf565b6040516102679190613136565b60405180910390f35b6102786107e1565b60405161028591906132d3565b60405180910390f35b6102a860048036038101906102a391906132ec565b6107ea565b6040516102b59190613136565b60405180910390f35b6102d860048036038101906102d3919061336f565b610818565b6040516102e591906133a9565b60405180910390f35b610308600480360381019061030391906133c2565b610835565b005b610312610857565b60405161031f919061341b565b60405180910390f35b61033061085f565b60405161033d91906133a9565b60405180910390f35b610360600480360381019061035b91906133c2565b61086d565b005b61037c60048036038101906103779190613286565b6108e8565b60405161038991906132d3565b60405180910390f35b6103ac60048036038101906103a79190613434565b6109be565b005b6103b66109d2565b6040516103c391906131d9565b60405180910390f35b6103e660048036038101906103e1919061345f565b610a66565b6040516103f39190613499565b60405180910390f35b6104166004803603810190610411919061345f565b610acb565b005b610432600480360381019061042d919061345f565b610ae4565b60405161043f91906134d0565b60405180910390f35b610462600480360381019061045d919061345f565b610af5565b60405161046f91906132d3565b60405180910390f35b610492600480360381019061048d9190613286565b610b3a565b005b6104ae60048036038101906104a9919061345f565b610b5a565b6040516104bb91906132d3565b60405180910390f35b6104cc610b6b565b6040516104df97969594939291906135da565b60405180910390f35b61050260048036038101906104fd9190613434565b610c10565b60405161050f91906132d3565b60405180910390f35b610532600480360381019061052d91906133c2565b610caa565b60405161053f9190613136565b60405180910390f35b610550610d0e565b60405161055d919061367c565b60405180910390f35b61056e610d1c565b60405161057b91906131d9565b60405180910390f35b61059e6004803603810190610599919061345f565b610dac565b6040516105ab91906132d3565b60405180910390f35b6105bc610e15565b6040516105c991906133a9565b60405180910390f35b6105ec60048036038101906105e79190613286565b610e1b565b6040516105f99190613136565b60405180910390f35b61061c600480360381019061061791906136bf565b610e3d565b005b61063860048036038101906106339190613748565b610f02565b005b610654600480360381019061064f91906133c2565b611047565b005b610670600480360381019061066b91906137e5565b611069565b60405161067d91906132d3565b60405180910390f35b6106a0600480360381019061069b919061384d565b6110eb565b6040516106ad91906138fb565b60405180910390f35b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061072857506107278261112f565b5b9050919050565b60606003805461073e90613941565b80601f016020809104026020016040519081016040528092919081815260200182805461076a90613941565b80156107b55780601f1061078c576101008083540402835291602001916107b5565b820191905f5260205f20905b81548152906001019060200180831161079857829003601f168201915b5050505050905090565b5f806107c9611198565b90506107d681858561119f565b600191505092915050565b5f600254905090565b5f806107f4611198565b90506108018582856111b1565b61080c858585611243565b60019150509392505050565b5f600b5f8381526020019081526020015f20600101549050919050565b61083e82610818565b61084781611333565b6108518383611347565b50505050565b5f6012905090565b5f610868611431565b905090565b610875611198565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146108d9576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108e382826114e7565b505050565b5f806108f2610d0e565b90508065ffffffffffff1683106109425782816040517fecd3f81e000000000000000000000000000000000000000000000000000000008152600401610939929190613971565b60405180910390fd5b61099961094e846115d1565b60095f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2061162a90919063ffffffff16565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff1691505092915050565b6109cf6109c9611198565b82611717565b50565b60606109dc611796565b65ffffffffffff166109ec610d0e565b65ffffffffffff1614610a2b576040517f6ff0714000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040518060400160405280601d81526020017f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c74000000815250905090565b5f60085f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f610ad4611198565b9050610ae081836117a5565b5050565b5f610aee826118b5565b9050919050565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610b4c82610b46611198565b836111b1565b610b568282611717565b5050565b5f610b648261190a565b9050919050565b5f6060805f805f6060610b7c61191b565b610b84611956565b46305f801b5f67ffffffffffffffff811115610ba357610ba2613998565b5b604051908082528060200260200182016040528015610bd15781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b5f80610c1a610d0e565b90508065ffffffffffff168310610c6a5782816040517fecd3f81e000000000000000000000000000000000000000000000000000000008152600401610c61929190613971565b60405180910390fd5b610c86610c76846115d1565b600a61162a90919063ffffffff16565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff16915050919050565b5f600b5f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f610d17611796565b905090565b606060048054610d2b90613941565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5790613941565b8015610da25780601f10610d7957610100808354040283529160200191610da2565b820191905f5260205f20905b815481529060010190602001808311610d8557829003601f168201915b5050505050905090565b5f610df260095f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20611991565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff169050919050565b5f801b81565b5f80610e25611198565b9050610e32818585611243565b600191505092915050565b83421115610e8257836040517f4683af0e000000000000000000000000000000000000000000000000000000008152600401610e7991906132d3565b60405180910390fd5b5f610ee3610edb7fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf898989604051602001610ec094939291906139c5565b604051602081830303815290604052805190602001206119f3565b858585611a0c565b9050610eef8187611a3a565b610ef981886117a5565b50505050505050565b83421115610f4757836040517f62791302000000000000000000000000000000000000000000000000000000008152600401610f3e91906132d3565b60405180910390fd5b5f7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610f758c611a91565b89604051602001610f8b96959493929190613a08565b6040516020818303038152906040528051906020012090505f610fad826119f3565b90505f610fbc82878787611a0c565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461103057808a6040517f4b800e46000000000000000000000000000000000000000000000000000000008152600401611027929190613a67565b60405180910390fd5b61103b8a8a8a61119f565b50505050505050505050565b61105082610818565b61105981611333565b61106383836114e7565b50505050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b6110f361305c565b6110fd8383611ae4565b905092915050565b5f81836111129190613abb565b905092915050565b5f81836111279190613b08565b905092915050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f33905090565b6111ac8383836001611b43565b505050565b5f6111bc8484611069565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461123d578181101561122e578281836040517ffb8f41b200000000000000000000000000000000000000000000000000000000815260040161122593929190613b55565b60405180910390fd5b61123c84848484035f611b43565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036112b3575f6040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081526004016112aa9190613499565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611323575f6040517fec442f0500000000000000000000000000000000000000000000000000000000815260040161131a9190613499565b60405180910390fd5b61132e838383611d12565b505050565b6113448161133f611198565b611d22565b50565b5f6113528383610caa565b611427576001600b5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506113c4611198565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a46001905061142b565b5f90505b92915050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff161480156114ac57507f000000000000000000000000000000000000000000000000000000000000000046145b156114d9577f000000000000000000000000000000000000000000000000000000000000000090506114e4565b6114e1611d73565b90505b90565b5f6114f28383610caa565b156115c7575f600b5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550611564611198565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a4600190506115cb565b5f90505b92915050565b5f65ffffffffffff8016821115611622576030826040517f6dfcc650000000000000000000000000000000000000000000000000000000008152600401611619929190613bcc565b60405180910390fd5b819050919050565b5f80835f018054905090505f8082905060058311156116ab575f61164d84611e08565b846116589190613bf3565b9050611666875f0182611efe565b5f015f9054906101000a900465ffffffffffff1665ffffffffffff168665ffffffffffff161015611699578091506116a9565b6001816116a69190613c26565b92505b505b5f6116ba875f01878585611f10565b90505f8114611709576116db875f016001836116d69190613bf3565b611efe565b5f0160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1661170b565b5f5b94505050505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611787575f6040517f96c6fd1e00000000000000000000000000000000000000000000000000000000815260040161177e9190613499565b60405180910390fd5b611792825f83611d12565b5050565b5f6117a0436115d1565b905090565b5f6117af83610a66565b90508160085f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a46118b081836118ab86611f85565b611f96565b505050565b5f6119036118fe60095f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20612206565b612215565b9050919050565b5f6119148261226c565b9050919050565b606061195160057f00000000000000000000000000000000000000000000000000000000000000006122b290919063ffffffff16565b905090565b606061198c60067f00000000000000000000000000000000000000000000000000000000000000006122b290919063ffffffff16565b905090565b5f80825f018054905090505f81146119e9576119bb835f016001836119b69190613bf3565b611efe565b5f0160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff166119eb565b5f5b915050919050565b5f611a056119ff611431565b8361235f565b9050919050565b5f805f80611a1c8888888861239f565b925092509250611a2c8282612486565b829350505050949350505050565b5f611a4483611a91565b9050808214611a8c5782816040517f752d88c0000000000000000000000000000000000000000000000000000000008152600401611a83929190613c59565b60405180910390fd5b505050565b5f60075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f815480929190600101919050559050919050565b611aec61305c565b611b3b8260095f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206125e890919063ffffffff16565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611bb3575f6040517fe602df05000000000000000000000000000000000000000000000000000000008152600401611baa9190613499565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611c23575f6040517f94280d62000000000000000000000000000000000000000000000000000000008152600401611c1a9190613499565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508015611d0c578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051611d0391906132d3565b60405180910390a35b50505050565b611d1d8383836126b7565b505050565b611d2c8282610caa565b611d6f5780826040517fe2517d3f000000000000000000000000000000000000000000000000000000008152600401611d66929190613c80565b60405180910390fd5b5050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000004630604051602001611ded959493929190613ca7565b60405160208183030381529060405280519060200120905090565b5f808203611e18575f9050611ef9565b5f6001611e2484612765565b901c6001901b90506001818481611e3e57611e3d613cf8565b5b048201901c90506001818481611e5757611e56613cf8565b5b048201901c90506001818481611e7057611e6f613cf8565b5b048201901c90506001818481611e8957611e88613cf8565b5b048201901c90506001818481611ea257611ea1613cf8565b5b048201901c90506001818481611ebb57611eba613cf8565b5b048201901c90506001818481611ed457611ed3613cf8565b5b048201901c9050611ef581828581611eef57611eee613cf8565b5b0461283c565b9150505b919050565b5f825f528160205f2001905092915050565b5f5b81831015611f7a575f611f258484612854565b90508465ffffffffffff16611f3a8783611efe565b5f015f9054906101000a900465ffffffffffff1665ffffffffffff161115611f6457809250611f74565b600181611f719190613c26565b93505b50611f12565b819050949350505050565b5f611f8f82610af5565b9050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015611fd157505f81115b15612201575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146120eb575f8061205c60095f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2061111a61205786612879565b6128e6565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff16915079ffffffffffffffffffffffffffffffffffffffffffffffffffff1691508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72483836040516120e0929190613d25565b60405180910390a250505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612200575f8061217160095f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2061110561216c86612879565b6128e6565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff16915079ffffffffffffffffffffffffffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72483836040516121f5929190613d25565b60405180910390a250505b5b505050565b5f815f01805490509050919050565b5f63ffffffff8016821115612264576020826040517f6dfcc65000000000000000000000000000000000000000000000000000000000815260040161225b929190613d85565b60405180910390fd5b819050919050565b5f60075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b606060ff5f1b83146122ce576122c783612925565b9050612359565b8180546122da90613941565b80601f016020809104026020016040519081016040528092919081815260200182805461230690613941565b80156123515780601f1061232857610100808354040283529160200191612351565b820191905f5260205f20905b81548152906001019060200180831161233457829003601f168201915b505050505090505b92915050565b5f6040517f190100000000000000000000000000000000000000000000000000000000000081528360028201528260228201526042812091505092915050565b5f805f7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0845f1c11156123db575f60038592509250925061247c565b5f6001888888886040515f81526020016040526040516123fe9493929190613dac565b6020604051602081039080840390855afa15801561241e573d5f803e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361246f575f60015f801b9350935093505061247c565b805f805f1b935093509350505b9450945094915050565b5f600381111561249957612498613def565b5b8260038111156124ac576124ab613def565b5b03156125e457600160038111156124c6576124c5613def565b5b8260038111156124d9576124d8613def565b5b03612510576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600381111561252457612523613def565b5b82600381111561253757612536613def565b5b0361257b57805f1c6040517ffce698f700000000000000000000000000000000000000000000000000000000815260040161257291906132d3565b60405180910390fd5b60038081111561258e5761258d613def565b5b8260038111156125a1576125a0613def565b5b036125e357806040517fd78bce0c0000000000000000000000000000000000000000000000000000000081526004016125da91906133a9565b60405180910390fd5b5b5050565b6125f061305c565b825f018263ffffffff168154811061260b5761260a613e1c565b5b905f5260205f20016040518060400160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff1681525050905092915050565b6126c2838383612997565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612755575f6126fe6107e1565b90505f612709612bb0565b9050808211156127525781816040517f1cb15d26000000000000000000000000000000000000000000000000000000008152600401612749929190613d25565b60405180910390fd5b50505b612760838383612bd3565b505050565b5f805f90505f608084901c111561278457608083901c92506080810190505b5f604084901c111561279e57604083901c92506040810190505b5f602084901c11156127b857602083901c92506020810190505b5f601084901c11156127d257601083901c92506010810190505b5f600884901c11156127ec57600883901c92506008810190505b5f600484901c111561280657600483901c92506004810190505b5f600284901c111561282057600283901c92506002810190505b5f600184901c1115612833576001810190505b80915050919050565b5f81831061284a578161284c565b825b905092915050565b5f60028284186128649190613e49565b8284166128719190613c26565b905092915050565b5f79ffffffffffffffffffffffffffffffffffffffffffffffffffff80168211156128de5760d0826040517f6dfcc6500000000000000000000000000000000000000000000000000000000081526004016128d5929190613eb2565b60405180910390fd5b819050919050565b5f806129196128f3610d0e565b6129096128ff88611991565b868863ffffffff16565b87612c8b9092919063ffffffff16565b91509150935093915050565b60605f61293183612ca6565b90505f602067ffffffffffffffff81111561294f5761294e613998565b5b6040519080825280601f01601f1916602001820160405280156129815781602001600182028036833780820191505090505b5090508181528360208201528092505050919050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036129e7578060025f8282546129db9190613c26565b92505081905550612ab5565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015612a70578381836040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401612a6793929190613b55565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612afc578060025f8282540392505081905550612b46565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612ba391906132d3565b60405180910390a3505050565b5f79ffffffffffffffffffffffffffffffffffffffffffffffffffff8016905090565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612c1f57612c1c600a611105612c1784612879565b6128e6565b50505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612c6b57612c68600a61111a612c6384612879565b6128e6565b50505b612c86612c7784610a66565b612c8084610a66565b83611f96565b505050565b5f80612c9a855f018585612cf4565b91509150935093915050565b5f8060ff835f1c169050601f811115612ceb576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80915050919050565b5f805f858054905090505f811115612f74575f612d1d87600184612d189190613bf3565b611efe565b6040518060400160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff168152505090508565ffffffffffff16815f015165ffffffffffff161115612e08576040517f2520601d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8565ffffffffffff16815f015165ffffffffffff1603612e8a5784612e3988600185612e349190613bf3565b611efe565b5f0160066101000a81548179ffffffffffffffffffffffffffffffffffffffffffffffffffff021916908379ffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550612f63565b8660405180604001604052808865ffffffffffff1681526020018779ffffffffffffffffffffffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003905f5260205f20015f909190919091505f820151815f015f6101000a81548165ffffffffffff021916908365ffffffffffff1602179055506020820151815f0160066101000a81548179ffffffffffffffffffffffffffffffffffffffffffffffffffff021916908379ffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b806020015185935093505050613054565b8560405180604001604052808765ffffffffffff1681526020018679ffffffffffffffffffffffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003905f5260205f20015f909190919091505f820151815f015f6101000a81548165ffffffffffff021916908365ffffffffffff1602179055506020820151815f0160066101000a81548179ffffffffffffffffffffffffffffffffffffffffffffffffffff021916908379ffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505f8492509250505b935093915050565b60405180604001604052805f65ffffffffffff1681526020015f79ffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090565b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6130d08161309c565b81146130da575f80fd5b50565b5f813590506130eb816130c7565b92915050565b5f6020828403121561310657613105613098565b5b5f613113848285016130dd565b91505092915050565b5f8115159050919050565b6131308161311c565b82525050565b5f6020820190506131495f830184613127565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561318657808201518184015260208101905061316b565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6131ab8261314f565b6131b58185613159565b93506131c5818560208601613169565b6131ce81613191565b840191505092915050565b5f6020820190508181035f8301526131f181846131a1565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f613222826131f9565b9050919050565b61323281613218565b811461323c575f80fd5b50565b5f8135905061324d81613229565b92915050565b5f819050919050565b61326581613253565b811461326f575f80fd5b50565b5f813590506132808161325c565b92915050565b5f806040838503121561329c5761329b613098565b5b5f6132a98582860161323f565b92505060206132ba85828601613272565b9150509250929050565b6132cd81613253565b82525050565b5f6020820190506132e65f8301846132c4565b92915050565b5f805f6060848603121561330357613302613098565b5b5f6133108682870161323f565b93505060206133218682870161323f565b925050604061333286828701613272565b9150509250925092565b5f819050919050565b61334e8161333c565b8114613358575f80fd5b50565b5f8135905061336981613345565b92915050565b5f6020828403121561338457613383613098565b5b5f6133918482850161335b565b91505092915050565b6133a38161333c565b82525050565b5f6020820190506133bc5f83018461339a565b92915050565b5f80604083850312156133d8576133d7613098565b5b5f6133e58582860161335b565b92505060206133f68582860161323f565b9150509250929050565b5f60ff82169050919050565b61341581613400565b82525050565b5f60208201905061342e5f83018461340c565b92915050565b5f6020828403121561344957613448613098565b5b5f61345684828501613272565b91505092915050565b5f6020828403121561347457613473613098565b5b5f6134818482850161323f565b91505092915050565b61349381613218565b82525050565b5f6020820190506134ac5f83018461348a565b92915050565b5f63ffffffff82169050919050565b6134ca816134b2565b82525050565b5f6020820190506134e35f8301846134c1565b92915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b61351d816134e9565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61355581613253565b82525050565b5f613566838361354c565b60208301905092915050565b5f602082019050919050565b5f61358882613523565b613592818561352d565b935061359d8361353d565b805f5b838110156135cd5781516135b4888261355b565b97506135bf83613572565b9250506001810190506135a0565b5085935050505092915050565b5f60e0820190506135ed5f83018a613514565b81810360208301526135ff81896131a1565b9050818103604083015261361381886131a1565b905061362260608301876132c4565b61362f608083018661348a565b61363c60a083018561339a565b81810360c083015261364e818461357e565b905098975050505050505050565b5f65ffffffffffff82169050919050565b6136768161365c565b82525050565b5f60208201905061368f5f83018461366d565b92915050565b61369e81613400565b81146136a8575f80fd5b50565b5f813590506136b981613695565b92915050565b5f805f805f8060c087890312156136d9576136d8613098565b5b5f6136e689828a0161323f565b96505060206136f789828a01613272565b955050604061370889828a01613272565b945050606061371989828a016136ab565b935050608061372a89828a0161335b565b92505060a061373b89828a0161335b565b9150509295509295509295565b5f805f805f805f60e0888a03121561376357613762613098565b5b5f6137708a828b0161323f565b97505060206137818a828b0161323f565b96505060406137928a828b01613272565b95505060606137a38a828b01613272565b94505060806137b48a828b016136ab565b93505060a06137c58a828b0161335b565b92505060c06137d68a828b0161335b565b91505092959891949750929550565b5f80604083850312156137fb576137fa613098565b5b5f6138088582860161323f565b92505060206138198582860161323f565b9150509250929050565b61382c816134b2565b8114613836575f80fd5b50565b5f8135905061384781613823565b92915050565b5f806040838503121561386357613862613098565b5b5f6138708582860161323f565b925050602061388185828601613839565b9150509250929050565b6138948161365c565b82525050565b5f79ffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b6138c88161389a565b82525050565b604082015f8201516138e25f85018261388b565b5060208201516138f560208501826138bf565b50505050565b5f60408201905061390e5f8301846138ce565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061395857607f821691505b60208210810361396b5761396a613914565b5b50919050565b5f6040820190506139845f8301856132c4565b613991602083018461366d565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f6080820190506139d85f83018761339a565b6139e5602083018661348a565b6139f260408301856132c4565b6139ff60608301846132c4565b95945050505050565b5f60c082019050613a1b5f83018961339a565b613a28602083018861348a565b613a35604083018761348a565b613a4260608301866132c4565b613a4f60808301856132c4565b613a5c60a08301846132c4565b979650505050505050565b5f604082019050613a7a5f83018561348a565b613a87602083018461348a565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f613ac58261389a565b9150613ad08361389a565b9250828201905079ffffffffffffffffffffffffffffffffffffffffffffffffffff811115613b0257613b01613a8e565b5b92915050565b5f613b128261389a565b9150613b1d8361389a565b9250828203905079ffffffffffffffffffffffffffffffffffffffffffffffffffff811115613b4f57613b4e613a8e565b5b92915050565b5f606082019050613b685f83018661348a565b613b7560208301856132c4565b613b8260408301846132c4565b949350505050565b5f819050919050565b5f819050919050565b5f613bb6613bb1613bac84613b8a565b613b93565b613400565b9050919050565b613bc681613b9c565b82525050565b5f604082019050613bdf5f830185613bbd565b613bec60208301846132c4565b9392505050565b5f613bfd82613253565b9150613c0883613253565b9250828203905081811115613c2057613c1f613a8e565b5b92915050565b5f613c3082613253565b9150613c3b83613253565b9250828201905080821115613c5357613c52613a8e565b5b92915050565b5f604082019050613c6c5f83018561348a565b613c7960208301846132c4565b9392505050565b5f604082019050613c935f83018561348a565b613ca0602083018461339a565b9392505050565b5f60a082019050613cba5f83018861339a565b613cc7602083018761339a565b613cd4604083018661339a565b613ce160608301856132c4565b613cee608083018461348a565b9695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f604082019050613d385f8301856132c4565b613d4560208301846132c4565b9392505050565b5f819050919050565b5f613d6f613d6a613d6584613d4c565b613b93565b613400565b9050919050565b613d7f81613d55565b82525050565b5f604082019050613d985f830185613d76565b613da560208301846132c4565b9392505050565b5f608082019050613dbf5f83018761339a565b613dcc602083018661340c565b613dd9604083018561339a565b613de6606083018461339a565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f613e5382613253565b9150613e5e83613253565b925082613e6e57613e6d613cf8565b5b828204905092915050565b5f819050919050565b5f613e9c613e97613e9284613e79565b613b93565b613400565b9050919050565b613eac81613e82565b82525050565b5f604082019050613ec55f830185613ea3565b613ed260208301846132c4565b939250505056fea26469706673582212209c18a340ff8ff5e94d45e3a14677ef813ace3ca3f8c5954ab110a0cba3fe70ac64736f6c63430008160033
Deployed Bytecode
0x608060405234801561000f575f80fd5b50600436106101ee575f3560e01c806370a082311161010d5780639ab24eb0116100a0578063d505accf1161006f578063d505accf1461061e578063d547741f1461063a578063dd62ed3e14610656578063f1127ed814610686576101ee565b80639ab24eb014610584578063a217fddf146105b4578063a9059cbb146105d2578063c3cda52014610602576101ee565b80638e539e8c116100dc5780638e539e8c146104e857806391d148541461051857806391ddadf41461054857806395d89b4114610566576101ee565b806370a082311461044857806379cc6790146104785780637ecebe001461049457806384b0196e146104c4576101ee565b80633644e515116101855780634bf5d7e9116101545780634bf5d7e9146103ae578063587cde1e146103cc5780635c19a95c146103fc5780636fcfff4514610418576101ee565b80633644e5151461032857806336568abe146103465780633a46b1a81461036257806342966c6814610392576101ee565b806323b872dd116101c157806323b872dd1461028e578063248a9ca3146102be5780632f2ff15d146102ee578063313ce5671461030a576101ee565b806301ffc9a7146101f257806306fdde0314610222578063095ea7b31461024057806318160ddd14610270575b5f80fd5b61020c600480360381019061020791906130f1565b6106b6565b6040516102199190613136565b60405180910390f35b61022a61072f565b60405161023791906131d9565b60405180910390f35b61025a60048036038101906102559190613286565b6107bf565b6040516102679190613136565b60405180910390f35b6102786107e1565b60405161028591906132d3565b60405180910390f35b6102a860048036038101906102a391906132ec565b6107ea565b6040516102b59190613136565b60405180910390f35b6102d860048036038101906102d3919061336f565b610818565b6040516102e591906133a9565b60405180910390f35b610308600480360381019061030391906133c2565b610835565b005b610312610857565b60405161031f919061341b565b60405180910390f35b61033061085f565b60405161033d91906133a9565b60405180910390f35b610360600480360381019061035b91906133c2565b61086d565b005b61037c60048036038101906103779190613286565b6108e8565b60405161038991906132d3565b60405180910390f35b6103ac60048036038101906103a79190613434565b6109be565b005b6103b66109d2565b6040516103c391906131d9565b60405180910390f35b6103e660048036038101906103e1919061345f565b610a66565b6040516103f39190613499565b60405180910390f35b6104166004803603810190610411919061345f565b610acb565b005b610432600480360381019061042d919061345f565b610ae4565b60405161043f91906134d0565b60405180910390f35b610462600480360381019061045d919061345f565b610af5565b60405161046f91906132d3565b60405180910390f35b610492600480360381019061048d9190613286565b610b3a565b005b6104ae60048036038101906104a9919061345f565b610b5a565b6040516104bb91906132d3565b60405180910390f35b6104cc610b6b565b6040516104df97969594939291906135da565b60405180910390f35b61050260048036038101906104fd9190613434565b610c10565b60405161050f91906132d3565b60405180910390f35b610532600480360381019061052d91906133c2565b610caa565b60405161053f9190613136565b60405180910390f35b610550610d0e565b60405161055d919061367c565b60405180910390f35b61056e610d1c565b60405161057b91906131d9565b60405180910390f35b61059e6004803603810190610599919061345f565b610dac565b6040516105ab91906132d3565b60405180910390f35b6105bc610e15565b6040516105c991906133a9565b60405180910390f35b6105ec60048036038101906105e79190613286565b610e1b565b6040516105f99190613136565b60405180910390f35b61061c600480360381019061061791906136bf565b610e3d565b005b61063860048036038101906106339190613748565b610f02565b005b610654600480360381019061064f91906133c2565b611047565b005b610670600480360381019061066b91906137e5565b611069565b60405161067d91906132d3565b60405180910390f35b6106a0600480360381019061069b919061384d565b6110eb565b6040516106ad91906138fb565b60405180910390f35b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061072857506107278261112f565b5b9050919050565b60606003805461073e90613941565b80601f016020809104026020016040519081016040528092919081815260200182805461076a90613941565b80156107b55780601f1061078c576101008083540402835291602001916107b5565b820191905f5260205f20905b81548152906001019060200180831161079857829003601f168201915b5050505050905090565b5f806107c9611198565b90506107d681858561119f565b600191505092915050565b5f600254905090565b5f806107f4611198565b90506108018582856111b1565b61080c858585611243565b60019150509392505050565b5f600b5f8381526020019081526020015f20600101549050919050565b61083e82610818565b61084781611333565b6108518383611347565b50505050565b5f6012905090565b5f610868611431565b905090565b610875611198565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146108d9576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108e382826114e7565b505050565b5f806108f2610d0e565b90508065ffffffffffff1683106109425782816040517fecd3f81e000000000000000000000000000000000000000000000000000000008152600401610939929190613971565b60405180910390fd5b61099961094e846115d1565b60095f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2061162a90919063ffffffff16565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff1691505092915050565b6109cf6109c9611198565b82611717565b50565b60606109dc611796565b65ffffffffffff166109ec610d0e565b65ffffffffffff1614610a2b576040517f6ff0714000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040518060400160405280601d81526020017f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c74000000815250905090565b5f60085f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f610ad4611198565b9050610ae081836117a5565b5050565b5f610aee826118b5565b9050919050565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610b4c82610b46611198565b836111b1565b610b568282611717565b5050565b5f610b648261190a565b9050919050565b5f6060805f805f6060610b7c61191b565b610b84611956565b46305f801b5f67ffffffffffffffff811115610ba357610ba2613998565b5b604051908082528060200260200182016040528015610bd15781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b5f80610c1a610d0e565b90508065ffffffffffff168310610c6a5782816040517fecd3f81e000000000000000000000000000000000000000000000000000000008152600401610c61929190613971565b60405180910390fd5b610c86610c76846115d1565b600a61162a90919063ffffffff16565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff16915050919050565b5f600b5f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f610d17611796565b905090565b606060048054610d2b90613941565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5790613941565b8015610da25780601f10610d7957610100808354040283529160200191610da2565b820191905f5260205f20905b815481529060010190602001808311610d8557829003601f168201915b5050505050905090565b5f610df260095f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20611991565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff169050919050565b5f801b81565b5f80610e25611198565b9050610e32818585611243565b600191505092915050565b83421115610e8257836040517f4683af0e000000000000000000000000000000000000000000000000000000008152600401610e7991906132d3565b60405180910390fd5b5f610ee3610edb7fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf898989604051602001610ec094939291906139c5565b604051602081830303815290604052805190602001206119f3565b858585611a0c565b9050610eef8187611a3a565b610ef981886117a5565b50505050505050565b83421115610f4757836040517f62791302000000000000000000000000000000000000000000000000000000008152600401610f3e91906132d3565b60405180910390fd5b5f7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610f758c611a91565b89604051602001610f8b96959493929190613a08565b6040516020818303038152906040528051906020012090505f610fad826119f3565b90505f610fbc82878787611a0c565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461103057808a6040517f4b800e46000000000000000000000000000000000000000000000000000000008152600401611027929190613a67565b60405180910390fd5b61103b8a8a8a61119f565b50505050505050505050565b61105082610818565b61105981611333565b61106383836114e7565b50505050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b6110f361305c565b6110fd8383611ae4565b905092915050565b5f81836111129190613abb565b905092915050565b5f81836111279190613b08565b905092915050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f33905090565b6111ac8383836001611b43565b505050565b5f6111bc8484611069565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461123d578181101561122e578281836040517ffb8f41b200000000000000000000000000000000000000000000000000000000815260040161122593929190613b55565b60405180910390fd5b61123c84848484035f611b43565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036112b3575f6040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081526004016112aa9190613499565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611323575f6040517fec442f0500000000000000000000000000000000000000000000000000000000815260040161131a9190613499565b60405180910390fd5b61132e838383611d12565b505050565b6113448161133f611198565b611d22565b50565b5f6113528383610caa565b611427576001600b5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506113c4611198565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a46001905061142b565b5f90505b92915050565b5f7f000000000000000000000000186ef81fd8e77eec8bffc3039e7ec41d5fc0b45773ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff161480156114ac57507f000000000000000000000000000000000000000000000000000000000000000146145b156114d9577fbee620dea7ad468f77407fd3bd49b75c263ce3d622755955965dcb0c558fc1fe90506114e4565b6114e1611d73565b90505b90565b5f6114f28383610caa565b156115c7575f600b5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550611564611198565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a4600190506115cb565b5f90505b92915050565b5f65ffffffffffff8016821115611622576030826040517f6dfcc650000000000000000000000000000000000000000000000000000000008152600401611619929190613bcc565b60405180910390fd5b819050919050565b5f80835f018054905090505f8082905060058311156116ab575f61164d84611e08565b846116589190613bf3565b9050611666875f0182611efe565b5f015f9054906101000a900465ffffffffffff1665ffffffffffff168665ffffffffffff161015611699578091506116a9565b6001816116a69190613c26565b92505b505b5f6116ba875f01878585611f10565b90505f8114611709576116db875f016001836116d69190613bf3565b611efe565b5f0160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1661170b565b5f5b94505050505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611787575f6040517f96c6fd1e00000000000000000000000000000000000000000000000000000000815260040161177e9190613499565b60405180910390fd5b611792825f83611d12565b5050565b5f6117a0436115d1565b905090565b5f6117af83610a66565b90508160085f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a46118b081836118ab86611f85565b611f96565b505050565b5f6119036118fe60095f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20612206565b612215565b9050919050565b5f6119148261226c565b9050919050565b606061195160057f496e7370656374000000000000000000000000000000000000000000000000076122b290919063ffffffff16565b905090565b606061198c60067f31000000000000000000000000000000000000000000000000000000000000016122b290919063ffffffff16565b905090565b5f80825f018054905090505f81146119e9576119bb835f016001836119b69190613bf3565b611efe565b5f0160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff166119eb565b5f5b915050919050565b5f611a056119ff611431565b8361235f565b9050919050565b5f805f80611a1c8888888861239f565b925092509250611a2c8282612486565b829350505050949350505050565b5f611a4483611a91565b9050808214611a8c5782816040517f752d88c0000000000000000000000000000000000000000000000000000000008152600401611a83929190613c59565b60405180910390fd5b505050565b5f60075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f815480929190600101919050559050919050565b611aec61305c565b611b3b8260095f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206125e890919063ffffffff16565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611bb3575f6040517fe602df05000000000000000000000000000000000000000000000000000000008152600401611baa9190613499565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611c23575f6040517f94280d62000000000000000000000000000000000000000000000000000000008152600401611c1a9190613499565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508015611d0c578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051611d0391906132d3565b60405180910390a35b50505050565b611d1d8383836126b7565b505050565b611d2c8282610caa565b611d6f5780826040517fe2517d3f000000000000000000000000000000000000000000000000000000008152600401611d66929190613c80565b60405180910390fd5b5050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f5278f6c2090a3fc8f29ed5755e0f40b064b568db6cc407506a0658d75bfeff727fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc64630604051602001611ded959493929190613ca7565b60405160208183030381529060405280519060200120905090565b5f808203611e18575f9050611ef9565b5f6001611e2484612765565b901c6001901b90506001818481611e3e57611e3d613cf8565b5b048201901c90506001818481611e5757611e56613cf8565b5b048201901c90506001818481611e7057611e6f613cf8565b5b048201901c90506001818481611e8957611e88613cf8565b5b048201901c90506001818481611ea257611ea1613cf8565b5b048201901c90506001818481611ebb57611eba613cf8565b5b048201901c90506001818481611ed457611ed3613cf8565b5b048201901c9050611ef581828581611eef57611eee613cf8565b5b0461283c565b9150505b919050565b5f825f528160205f2001905092915050565b5f5b81831015611f7a575f611f258484612854565b90508465ffffffffffff16611f3a8783611efe565b5f015f9054906101000a900465ffffffffffff1665ffffffffffff161115611f6457809250611f74565b600181611f719190613c26565b93505b50611f12565b819050949350505050565b5f611f8f82610af5565b9050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015611fd157505f81115b15612201575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146120eb575f8061205c60095f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2061111a61205786612879565b6128e6565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff16915079ffffffffffffffffffffffffffffffffffffffffffffffffffff1691508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72483836040516120e0929190613d25565b60405180910390a250505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612200575f8061217160095f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2061110561216c86612879565b6128e6565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff16915079ffffffffffffffffffffffffffffffffffffffffffffffffffff1691508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72483836040516121f5929190613d25565b60405180910390a250505b5b505050565b5f815f01805490509050919050565b5f63ffffffff8016821115612264576020826040517f6dfcc65000000000000000000000000000000000000000000000000000000000815260040161225b929190613d85565b60405180910390fd5b819050919050565b5f60075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b606060ff5f1b83146122ce576122c783612925565b9050612359565b8180546122da90613941565b80601f016020809104026020016040519081016040528092919081815260200182805461230690613941565b80156123515780601f1061232857610100808354040283529160200191612351565b820191905f5260205f20905b81548152906001019060200180831161233457829003601f168201915b505050505090505b92915050565b5f6040517f190100000000000000000000000000000000000000000000000000000000000081528360028201528260228201526042812091505092915050565b5f805f7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0845f1c11156123db575f60038592509250925061247c565b5f6001888888886040515f81526020016040526040516123fe9493929190613dac565b6020604051602081039080840390855afa15801561241e573d5f803e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361246f575f60015f801b9350935093505061247c565b805f805f1b935093509350505b9450945094915050565b5f600381111561249957612498613def565b5b8260038111156124ac576124ab613def565b5b03156125e457600160038111156124c6576124c5613def565b5b8260038111156124d9576124d8613def565b5b03612510576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600381111561252457612523613def565b5b82600381111561253757612536613def565b5b0361257b57805f1c6040517ffce698f700000000000000000000000000000000000000000000000000000000815260040161257291906132d3565b60405180910390fd5b60038081111561258e5761258d613def565b5b8260038111156125a1576125a0613def565b5b036125e357806040517fd78bce0c0000000000000000000000000000000000000000000000000000000081526004016125da91906133a9565b60405180910390fd5b5b5050565b6125f061305c565b825f018263ffffffff168154811061260b5761260a613e1c565b5b905f5260205f20016040518060400160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff1681525050905092915050565b6126c2838383612997565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612755575f6126fe6107e1565b90505f612709612bb0565b9050808211156127525781816040517f1cb15d26000000000000000000000000000000000000000000000000000000008152600401612749929190613d25565b60405180910390fd5b50505b612760838383612bd3565b505050565b5f805f90505f608084901c111561278457608083901c92506080810190505b5f604084901c111561279e57604083901c92506040810190505b5f602084901c11156127b857602083901c92506020810190505b5f601084901c11156127d257601083901c92506010810190505b5f600884901c11156127ec57600883901c92506008810190505b5f600484901c111561280657600483901c92506004810190505b5f600284901c111561282057600283901c92506002810190505b5f600184901c1115612833576001810190505b80915050919050565b5f81831061284a578161284c565b825b905092915050565b5f60028284186128649190613e49565b8284166128719190613c26565b905092915050565b5f79ffffffffffffffffffffffffffffffffffffffffffffffffffff80168211156128de5760d0826040517f6dfcc6500000000000000000000000000000000000000000000000000000000081526004016128d5929190613eb2565b60405180910390fd5b819050919050565b5f806129196128f3610d0e565b6129096128ff88611991565b868863ffffffff16565b87612c8b9092919063ffffffff16565b91509150935093915050565b60605f61293183612ca6565b90505f602067ffffffffffffffff81111561294f5761294e613998565b5b6040519080825280601f01601f1916602001820160405280156129815781602001600182028036833780820191505090505b5090508181528360208201528092505050919050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036129e7578060025f8282546129db9190613c26565b92505081905550612ab5565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015612a70578381836040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401612a6793929190613b55565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612afc578060025f8282540392505081905550612b46565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612ba391906132d3565b60405180910390a3505050565b5f79ffffffffffffffffffffffffffffffffffffffffffffffffffff8016905090565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612c1f57612c1c600a611105612c1784612879565b6128e6565b50505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612c6b57612c68600a61111a612c6384612879565b6128e6565b50505b612c86612c7784610a66565b612c8084610a66565b83611f96565b505050565b5f80612c9a855f018585612cf4565b91509150935093915050565b5f8060ff835f1c169050601f811115612ceb576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80915050919050565b5f805f858054905090505f811115612f74575f612d1d87600184612d189190613bf3565b611efe565b6040518060400160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900479ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff1679ffffffffffffffffffffffffffffffffffffffffffffffffffff168152505090508565ffffffffffff16815f015165ffffffffffff161115612e08576040517f2520601d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8565ffffffffffff16815f015165ffffffffffff1603612e8a5784612e3988600185612e349190613bf3565b611efe565b5f0160066101000a81548179ffffffffffffffffffffffffffffffffffffffffffffffffffff021916908379ffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550612f63565b8660405180604001604052808865ffffffffffff1681526020018779ffffffffffffffffffffffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003905f5260205f20015f909190919091505f820151815f015f6101000a81548165ffffffffffff021916908365ffffffffffff1602179055506020820151815f0160066101000a81548179ffffffffffffffffffffffffffffffffffffffffffffffffffff021916908379ffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b806020015185935093505050613054565b8560405180604001604052808765ffffffffffff1681526020018679ffffffffffffffffffffffffffffffffffffffffffffffffffff16815250908060018154018082558091505060019003905f5260205f20015f909190919091505f820151815f015f6101000a81548165ffffffffffff021916908365ffffffffffff1602179055506020820151815f0160066101000a81548179ffffffffffffffffffffffffffffffffffffffffffffffffffff021916908379ffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505f8492509250505b935093915050565b60405180604001604052805f65ffffffffffff1681526020015f79ffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090565b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6130d08161309c565b81146130da575f80fd5b50565b5f813590506130eb816130c7565b92915050565b5f6020828403121561310657613105613098565b5b5f613113848285016130dd565b91505092915050565b5f8115159050919050565b6131308161311c565b82525050565b5f6020820190506131495f830184613127565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561318657808201518184015260208101905061316b565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6131ab8261314f565b6131b58185613159565b93506131c5818560208601613169565b6131ce81613191565b840191505092915050565b5f6020820190508181035f8301526131f181846131a1565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f613222826131f9565b9050919050565b61323281613218565b811461323c575f80fd5b50565b5f8135905061324d81613229565b92915050565b5f819050919050565b61326581613253565b811461326f575f80fd5b50565b5f813590506132808161325c565b92915050565b5f806040838503121561329c5761329b613098565b5b5f6132a98582860161323f565b92505060206132ba85828601613272565b9150509250929050565b6132cd81613253565b82525050565b5f6020820190506132e65f8301846132c4565b92915050565b5f805f6060848603121561330357613302613098565b5b5f6133108682870161323f565b93505060206133218682870161323f565b925050604061333286828701613272565b9150509250925092565b5f819050919050565b61334e8161333c565b8114613358575f80fd5b50565b5f8135905061336981613345565b92915050565b5f6020828403121561338457613383613098565b5b5f6133918482850161335b565b91505092915050565b6133a38161333c565b82525050565b5f6020820190506133bc5f83018461339a565b92915050565b5f80604083850312156133d8576133d7613098565b5b5f6133e58582860161335b565b92505060206133f68582860161323f565b9150509250929050565b5f60ff82169050919050565b61341581613400565b82525050565b5f60208201905061342e5f83018461340c565b92915050565b5f6020828403121561344957613448613098565b5b5f61345684828501613272565b91505092915050565b5f6020828403121561347457613473613098565b5b5f6134818482850161323f565b91505092915050565b61349381613218565b82525050565b5f6020820190506134ac5f83018461348a565b92915050565b5f63ffffffff82169050919050565b6134ca816134b2565b82525050565b5f6020820190506134e35f8301846134c1565b92915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b61351d816134e9565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61355581613253565b82525050565b5f613566838361354c565b60208301905092915050565b5f602082019050919050565b5f61358882613523565b613592818561352d565b935061359d8361353d565b805f5b838110156135cd5781516135b4888261355b565b97506135bf83613572565b9250506001810190506135a0565b5085935050505092915050565b5f60e0820190506135ed5f83018a613514565b81810360208301526135ff81896131a1565b9050818103604083015261361381886131a1565b905061362260608301876132c4565b61362f608083018661348a565b61363c60a083018561339a565b81810360c083015261364e818461357e565b905098975050505050505050565b5f65ffffffffffff82169050919050565b6136768161365c565b82525050565b5f60208201905061368f5f83018461366d565b92915050565b61369e81613400565b81146136a8575f80fd5b50565b5f813590506136b981613695565b92915050565b5f805f805f8060c087890312156136d9576136d8613098565b5b5f6136e689828a0161323f565b96505060206136f789828a01613272565b955050604061370889828a01613272565b945050606061371989828a016136ab565b935050608061372a89828a0161335b565b92505060a061373b89828a0161335b565b9150509295509295509295565b5f805f805f805f60e0888a03121561376357613762613098565b5b5f6137708a828b0161323f565b97505060206137818a828b0161323f565b96505060406137928a828b01613272565b95505060606137a38a828b01613272565b94505060806137b48a828b016136ab565b93505060a06137c58a828b0161335b565b92505060c06137d68a828b0161335b565b91505092959891949750929550565b5f80604083850312156137fb576137fa613098565b5b5f6138088582860161323f565b92505060206138198582860161323f565b9150509250929050565b61382c816134b2565b8114613836575f80fd5b50565b5f8135905061384781613823565b92915050565b5f806040838503121561386357613862613098565b5b5f6138708582860161323f565b925050602061388185828601613839565b9150509250929050565b6138948161365c565b82525050565b5f79ffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b6138c88161389a565b82525050565b604082015f8201516138e25f85018261388b565b5060208201516138f560208501826138bf565b50505050565b5f60408201905061390e5f8301846138ce565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061395857607f821691505b60208210810361396b5761396a613914565b5b50919050565b5f6040820190506139845f8301856132c4565b613991602083018461366d565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f6080820190506139d85f83018761339a565b6139e5602083018661348a565b6139f260408301856132c4565b6139ff60608301846132c4565b95945050505050565b5f60c082019050613a1b5f83018961339a565b613a28602083018861348a565b613a35604083018761348a565b613a4260608301866132c4565b613a4f60808301856132c4565b613a5c60a08301846132c4565b979650505050505050565b5f604082019050613a7a5f83018561348a565b613a87602083018461348a565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f613ac58261389a565b9150613ad08361389a565b9250828201905079ffffffffffffffffffffffffffffffffffffffffffffffffffff811115613b0257613b01613a8e565b5b92915050565b5f613b128261389a565b9150613b1d8361389a565b9250828203905079ffffffffffffffffffffffffffffffffffffffffffffffffffff811115613b4f57613b4e613a8e565b5b92915050565b5f606082019050613b685f83018661348a565b613b7560208301856132c4565b613b8260408301846132c4565b949350505050565b5f819050919050565b5f819050919050565b5f613bb6613bb1613bac84613b8a565b613b93565b613400565b9050919050565b613bc681613b9c565b82525050565b5f604082019050613bdf5f830185613bbd565b613bec60208301846132c4565b9392505050565b5f613bfd82613253565b9150613c0883613253565b9250828203905081811115613c2057613c1f613a8e565b5b92915050565b5f613c3082613253565b9150613c3b83613253565b9250828201905080821115613c5357613c52613a8e565b5b92915050565b5f604082019050613c6c5f83018561348a565b613c7960208301846132c4565b9392505050565b5f604082019050613c935f83018561348a565b613ca0602083018461339a565b9392505050565b5f60a082019050613cba5f83018861339a565b613cc7602083018761339a565b613cd4604083018661339a565b613ce160608301856132c4565b613cee608083018461348a565b9695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f604082019050613d385f8301856132c4565b613d4560208301846132c4565b9392505050565b5f819050919050565b5f613d6f613d6a613d6584613d4c565b613b93565b613400565b9050919050565b613d7f81613d55565b82525050565b5f604082019050613d985f830185613d76565b613da560208301846132c4565b9392505050565b5f608082019050613dbf5f83018761339a565b613dcc602083018661340c565b613dd9604083018561339a565b613de6606083018461339a565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f613e5382613253565b9150613e5e83613253565b925082613e6e57613e6d613cf8565b5b828204905092915050565b5f819050919050565b5f613e9c613e97613e9284613e79565b613b93565b613400565b9050919050565b613eac81613e82565b82525050565b5f604082019050613ec55f830185613ea3565b613ed260208301846132c4565b939250505056fea26469706673582212209c18a340ff8ff5e94d45e3a14677ef813ace3ca3f8c5954ab110a0cba3fe70ac64736f6c63430008160033
Deployed Bytecode Sourcemap
171269:2161:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;134787:204;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;154479:91;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;156772:190;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;155581:99;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;157540:249;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;136067:122;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;136499:138;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;155432:84;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;169887:114;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;137636:251;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;143027:370;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;170609:89;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;142122:278;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;144682:119;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;144888:141;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;166976:128;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;155743:118;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;171027:161;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;173250:177;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;111212:580;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;144047:347;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135083:138;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;141863:98;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;154689:95;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;142495:137;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;134395:49;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;156066:182;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;145112:573;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;168875:695;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;136930:140;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;156311:142;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;167186:165;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;134787:204;134872:4;134911:32;134896:47;;;:11;:47;;;;:87;;;;134947:36;134971:11;134947:23;:36::i;:::-;134896:87;134889:94;;134787:204;;;:::o;154479:91::-;154524:13;154557:5;154550:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;154479:91;:::o;156772:190::-;156845:4;156862:13;156878:12;:10;:12::i;:::-;156862:28;;156901:31;156910:5;156917:7;156926:5;156901:8;:31::i;:::-;156950:4;156943:11;;;156772:190;;;;:::o;155581:99::-;155633:7;155660:12;;155653:19;;155581:99;:::o;157540:249::-;157627:4;157644:15;157662:12;:10;:12::i;:::-;157644:30;;157685:37;157701:4;157707:7;157716:5;157685:15;:37::i;:::-;157733:26;157743:4;157749:2;157753:5;157733:9;:26::i;:::-;157777:4;157770:11;;;157540:249;;;;;:::o;136067:122::-;136132:7;136159:6;:12;136166:4;136159:12;;;;;;;;;;;:22;;;136152:29;;136067:122;;;:::o;136499:138::-;136573:18;136586:4;136573:12;:18::i;:::-;134679:16;134690:4;134679:10;:16::i;:::-;136604:25:::1;136615:4;136621:7;136604:10;:25::i;:::-;;136499:138:::0;;;:::o;155432:84::-;155481:5;155506:2;155499:9;;155432:84;:::o;169887:114::-;169946:7;169973:20;:18;:20::i;:::-;169966:27;;169887:114;:::o;137636:251::-;137752:12;:10;:12::i;:::-;137730:34;;:18;:34;;;137726:104;;137788:30;;;;;;;;;;;;;;137726:104;137842:37;137854:4;137860:18;137842:11;:37::i;:::-;;137636:251;;:::o;143027:370::-;143114:7;143134:23;143160:7;:5;:7::i;:::-;143134:33;;143195:16;143182:29;;:9;:29;143178:117;;143255:9;143266:16;143235:48;;;;;;;;;;;;:::i;:::-;;;;;;;;143178:117;143312:77;143360:28;143378:9;143360:17;:28::i;:::-;143312:20;:29;143333:7;143312:29;;;;;;;;;;;;;;;:47;;:77;;;;:::i;:::-;143305:84;;;;;143027:370;;;;:::o;170609:89::-;170664:26;170670:12;:10;:12::i;:::-;170684:5;170664;:26::i;:::-;170609:89;:::o;142122:278::-;142173:13;142264:18;:16;:18::i;:::-;142253:29;;:7;:5;:7::i;:::-;:29;;;142249:95;;142306:26;;;;;;;;;;;;;;142249:95;142354:38;;;;;;;;;;;;;;;;;;;142122:278;:::o;144682:119::-;144747:7;144774:10;:19;144785:7;144774:19;;;;;;;;;;;;;;;;;;;;;;;;;144767:26;;144682:119;;;:::o;144888:141::-;144951:15;144969:12;:10;:12::i;:::-;144951:30;;144992:29;145002:7;145011:9;144992;:29::i;:::-;144940:89;144888:141;:::o;166976:128::-;167046:6;167072:24;167088:7;167072:15;:24::i;:::-;167065:31;;166976:128;;;:::o;155743:118::-;155808:7;155835:9;:18;155845:7;155835:18;;;;;;;;;;;;;;;;155828:25;;155743:118;;;:::o;171027:161::-;171103:45;171119:7;171128:12;:10;:12::i;:::-;171142:5;171103:15;:45::i;:::-;171159:21;171165:7;171174:5;171159;:21::i;:::-;171027:161;;:::o;173250:177::-;173368:7;173400:19;173413:5;173400:12;:19::i;:::-;173393:26;;173250:177;;;:::o;111212:580::-;111315:13;111343:18;111376:21;111412:15;111442:25;111482:12;111509:27;111617:13;:11;:13::i;:::-;111645:16;:14;:16::i;:::-;111676:13;111712:4;111740:1;111732:10;;111771:1;111757:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;111564:220;;;;;;;;;;;;;;;;;;;;;111212:580;;;;;;;:::o;144047:347::-;144123:7;144143:23;144169:7;:5;:7::i;:::-;144143:33;;144204:16;144191:29;;:9;:29;144187:117;;144264:9;144275:16;144244:48;;;;;;;;;;;;:::i;:::-;;;;;;;;144187:117;144321:65;144357:28;144375:9;144357:17;:28::i;:::-;144321:17;:35;;:65;;;;:::i;:::-;144314:72;;;;;144047:347;;;:::o;135083:138::-;135160:4;135184:6;:12;135191:4;135184:12;;;;;;;;;;;:20;;:29;135205:7;135184:29;;;;;;;;;;;;;;;;;;;;;;;;;135177:36;;135083:138;;;;:::o;141863:98::-;141909:6;141935:18;:16;:18::i;:::-;141928:25;;141863:98;:::o;154689:95::-;154736:13;154769:7;154762:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;154689:95;:::o;142495:137::-;142559:7;142586:38;:20;:29;142607:7;142586:29;;;;;;;;;;;;;;;:36;:38::i;:::-;142579:45;;;;142495:137;;;:::o;134395:49::-;134440:4;134395:49;;;:::o;156066:182::-;156135:4;156152:13;156168:12;:10;:12::i;:::-;156152:28;;156191:27;156201:5;156208:2;156212:5;156191:9;:27::i;:::-;156236:4;156229:11;;;156066:182;;;;:::o;145112:573::-;145325:6;145307:15;:24;145303:93;;;145377:6;145355:29;;;;;;;;;;;:::i;:::-;;;;;;;;145303:93;145406:14;145423:173;145451:86;141115:71;145510:9;145521:5;145528:6;145478:57;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;145468:68;;;;;;145451:16;:86::i;:::-;145552:1;145568;145584;145423:13;:173::i;:::-;145406:190;;145607:31;145624:6;145632:5;145607:16;:31::i;:::-;145649:28;145659:6;145667:9;145649;:28::i;:::-;145292:393;145112:573;;;;;;:::o;168875:695::-;169105:8;169087:15;:26;169083:99;;;169161:8;169137:33;;;;;;;;;;;:::i;:::-;;;;;;;;169083:99;169194:18;168195:95;169253:5;169260:7;169269:5;169276:16;169286:5;169276:9;:16::i;:::-;169294:8;169225:78;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;169215:89;;;;;;169194:110;;169317:12;169332:28;169349:10;169332:16;:28::i;:::-;169317:43;;169373:14;169390:28;169404:4;169410:1;169413;169416;169390:13;:28::i;:::-;169373:45;;169443:5;169433:15;;:6;:15;;;169429:90;;169493:6;169501:5;169472:35;;;;;;;;;;;;:::i;:::-;;;;;;;;169429:90;169531:31;169540:5;169547:7;169556:5;169531:8;:31::i;:::-;169072:498;;;168875:695;;;;;;;:::o;136930:140::-;137005:18;137018:4;137005:12;:18::i;:::-;134679:16;134690:4;134679:10;:16::i;:::-;137036:26:::1;137048:4;137054:7;137036:11;:26::i;:::-;;136930:140:::0;;;:::o;156311:142::-;156391:7;156418:11;:18;156430:5;156418:18;;;;;;;;;;;;;;;:27;156437:7;156418:27;;;;;;;;;;;;;;;;156411:34;;156311:142;;;;:::o;167186:165::-;167265:32;;:::i;:::-;167317:26;167330:7;167339:3;167317:12;:26::i;:::-;167310:33;;167186:165;;;;:::o;148532:98::-;148590:7;148621:1;148617;:5;;;;:::i;:::-;148610:12;;148532:98;;;;:::o;148638:103::-;148701:7;148732:1;148728;:5;;;;:::i;:::-;148721:12;;148638:103;;;;:::o;1726:148::-;1802:4;1841:25;1826:40;;;:11;:40;;;;1819:47;;1726:148;;;:::o;132058:98::-;132111:7;132138:10;132131:17;;132058:98;:::o;161599:130::-;161684:37;161693:5;161700:7;161709:5;161716:4;161684:8;:37::i;:::-;161599:130;;;:::o;163315:487::-;163415:24;163442:25;163452:5;163459:7;163442:9;:25::i;:::-;163415:52;;163502:17;163482:16;:37;163478:317;;163559:5;163540:16;:24;163536:132;;;163619:7;163628:16;163646:5;163592:60;;;;;;;;;;;;;:::i;:::-;;;;;;;;163536:132;163711:57;163720:5;163727:7;163755:5;163736:16;:24;163762:5;163711:8;:57::i;:::-;163478:317;163404:398;163315:487;;;:::o;158174:308::-;158274:1;158258:18;;:4;:18;;;158254:88;;158327:1;158300:30;;;;;;;;;;;:::i;:::-;;;;;;;;158254:88;158370:1;158356:16;;:2;:16;;;158352:88;;158425:1;158396:32;;;;;;;;;;;:::i;:::-;;;;;;;;158352:88;158450:24;158458:4;158464:2;158468:5;158450:7;:24::i;:::-;158174:308;;;:::o;135436:105::-;135503:30;135514:4;135520:12;:10;:12::i;:::-;135503:10;:30::i;:::-;135436:105;:::o;138513:324::-;138590:4;138612:22;138620:4;138626:7;138612;:22::i;:::-;138607:223;;138683:4;138651:6;:12;138658:4;138651:12;;;;;;;;;;;:20;;:29;138672:7;138651:29;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;138734:12;:10;:12::i;:::-;138707:40;;138725:7;138707:40;;138719:4;138707:40;;;;;;;;;;138769:4;138762:11;;;;138607:223;138813:5;138806:12;;138513:324;;;;;:::o;109879:268::-;109932:7;109973:11;109956:28;;109964:4;109956:28;;;:63;;;;;110005:14;109988:13;:31;109956:63;109952:188;;;110043:22;110036:29;;;;109952:188;110105:23;:21;:23::i;:::-;110098:30;;109879:268;;:::o;139081:325::-;139159:4;139180:22;139188:4;139194:7;139180;:22::i;:::-;139176:223;;;139251:5;139219:6;:12;139226:4;139219:12;;;;;;;;;;;:20;;:29;139240:7;139219:29;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;139303:12;:10;:12::i;:::-;139276:40;;139294:7;139276:40;;139288:4;139276:40;;;;;;;;;;139338:4;139331:11;;;;139176:223;139382:5;139375:12;;139081:325;;;;;:::o;20077:218::-;20133:6;20164:16;20156:24;;:5;:24;20152:105;;;20235:2;20239:5;20204:41;;;;;;;;;;;;:::i;:::-;;;;;;;;20152:105;20281:5;20267:20;;20077:218;;;:::o;87057:624::-;87142:7;87162:11;87176:4;:17;;:24;;;;87162:38;;87213:11;87239:12;87254:3;87239:18;;87280:1;87274:3;:7;87270:241;;;87298:11;87318:14;87328:3;87318:9;:14::i;:::-;87312:3;:20;;;;:::i;:::-;87298:34;;87357:37;87371:4;:17;;87390:3;87357:13;:37::i;:::-;:42;;;;;;;;;;;;87351:48;;:3;:48;;;87347:153;;;87427:3;87420:10;;87347:153;;;87483:1;87477:3;:7;;;;:::i;:::-;87471:13;;87347:153;87283:228;87270:241;87523:11;87537:53;87556:4;:17;;87575:3;87580;87585:4;87537:18;:53::i;:::-;87523:67;;87617:1;87610:3;:8;:63;;87625:41;87639:4;:17;;87664:1;87658:3;:7;;;;:::i;:::-;87625:13;:41::i;:::-;:48;;;;;;;;;;;;87610:63;;;87621:1;87610:63;87603:70;;;;;;87057:624;;;;:::o;160835:211::-;160925:1;160906:21;;:7;:21;;;160902:91;;160978:1;160951:30;;;;;;;;;;;:::i;:::-;;;;;;;;160902:91;161003:35;161011:7;161028:1;161032:5;161003:7;:35::i;:::-;160835:211;;:::o;73088:111::-;73134:6;73160:31;73178:12;73160:17;:31::i;:::-;73153:38;;73088:111;:::o;145870:318::-;145953:19;145975:18;145985:7;145975:9;:18::i;:::-;145953:40;;146026:9;146004:10;:19;146015:7;146004:19;;;;;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;146091:9;146053:48;;146078:11;146053:48;;146069:7;146053:48;;;;;;;;;;;;146112:68;146131:11;146144:9;146155:24;146171:7;146155:15;:24::i;:::-;146112:18;:68::i;:::-;145942:246;145870:318;;:::o;147805:164::-;147878:6;147904:57;147922:38;:20;:29;147943:7;147922:29;;;;;;;;;;;;;;;:36;:38::i;:::-;147904:17;:57::i;:::-;147897:64;;147805:164;;;:::o;169629:145::-;169720:7;169747:19;169760:5;169747:12;:19::i;:::-;169740:26;;169629:145;;;:::o;112121:128::-;112167:13;112200:41;112227:13;112200:5;:26;;:41;;;;:::i;:::-;112193:48;;112121:128;:::o;112584:137::-;112633:13;112666:47;112696:16;112666:8;:29;;:47;;;;:::i;:::-;112659:54;;112584:137;:::o;87806:209::-;87868:7;87888:11;87902:4;:17;;:24;;;;87888:38;;87951:1;87944:3;:8;:63;;87959:41;87973:4;:17;;87998:1;87992:3;:7;;;;:::i;:::-;87959:13;:41::i;:::-;:48;;;;;;;;;;;;87944:63;;;87955:1;87944:63;87937:70;;;87806:209;;;:::o;110978:178::-;111055:7;111082:66;111115:20;:18;:20::i;:::-;111137:10;111082:32;:66::i;:::-;111075:73;;110978:178;;;:::o;119724:264::-;119809:7;119830:17;119849:18;119869:16;119889:25;119900:4;119906:1;119909;119912;119889:10;:25::i;:::-;119829:85;;;;;;119925:28;119937:5;119944:8;119925:11;:28::i;:::-;119971:9;119964:16;;;;;119724:264;;;;;;:::o;45708:227::-;45792:15;45810:16;45820:5;45810:9;:16::i;:::-;45792:34;;45850:7;45841:5;:16;45837:91;;45901:5;45908:7;45881:35;;;;;;;;;;;;:::i;:::-;;;;;;;;45837:91;45781:154;45708:227;;:::o;45190:402::-;45250:7;45557;:14;45565:5;45557:14;;;;;;;;;;;;;;;;:16;;;;;;;;;;;;45550:23;;45190:402;;;:::o;148051:204::-;148158:32;;:::i;:::-;148210:37;148243:3;148210:20;:29;148231:7;148210:29;;;;;;;;;;;;;;;:32;;:37;;;;:::i;:::-;148203:44;;148051:204;;;;:::o;162580:443::-;162710:1;162693:19;;:5;:19;;;162689:91;;162765:1;162736:32;;;;;;;;;;;:::i;:::-;;;;;;;;162689:91;162813:1;162794:21;;:7;:21;;;162790:92;;162867:1;162839:31;;;;;;;;;;;:::i;:::-;;;;;;;;162790:92;162922:5;162892:11;:18;162904:5;162892:18;;;;;;;;;;;;;;;:27;162911:7;162892:27;;;;;;;;;;;;;;;:35;;;;162942:9;162938:78;;;162989:7;162973:31;;162982:5;162973:31;;;162998:5;162973:31;;;;;;:::i;:::-;;;;;;;;162938:78;162580:443;;;;:::o;173075:167::-;173204:30;173218:4;173224:2;173228:5;173204:13;:30::i;:::-;173075:167;;;:::o;135677:201::-;135766:22;135774:4;135780:7;135766;:22::i;:::-;135761:110;;135845:7;135854:4;135812:47;;;;;;;;;;;;:::i;:::-;;;;;;;;135761:110;135677:201;;:::o;110155:181::-;110210:7;108071:95;110269:11;110282:14;110298:13;110321:4;110247:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;110237:91;;;;;;110230:98;;110155:181;:::o;65451:1673::-;65499:7;65528:1;65523;:6;65519:47;;65553:1;65546:8;;;;65519:47;66257:14;66291:1;66280:7;66285:1;66280:4;:7::i;:::-;:12;;66274:1;:19;;66257:36;;66759:1;66748:6;66744:1;:10;;;;;:::i;:::-;;;66735:6;:19;66734:26;;66725:35;;66809:1;66798:6;66794:1;:10;;;;;:::i;:::-;;;66785:6;:19;66784:26;;66775:35;;66859:1;66848:6;66844:1;:10;;;;;:::i;:::-;;;66835:6;:19;66834:26;;66825:35;;66909:1;66898:6;66894:1;:10;;;;;:::i;:::-;;;66885:6;:19;66884:26;;66875:35;;66959:1;66948:6;66944:1;:10;;;;;:::i;:::-;;;66935:6;:19;66934:26;;66925:35;;67009:1;66998:6;66994:1;:10;;;;;:::i;:::-;;;66985:6;:19;66984:26;;66975:35;;67059:1;67048:6;67044:1;:10;;;;;:::i;:::-;;;67035:6;:19;67034:26;;67025:35;;67082:23;67086:6;67098;67094:1;:10;;;;;:::i;:::-;;;67082:3;:23::i;:::-;67075:30;;;65451:1673;;;;:::o;91851:273::-;91964:28;92039:9;92036:1;92029:20;92102:3;92095:4;92092:1;92082:18;92078:28;92063:43;;91851:273;;;;:::o;90444:448::-;90606:7;90626:237;90639:4;90633:3;:10;90626:237;;;90660:11;90674:23;90687:3;90692:4;90674:12;:23::i;:::-;90660:37;;90748:3;90716:35;;:24;90730:4;90736:3;90716:13;:24::i;:::-;:29;;;;;;;;;;;;:35;;;90712:140;;;90779:3;90772:10;;90712:140;;;90835:1;90829:3;:7;;;;:::i;:::-;90823:13;;90712:140;90645:218;90626:237;;;90880:4;90873:11;;90444:448;;;;;;:::o;166761:135::-;166843:7;166870:18;166880:7;166870:9;:18::i;:::-;166863:25;;166761:135;;;:::o;146926:799::-;147027:2;147019:10;;:4;:10;;;;:24;;;;;147042:1;147033:6;:10;147019:24;147015:703;;;147080:1;147064:18;;:4;:18;;;147060:322;;147104:16;147122;147142:154;147170:20;:26;147191:4;147170:26;;;;;;;;;;;;;;;147219:9;147251:26;147270:6;147251:18;:26::i;:::-;147142:5;:154::i;:::-;147103:193;;;;;;;;147341:4;147320:46;;;147347:8;147357;147320:46;;;;;;;:::i;:::-;;;;;;;;147084:298;;147060:322;147414:1;147400:16;;:2;:16;;;147396:311;;147438:16;147456;147476:147;147504:20;:24;147525:2;147504:24;;;;;;;;;;;;;;;147551:4;147578:26;147597:6;147578:18;:26::i;:::-;147476:5;:147::i;:::-;147437:186;;;;;;;;147668:2;147647:44;;;147672:8;147682;147647:44;;;;;;;:::i;:::-;;;;;;;;147418:289;;147396:311;147015:703;146926:799;;;:::o;88669:121::-;88731:7;88758:4;:17;;:24;;;;88751:31;;88669:121;;;:::o;21111:218::-;21167:6;21198:16;21190:24;;:5;:24;21186:105;;;21269:2;21273:5;21238:41;;;;;;;;;;;;:::i;:::-;;;;;;;;21186:105;21315:5;21301:20;;21111:218;;;:::o;44960:109::-;45020:7;45047;:14;45055:5;45047:14;;;;;;;;;;;;;;;;45040:21;;44960:109;;;:::o;54318:273::-;54412:13;52264:66;54471:17;;54461:5;54442:46;54438:146;;54512:15;54521:5;54512:8;:15::i;:::-;54505:22;;;;54438:146;54567:5;54560:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54318:273;;;;;:::o;105672:410::-;105765:14;105877:4;105871:11;105908:10;105903:3;105896:23;105956:15;105949:4;105944:3;105940:14;105933:39;106009:10;106002:4;105997:3;105993:14;105986:34;106059:4;106054:3;106044:20;106034:30;;105845:230;105672:410;;;;:::o;118029:1556::-;118160:7;118169:12;118183:7;119103:66;119098:1;119090:10;;:79;119086:166;;;119202:1;119206:30;119238:1;119186:54;;;;;;;;119086:166;119349:14;119366:24;119376:4;119382:1;119385;119388;119366:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;119349:41;;119423:1;119405:20;;:6;:20;;;119401:115;;119458:1;119462:29;119501:1;119493:10;;119442:62;;;;;;;;;119401:115;119536:6;119544:20;119574:1;119566:10;;119528:49;;;;;;;118029:1556;;;;;;;;;:::o;120126:542::-;120222:20;120213:29;;;;;;;;:::i;:::-;;:5;:29;;;;;;;;:::i;:::-;;;120209:452;120259:7;120209:452;120320:29;120311:38;;;;;;;;:::i;:::-;;:5;:38;;;;;;;;:::i;:::-;;;120307:354;;120373:23;;;;;;;;;;;;;;120307:354;120427:35;120418:44;;;;;;;;:::i;:::-;;:5;:44;;;;;;;;:::i;:::-;;;120414:247;;120522:8;120514:17;;120486:46;;;;;;;;;;;:::i;:::-;;;;;;;;120414:247;120563:30;120554:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;120550:111;;120640:8;120617:32;;;;;;;;;;;:::i;:::-;;;;;;;;120550:111;120126:542;;;:::o;88867:140::-;88937:20;;:::i;:::-;88977:4;:17;;88995:3;88977:22;;;;;;;;;;:::i;:::-;;;;;;;;;88970:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88867:140;;;;:::o;166070:423::-;166165:30;166179:4;166185:2;166189:5;166165:13;:30::i;:::-;166226:1;166210:18;;:4;:18;;;166206:232;;166245:14;166262:13;:11;:13::i;:::-;166245:30;;166290:11;166304:12;:10;:12::i;:::-;166290:26;;166344:3;166335:6;:12;166331:96;;;166399:6;166407:3;166375:36;;;;;;;;;;;;:::i;:::-;;;;;;;;166331:96;166230:208;;166206:232;166448:37;166469:4;166475:2;166479:5;166448:20;:37::i;:::-;166070:423;;;:::o;67610:1019::-;67662:7;67682:14;67699:1;67682:18;;67755:1;67749:3;67740:5;:12;;:16;67736:102;;;67787:3;67777:13;;;;;67819:3;67809:13;;;;67736:102;67870:1;67865:2;67856:5;:11;;:15;67852:99;;;67902:2;67892:12;;;;;67933:2;67923:12;;;;67852:99;67983:1;67978:2;67969:5;:11;;:15;67965:99;;;68015:2;68005:12;;;;;68046:2;68036:12;;;;67965:99;68096:1;68091:2;68082:5;:11;;:15;68078:99;;;68128:2;68118:12;;;;;68159:2;68149:12;;;;68078:99;68208:1;68204;68195:5;:10;;:14;68191:96;;;68240:1;68230:11;;;;;68270:1;68260:11;;;;68191:96;68318:1;68314;68305:5;:10;;:14;68301:96;;;68350:1;68340:11;;;;;68380:1;68370:11;;;;68301:96;68428:1;68424;68415:5;:10;;:14;68411:96;;;68460:1;68450:11;;;;;68490:1;68480:11;;;;68411:96;68538:1;68534;68525:5;:10;;:14;68521:66;;;68570:1;68560:11;;;;68521:66;68615:6;68608:13;;;67610:1019;;;:::o;59288:106::-;59346:7;59377:1;59373;:5;:13;;59385:1;59373:13;;;59381:1;59373:13;59366:20;;59288:106;;;;:::o;59513:156::-;59575:7;59660:1;59655;59651;:5;59650:11;;;;:::i;:::-;59645:1;59641;:5;59640:21;;;;:::i;:::-;59633:28;;59513:156;;;;:::o;9615:223::-;9672:7;9704:17;9696:25;;:5;:25;9692:107;;;9776:3;9781:5;9745:42;;;;;;;;;;;;:::i;:::-;;;;;;;;9692:107;9824:5;9809:21;;9615:223;;;:::o;148263:261::-;148434:7;148443;148470:46;148481:7;:5;:7::i;:::-;148490:25;148493:14;:5;:12;:14::i;:::-;148509:5;148490:2;:25;;:::i;:::-;148470:5;:10;;:46;;;;;:::i;:::-;148463:53;;;;148263:261;;;;;;:::o;52973:415::-;53032:13;53058:11;53072:16;53083:4;53072:10;:16::i;:::-;53058:30;;53178:17;53209:2;53198:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53178:34;;53303:3;53298;53291:16;53344:4;53337;53332:3;53328:14;53321:28;53377:3;53370:10;;;;52973:415;;;:::o;158806:1135::-;158912:1;158896:18;;:4;:18;;;158892:552;;159050:5;159034:12;;:21;;;;;;;:::i;:::-;;;;;;;;158892:552;;;159088:19;159110:9;:15;159120:4;159110:15;;;;;;;;;;;;;;;;159088:37;;159158:5;159144:11;:19;159140:117;;;159216:4;159222:11;159235:5;159191:50;;;;;;;;;;;;;:::i;:::-;;;;;;;;159140:117;159412:5;159398:11;:19;159380:9;:15;159390:4;159380:15;;;;;;;;;;;;;;;:37;;;;159073:371;158892:552;159474:1;159460:16;;:2;:16;;;159456:435;;159642:5;159626:12;;:21;;;;;;;;;;;159456:435;;;159859:5;159842:9;:13;159852:2;159842:13;;;;;;;;;;;;;;;;:22;;;;;;;;;;;159456:435;159923:2;159908:25;;159917:4;159908:25;;;159927:5;159908:25;;;;;;:::i;:::-;;;;;;;;158806:1135;;;:::o;165818:105::-;165871:7;165898:17;165891:24;;;;165818:105;:::o;146428:407::-;146548:1;146532:18;;:4;:18;;;146528:109;;146567:58;146573:17;146592:4;146598:26;146617:6;146598:18;:26::i;:::-;146567:5;:58::i;:::-;;;146528:109;146665:1;146651:16;;:2;:16;;;146647:112;;146684:63;146690:17;146709:9;146720:26;146739:6;146720:18;:26::i;:::-;146684:5;:63::i;:::-;;;146647:112;146769:58;146788:15;146798:4;146788:9;:15::i;:::-;146805:13;146815:2;146805:9;:13::i;:::-;146820:6;146769:18;:58::i;:::-;146428:407;;;:::o;85635:164::-;85717:7;85726;85753:38;85761:4;:17;;85780:3;85785:5;85753:7;:38::i;:::-;85746:45;;;;85635:164;;;;;;:::o;53465:251::-;53526:7;53546:14;53599:4;53590;53563:33;;:40;53546:57;;53627:2;53618:6;:11;53614:71;;;53653:20;;;;;;;;;;;;;;53614:71;53702:6;53695:13;;;53465:251;;;:::o;89189:893::-;89280:7;89289;89309:11;89323:4;:11;;;;89309:25;;89357:1;89351:3;:7;89347:728;;;89428:25;89456:28;89470:4;89482:1;89476:3;:7;;;;:::i;:::-;89456:13;:28::i;:::-;89428:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89573:3;89561:15;;:4;:9;;;:15;;;89557:93;;;89604:30;;;;;;;;;;;;;;89557:93;89729:3;89716:16;;:4;:9;;;:16;;;89712:193;;89791:5;89753:28;89767:4;89779:1;89773:3;:7;;;;:::i;:::-;89753:13;:28::i;:::-;:35;;;:43;;;;;;;;;;;;;;;;;;89712:193;;;89837:4;89847:41;;;;;;;;89868:3;89847:41;;;;;;89881:5;89847:41;;;;;89837:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89712:193;89927:4;:11;;;89940:5;89919:27;;;;;;;;89347:728;89979:4;89989:41;;;;;;;;90010:3;89989:41;;;;;;90023:5;89989:41;;;;;89979:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90054:1;90057:5;90046:17;;;;;89189:893;;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;:::o;88:117:1:-;197:1;194;187: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:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:126::-;2897:7;2937:42;2930:5;2926:54;2915:65;;2860:126;;;:::o;2992:96::-;3029:7;3058:24;3076:5;3058:24;:::i;:::-;3047:35;;2992:96;;;:::o;3094:122::-;3167:24;3185:5;3167:24;:::i;:::-;3160:5;3157:35;3147:63;;3206:1;3203;3196:12;3147:63;3094:122;:::o;3222:139::-;3268:5;3306:6;3293:20;3284:29;;3322:33;3349:5;3322:33;:::i;:::-;3222:139;;;;:::o;3367:77::-;3404:7;3433:5;3422:16;;3367:77;;;:::o;3450:122::-;3523:24;3541:5;3523:24;:::i;:::-;3516:5;3513:35;3503:63;;3562:1;3559;3552:12;3503:63;3450:122;:::o;3578:139::-;3624:5;3662:6;3649:20;3640:29;;3678:33;3705:5;3678:33;:::i;:::-;3578:139;;;;:::o;3723:474::-;3791:6;3799;3848:2;3836:9;3827:7;3823:23;3819:32;3816:119;;;3854:79;;:::i;:::-;3816:119;3974:1;3999:53;4044:7;4035:6;4024:9;4020:22;3999:53;:::i;:::-;3989:63;;3945:117;4101:2;4127:53;4172:7;4163:6;4152:9;4148:22;4127:53;:::i;:::-;4117:63;;4072:118;3723:474;;;;;:::o;4203:118::-;4290:24;4308:5;4290:24;:::i;:::-;4285:3;4278:37;4203:118;;:::o;4327:222::-;4420:4;4458:2;4447:9;4443:18;4435:26;;4471:71;4539:1;4528:9;4524:17;4515:6;4471:71;:::i;:::-;4327:222;;;;:::o;4555:619::-;4632:6;4640;4648;4697:2;4685:9;4676:7;4672:23;4668:32;4665:119;;;4703:79;;:::i;:::-;4665:119;4823:1;4848:53;4893:7;4884:6;4873:9;4869:22;4848:53;:::i;:::-;4838:63;;4794:117;4950:2;4976:53;5021:7;5012:6;5001:9;4997:22;4976:53;:::i;:::-;4966:63;;4921:118;5078:2;5104:53;5149:7;5140:6;5129:9;5125:22;5104:53;:::i;:::-;5094:63;;5049:118;4555:619;;;;;:::o;5180:77::-;5217:7;5246:5;5235:16;;5180:77;;;:::o;5263:122::-;5336:24;5354:5;5336:24;:::i;:::-;5329:5;5326:35;5316:63;;5375:1;5372;5365:12;5316:63;5263:122;:::o;5391:139::-;5437:5;5475:6;5462:20;5453:29;;5491:33;5518:5;5491:33;:::i;:::-;5391:139;;;;:::o;5536:329::-;5595:6;5644:2;5632:9;5623:7;5619:23;5615:32;5612:119;;;5650:79;;:::i;:::-;5612:119;5770:1;5795:53;5840:7;5831:6;5820:9;5816:22;5795:53;:::i;:::-;5785:63;;5741:117;5536:329;;;;:::o;5871:118::-;5958:24;5976:5;5958:24;:::i;:::-;5953:3;5946:37;5871:118;;:::o;5995:222::-;6088:4;6126:2;6115:9;6111:18;6103:26;;6139:71;6207:1;6196:9;6192:17;6183:6;6139:71;:::i;:::-;5995:222;;;;:::o;6223:474::-;6291:6;6299;6348:2;6336:9;6327:7;6323:23;6319:32;6316:119;;;6354:79;;:::i;:::-;6316:119;6474:1;6499:53;6544:7;6535:6;6524:9;6520:22;6499:53;:::i;:::-;6489:63;;6445:117;6601:2;6627:53;6672:7;6663:6;6652:9;6648:22;6627:53;:::i;:::-;6617:63;;6572:118;6223:474;;;;;:::o;6703:86::-;6738:7;6778:4;6771:5;6767:16;6756:27;;6703:86;;;:::o;6795:112::-;6878:22;6894:5;6878:22;:::i;:::-;6873:3;6866:35;6795:112;;:::o;6913:214::-;7002:4;7040:2;7029:9;7025:18;7017:26;;7053:67;7117:1;7106:9;7102:17;7093:6;7053:67;:::i;:::-;6913:214;;;;:::o;7133:329::-;7192:6;7241:2;7229:9;7220:7;7216:23;7212:32;7209:119;;;7247:79;;:::i;:::-;7209:119;7367:1;7392:53;7437:7;7428:6;7417:9;7413:22;7392:53;:::i;:::-;7382:63;;7338:117;7133:329;;;;:::o;7468:::-;7527:6;7576:2;7564:9;7555:7;7551:23;7547:32;7544:119;;;7582:79;;:::i;:::-;7544:119;7702:1;7727:53;7772:7;7763:6;7752:9;7748:22;7727:53;:::i;:::-;7717:63;;7673:117;7468:329;;;;:::o;7803:118::-;7890:24;7908:5;7890:24;:::i;:::-;7885:3;7878:37;7803:118;;:::o;7927:222::-;8020:4;8058:2;8047:9;8043:18;8035:26;;8071:71;8139:1;8128:9;8124:17;8115:6;8071:71;:::i;:::-;7927:222;;;;:::o;8155:93::-;8191:7;8231:10;8224:5;8220:22;8209:33;;8155:93;;;:::o;8254:115::-;8339:23;8356:5;8339:23;:::i;:::-;8334:3;8327:36;8254:115;;:::o;8375:218::-;8466:4;8504:2;8493:9;8489:18;8481:26;;8517:69;8583:1;8572:9;8568:17;8559:6;8517:69;:::i;:::-;8375:218;;;;:::o;8599:149::-;8635:7;8675:66;8668:5;8664:78;8653:89;;8599:149;;;:::o;8754:115::-;8839:23;8856:5;8839:23;:::i;:::-;8834:3;8827:36;8754:115;;:::o;8875:114::-;8942:6;8976:5;8970:12;8960:22;;8875:114;;;:::o;8995:184::-;9094:11;9128:6;9123:3;9116:19;9168:4;9163:3;9159:14;9144:29;;8995:184;;;;:::o;9185:132::-;9252:4;9275:3;9267:11;;9305:4;9300:3;9296:14;9288:22;;9185:132;;;:::o;9323:108::-;9400:24;9418:5;9400:24;:::i;:::-;9395:3;9388:37;9323:108;;:::o;9437:179::-;9506:10;9527:46;9569:3;9561:6;9527:46;:::i;:::-;9605:4;9600:3;9596:14;9582:28;;9437:179;;;;:::o;9622:113::-;9692:4;9724;9719:3;9715:14;9707:22;;9622:113;;;:::o;9771:732::-;9890:3;9919:54;9967:5;9919:54;:::i;:::-;9989:86;10068:6;10063:3;9989:86;:::i;:::-;9982:93;;10099:56;10149:5;10099:56;:::i;:::-;10178:7;10209:1;10194:284;10219:6;10216:1;10213:13;10194:284;;;10295:6;10289:13;10322:63;10381:3;10366:13;10322:63;:::i;:::-;10315:70;;10408:60;10461:6;10408:60;:::i;:::-;10398:70;;10254:224;10241:1;10238;10234:9;10229:14;;10194:284;;;10198:14;10494:3;10487:10;;9895:608;;;9771:732;;;;:::o;10509:1215::-;10858:4;10896:3;10885:9;10881:19;10873:27;;10910:69;10976:1;10965:9;10961:17;10952:6;10910:69;:::i;:::-;11026:9;11020:4;11016:20;11011:2;11000:9;10996:18;10989:48;11054:78;11127:4;11118:6;11054:78;:::i;:::-;11046:86;;11179:9;11173:4;11169:20;11164:2;11153:9;11149:18;11142:48;11207:78;11280:4;11271:6;11207:78;:::i;:::-;11199:86;;11295:72;11363:2;11352:9;11348:18;11339:6;11295:72;:::i;:::-;11377:73;11445:3;11434:9;11430:19;11421:6;11377:73;:::i;:::-;11460;11528:3;11517:9;11513:19;11504:6;11460:73;:::i;:::-;11581:9;11575:4;11571:20;11565:3;11554:9;11550:19;11543:49;11609:108;11712:4;11703:6;11609:108;:::i;:::-;11601:116;;10509:1215;;;;;;;;;;:::o;11730:97::-;11766:7;11806:14;11799:5;11795:26;11784:37;;11730:97;;;:::o;11833:115::-;11918:23;11935:5;11918:23;:::i;:::-;11913:3;11906:36;11833:115;;:::o;11954:218::-;12045:4;12083:2;12072:9;12068:18;12060:26;;12096:69;12162:1;12151:9;12147:17;12138:6;12096:69;:::i;:::-;11954:218;;;;:::o;12178:118::-;12249:22;12265:5;12249:22;:::i;:::-;12242:5;12239:33;12229:61;;12286:1;12283;12276:12;12229:61;12178:118;:::o;12302:135::-;12346:5;12384:6;12371:20;12362:29;;12400:31;12425:5;12400:31;:::i;:::-;12302:135;;;;:::o;12443:1053::-;12545:6;12553;12561;12569;12577;12585;12634:3;12622:9;12613:7;12609:23;12605:33;12602:120;;;12641:79;;:::i;:::-;12602:120;12761:1;12786:53;12831:7;12822:6;12811:9;12807:22;12786:53;:::i;:::-;12776:63;;12732:117;12888:2;12914:53;12959:7;12950:6;12939:9;12935:22;12914:53;:::i;:::-;12904:63;;12859:118;13016:2;13042:53;13087:7;13078:6;13067:9;13063:22;13042:53;:::i;:::-;13032:63;;12987:118;13144:2;13170:51;13213:7;13204:6;13193:9;13189:22;13170:51;:::i;:::-;13160:61;;13115:116;13270:3;13297:53;13342:7;13333:6;13322:9;13318:22;13297:53;:::i;:::-;13287:63;;13241:119;13399:3;13426:53;13471:7;13462:6;13451:9;13447:22;13426:53;:::i;:::-;13416:63;;13370:119;12443:1053;;;;;;;;:::o;13502:1199::-;13613:6;13621;13629;13637;13645;13653;13661;13710:3;13698:9;13689:7;13685:23;13681:33;13678:120;;;13717:79;;:::i;:::-;13678:120;13837:1;13862:53;13907:7;13898:6;13887:9;13883:22;13862:53;:::i;:::-;13852:63;;13808:117;13964:2;13990:53;14035:7;14026:6;14015:9;14011:22;13990:53;:::i;:::-;13980:63;;13935:118;14092:2;14118:53;14163:7;14154:6;14143:9;14139:22;14118:53;:::i;:::-;14108:63;;14063:118;14220:2;14246:53;14291:7;14282:6;14271:9;14267:22;14246:53;:::i;:::-;14236:63;;14191:118;14348:3;14375:51;14418:7;14409:6;14398:9;14394:22;14375:51;:::i;:::-;14365:61;;14319:117;14475:3;14502:53;14547:7;14538:6;14527:9;14523:22;14502:53;:::i;:::-;14492:63;;14446:119;14604:3;14631:53;14676:7;14667:6;14656:9;14652:22;14631:53;:::i;:::-;14621:63;;14575:119;13502:1199;;;;;;;;;;:::o;14707:474::-;14775:6;14783;14832:2;14820:9;14811:7;14807:23;14803:32;14800:119;;;14838:79;;:::i;:::-;14800:119;14958:1;14983:53;15028:7;15019:6;15008:9;15004:22;14983:53;:::i;:::-;14973:63;;14929:117;15085:2;15111:53;15156:7;15147:6;15136:9;15132:22;15111:53;:::i;:::-;15101:63;;15056:118;14707:474;;;;;:::o;15187:120::-;15259:23;15276:5;15259:23;:::i;:::-;15252:5;15249:34;15239:62;;15297:1;15294;15287:12;15239:62;15187:120;:::o;15313:137::-;15358:5;15396:6;15383:20;15374:29;;15412:32;15438:5;15412:32;:::i;:::-;15313:137;;;;:::o;15456:472::-;15523:6;15531;15580:2;15568:9;15559:7;15555:23;15551:32;15548:119;;;15586:79;;:::i;:::-;15548:119;15706:1;15731:53;15776:7;15767:6;15756:9;15752:22;15731:53;:::i;:::-;15721:63;;15677:117;15833:2;15859:52;15903:7;15894:6;15883:9;15879:22;15859:52;:::i;:::-;15849:62;;15804:117;15456:472;;;;;:::o;15934:105::-;16009:23;16026:5;16009:23;:::i;:::-;16004:3;15997:36;15934:105;;:::o;16045:138::-;16082:7;16122:54;16115:5;16111:66;16100:77;;16045:138;;;:::o;16189:108::-;16266:24;16284:5;16266:24;:::i;:::-;16261:3;16254:37;16189:108;;:::o;16379:519::-;16538:4;16533:3;16529:14;16625:4;16618:5;16614:16;16608:23;16644:61;16699:4;16694:3;16690:14;16676:12;16644:61;:::i;:::-;16553:162;16799:4;16792:5;16788:16;16782:23;16818:63;16875:4;16870:3;16866:14;16852:12;16818:63;:::i;:::-;16725:166;16507:391;16379:519;;:::o;16904:346::-;17059:4;17097:2;17086:9;17082:18;17074:26;;17110:133;17240:1;17229:9;17225:17;17216:6;17110:133;:::i;:::-;16904:346;;;;:::o;17256:180::-;17304:77;17301:1;17294:88;17401:4;17398:1;17391:15;17425:4;17422:1;17415:15;17442:320;17486:6;17523:1;17517:4;17513:12;17503:22;;17570:1;17564:4;17560:12;17591:18;17581:81;;17647:4;17639:6;17635:17;17625:27;;17581:81;17709:2;17701:6;17698:14;17678:18;17675:38;17672:84;;17728:18;;:::i;:::-;17672:84;17493:269;17442:320;;;:::o;17768:328::-;17887:4;17925:2;17914:9;17910:18;17902:26;;17938:71;18006:1;17995:9;17991:17;17982:6;17938:71;:::i;:::-;18019:70;18085:2;18074:9;18070:18;18061:6;18019:70;:::i;:::-;17768:328;;;;;:::o;18102:180::-;18150:77;18147:1;18140:88;18247:4;18244:1;18237:15;18271:4;18268:1;18261:15;18288:553;18465:4;18503:3;18492:9;18488:19;18480:27;;18517:71;18585:1;18574:9;18570:17;18561:6;18517:71;:::i;:::-;18598:72;18666:2;18655:9;18651:18;18642:6;18598:72;:::i;:::-;18680;18748:2;18737:9;18733:18;18724:6;18680:72;:::i;:::-;18762;18830:2;18819:9;18815:18;18806:6;18762:72;:::i;:::-;18288:553;;;;;;;:::o;18847:775::-;19080:4;19118:3;19107:9;19103:19;19095:27;;19132:71;19200:1;19189:9;19185:17;19176:6;19132:71;:::i;:::-;19213:72;19281:2;19270:9;19266:18;19257:6;19213:72;:::i;:::-;19295;19363:2;19352:9;19348:18;19339:6;19295:72;:::i;:::-;19377;19445:2;19434:9;19430:18;19421:6;19377:72;:::i;:::-;19459:73;19527:3;19516:9;19512:19;19503:6;19459:73;:::i;:::-;19542;19610:3;19599:9;19595:19;19586:6;19542:73;:::i;:::-;18847:775;;;;;;;;;:::o;19628:332::-;19749:4;19787:2;19776:9;19772:18;19764:26;;19800:71;19868:1;19857:9;19853:17;19844:6;19800:71;:::i;:::-;19881:72;19949:2;19938:9;19934:18;19925:6;19881:72;:::i;:::-;19628:332;;;;;:::o;19966:180::-;20014:77;20011:1;20004:88;20111:4;20108:1;20101:15;20135:4;20132:1;20125:15;20152:244;20192:3;20211:20;20229:1;20211:20;:::i;:::-;20206:25;;20245:20;20263:1;20245:20;:::i;:::-;20240:25;;20288:1;20285;20281:9;20274:16;;20311:54;20306:3;20303:63;20300:89;;;20369:18;;:::i;:::-;20300:89;20152:244;;;;:::o;20402:247::-;20442:4;20462:20;20480:1;20462:20;:::i;:::-;20457:25;;20496:20;20514:1;20496:20;:::i;:::-;20491:25;;20540:1;20537;20533:9;20525:17;;20564:54;20558:4;20555:64;20552:90;;;20622:18;;:::i;:::-;20552:90;20402:247;;;;:::o;20655:442::-;20804:4;20842:2;20831:9;20827:18;20819:26;;20855:71;20923:1;20912:9;20908:17;20899:6;20855:71;:::i;:::-;20936:72;21004:2;20993:9;20989:18;20980:6;20936:72;:::i;:::-;21018;21086:2;21075:9;21071:18;21062:6;21018:72;:::i;:::-;20655:442;;;;;;:::o;21103:86::-;21149:7;21178:5;21167:16;;21103:86;;;:::o;21195:60::-;21223:3;21244:5;21237:12;;21195:60;;;:::o;21261:156::-;21318:9;21351:60;21367:43;21376:33;21403:5;21376:33;:::i;:::-;21367:43;:::i;:::-;21351:60;:::i;:::-;21338:73;;21261:156;;;:::o;21423:145::-;21517:44;21555:5;21517:44;:::i;:::-;21512:3;21505:57;21423:145;;:::o;21574:346::-;21702:4;21740:2;21729:9;21725:18;21717:26;;21753:78;21828:1;21817:9;21813:17;21804:6;21753:78;:::i;:::-;21841:72;21909:2;21898:9;21894:18;21885:6;21841:72;:::i;:::-;21574:346;;;;;:::o;21926:194::-;21966:4;21986:20;22004:1;21986:20;:::i;:::-;21981:25;;22020:20;22038:1;22020:20;:::i;:::-;22015:25;;22064:1;22061;22057:9;22049:17;;22088:1;22082:4;22079:11;22076:37;;;22093:18;;:::i;:::-;22076:37;21926:194;;;;:::o;22126:191::-;22166:3;22185:20;22203:1;22185:20;:::i;:::-;22180:25;;22219:20;22237:1;22219:20;:::i;:::-;22214:25;;22262:1;22259;22255:9;22248:16;;22283:3;22280:1;22277:10;22274:36;;;22290:18;;:::i;:::-;22274:36;22126:191;;;;:::o;22323:332::-;22444:4;22482:2;22471:9;22467:18;22459:26;;22495:71;22563:1;22552:9;22548:17;22539:6;22495:71;:::i;:::-;22576:72;22644:2;22633:9;22629:18;22620:6;22576:72;:::i;:::-;22323:332;;;;;:::o;22661:::-;22782:4;22820:2;22809:9;22805:18;22797:26;;22833:71;22901:1;22890:9;22886:17;22877:6;22833:71;:::i;:::-;22914:72;22982:2;22971:9;22967:18;22958:6;22914:72;:::i;:::-;22661:332;;;;;:::o;22999:664::-;23204:4;23242:3;23231:9;23227:19;23219:27;;23256:71;23324:1;23313:9;23309:17;23300:6;23256:71;:::i;:::-;23337:72;23405:2;23394:9;23390:18;23381:6;23337:72;:::i;:::-;23419;23487:2;23476:9;23472:18;23463:6;23419:72;:::i;:::-;23501;23569:2;23558:9;23554:18;23545:6;23501:72;:::i;:::-;23583:73;23651:3;23640:9;23636:19;23627:6;23583:73;:::i;:::-;22999:664;;;;;;;;:::o;23669:180::-;23717:77;23714:1;23707:88;23814:4;23811:1;23804:15;23838:4;23835:1;23828:15;23855:332;23976:4;24014:2;24003:9;23999:18;23991:26;;24027:71;24095:1;24084:9;24080:17;24071:6;24027:71;:::i;:::-;24108:72;24176:2;24165:9;24161:18;24152:6;24108:72;:::i;:::-;23855:332;;;;;:::o;24193:86::-;24239:7;24268:5;24257:16;;24193:86;;;:::o;24285:156::-;24342:9;24375:60;24391:43;24400:33;24427:5;24400:33;:::i;:::-;24391:43;:::i;:::-;24375:60;:::i;:::-;24362:73;;24285:156;;;:::o;24447:145::-;24541:44;24579:5;24541:44;:::i;:::-;24536:3;24529:57;24447:145;;:::o;24598:346::-;24726:4;24764:2;24753:9;24749:18;24741:26;;24777:78;24852:1;24841:9;24837:17;24828:6;24777:78;:::i;:::-;24865:72;24933:2;24922:9;24918:18;24909:6;24865:72;:::i;:::-;24598:346;;;;;:::o;24950:545::-;25123:4;25161:3;25150:9;25146:19;25138:27;;25175:71;25243:1;25232:9;25228:17;25219:6;25175:71;:::i;:::-;25256:68;25320:2;25309:9;25305:18;25296:6;25256:68;:::i;:::-;25334:72;25402:2;25391:9;25387:18;25378:6;25334:72;:::i;:::-;25416;25484:2;25473:9;25469:18;25460:6;25416:72;:::i;:::-;24950:545;;;;;;;:::o;25501:180::-;25549:77;25546:1;25539:88;25646:4;25643:1;25636:15;25670:4;25667:1;25660:15;25687:180;25735:77;25732:1;25725:88;25832:4;25829:1;25822:15;25856:4;25853:1;25846:15;25873:185;25913:1;25930:20;25948:1;25930:20;:::i;:::-;25925:25;;25964:20;25982:1;25964:20;:::i;:::-;25959:25;;26003:1;25993:35;;26008:18;;:::i;:::-;25993:35;26050:1;26047;26043:9;26038:14;;25873:185;;;;:::o;26064:87::-;26111:7;26140:5;26129:16;;26064:87;;;:::o;26157:158::-;26215:9;26248:61;26264:44;26273:34;26301:5;26273:34;:::i;:::-;26264:44;:::i;:::-;26248:61;:::i;:::-;26235:74;;26157:158;;;:::o;26321:147::-;26416:45;26455:5;26416:45;:::i;:::-;26411:3;26404:58;26321:147;;:::o;26474:348::-;26603:4;26641:2;26630:9;26626:18;26618:26;;26654:79;26730:1;26719:9;26715:17;26706:6;26654:79;:::i;:::-;26743:72;26811:2;26800:9;26796:18;26787:6;26743:72;:::i;:::-;26474:348;;;;;:::o
Swarm Source
ipfs://9c18a340ff8ff5e94d45e3a14677ef813ace3ca3f8c5954ab110a0cba3fe70ac
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.