Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 5 from a total of 5 transactions
Loading...
Loading
Contract Name:
CromyGovernanceToken
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-10-12 */ // SPDX-License-Identifier: MIT // File: @openzeppelin/contracts/utils/math/SafeCast.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol) pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toUint248(uint256 value) internal pure returns (uint248) { require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toUint240(uint256 value) internal pure returns (uint240) { require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toUint232(uint256 value) internal pure returns (uint232) { require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.2._ */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toUint216(uint256 value) internal pure returns (uint216) { require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toUint208(uint256 value) internal pure returns (uint208) { require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toUint200(uint256 value) internal pure returns (uint200) { require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toUint192(uint256 value) internal pure returns (uint192) { require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toUint184(uint256 value) internal pure returns (uint184) { require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toUint176(uint256 value) internal pure returns (uint176) { require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toUint168(uint256 value) internal pure returns (uint168) { require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toUint160(uint256 value) internal pure returns (uint160) { require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toUint152(uint256 value) internal pure returns (uint152) { require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toUint144(uint256 value) internal pure returns (uint144) { require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toUint136(uint256 value) internal pure returns (uint136) { require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v2.5._ */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toUint120(uint256 value) internal pure returns (uint120) { require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toUint112(uint256 value) internal pure returns (uint112) { require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toUint104(uint256 value) internal pure returns (uint104) { require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.2._ */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toUint88(uint256 value) internal pure returns (uint88) { require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toUint80(uint256 value) internal pure returns (uint80) { require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toUint72(uint256 value) internal pure returns (uint72) { require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v2.5._ */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toUint56(uint256 value) internal pure returns (uint56) { require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toUint48(uint256 value) internal pure returns (uint48) { require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toUint40(uint256 value) internal pure returns (uint40) { require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v2.5._ */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toUint24(uint256 value) internal pure returns (uint24) { require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v2.5._ */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v2.5._ */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. * * _Available since v3.0._ */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toInt248(int256 value) internal pure returns (int248) { require(value >= type(int248).min && value <= type(int248).max, "SafeCast: value doesn't fit in 248 bits"); return int248(value); } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toInt240(int256 value) internal pure returns (int240) { require(value >= type(int240).min && value <= type(int240).max, "SafeCast: value doesn't fit in 240 bits"); return int240(value); } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toInt232(int256 value) internal pure returns (int232) { require(value >= type(int232).min && value <= type(int232).max, "SafeCast: value doesn't fit in 232 bits"); return int232(value); } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.7._ */ function toInt224(int256 value) internal pure returns (int224) { require(value >= type(int224).min && value <= type(int224).max, "SafeCast: value doesn't fit in 224 bits"); return int224(value); } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toInt216(int256 value) internal pure returns (int216) { require(value >= type(int216).min && value <= type(int216).max, "SafeCast: value doesn't fit in 216 bits"); return int216(value); } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toInt208(int256 value) internal pure returns (int208) { require(value >= type(int208).min && value <= type(int208).max, "SafeCast: value doesn't fit in 208 bits"); return int208(value); } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toInt200(int256 value) internal pure returns (int200) { require(value >= type(int200).min && value <= type(int200).max, "SafeCast: value doesn't fit in 200 bits"); return int200(value); } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toInt192(int256 value) internal pure returns (int192) { require(value >= type(int192).min && value <= type(int192).max, "SafeCast: value doesn't fit in 192 bits"); return int192(value); } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toInt184(int256 value) internal pure returns (int184) { require(value >= type(int184).min && value <= type(int184).max, "SafeCast: value doesn't fit in 184 bits"); return int184(value); } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toInt176(int256 value) internal pure returns (int176) { require(value >= type(int176).min && value <= type(int176).max, "SafeCast: value doesn't fit in 176 bits"); return int176(value); } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toInt168(int256 value) internal pure returns (int168) { require(value >= type(int168).min && value <= type(int168).max, "SafeCast: value doesn't fit in 168 bits"); return int168(value); } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toInt160(int256 value) internal pure returns (int160) { require(value >= type(int160).min && value <= type(int160).max, "SafeCast: value doesn't fit in 160 bits"); return int160(value); } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toInt152(int256 value) internal pure returns (int152) { require(value >= type(int152).min && value <= type(int152).max, "SafeCast: value doesn't fit in 152 bits"); return int152(value); } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toInt144(int256 value) internal pure returns (int144) { require(value >= type(int144).min && value <= type(int144).max, "SafeCast: value doesn't fit in 144 bits"); return int144(value); } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toInt136(int256 value) internal pure returns (int136) { require(value >= type(int136).min && value <= type(int136).max, "SafeCast: value doesn't fit in 136 bits"); return int136(value); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128) { require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits"); return int128(value); } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toInt120(int256 value) internal pure returns (int120) { require(value >= type(int120).min && value <= type(int120).max, "SafeCast: value doesn't fit in 120 bits"); return int120(value); } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toInt112(int256 value) internal pure returns (int112) { require(value >= type(int112).min && value <= type(int112).max, "SafeCast: value doesn't fit in 112 bits"); return int112(value); } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toInt104(int256 value) internal pure returns (int104) { require(value >= type(int104).min && value <= type(int104).max, "SafeCast: value doesn't fit in 104 bits"); return int104(value); } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.7._ */ function toInt96(int256 value) internal pure returns (int96) { require(value >= type(int96).min && value <= type(int96).max, "SafeCast: value doesn't fit in 96 bits"); return int96(value); } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toInt88(int256 value) internal pure returns (int88) { require(value >= type(int88).min && value <= type(int88).max, "SafeCast: value doesn't fit in 88 bits"); return int88(value); } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toInt80(int256 value) internal pure returns (int80) { require(value >= type(int80).min && value <= type(int80).max, "SafeCast: value doesn't fit in 80 bits"); return int80(value); } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toInt72(int256 value) internal pure returns (int72) { require(value >= type(int72).min && value <= type(int72).max, "SafeCast: value doesn't fit in 72 bits"); return int72(value); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64) { require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits"); return int64(value); } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toInt56(int256 value) internal pure returns (int56) { require(value >= type(int56).min && value <= type(int56).max, "SafeCast: value doesn't fit in 56 bits"); return int56(value); } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toInt48(int256 value) internal pure returns (int48) { require(value >= type(int48).min && value <= type(int48).max, "SafeCast: value doesn't fit in 48 bits"); return int48(value); } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toInt40(int256 value) internal pure returns (int40) { require(value >= type(int40).min && value <= type(int40).max, "SafeCast: value doesn't fit in 40 bits"); return int40(value); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32) { require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits"); return int32(value); } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toInt24(int256 value) internal pure returns (int24) { require(value >= type(int24).min && value <= type(int24).max, "SafeCast: value doesn't fit in 24 bits"); return int24(value); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16) { require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits"); return int16(value); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8) { require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits"); return int8(value); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. * * _Available since v3.0._ */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } } // File: @openzeppelin/contracts/governance/utils/IVotes.sol // OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol) pragma solidity ^0.8.0; /** * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts. * * _Available since v4.5._ */ interface IVotes { /** * @dev Emitted when an account changes their delegate. */ event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); /** * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes. */ event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance); /** * @dev Returns the current amount of votes that `account` has. */ function getVotes(address account) external view returns (uint256); /** * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`). */ function getPastVotes(address account, uint256 blockNumber) external view returns (uint256); /** * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`). * * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. * Votes that have not been delegated are still part of total supply, even though they would not participate in a * vote. */ function getPastTotalSupply(uint256 blockNumber) external view returns (uint256); /** * @dev Returns the delegate that `account` has chosen. */ function delegates(address account) external view returns (address); /** * @dev Delegates votes from the sender to `delegatee`. */ function delegate(address delegatee) external; /** * @dev Delegates votes from signer to `delegatee`. */ function delegateBySig( address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external; } // File: @openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface 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]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } // File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol // OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } } // File: @openzeppelin/contracts/utils/cryptography/draft-EIP712.sol // OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol) pragma solidity ^0.8.0; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * _Available since v3.4._ */ abstract contract EIP712 { /* solhint-disable var-name-mixedcase */ // 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 _CACHED_DOMAIN_SEPARATOR; uint256 private immutable _CACHED_CHAIN_ID; address private immutable _CACHED_THIS; bytes32 private immutable _HASHED_NAME; bytes32 private immutable _HASHED_VERSION; bytes32 private immutable _TYPE_HASH; /* solhint-enable var-name-mixedcase */ /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { bytes32 hashedName = keccak256(bytes(name)); bytes32 hashedVersion = keccak256(bytes(version)); bytes32 typeHash = keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ); _HASHED_NAME = hashedName; _HASHED_VERSION = hashedVersion; _CACHED_CHAIN_ID = block.chainid; _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion); _CACHED_THIS = address(this); _TYPE_HASH = typeHash; } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) { return _CACHED_DOMAIN_SEPARATOR; } else { return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION); } } function _buildDomainSeparator( bytes32 typeHash, bytes32 nameHash, bytes32 versionHash ) private view returns (bytes32) { return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); } } // File: @openzeppelin/contracts/access/IAccessControl.sol // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; } // File: @openzeppelin/contracts/utils/Counters.sol // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } } // File: @openzeppelin/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`. // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`. // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a // good first aproximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1; uint256 x = a; if (x >> 128 > 0) { x >>= 128; result <<= 64; } if (x >> 64 > 0) { x >>= 64; result <<= 32; } if (x >> 32 > 0) { x >>= 32; result <<= 16; } if (x >> 16 > 0) { x >>= 16; result <<= 8; } if (x >> 8 > 0) { x >>= 8; result <<= 4; } if (x >> 4 > 0) { x >>= 4; result <<= 2; } if (x >> 2 > 0) { result <<= 1; } // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { uint256 result = sqrt(a); if (rounding == Rounding.Up && result * result < a) { result += 1; } return result; } } // File: @openzeppelin/contracts/utils/Arrays.sol // OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to array types. */ library Arrays { /** * @dev Searches a sorted `array` and returns the first index that contains * a value greater or equal to `element`. If no such index exists (i.e. all * values in the array are strictly less than `element`), the array length is * returned. Time complexity O(log n). * * `array` is expected to be sorted in ascending order, and to contain no * repeated elements. */ function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) { if (array.length == 0) { return 0; } uint256 low = 0; uint256 high = array.length; while (low < high) { uint256 mid = Math.average(low, high); // Note that mid will always be strictly less than high (i.e. it will be a valid array index) // because Math.average rounds down (it does integer division with truncation). if (array[mid] > element) { high = mid; } else { low = mid + 1; } } // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound. if (low > 0 && array[low - 1] == element) { return low - 1; } else { return low; } } } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/access/AccessControl.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol) pragma solidity ^0.8.0; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(uint160(account), 20), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } } // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); } // File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File: @openzeppelin/contracts/token/ERC20/ERC20.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer( address from, address to, uint256 amount ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; } _balances[to] += amount; emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 amount ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } // File: @openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Capped.sol) pragma solidity ^0.8.0; /** * @dev Extension of {ERC20} that adds a cap to the supply of tokens. */ abstract contract ERC20Capped is ERC20 { uint256 private immutable _cap; /** * @dev Sets the value of the `cap`. This value is immutable, it can only be * set once during construction. */ constructor(uint256 cap_) { require(cap_ > 0, "ERC20Capped: cap is 0"); _cap = cap_; } /** * @dev Returns the cap on the token's total supply. */ function cap() public view virtual returns (uint256) { return _cap; } /** * @dev See {ERC20-_mint}. */ function _mint(address account, uint256 amount) internal virtual override { require(ERC20.totalSupply() + amount <= cap(), "ERC20Capped: cap exceeded"); super._mint(account, amount); } } // File: @openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * _Available since v3.4._ */ abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 { using Counters for Counters.Counter; mapping(address => Counters.Counter) private _nonces; // solhint-disable-next-line var-name-mixedcase bytes32 private constant _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); /** * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`. * However, to ensure consistency with the upgradeable transpiler, we will continue * to reserve a slot. * @custom:oz-renamed-from _PERMIT_TYPEHASH */ // solhint-disable-next-line var-name-mixedcase bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT; /** * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`. * * It's a good idea to use the same `name` that is defined as the ERC20 token name. */ constructor(string memory name) EIP712(name, "1") {} /** * @dev See {IERC20Permit-permit}. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual override { require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); bytes32 hash = _hashTypedDataV4(structHash); address signer = ECDSA.recover(hash, v, r, s); require(signer == owner, "ERC20Permit: invalid signature"); _approve(owner, spender, value); } /** * @dev See {IERC20Permit-nonces}. */ function nonces(address owner) public view virtual override returns (uint256) { return _nonces[owner].current(); } /** * @dev See {IERC20Permit-DOMAIN_SEPARATOR}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view override returns (bytes32) { return _domainSeparatorV4(); } /** * @dev "Consume a nonce": return the current value and increment. * * _Available since v4.1._ */ function _useNonce(address owner) internal virtual returns (uint256 current) { Counters.Counter storage nonce = _nonces[owner]; current = nonce.current(); nonce.increment(); } } // File: @openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol) pragma solidity ^0.8.0; /** * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's, * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1. * * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module. * * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting * power can be queried through the public accessors {getVotes} and {getPastVotes}. * * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked. * * _Available since v4.2._ */ abstract contract ERC20Votes is IVotes, ERC20Permit { struct Checkpoint { uint32 fromBlock; uint224 votes; } bytes32 private constant _DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); mapping(address => address) private _delegates; mapping(address => Checkpoint[]) private _checkpoints; Checkpoint[] private _totalSupplyCheckpoints; /** * @dev Get the `pos`-th checkpoint for `account`. */ function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) { return _checkpoints[account][pos]; } /** * @dev Get number of checkpoints for `account`. */ function numCheckpoints(address account) public view virtual returns (uint32) { return SafeCast.toUint32(_checkpoints[account].length); } /** * @dev Get the address `account` is currently delegating to. */ function delegates(address account) public view virtual override returns (address) { return _delegates[account]; } /** * @dev Gets the current votes balance for `account` */ function getVotes(address account) public view virtual override returns (uint256) { uint256 pos = _checkpoints[account].length; return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes; } /** * @dev Retrieve the number of votes for `account` at the end of `blockNumber`. * * Requirements: * * - `blockNumber` must have been already mined */ function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) { require(blockNumber < block.number, "ERC20Votes: block not yet mined"); return _checkpointsLookup(_checkpoints[account], blockNumber); } /** * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances. * It is but NOT the sum of all the delegated votes! * * Requirements: * * - `blockNumber` must have been already mined */ function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) { require(blockNumber < block.number, "ERC20Votes: block not yet mined"); return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber); } /** * @dev Lookup a value in a list of (sorted) checkpoints. */ function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) { // We run a binary search to look for the earliest checkpoint taken after `blockNumber`. // // During the loop, the index of the wanted checkpoint remains in the range [low-1, high). // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant. // - If the middle checkpoint is after `blockNumber`, we look in [low, mid) // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high) // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not // out of bounds (in which case we're looking too far in the past and the result is 0). // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out // the same. uint256 high = ckpts.length; uint256 low = 0; while (low < high) { uint256 mid = Math.average(low, high); if (ckpts[mid].fromBlock > blockNumber) { high = mid; } else { low = mid + 1; } } return high == 0 ? 0 : ckpts[high - 1].votes; } /** * @dev Delegate votes from the sender to `delegatee`. */ function delegate(address delegatee) public virtual override { _delegate(_msgSender(), delegatee); } /** * @dev Delegates votes from signer to `delegatee` */ function delegateBySig( address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) public virtual override { require(block.timestamp <= expiry, "ERC20Votes: signature expired"); address signer = ECDSA.recover( _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))), v, r, s ); require(nonce == _useNonce(signer), "ERC20Votes: invalid nonce"); _delegate(signer, delegatee); } /** * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1). */ function _maxSupply() internal view virtual returns (uint224) { return type(uint224).max; } /** * @dev Snapshots the totalSupply after it has been increased. */ function _mint(address account, uint256 amount) internal virtual override { super._mint(account, amount); require(totalSupply() <= _maxSupply(), "ERC20Votes: total supply risks overflowing votes"); _writeCheckpoint(_totalSupplyCheckpoints, _add, amount); } /** * @dev Snapshots the totalSupply after it has been decreased. */ function _burn(address account, uint256 amount) internal virtual override { super._burn(account, amount); _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount); } /** * @dev Move voting power when tokens are transferred. * * Emits a {DelegateVotesChanged} event. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual override { super._afterTokenTransfer(from, to, amount); _moveVotingPower(delegates(from), delegates(to), amount); } /** * @dev Change delegation for `delegator` to `delegatee`. * * Emits events {DelegateChanged} and {DelegateVotesChanged}. */ function _delegate(address delegator, address delegatee) internal virtual { address currentDelegate = delegates(delegator); uint256 delegatorBalance = balanceOf(delegator); _delegates[delegator] = delegatee; emit DelegateChanged(delegator, currentDelegate, delegatee); _moveVotingPower(currentDelegate, delegatee, delegatorBalance); } function _moveVotingPower( address src, address dst, uint256 amount ) private { if (src != dst && amount > 0) { if (src != address(0)) { (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount); emit DelegateVotesChanged(src, oldWeight, newWeight); } if (dst != address(0)) { (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount); emit DelegateVotesChanged(dst, oldWeight, newWeight); } } } function _writeCheckpoint( Checkpoint[] storage ckpts, function(uint256, uint256) view returns (uint256) op, uint256 delta ) private returns (uint256 oldWeight, uint256 newWeight) { uint256 pos = ckpts.length; oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes; newWeight = op(oldWeight, delta); if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) { ckpts[pos - 1].votes = SafeCast.toUint224(newWeight); } else { ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)})); } } function _add(uint256 a, uint256 b) private pure returns (uint256) { return a + b; } function _subtract(uint256 a, uint256 b) private pure returns (uint256) { return a - b; } } // File: @openzeppelin/contracts/token/ERC20/extensions/ERC20Snapshot.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/extensions/ERC20Snapshot.sol) pragma solidity ^0.8.0; /** * @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and * total supply at the time are recorded for later access. * * This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting. * In naive implementations it's possible to perform a "double spend" attack by reusing the same balance from different * accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be * used to create an efficient ERC20 forking mechanism. * * Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a * snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot * id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id * and the account address. * * NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it * return `block.number` will trigger the creation of snapshot at the beginning of each new block. When overriding this * function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract. * * Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient * alternative consider {ERC20Votes}. * * ==== Gas Costs * * Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log * n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much * smaller since identical balances in subsequent snapshots are stored as a single entry. * * There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is * only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent * transfers will have normal cost until the next snapshot, and so on. */ abstract contract ERC20Snapshot is ERC20 { // Inspired by Jordi Baylina's MiniMeToken to record historical balances: // https://github.com/Giveth/minime/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol using Arrays for uint256[]; using Counters for Counters.Counter; // Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a // Snapshot struct, but that would impede usage of functions that work on an array. struct Snapshots { uint256[] ids; uint256[] values; } mapping(address => Snapshots) private _accountBalanceSnapshots; Snapshots private _totalSupplySnapshots; // Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid. Counters.Counter private _currentSnapshotId; /** * @dev Emitted by {_snapshot} when a snapshot identified by `id` is created. */ event Snapshot(uint256 id); /** * @dev Creates a new snapshot and returns its snapshot id. * * Emits a {Snapshot} event that contains the same id. * * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a * set of accounts, for example using {AccessControl}, or it may be open to the public. * * [WARNING] * ==== * While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking, * you must consider that it can potentially be used by attackers in two ways. * * First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow * logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target * specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs * section above. * * We haven't measured the actual numbers; if this is something you're interested in please reach out to us. * ==== */ function _snapshot() internal virtual returns (uint256) { _currentSnapshotId.increment(); uint256 currentId = _getCurrentSnapshotId(); emit Snapshot(currentId); return currentId; } /** * @dev Get the current snapshotId */ function _getCurrentSnapshotId() internal view virtual returns (uint256) { return _currentSnapshotId.current(); } /** * @dev Retrieves the balance of `account` at the time `snapshotId` was created. */ function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) { (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]); return snapshotted ? value : balanceOf(account); } /** * @dev Retrieves the total supply at the time `snapshotId` was created. */ function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) { (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots); return snapshotted ? value : totalSupply(); } // Update balance and/or total supply snapshots before the values are modified. This is implemented // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations. function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override { super._beforeTokenTransfer(from, to, amount); if (from == address(0)) { // mint _updateAccountSnapshot(to); _updateTotalSupplySnapshot(); } else if (to == address(0)) { // burn _updateAccountSnapshot(from); _updateTotalSupplySnapshot(); } else { // transfer _updateAccountSnapshot(from); _updateAccountSnapshot(to); } } function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) { require(snapshotId > 0, "ERC20Snapshot: id is 0"); require(snapshotId <= _getCurrentSnapshotId(), "ERC20Snapshot: nonexistent id"); // When a valid snapshot is queried, there are three possibilities: // a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never // created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds // to this id is the current one. // b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the // requested id, and its value is the one to return. // c) More snapshots were created after the requested one, and the queried value was later modified. There will be // no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is // larger than the requested one. // // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does // exactly this. uint256 index = snapshots.ids.findUpperBound(snapshotId); if (index == snapshots.ids.length) { return (false, 0); } else { return (true, snapshots.values[index]); } } function _updateAccountSnapshot(address account) private { _updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account)); } function _updateTotalSupplySnapshot() private { _updateSnapshot(_totalSupplySnapshots, totalSupply()); } function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private { uint256 currentId = _getCurrentSnapshotId(); if (_lastSnapshotId(snapshots.ids) < currentId) { snapshots.ids.push(currentId); snapshots.values.push(currentValue); } } function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) { if (ids.length == 0) { return 0; } else { return ids[ids.length - 1]; } } } // File: @openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol) pragma solidity ^0.8.0; /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ abstract contract ERC20Burnable is Context, ERC20 { /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) public virtual { _burn(_msgSender(), amount); } /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) public virtual { _spendAllowance(account, _msgSender(), amount); _burn(account, amount); } } // File: CromyGovernanceToken.sol pragma solidity ^0.8.9; /// @custom:security-contact [email protected] contract CromyGovernanceToken is ERC20, ERC20Burnable, ERC20Capped, ERC20Snapshot, AccessControl, ERC20Permit, ERC20Votes { bytes32 public constant SNAPSHOT_ROLE = keccak256("SNAPSHOT_ROLE"); bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); uint256 public constant MAX_SUPPLY = 50000000 * (10 ** 18); event Mint(address indexed to, uint256 amount); event Burn(address indexed from, uint256 amount); constructor(uint256 initialSupply) ERC20("Cromy Governance Token", "CROMY") ERC20Capped(MAX_SUPPLY) ERC20Permit("Cromy Governance Token") { _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); _setupRole(SNAPSHOT_ROLE, msg.sender); _setupRole(MINTER_ROLE, msg.sender); _mint(msg.sender, initialSupply * (10 ** 18)); } function snapshot() public onlyRole(SNAPSHOT_ROLE) { _snapshot(); } function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) { _mint(to, amount); } // The following functions are overrides required by Solidity. function _beforeTokenTransfer(address from, address to, uint256 amount) internal override(ERC20, ERC20Snapshot) { super._beforeTokenTransfer(from, to, amount); } function _afterTokenTransfer(address from, address to, uint256 amount) internal override(ERC20, ERC20Votes) { super._afterTokenTransfer(from, to, amount); } function _mint(address to, uint256 amount) internal override(ERC20, ERC20Capped, ERC20Votes) { emit Mint(to, amount); super._mint(to, amount); } function _burn(address account, uint256 amount) internal override(ERC20, ERC20Votes) { super._burn(account, amount); emit Burn(account, amount); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"uint256","name":"initialSupply","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Snapshot","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"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":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SNAPSHOT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"snapshotId","type":"uint256"}],"name":"balanceOfAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint32","name":"pos","type":"uint32"}],"name":"checkpoints","outputs":[{"components":[{"internalType":"uint32","name":"fromBlock","type":"uint32"},{"internalType":"uint224","name":"votes","type":"uint224"}],"internalType":"struct ERC20Votes.Checkpoint","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"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":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"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":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"snapshot","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":"uint256","name":"snapshotId","type":"uint256"}],"name":"totalSupplyAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101606040523480156200001257600080fd5b5060405162006b3b38038062006b3b8339818101604052810190620000389190620011e6565b6040518060400160405280601681526020017f43726f6d7920476f7665726e616e636520546f6b656e00000000000000000000815250806040518060400160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152506a295be96e640669720000006040518060400160405280601681526020017f43726f6d7920476f7665726e616e636520546f6b656e000000000000000000008152506040518060400160405280600581526020017f43524f4d5900000000000000000000000000000000000000000000000000000081525081600390816200012e919062001488565b50806004908162000140919062001488565b5050506000811162000189576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200018090620015d0565b60405180910390fd5b80608081815250505060008280519060200120905060008280519060200120905060007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f90508261010081815250508161012081815250504660c08181525050620001fc818484620002ed60201b60201c565b60a081815250503073ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff16815250508061014081815250505050505050506200025b6000801b336200032960201b60201c565b6200028d7f5fdbd35e8da83ee755d5e62a539e5ed7f47126abede0b8b10f9ea43dc6eed07f336200032960201b60201c565b620002bf7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336200032960201b60201c565b620002e633670de0b6b3a764000083620002da919062001621565b6200033f60201b60201c565b5062001ad5565b600083838346306040516020016200030a959493929190620016dd565b6040516020818303038152906040528051906020012090509392505050565b6200033b8282620003aa60201b60201c565b5050565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885826040516200038791906200173a565b60405180910390a2620003a682826200049c60201b620015421760201c565b5050565b620003bc82826200055a60201b60201c565b620004985760016009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506200043d620005c560201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b620004b38282620005cd60201b620015cf1760201c565b620004c36200065e60201b60201c565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16620004f16200068260201b60201c565b111562000535576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200052c90620017cd565b60405180910390fd5b62000554600e6200068c60201b620016391783620006a460201b60201c565b50505050565b60006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b620005dd6200095560201b60201c565b81620005f36200068260201b620009331760201c565b620005ff9190620017ef565b111562000643576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200063a906200187a565b60405180910390fd5b6200065a82826200095f60201b6200164f1760201c565b5050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b6000600254905090565b600081836200069c9190620017ef565b905092915050565b60008060008580549050905060008114620007195785600182620006c991906200189c565b81548110620006dd57620006dc620018d7565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166200071c565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1692506200074883858760201c565b9150600081118015620007a1575043866001836200076791906200189c565b815481106200077b576200077a620018d7565b5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff16145b156200084257620007bd8262000ad760201b620017ae1760201c565b86600183620007cd91906200189c565b81548110620007e157620007e0620018d7565b5b9060005260206000200160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1602179055506200094c565b856040518060400160405280620008644362000b4560201b620018191760201c565b63ffffffff168152602001620008858562000ad760201b620017ae1760201c565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b50935093915050565b6000608051905090565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603620009d1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620009c89062001956565b60405180910390fd5b620009e56000838362000b9b60201b60201c565b8060026000828254620009f99190620017ef565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825462000a509190620017ef565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405162000ab791906200173a565b60405180910390a362000ad36000838362000bb860201b60201c565b5050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff801682111562000b3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000b3490620019ee565b60405180910390fd5b819050919050565b600063ffffffff801682111562000b93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000b8a9062001a86565b60405180910390fd5b819050919050565b62000bb383838362000bd560201b6200186c1760201c565b505050565b62000bd083838362000cce60201b620019241760201c565b505050565b62000bed83838362000d1e60201b6200194f1760201c565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160362000c495762000c338262000d2360201b60201c565b62000c4362000d8660201b60201c565b62000cc9565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160362000ca55762000c8f8362000d2360201b60201c565b62000c9f62000d8660201b60201c565b62000cc8565b62000cb68362000d2360201b60201c565b62000cc78262000d2360201b60201c565b5b5b505050565b62000ce683838362000daa60201b620019541760201c565b62000d1962000cfb8462000daf60201b60201c565b62000d0c8462000daf60201b60201c565b8362000e1860201b60201c565b505050565b505050565b62000d83600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002062000d77836200103b60201b60201c565b6200108360201b60201c565b50565b62000da8600662000d9c6200068260201b60201c565b6200108360201b60201c565b565b505050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801562000e555750600081115b156200103657600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161462000f485760008062000eef600d60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206200110f60201b620019591785620006a460201b60201c565b915091508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724838360405162000f3d92919062001aa8565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614620010355760008062000fdc600d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206200068c60201b620016391785620006a460201b60201c565b915091508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72483836040516200102a92919062001aa8565b60405180910390a250505b5b505050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000620010956200112760201b60201c565b905080620010ac846000016200114560201b60201c565b10156200110a5782600001819080600181540180825580915050600190039060005260206000200160009091909190915055826001018290806001815401808255809150506001900390600052602060002001600090919091909150555b505050565b600081836200111f91906200189c565b905092915050565b60006200114060086200119860201b6200196f1760201c565b905090565b6000808280549050036200115d576000905062001193565b81600183805490506200117191906200189c565b81548110620011855762001184620018d7565b5b906000526020600020015490505b919050565b600081600001549050919050565b600080fd5b6000819050919050565b620011c081620011ab565b8114620011cc57600080fd5b50565b600081519050620011e081620011b5565b92915050565b600060208284031215620011ff57620011fe620011a6565b5b60006200120f84828501620011cf565b91505092915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200129a57607f821691505b602082108103620012b057620012af62001252565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026200131a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620012db565b620013268683620012db565b95508019841693508086168417925050509392505050565b6000819050919050565b600062001369620013636200135d84620011ab565b6200133e565b620011ab565b9050919050565b6000819050919050565b620013858362001348565b6200139d620013948262001370565b848454620012e8565b825550505050565b600090565b620013b4620013a5565b620013c18184846200137a565b505050565b5b81811015620013e957620013dd600082620013aa565b600181019050620013c7565b5050565b601f82111562001438576200140281620012b6565b6200140d84620012cb565b810160208510156200141d578190505b620014356200142c85620012cb565b830182620013c6565b50505b505050565b600082821c905092915050565b60006200145d600019846008026200143d565b1980831691505092915050565b60006200147883836200144a565b9150826002028217905092915050565b620014938262001218565b67ffffffffffffffff811115620014af57620014ae62001223565b5b620014bb825462001281565b620014c8828285620013ed565b600060209050601f831160018114620015005760008415620014eb578287015190505b620014f785826200146a565b86555062001567565b601f1984166200151086620012b6565b60005b828110156200153a5784890151825560018201915060208501945060208101905062001513565b868310156200155a578489015162001556601f8916826200144a565b8355505b6001600288020188555050505b505050505050565b600082825260208201905092915050565b7f45524332304361707065643a2063617020697320300000000000000000000000600082015250565b6000620015b86015836200156f565b9150620015c58262001580565b602082019050919050565b60006020820190508181036000830152620015eb81620015a9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006200162e82620011ab565b91506200163b83620011ab565b92508282026200164b81620011ab565b91508282048414831517620016655762001664620015f2565b5b5092915050565b6000819050919050565b62001681816200166c565b82525050565b6200169281620011ab565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620016c58262001698565b9050919050565b620016d781620016b8565b82525050565b600060a082019050620016f4600083018862001676565b62001703602083018762001676565b62001712604083018662001676565b62001721606083018562001687565b620017306080830184620016cc565b9695505050505050565b600060208201905062001751600083018462001687565b92915050565b7f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60008201527f766572666c6f77696e6720766f74657300000000000000000000000000000000602082015250565b6000620017b56030836200156f565b9150620017c28262001757565b604082019050919050565b60006020820190508181036000830152620017e881620017a6565b9050919050565b6000620017fc82620011ab565b91506200180983620011ab565b9250828201905080821115620018245762001823620015f2565b5b92915050565b7f45524332304361707065643a2063617020657863656564656400000000000000600082015250565b6000620018626019836200156f565b91506200186f826200182a565b602082019050919050565b60006020820190508181036000830152620018958162001853565b9050919050565b6000620018a982620011ab565b9150620018b683620011ab565b9250828203905081811115620018d157620018d0620015f2565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b60006200193e601f836200156f565b91506200194b8262001906565b602082019050919050565b6000602082019050818103600083015262001971816200192f565b9050919050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203260008201527f3234206269747300000000000000000000000000000000000000000000000000602082015250565b6000620019d66027836200156f565b9150620019e38262001978565b604082019050919050565b6000602082019050818103600083015262001a0981620019c7565b9050919050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203360008201527f3220626974730000000000000000000000000000000000000000000000000000602082015250565b600062001a6e6026836200156f565b915062001a7b8262001a10565b604082019050919050565b6000602082019050818103600083015262001aa18162001a5f565b9050919050565b600060408201905062001abf600083018562001687565b62001ace602083018462001687565b9392505050565b60805160a05160c05160e05161010051610120516101405161500b62001b306000396000612066015260006120a80152600061208701526000611fbc015260006120120152600061203b015260006109c9015261500b6000f3fe608060405234801561001057600080fd5b506004361061023d5760003560e01c80636fcfff451161013b5780639ab24eb0116100b8578063d505accf1161007c578063d505accf1461074e578063d53913931461076a578063d547741f14610788578063dd62ed3e146107a4578063f1127ed8146107d45761023d565b80639ab24eb014610684578063a217fddf146106b4578063a457c2d7146106d2578063a9059cbb14610702578063c3cda520146107325761023d565b80638e539e8c116100ff5780638e539e8c146105cc57806391d14854146105fc57806395d89b411461062c5780639711715a1461064a578063981b24d0146106545761023d565b80636fcfff45146105025780637028e2cd1461053257806370a082311461055057806379cc6790146105805780637ecebe001461059c5761023d565b8063355274ea116101c957806340c10f191161018d57806340c10f191461044e57806342966c681461046a5780634ee2cd7e14610486578063587cde1e146104b65780635c19a95c146104e65761023d565b8063355274ea146103965780633644e515146103b457806336568abe146103d257806339509351146103ee5780633a46b1a81461041e5761023d565b806323b872dd1161021057806323b872dd146102de578063248a9ca31461030e5780632f2ff15d1461033e578063313ce5671461035a57806332cb6b0c146103785761023d565b806301ffc9a71461024257806306fdde0314610272578063095ea7b31461029057806318160ddd146102c0575b600080fd5b61025c60048036038101906102579190613636565b610804565b604051610269919061367e565b60405180910390f35b61027a61087e565b6040516102879190613729565b60405180910390f35b6102aa60048036038101906102a591906137df565b610910565b6040516102b7919061367e565b60405180910390f35b6102c8610933565b6040516102d5919061382e565b60405180910390f35b6102f860048036038101906102f39190613849565b61093d565b604051610305919061367e565b60405180910390f35b610328600480360381019061032391906138d2565b61096c565b604051610335919061390e565b60405180910390f35b61035860048036038101906103539190613929565b61098c565b005b6103626109ad565b60405161036f9190613985565b60405180910390f35b6103806109b6565b60405161038d919061382e565b60405180910390f35b61039e6109c5565b6040516103ab919061382e565b60405180910390f35b6103bc6109ed565b6040516103c9919061390e565b60405180910390f35b6103ec60048036038101906103e79190613929565b6109fc565b005b610408600480360381019061040391906137df565b610a7f565b604051610415919061367e565b60405180910390f35b610438600480360381019061043391906137df565b610ab6565b604051610445919061382e565b60405180910390f35b610468600480360381019061046391906137df565b610b4a565b005b610484600480360381019061047f91906139a0565b610b83565b005b6104a0600480360381019061049b91906137df565b610b97565b6040516104ad919061382e565b60405180910390f35b6104d060048036038101906104cb91906139cd565b610c07565b6040516104dd9190613a09565b60405180910390f35b61050060048036038101906104fb91906139cd565b610c70565b005b61051c600480360381019061051791906139cd565b610c84565b6040516105299190613a43565b60405180910390f35b61053a610cd8565b604051610547919061390e565b60405180910390f35b61056a600480360381019061056591906139cd565b610cfc565b604051610577919061382e565b60405180910390f35b61059a600480360381019061059591906137df565b610d44565b005b6105b660048036038101906105b191906139cd565b610d64565b6040516105c3919061382e565b60405180910390f35b6105e660048036038101906105e191906139a0565b610db4565b6040516105f3919061382e565b60405180910390f35b61061660048036038101906106119190613929565b610e0a565b604051610623919061367e565b60405180910390f35b610634610e75565b6040516106419190613729565b60405180910390f35b610652610f07565b005b61066e600480360381019061066991906139a0565b610f3d565b60405161067b919061382e565b60405180910390f35b61069e600480360381019061069991906139cd565b610f6e565b6040516106ab919061382e565b60405180910390f35b6106bc61107f565b6040516106c9919061390e565b60405180910390f35b6106ec60048036038101906106e791906137df565b611086565b6040516106f9919061367e565b60405180910390f35b61071c600480360381019061071791906137df565b6110fd565b604051610729919061367e565b60405180910390f35b61074c60048036038101906107479190613a8a565b611120565b005b61076860048036038101906107639190613b17565b611224565b005b610772611366565b60405161077f919061390e565b60405180910390f35b6107a2600480360381019061079d9190613929565b61138a565b005b6107be60048036038101906107b99190613bb9565b6113ab565b6040516107cb919061382e565b60405180910390f35b6107ee60048036038101906107e99190613c25565b611432565b6040516107fb9190613cda565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061087757506108768261197d565b5b9050919050565b60606003805461088d90613d24565b80601f01602080910402602001604051908101604052809291908181526020018280546108b990613d24565b80156109065780601f106108db57610100808354040283529160200191610906565b820191906000526020600020905b8154815290600101906020018083116108e957829003601f168201915b5050505050905090565b60008061091b6119e7565b90506109288185856119ef565b600191505092915050565b6000600254905090565b6000806109486119e7565b9050610955858285611bb8565b610960858585611c44565b60019150509392505050565b600060096000838152602001908152602001600020600101549050919050565b6109958261096c565b61099e81611ec3565b6109a88383611ed7565b505050565b60006012905090565b6a295be96e6406697200000081565b60007f0000000000000000000000000000000000000000000000000000000000000000905090565b60006109f7611fb8565b905090565b610a046119e7565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6890613dc7565b60405180910390fd5b610a7b82826120d2565b5050565b600080610a8a6119e7565b9050610aab818585610a9c85896113ab565b610aa69190613e16565b6119ef565b600191505092915050565b6000438210610afa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af190613e96565b60405180910390fd5b610b42600d60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020836121b4565b905092915050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610b7481611ec3565b610b7e83836122c0565b505050565b610b94610b8e6119e7565b8261231c565b50565b6000806000610be484600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612378565b9150915081610bfb57610bf685610cfc565b610bfd565b805b9250505092915050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610c81610c7b6119e7565b8261246d565b50565b6000610cd1600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050611819565b9050919050565b7f5fdbd35e8da83ee755d5e62a539e5ed7f47126abede0b8b10f9ea43dc6eed07f81565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610d5682610d506119e7565b83611bb8565b610d60828261231c565b5050565b6000610dad600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061196f565b9050919050565b6000438210610df8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610def90613e96565b60405180910390fd5b610e03600e836121b4565b9050919050565b60006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060048054610e8490613d24565b80601f0160208091040260200160405190810160405280929190818152602001828054610eb090613d24565b8015610efd5780601f10610ed257610100808354040283529160200191610efd565b820191906000526020600020905b815481529060010190602001808311610ee057829003601f168201915b5050505050905090565b7f5fdbd35e8da83ee755d5e62a539e5ed7f47126abede0b8b10f9ea43dc6eed07f610f3181611ec3565b610f39612587565b5050565b6000806000610f4d846006612378565b9150915081610f6357610f5e610933565b610f65565b805b92505050919050565b600080600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090506000811461105657600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060018261100a9190613eb6565b8154811061101b5761101a613eea565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16611059565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16915050919050565b6000801b81565b6000806110916119e7565b9050600061109f82866113ab565b9050838110156110e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110db90613f8b565b60405180910390fd5b6110f182868684036119ef565b60019250505092915050565b6000806111086119e7565b9050611115818585611c44565b600191505092915050565b83421115611163576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161115a90613ff7565b60405180910390fd5b60006111c56111bd7fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf8989896040516020016111a29493929190614017565b604051602081830303815290604052805190602001206125dd565b8585856125f7565b90506111d081612622565b8614611211576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611208906140a8565b60405180910390fd5b61121b818861246d565b50505050505050565b83421115611267576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125e90614114565b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886112968c612622565b896040516020016112ac96959493929190614134565b60405160208183030381529060405280519060200120905060006112cf826125dd565b905060006112df828787876125f7565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461134f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611346906141e1565b60405180910390fd5b61135a8a8a8a6119ef565b50505050505050505050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6113938261096c565b61139c81611ec3565b6113a683836120d2565b505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b61143a61359b565b600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208263ffffffff168154811061149157611490613eea565b5b906000526020600020016040518060400160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525050905092915050565b61154c82826115cf565b611554612680565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661157a610933565b11156115bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115b290614273565b60405180910390fd5b6115c9600e611639836126a4565b50505050565b6115d76109c5565b816115e0610933565b6115ea9190613e16565b111561162b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611622906142df565b60405180910390fd5b611635828261164f565b5050565b600081836116479190613e16565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036116be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116b59061434b565b60405180910390fd5b6116ca6000838361291c565b80600260008282546116dc9190613e16565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546117319190613e16565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611796919061382e565b60405180910390a36117aa6000838361292c565b5050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8016821115611811576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611808906143dd565b60405180910390fd5b819050919050565b600063ffffffff8016821115611864576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185b9061446f565b60405180910390fd5b819050919050565b61187783838361194f565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118c1576118b48261293c565b6118bc61298f565b61191f565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361190b576118fe8361293c565b61190661298f565b61191e565b6119148361293c565b61191d8261293c565b5b5b505050565b61192f838383611954565b61194a61193b84610c07565b61194484610c07565b836129a3565b505050565b505050565b505050565b600081836119679190613eb6565b905092915050565b600081600001549050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611a5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a5590614501565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac490614593565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051611bab919061382e565b60405180910390a3505050565b6000611bc484846113ab565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611c3e5781811015611c30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c27906145ff565b60405180910390fd5b611c3d84848484036119ef565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611cb3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611caa90614691565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611d22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1990614723565b60405180910390fd5b611d2d83838361291c565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611db3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611daa906147b5565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611e469190613e16565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611eaa919061382e565b60405180910390a3611ebd84848461292c565b50505050565b611ed481611ecf6119e7565b612b9c565b50565b611ee18282610e0a565b611fb45760016009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611f596119e7565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614801561203457507f000000000000000000000000000000000000000000000000000000000000000046145b15612061577f000000000000000000000000000000000000000000000000000000000000000090506120cf565b6120cc7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612c39565b90505b90565b6120dc8282610e0a565b156121b05760006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506121556119e7565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6000808380549050905060005b818110156122335760006121d58284612c73565b9050848682815481106121eb576121ea613eea565b5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff16111561221d5780925061222d565b60018161222a9190613e16565b91505b506121c1565b6000821461229557846001836122499190613eb6565b8154811061225a57612259613eea565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612298565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169250505092915050565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688582604051612306919061382e565b60405180910390a26123188282611542565b5050565b6123268282612c99565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161236c919061382e565b60405180910390a25050565b600080600084116123be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123b590614821565b60405180910390fd5b6123c6612cb7565b841115612408576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123ff9061488d565b60405180910390fd5b60006124208585600001612cc890919063ffffffff16565b90508360000180549050810361243d576000809250925050612466565b600184600101828154811061245557612454613eea565b5b906000526020600020015492509250505b9250929050565b600061247883610c07565b9050600061248584610cfc565b905082600c60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a46125818284836129a3565b50505050565b60006125936008612da1565b600061259d612cb7565b90507f8030e83b04d87bef53480e26263266d6ca66863aa8506aca6f2559d18aa1cb67816040516125ce919061382e565b60405180910390a18091505090565b60006125f06125ea611fb8565b83612db7565b9050919050565b600080600061260887878787612dea565b9150915061261581612ef6565b8192505050949350505050565b600080600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061266f8161196f565b915061267a81612da1565b50919050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b6000806000858054905090506000811461271257856001826126c69190613eb6565b815481106126d7576126d6613eea565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612715565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16925061274383858763ffffffff16565b91506000811180156127965750438660018361275f9190613eb6565b815481106127705761276f613eea565b5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff16145b15612823576127a4826117ae565b866001836127b29190613eb6565b815481106127c3576127c2613eea565b5b9060005260206000200160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550612913565b85604051806040016040528061283843611819565b63ffffffff16815260200161284c856117ae565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b50935093915050565b61292783838361186c565b505050565b612937838383611924565b505050565b61298c600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061298783610cfc565b6130c2565b50565b6129a1600661299c610933565b6130c2565b565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156129df5750600081115b15612b9757600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614612abd57600080612a66600d60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611959856126a4565b915091508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612ab29291906148ad565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612b9657600080612b3f600d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611639856126a4565b915091508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612b8b9291906148ad565b60405180910390a250505b5b505050565b612ba68282610e0a565b612c3557612bcb8173ffffffffffffffffffffffffffffffffffffffff16601461313d565b612bd98360001c602061313d565b604051602001612bea9291906149aa565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c2c9190613729565b60405180910390fd5b5050565b60008383834630604051602001612c549594939291906149e4565b6040516020818303038152906040528051906020012090509392505050565b60006002828418612c849190614a66565b828416612c919190613e16565b905092915050565b612ca38282613379565b612cb1600e611959836126a4565b50505050565b6000612cc3600861196f565b905090565b600080838054905003612cde5760009050612d9b565b600080848054905090505b80821015612d42576000612cfd8383612c73565b905084868281548110612d1357612d12613eea565b5b90600052602060002001541115612d2c57809150612d3c565b600181612d399190613e16565b92505b50612ce9565b600082118015612d7a57508385600184612d5c9190613eb6565b81548110612d6d57612d6c613eea565b5b9060005260206000200154145b15612d9557600182612d8c9190613eb6565b92505050612d9b565b81925050505b92915050565b6001816000016000828254019250508190555050565b60008282604051602001612dcc929190614b04565b60405160208183030381529060405280519060200120905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c1115612e25576000600391509150612eed565b601b8560ff1614158015612e3d5750601c8560ff1614155b15612e4f576000600491509150612eed565b600060018787878760405160008152602001604052604051612e749493929190614b3b565b6020604051602081039080840390855afa158015612e96573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612ee457600060019250925050612eed565b80600092509250505b94509492505050565b60006004811115612f0a57612f09614b80565b5b816004811115612f1d57612f1c614b80565b5b03156130bf5760016004811115612f3757612f36614b80565b5b816004811115612f4a57612f49614b80565b5b03612f8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f8190614bfb565b60405180910390fd5b60026004811115612f9e57612f9d614b80565b5b816004811115612fb157612fb0614b80565b5b03612ff1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fe890614c67565b60405180910390fd5b6003600481111561300557613004614b80565b5b81600481111561301857613017614b80565b5b03613058576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161304f90614cf9565b60405180910390fd5b60048081111561306b5761306a614b80565b5b81600481111561307e5761307d614b80565b5b036130be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130b590614d8b565b60405180910390fd5b5b50565b60006130cc612cb7565b9050806130db8460000161354f565b10156131385782600001819080600181540180825580915050600190039060005260206000200160009091909190915055826001018290806001815401808255809150506001900390600052602060002001600090919091909150555b505050565b6060600060028360026131509190614dab565b61315a9190613e16565b67ffffffffffffffff81111561317357613172614ded565b5b6040519080825280601f01601f1916602001820160405280156131a55781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106131dd576131dc613eea565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061324157613240613eea565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600060018460026132819190614dab565b61328b9190613e16565b90505b600181111561332b577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106132cd576132cc613eea565b5b1a60f81b8282815181106132e4576132e3613eea565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c94508061332490614e1c565b905061328e565b506000841461336f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161336690614e91565b60405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036133e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133df90614f23565b60405180910390fd5b6133f48260008361291c565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561347a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161347190614fb5565b60405180910390fd5b8181036000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600260008282546134d19190613eb6565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613536919061382e565b60405180910390a361354a8360008461292c565b505050565b6000808280549050036135655760009050613596565b81600183805490506135779190613eb6565b8154811061358857613587613eea565b5b906000526020600020015490505b919050565b6040518060400160405280600063ffffffff16815260200160007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613613816135de565b811461361e57600080fd5b50565b6000813590506136308161360a565b92915050565b60006020828403121561364c5761364b6135d9565b5b600061365a84828501613621565b91505092915050565b60008115159050919050565b61367881613663565b82525050565b6000602082019050613693600083018461366f565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156136d35780820151818401526020810190506136b8565b60008484015250505050565b6000601f19601f8301169050919050565b60006136fb82613699565b61370581856136a4565b93506137158185602086016136b5565b61371e816136df565b840191505092915050565b6000602082019050818103600083015261374381846136f0565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006137768261374b565b9050919050565b6137868161376b565b811461379157600080fd5b50565b6000813590506137a38161377d565b92915050565b6000819050919050565b6137bc816137a9565b81146137c757600080fd5b50565b6000813590506137d9816137b3565b92915050565b600080604083850312156137f6576137f56135d9565b5b600061380485828601613794565b9250506020613815858286016137ca565b9150509250929050565b613828816137a9565b82525050565b6000602082019050613843600083018461381f565b92915050565b600080600060608486031215613862576138616135d9565b5b600061387086828701613794565b935050602061388186828701613794565b9250506040613892868287016137ca565b9150509250925092565b6000819050919050565b6138af8161389c565b81146138ba57600080fd5b50565b6000813590506138cc816138a6565b92915050565b6000602082840312156138e8576138e76135d9565b5b60006138f6848285016138bd565b91505092915050565b6139088161389c565b82525050565b600060208201905061392360008301846138ff565b92915050565b600080604083850312156139405761393f6135d9565b5b600061394e858286016138bd565b925050602061395f85828601613794565b9150509250929050565b600060ff82169050919050565b61397f81613969565b82525050565b600060208201905061399a6000830184613976565b92915050565b6000602082840312156139b6576139b56135d9565b5b60006139c4848285016137ca565b91505092915050565b6000602082840312156139e3576139e26135d9565b5b60006139f184828501613794565b91505092915050565b613a038161376b565b82525050565b6000602082019050613a1e60008301846139fa565b92915050565b600063ffffffff82169050919050565b613a3d81613a24565b82525050565b6000602082019050613a586000830184613a34565b92915050565b613a6781613969565b8114613a7257600080fd5b50565b600081359050613a8481613a5e565b92915050565b60008060008060008060c08789031215613aa757613aa66135d9565b5b6000613ab589828a01613794565b9650506020613ac689828a016137ca565b9550506040613ad789828a016137ca565b9450506060613ae889828a01613a75565b9350506080613af989828a016138bd565b92505060a0613b0a89828a016138bd565b9150509295509295509295565b600080600080600080600060e0888a031215613b3657613b356135d9565b5b6000613b448a828b01613794565b9750506020613b558a828b01613794565b9650506040613b668a828b016137ca565b9550506060613b778a828b016137ca565b9450506080613b888a828b01613a75565b93505060a0613b998a828b016138bd565b92505060c0613baa8a828b016138bd565b91505092959891949750929550565b60008060408385031215613bd057613bcf6135d9565b5b6000613bde85828601613794565b9250506020613bef85828601613794565b9150509250929050565b613c0281613a24565b8114613c0d57600080fd5b50565b600081359050613c1f81613bf9565b92915050565b60008060408385031215613c3c57613c3b6135d9565b5b6000613c4a85828601613794565b9250506020613c5b85828601613c10565b9150509250929050565b613c6e81613a24565b82525050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b613ca581613c74565b82525050565b604082016000820151613cc16000850182613c65565b506020820151613cd46020850182613c9c565b50505050565b6000604082019050613cef6000830184613cab565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613d3c57607f821691505b602082108103613d4f57613d4e613cf5565b5b50919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b6000613db1602f836136a4565b9150613dbc82613d55565b604082019050919050565b60006020820190508181036000830152613de081613da4565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613e21826137a9565b9150613e2c836137a9565b9250828201905080821115613e4457613e43613de7565b5b92915050565b7f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e656400600082015250565b6000613e80601f836136a4565b9150613e8b82613e4a565b602082019050919050565b60006020820190508181036000830152613eaf81613e73565b9050919050565b6000613ec1826137a9565b9150613ecc836137a9565b9250828203905081811115613ee457613ee3613de7565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b6000613f756025836136a4565b9150613f8082613f19565b604082019050919050565b60006020820190508181036000830152613fa481613f68565b9050919050565b7f4552433230566f7465733a207369676e61747572652065787069726564000000600082015250565b6000613fe1601d836136a4565b9150613fec82613fab565b602082019050919050565b6000602082019050818103600083015261401081613fd4565b9050919050565b600060808201905061402c60008301876138ff565b61403960208301866139fa565b614046604083018561381f565b614053606083018461381f565b95945050505050565b7f4552433230566f7465733a20696e76616c6964206e6f6e636500000000000000600082015250565b60006140926019836136a4565b915061409d8261405c565b602082019050919050565b600060208201905081810360008301526140c181614085565b9050919050565b7f45524332305065726d69743a206578706972656420646561646c696e65000000600082015250565b60006140fe601d836136a4565b9150614109826140c8565b602082019050919050565b6000602082019050818103600083015261412d816140f1565b9050919050565b600060c08201905061414960008301896138ff565b61415660208301886139fa565b61416360408301876139fa565b614170606083018661381f565b61417d608083018561381f565b61418a60a083018461381f565b979650505050505050565b7f45524332305065726d69743a20696e76616c6964207369676e61747572650000600082015250565b60006141cb601e836136a4565b91506141d682614195565b602082019050919050565b600060208201905081810360008301526141fa816141be565b9050919050565b7f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60008201527f766572666c6f77696e6720766f74657300000000000000000000000000000000602082015250565b600061425d6030836136a4565b915061426882614201565b604082019050919050565b6000602082019050818103600083015261428c81614250565b9050919050565b7f45524332304361707065643a2063617020657863656564656400000000000000600082015250565b60006142c96019836136a4565b91506142d482614293565b602082019050919050565b600060208201905081810360008301526142f8816142bc565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000614335601f836136a4565b9150614340826142ff565b602082019050919050565b6000602082019050818103600083015261436481614328565b9050919050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203260008201527f3234206269747300000000000000000000000000000000000000000000000000602082015250565b60006143c76027836136a4565b91506143d28261436b565b604082019050919050565b600060208201905081810360008301526143f6816143ba565b9050919050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203360008201527f3220626974730000000000000000000000000000000000000000000000000000602082015250565b60006144596026836136a4565b9150614464826143fd565b604082019050919050565b600060208201905081810360008301526144888161444c565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006144eb6024836136a4565b91506144f68261448f565b604082019050919050565b6000602082019050818103600083015261451a816144de565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b600061457d6022836136a4565b915061458882614521565b604082019050919050565b600060208201905081810360008301526145ac81614570565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b60006145e9601d836136a4565b91506145f4826145b3565b602082019050919050565b60006020820190508181036000830152614618816145dc565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b600061467b6025836136a4565b91506146868261461f565b604082019050919050565b600060208201905081810360008301526146aa8161466e565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b600061470d6023836136a4565b9150614718826146b1565b604082019050919050565b6000602082019050818103600083015261473c81614700565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b600061479f6026836136a4565b91506147aa82614743565b604082019050919050565b600060208201905081810360008301526147ce81614792565b9050919050565b7f4552433230536e617073686f743a206964206973203000000000000000000000600082015250565b600061480b6016836136a4565b9150614816826147d5565b602082019050919050565b6000602082019050818103600083015261483a816147fe565b9050919050565b7f4552433230536e617073686f743a206e6f6e6578697374656e74206964000000600082015250565b6000614877601d836136a4565b915061488282614841565b602082019050919050565b600060208201905081810360008301526148a68161486a565b9050919050565b60006040820190506148c2600083018561381f565b6148cf602083018461381f565b9392505050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b60006149176017836148d6565b9150614922826148e1565b601782019050919050565b600061493882613699565b61494281856148d6565b93506149528185602086016136b5565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b60006149946011836148d6565b915061499f8261495e565b601182019050919050565b60006149b58261490a565b91506149c1828561492d565b91506149cc82614987565b91506149d8828461492d565b91508190509392505050565b600060a0820190506149f960008301886138ff565b614a0660208301876138ff565b614a1360408301866138ff565b614a20606083018561381f565b614a2d60808301846139fa565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614a71826137a9565b9150614a7c836137a9565b925082614a8c57614a8b614a37565b5b828204905092915050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b6000614acd6002836148d6565b9150614ad882614a97565b600282019050919050565b6000819050919050565b614afe614af98261389c565b614ae3565b82525050565b6000614b0f82614ac0565b9150614b1b8285614aed565b602082019150614b2b8284614aed565b6020820191508190509392505050565b6000608082019050614b5060008301876138ff565b614b5d6020830186613976565b614b6a60408301856138ff565b614b7760608301846138ff565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b6000614be56018836136a4565b9150614bf082614baf565b602082019050919050565b60006020820190508181036000830152614c1481614bd8565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000614c51601f836136a4565b9150614c5c82614c1b565b602082019050919050565b60006020820190508181036000830152614c8081614c44565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000614ce36022836136a4565b9150614cee82614c87565b604082019050919050565b60006020820190508181036000830152614d1281614cd6565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000614d756022836136a4565b9150614d8082614d19565b604082019050919050565b60006020820190508181036000830152614da481614d68565b9050919050565b6000614db6826137a9565b9150614dc1836137a9565b9250828202614dcf816137a9565b91508282048414831517614de657614de5613de7565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000614e27826137a9565b915060008203614e3a57614e39613de7565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b6000614e7b6020836136a4565b9150614e8682614e45565b602082019050919050565b60006020820190508181036000830152614eaa81614e6e565b9050919050565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b6000614f0d6021836136a4565b9150614f1882614eb1565b604082019050919050565b60006020820190508181036000830152614f3c81614f00565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b6000614f9f6022836136a4565b9150614faa82614f43565b604082019050919050565b60006020820190508181036000830152614fce81614f92565b905091905056fea26469706673582212207a36d0a54338b1171d26b7b0fd45268682361cc140cbc1ff647d16db06f8c78964736f6c63430008110033000000000000000000000000000000000000000000000000000000000065da38
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061023d5760003560e01c80636fcfff451161013b5780639ab24eb0116100b8578063d505accf1161007c578063d505accf1461074e578063d53913931461076a578063d547741f14610788578063dd62ed3e146107a4578063f1127ed8146107d45761023d565b80639ab24eb014610684578063a217fddf146106b4578063a457c2d7146106d2578063a9059cbb14610702578063c3cda520146107325761023d565b80638e539e8c116100ff5780638e539e8c146105cc57806391d14854146105fc57806395d89b411461062c5780639711715a1461064a578063981b24d0146106545761023d565b80636fcfff45146105025780637028e2cd1461053257806370a082311461055057806379cc6790146105805780637ecebe001461059c5761023d565b8063355274ea116101c957806340c10f191161018d57806340c10f191461044e57806342966c681461046a5780634ee2cd7e14610486578063587cde1e146104b65780635c19a95c146104e65761023d565b8063355274ea146103965780633644e515146103b457806336568abe146103d257806339509351146103ee5780633a46b1a81461041e5761023d565b806323b872dd1161021057806323b872dd146102de578063248a9ca31461030e5780632f2ff15d1461033e578063313ce5671461035a57806332cb6b0c146103785761023d565b806301ffc9a71461024257806306fdde0314610272578063095ea7b31461029057806318160ddd146102c0575b600080fd5b61025c60048036038101906102579190613636565b610804565b604051610269919061367e565b60405180910390f35b61027a61087e565b6040516102879190613729565b60405180910390f35b6102aa60048036038101906102a591906137df565b610910565b6040516102b7919061367e565b60405180910390f35b6102c8610933565b6040516102d5919061382e565b60405180910390f35b6102f860048036038101906102f39190613849565b61093d565b604051610305919061367e565b60405180910390f35b610328600480360381019061032391906138d2565b61096c565b604051610335919061390e565b60405180910390f35b61035860048036038101906103539190613929565b61098c565b005b6103626109ad565b60405161036f9190613985565b60405180910390f35b6103806109b6565b60405161038d919061382e565b60405180910390f35b61039e6109c5565b6040516103ab919061382e565b60405180910390f35b6103bc6109ed565b6040516103c9919061390e565b60405180910390f35b6103ec60048036038101906103e79190613929565b6109fc565b005b610408600480360381019061040391906137df565b610a7f565b604051610415919061367e565b60405180910390f35b610438600480360381019061043391906137df565b610ab6565b604051610445919061382e565b60405180910390f35b610468600480360381019061046391906137df565b610b4a565b005b610484600480360381019061047f91906139a0565b610b83565b005b6104a0600480360381019061049b91906137df565b610b97565b6040516104ad919061382e565b60405180910390f35b6104d060048036038101906104cb91906139cd565b610c07565b6040516104dd9190613a09565b60405180910390f35b61050060048036038101906104fb91906139cd565b610c70565b005b61051c600480360381019061051791906139cd565b610c84565b6040516105299190613a43565b60405180910390f35b61053a610cd8565b604051610547919061390e565b60405180910390f35b61056a600480360381019061056591906139cd565b610cfc565b604051610577919061382e565b60405180910390f35b61059a600480360381019061059591906137df565b610d44565b005b6105b660048036038101906105b191906139cd565b610d64565b6040516105c3919061382e565b60405180910390f35b6105e660048036038101906105e191906139a0565b610db4565b6040516105f3919061382e565b60405180910390f35b61061660048036038101906106119190613929565b610e0a565b604051610623919061367e565b60405180910390f35b610634610e75565b6040516106419190613729565b60405180910390f35b610652610f07565b005b61066e600480360381019061066991906139a0565b610f3d565b60405161067b919061382e565b60405180910390f35b61069e600480360381019061069991906139cd565b610f6e565b6040516106ab919061382e565b60405180910390f35b6106bc61107f565b6040516106c9919061390e565b60405180910390f35b6106ec60048036038101906106e791906137df565b611086565b6040516106f9919061367e565b60405180910390f35b61071c600480360381019061071791906137df565b6110fd565b604051610729919061367e565b60405180910390f35b61074c60048036038101906107479190613a8a565b611120565b005b61076860048036038101906107639190613b17565b611224565b005b610772611366565b60405161077f919061390e565b60405180910390f35b6107a2600480360381019061079d9190613929565b61138a565b005b6107be60048036038101906107b99190613bb9565b6113ab565b6040516107cb919061382e565b60405180910390f35b6107ee60048036038101906107e99190613c25565b611432565b6040516107fb9190613cda565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061087757506108768261197d565b5b9050919050565b60606003805461088d90613d24565b80601f01602080910402602001604051908101604052809291908181526020018280546108b990613d24565b80156109065780601f106108db57610100808354040283529160200191610906565b820191906000526020600020905b8154815290600101906020018083116108e957829003601f168201915b5050505050905090565b60008061091b6119e7565b90506109288185856119ef565b600191505092915050565b6000600254905090565b6000806109486119e7565b9050610955858285611bb8565b610960858585611c44565b60019150509392505050565b600060096000838152602001908152602001600020600101549050919050565b6109958261096c565b61099e81611ec3565b6109a88383611ed7565b505050565b60006012905090565b6a295be96e6406697200000081565b60007f000000000000000000000000000000000000000000295be96e64066972000000905090565b60006109f7611fb8565b905090565b610a046119e7565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6890613dc7565b60405180910390fd5b610a7b82826120d2565b5050565b600080610a8a6119e7565b9050610aab818585610a9c85896113ab565b610aa69190613e16565b6119ef565b600191505092915050565b6000438210610afa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af190613e96565b60405180910390fd5b610b42600d60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020836121b4565b905092915050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610b7481611ec3565b610b7e83836122c0565b505050565b610b94610b8e6119e7565b8261231c565b50565b6000806000610be484600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612378565b9150915081610bfb57610bf685610cfc565b610bfd565b805b9250505092915050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610c81610c7b6119e7565b8261246d565b50565b6000610cd1600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050611819565b9050919050565b7f5fdbd35e8da83ee755d5e62a539e5ed7f47126abede0b8b10f9ea43dc6eed07f81565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610d5682610d506119e7565b83611bb8565b610d60828261231c565b5050565b6000610dad600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061196f565b9050919050565b6000438210610df8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610def90613e96565b60405180910390fd5b610e03600e836121b4565b9050919050565b60006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060048054610e8490613d24565b80601f0160208091040260200160405190810160405280929190818152602001828054610eb090613d24565b8015610efd5780601f10610ed257610100808354040283529160200191610efd565b820191906000526020600020905b815481529060010190602001808311610ee057829003601f168201915b5050505050905090565b7f5fdbd35e8da83ee755d5e62a539e5ed7f47126abede0b8b10f9ea43dc6eed07f610f3181611ec3565b610f39612587565b5050565b6000806000610f4d846006612378565b9150915081610f6357610f5e610933565b610f65565b805b92505050919050565b600080600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090506000811461105657600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060018261100a9190613eb6565b8154811061101b5761101a613eea565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16611059565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16915050919050565b6000801b81565b6000806110916119e7565b9050600061109f82866113ab565b9050838110156110e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110db90613f8b565b60405180910390fd5b6110f182868684036119ef565b60019250505092915050565b6000806111086119e7565b9050611115818585611c44565b600191505092915050565b83421115611163576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161115a90613ff7565b60405180910390fd5b60006111c56111bd7fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf8989896040516020016111a29493929190614017565b604051602081830303815290604052805190602001206125dd565b8585856125f7565b90506111d081612622565b8614611211576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611208906140a8565b60405180910390fd5b61121b818861246d565b50505050505050565b83421115611267576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125e90614114565b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886112968c612622565b896040516020016112ac96959493929190614134565b60405160208183030381529060405280519060200120905060006112cf826125dd565b905060006112df828787876125f7565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461134f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611346906141e1565b60405180910390fd5b61135a8a8a8a6119ef565b50505050505050505050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6113938261096c565b61139c81611ec3565b6113a683836120d2565b505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b61143a61359b565b600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208263ffffffff168154811061149157611490613eea565b5b906000526020600020016040518060400160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525050905092915050565b61154c82826115cf565b611554612680565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661157a610933565b11156115bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115b290614273565b60405180910390fd5b6115c9600e611639836126a4565b50505050565b6115d76109c5565b816115e0610933565b6115ea9190613e16565b111561162b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611622906142df565b60405180910390fd5b611635828261164f565b5050565b600081836116479190613e16565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036116be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116b59061434b565b60405180910390fd5b6116ca6000838361291c565b80600260008282546116dc9190613e16565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546117319190613e16565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611796919061382e565b60405180910390a36117aa6000838361292c565b5050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8016821115611811576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611808906143dd565b60405180910390fd5b819050919050565b600063ffffffff8016821115611864576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185b9061446f565b60405180910390fd5b819050919050565b61187783838361194f565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118c1576118b48261293c565b6118bc61298f565b61191f565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361190b576118fe8361293c565b61190661298f565b61191e565b6119148361293c565b61191d8261293c565b5b5b505050565b61192f838383611954565b61194a61193b84610c07565b61194484610c07565b836129a3565b505050565b505050565b505050565b600081836119679190613eb6565b905092915050565b600081600001549050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611a5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a5590614501565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac490614593565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051611bab919061382e565b60405180910390a3505050565b6000611bc484846113ab565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611c3e5781811015611c30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c27906145ff565b60405180910390fd5b611c3d84848484036119ef565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611cb3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611caa90614691565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611d22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1990614723565b60405180910390fd5b611d2d83838361291c565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611db3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611daa906147b5565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611e469190613e16565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611eaa919061382e565b60405180910390a3611ebd84848461292c565b50505050565b611ed481611ecf6119e7565b612b9c565b50565b611ee18282610e0a565b611fb45760016009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611f596119e7565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b60007f000000000000000000000000baddc984ef674c76c89c7ac310a65fd2078a70f273ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614801561203457507f000000000000000000000000000000000000000000000000000000000000000146145b15612061577f0169b36481f73bd8f7ffd186ea0f838269f42d9a6f84695e8e5b59b61c45fafe90506120cf565b6120cc7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7ff6bb3efcc51354e7507d6431a0eb28995728145d9b56c035fd28b6fe19b722de7fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6612c39565b90505b90565b6120dc8282610e0a565b156121b05760006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506121556119e7565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6000808380549050905060005b818110156122335760006121d58284612c73565b9050848682815481106121eb576121ea613eea565b5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff16111561221d5780925061222d565b60018161222a9190613e16565b91505b506121c1565b6000821461229557846001836122499190613eb6565b8154811061225a57612259613eea565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612298565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169250505092915050565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688582604051612306919061382e565b60405180910390a26123188282611542565b5050565b6123268282612c99565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161236c919061382e565b60405180910390a25050565b600080600084116123be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123b590614821565b60405180910390fd5b6123c6612cb7565b841115612408576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123ff9061488d565b60405180910390fd5b60006124208585600001612cc890919063ffffffff16565b90508360000180549050810361243d576000809250925050612466565b600184600101828154811061245557612454613eea565b5b906000526020600020015492509250505b9250929050565b600061247883610c07565b9050600061248584610cfc565b905082600c60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a46125818284836129a3565b50505050565b60006125936008612da1565b600061259d612cb7565b90507f8030e83b04d87bef53480e26263266d6ca66863aa8506aca6f2559d18aa1cb67816040516125ce919061382e565b60405180910390a18091505090565b60006125f06125ea611fb8565b83612db7565b9050919050565b600080600061260887878787612dea565b9150915061261581612ef6565b8192505050949350505050565b600080600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061266f8161196f565b915061267a81612da1565b50919050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b6000806000858054905090506000811461271257856001826126c69190613eb6565b815481106126d7576126d6613eea565b5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612715565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16925061274383858763ffffffff16565b91506000811180156127965750438660018361275f9190613eb6565b815481106127705761276f613eea565b5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff16145b15612823576127a4826117ae565b866001836127b29190613eb6565b815481106127c3576127c2613eea565b5b9060005260206000200160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550612913565b85604051806040016040528061283843611819565b63ffffffff16815260200161284c856117ae565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b50935093915050565b61292783838361186c565b505050565b612937838383611924565b505050565b61298c600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061298783610cfc565b6130c2565b50565b6129a1600661299c610933565b6130c2565b565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156129df5750600081115b15612b9757600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614612abd57600080612a66600d60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611959856126a4565b915091508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612ab29291906148ad565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612b9657600080612b3f600d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611639856126a4565b915091508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612b8b9291906148ad565b60405180910390a250505b5b505050565b612ba68282610e0a565b612c3557612bcb8173ffffffffffffffffffffffffffffffffffffffff16601461313d565b612bd98360001c602061313d565b604051602001612bea9291906149aa565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c2c9190613729565b60405180910390fd5b5050565b60008383834630604051602001612c549594939291906149e4565b6040516020818303038152906040528051906020012090509392505050565b60006002828418612c849190614a66565b828416612c919190613e16565b905092915050565b612ca38282613379565b612cb1600e611959836126a4565b50505050565b6000612cc3600861196f565b905090565b600080838054905003612cde5760009050612d9b565b600080848054905090505b80821015612d42576000612cfd8383612c73565b905084868281548110612d1357612d12613eea565b5b90600052602060002001541115612d2c57809150612d3c565b600181612d399190613e16565b92505b50612ce9565b600082118015612d7a57508385600184612d5c9190613eb6565b81548110612d6d57612d6c613eea565b5b9060005260206000200154145b15612d9557600182612d8c9190613eb6565b92505050612d9b565b81925050505b92915050565b6001816000016000828254019250508190555050565b60008282604051602001612dcc929190614b04565b60405160208183030381529060405280519060200120905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c1115612e25576000600391509150612eed565b601b8560ff1614158015612e3d5750601c8560ff1614155b15612e4f576000600491509150612eed565b600060018787878760405160008152602001604052604051612e749493929190614b3b565b6020604051602081039080840390855afa158015612e96573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612ee457600060019250925050612eed565b80600092509250505b94509492505050565b60006004811115612f0a57612f09614b80565b5b816004811115612f1d57612f1c614b80565b5b03156130bf5760016004811115612f3757612f36614b80565b5b816004811115612f4a57612f49614b80565b5b03612f8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f8190614bfb565b60405180910390fd5b60026004811115612f9e57612f9d614b80565b5b816004811115612fb157612fb0614b80565b5b03612ff1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fe890614c67565b60405180910390fd5b6003600481111561300557613004614b80565b5b81600481111561301857613017614b80565b5b03613058576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161304f90614cf9565b60405180910390fd5b60048081111561306b5761306a614b80565b5b81600481111561307e5761307d614b80565b5b036130be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130b590614d8b565b60405180910390fd5b5b50565b60006130cc612cb7565b9050806130db8460000161354f565b10156131385782600001819080600181540180825580915050600190039060005260206000200160009091909190915055826001018290806001815401808255809150506001900390600052602060002001600090919091909150555b505050565b6060600060028360026131509190614dab565b61315a9190613e16565b67ffffffffffffffff81111561317357613172614ded565b5b6040519080825280601f01601f1916602001820160405280156131a55781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106131dd576131dc613eea565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061324157613240613eea565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600060018460026132819190614dab565b61328b9190613e16565b90505b600181111561332b577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106132cd576132cc613eea565b5b1a60f81b8282815181106132e4576132e3613eea565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c94508061332490614e1c565b905061328e565b506000841461336f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161336690614e91565b60405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036133e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133df90614f23565b60405180910390fd5b6133f48260008361291c565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561347a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161347190614fb5565b60405180910390fd5b8181036000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600260008282546134d19190613eb6565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613536919061382e565b60405180910390a361354a8360008461292c565b505050565b6000808280549050036135655760009050613596565b81600183805490506135779190613eb6565b8154811061358857613587613eea565b5b906000526020600020015490505b919050565b6040518060400160405280600063ffffffff16815260200160007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613613816135de565b811461361e57600080fd5b50565b6000813590506136308161360a565b92915050565b60006020828403121561364c5761364b6135d9565b5b600061365a84828501613621565b91505092915050565b60008115159050919050565b61367881613663565b82525050565b6000602082019050613693600083018461366f565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156136d35780820151818401526020810190506136b8565b60008484015250505050565b6000601f19601f8301169050919050565b60006136fb82613699565b61370581856136a4565b93506137158185602086016136b5565b61371e816136df565b840191505092915050565b6000602082019050818103600083015261374381846136f0565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006137768261374b565b9050919050565b6137868161376b565b811461379157600080fd5b50565b6000813590506137a38161377d565b92915050565b6000819050919050565b6137bc816137a9565b81146137c757600080fd5b50565b6000813590506137d9816137b3565b92915050565b600080604083850312156137f6576137f56135d9565b5b600061380485828601613794565b9250506020613815858286016137ca565b9150509250929050565b613828816137a9565b82525050565b6000602082019050613843600083018461381f565b92915050565b600080600060608486031215613862576138616135d9565b5b600061387086828701613794565b935050602061388186828701613794565b9250506040613892868287016137ca565b9150509250925092565b6000819050919050565b6138af8161389c565b81146138ba57600080fd5b50565b6000813590506138cc816138a6565b92915050565b6000602082840312156138e8576138e76135d9565b5b60006138f6848285016138bd565b91505092915050565b6139088161389c565b82525050565b600060208201905061392360008301846138ff565b92915050565b600080604083850312156139405761393f6135d9565b5b600061394e858286016138bd565b925050602061395f85828601613794565b9150509250929050565b600060ff82169050919050565b61397f81613969565b82525050565b600060208201905061399a6000830184613976565b92915050565b6000602082840312156139b6576139b56135d9565b5b60006139c4848285016137ca565b91505092915050565b6000602082840312156139e3576139e26135d9565b5b60006139f184828501613794565b91505092915050565b613a038161376b565b82525050565b6000602082019050613a1e60008301846139fa565b92915050565b600063ffffffff82169050919050565b613a3d81613a24565b82525050565b6000602082019050613a586000830184613a34565b92915050565b613a6781613969565b8114613a7257600080fd5b50565b600081359050613a8481613a5e565b92915050565b60008060008060008060c08789031215613aa757613aa66135d9565b5b6000613ab589828a01613794565b9650506020613ac689828a016137ca565b9550506040613ad789828a016137ca565b9450506060613ae889828a01613a75565b9350506080613af989828a016138bd565b92505060a0613b0a89828a016138bd565b9150509295509295509295565b600080600080600080600060e0888a031215613b3657613b356135d9565b5b6000613b448a828b01613794565b9750506020613b558a828b01613794565b9650506040613b668a828b016137ca565b9550506060613b778a828b016137ca565b9450506080613b888a828b01613a75565b93505060a0613b998a828b016138bd565b92505060c0613baa8a828b016138bd565b91505092959891949750929550565b60008060408385031215613bd057613bcf6135d9565b5b6000613bde85828601613794565b9250506020613bef85828601613794565b9150509250929050565b613c0281613a24565b8114613c0d57600080fd5b50565b600081359050613c1f81613bf9565b92915050565b60008060408385031215613c3c57613c3b6135d9565b5b6000613c4a85828601613794565b9250506020613c5b85828601613c10565b9150509250929050565b613c6e81613a24565b82525050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b613ca581613c74565b82525050565b604082016000820151613cc16000850182613c65565b506020820151613cd46020850182613c9c565b50505050565b6000604082019050613cef6000830184613cab565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613d3c57607f821691505b602082108103613d4f57613d4e613cf5565b5b50919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b6000613db1602f836136a4565b9150613dbc82613d55565b604082019050919050565b60006020820190508181036000830152613de081613da4565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613e21826137a9565b9150613e2c836137a9565b9250828201905080821115613e4457613e43613de7565b5b92915050565b7f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e656400600082015250565b6000613e80601f836136a4565b9150613e8b82613e4a565b602082019050919050565b60006020820190508181036000830152613eaf81613e73565b9050919050565b6000613ec1826137a9565b9150613ecc836137a9565b9250828203905081811115613ee457613ee3613de7565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b6000613f756025836136a4565b9150613f8082613f19565b604082019050919050565b60006020820190508181036000830152613fa481613f68565b9050919050565b7f4552433230566f7465733a207369676e61747572652065787069726564000000600082015250565b6000613fe1601d836136a4565b9150613fec82613fab565b602082019050919050565b6000602082019050818103600083015261401081613fd4565b9050919050565b600060808201905061402c60008301876138ff565b61403960208301866139fa565b614046604083018561381f565b614053606083018461381f565b95945050505050565b7f4552433230566f7465733a20696e76616c6964206e6f6e636500000000000000600082015250565b60006140926019836136a4565b915061409d8261405c565b602082019050919050565b600060208201905081810360008301526140c181614085565b9050919050565b7f45524332305065726d69743a206578706972656420646561646c696e65000000600082015250565b60006140fe601d836136a4565b9150614109826140c8565b602082019050919050565b6000602082019050818103600083015261412d816140f1565b9050919050565b600060c08201905061414960008301896138ff565b61415660208301886139fa565b61416360408301876139fa565b614170606083018661381f565b61417d608083018561381f565b61418a60a083018461381f565b979650505050505050565b7f45524332305065726d69743a20696e76616c6964207369676e61747572650000600082015250565b60006141cb601e836136a4565b91506141d682614195565b602082019050919050565b600060208201905081810360008301526141fa816141be565b9050919050565b7f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60008201527f766572666c6f77696e6720766f74657300000000000000000000000000000000602082015250565b600061425d6030836136a4565b915061426882614201565b604082019050919050565b6000602082019050818103600083015261428c81614250565b9050919050565b7f45524332304361707065643a2063617020657863656564656400000000000000600082015250565b60006142c96019836136a4565b91506142d482614293565b602082019050919050565b600060208201905081810360008301526142f8816142bc565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000614335601f836136a4565b9150614340826142ff565b602082019050919050565b6000602082019050818103600083015261436481614328565b9050919050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203260008201527f3234206269747300000000000000000000000000000000000000000000000000602082015250565b60006143c76027836136a4565b91506143d28261436b565b604082019050919050565b600060208201905081810360008301526143f6816143ba565b9050919050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203360008201527f3220626974730000000000000000000000000000000000000000000000000000602082015250565b60006144596026836136a4565b9150614464826143fd565b604082019050919050565b600060208201905081810360008301526144888161444c565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006144eb6024836136a4565b91506144f68261448f565b604082019050919050565b6000602082019050818103600083015261451a816144de565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b600061457d6022836136a4565b915061458882614521565b604082019050919050565b600060208201905081810360008301526145ac81614570565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b60006145e9601d836136a4565b91506145f4826145b3565b602082019050919050565b60006020820190508181036000830152614618816145dc565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b600061467b6025836136a4565b91506146868261461f565b604082019050919050565b600060208201905081810360008301526146aa8161466e565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b600061470d6023836136a4565b9150614718826146b1565b604082019050919050565b6000602082019050818103600083015261473c81614700565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b600061479f6026836136a4565b91506147aa82614743565b604082019050919050565b600060208201905081810360008301526147ce81614792565b9050919050565b7f4552433230536e617073686f743a206964206973203000000000000000000000600082015250565b600061480b6016836136a4565b9150614816826147d5565b602082019050919050565b6000602082019050818103600083015261483a816147fe565b9050919050565b7f4552433230536e617073686f743a206e6f6e6578697374656e74206964000000600082015250565b6000614877601d836136a4565b915061488282614841565b602082019050919050565b600060208201905081810360008301526148a68161486a565b9050919050565b60006040820190506148c2600083018561381f565b6148cf602083018461381f565b9392505050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b60006149176017836148d6565b9150614922826148e1565b601782019050919050565b600061493882613699565b61494281856148d6565b93506149528185602086016136b5565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b60006149946011836148d6565b915061499f8261495e565b601182019050919050565b60006149b58261490a565b91506149c1828561492d565b91506149cc82614987565b91506149d8828461492d565b91508190509392505050565b600060a0820190506149f960008301886138ff565b614a0660208301876138ff565b614a1360408301866138ff565b614a20606083018561381f565b614a2d60808301846139fa565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614a71826137a9565b9150614a7c836137a9565b925082614a8c57614a8b614a37565b5b828204905092915050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b6000614acd6002836148d6565b9150614ad882614a97565b600282019050919050565b6000819050919050565b614afe614af98261389c565b614ae3565b82525050565b6000614b0f82614ac0565b9150614b1b8285614aed565b602082019150614b2b8284614aed565b6020820191508190509392505050565b6000608082019050614b5060008301876138ff565b614b5d6020830186613976565b614b6a60408301856138ff565b614b7760608301846138ff565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b6000614be56018836136a4565b9150614bf082614baf565b602082019050919050565b60006020820190508181036000830152614c1481614bd8565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000614c51601f836136a4565b9150614c5c82614c1b565b602082019050919050565b60006020820190508181036000830152614c8081614c44565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000614ce36022836136a4565b9150614cee82614c87565b604082019050919050565b60006020820190508181036000830152614d1281614cd6565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000614d756022836136a4565b9150614d8082614d19565b604082019050919050565b60006020820190508181036000830152614da481614d68565b9050919050565b6000614db6826137a9565b9150614dc1836137a9565b9250828202614dcf816137a9565b91508282048414831517614de657614de5613de7565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000614e27826137a9565b915060008203614e3a57614e39613de7565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b6000614e7b6020836136a4565b9150614e8682614e45565b602082019050919050565b60006020820190508181036000830152614eaa81614e6e565b9050919050565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b6000614f0d6021836136a4565b9150614f1882614eb1565b604082019050919050565b60006020820190508181036000830152614f3c81614f00565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b6000614f9f6022836136a4565b9150614faa82614f43565b604082019050919050565b60006020820190508181036000830152614fce81614f92565b905091905056fea26469706673582212207a36d0a54338b1171d26b7b0fd45268682361cc140cbc1ff647d16db06f8c78964736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000065da38
-----Decoded View---------------
Arg [0] : initialSupply (uint256): 6675000
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000000000000000000000000000000000000065da38
Deployed Bytecode Sourcemap
124078:1913:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77931:204;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;89373:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91724:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90493:108;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92505:295;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;79767:131;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80208:147;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;90335:93;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;124351:58;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100839:83;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104013:115;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81352:218;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93209:238;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;107215:268;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;125006:107;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;123372:91;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;118894:266;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;106589:128;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;109688:114;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;106345:151;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;124207:66;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90664:127;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123782:164;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103755:128;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;107772:259;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;78227:147;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;89592:104;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;124917:81;;;:::i;:::-;;119264:234;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;106801:212;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77332:49;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93950:436;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90997:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;109884:591;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103044:645;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;124280:62;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80648:149;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;91253:151;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;106115:150;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77931:204;78016:4;78055:32;78040:47;;;:11;:47;;;;:87;;;;78091:36;78115:11;78091:23;:36::i;:::-;78040:87;78033:94;;77931:204;;;:::o;89373:100::-;89427:13;89460:5;89453:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89373:100;:::o;91724:201::-;91807:4;91824:13;91840:12;:10;:12::i;:::-;91824:28;;91863:32;91872:5;91879:7;91888:6;91863:8;:32::i;:::-;91913:4;91906:11;;;91724:201;;;;:::o;90493:108::-;90554:7;90581:12;;90574:19;;90493:108;:::o;92505:295::-;92636:4;92653:15;92671:12;:10;:12::i;:::-;92653:30;;92694:38;92710:4;92716:7;92725:6;92694:15;:38::i;:::-;92743:27;92753:4;92759:2;92763:6;92743:9;:27::i;:::-;92788:4;92781:11;;;92505:295;;;;;:::o;79767:131::-;79841:7;79868:6;:12;79875:4;79868:12;;;;;;;;;;;:22;;;79861:29;;79767:131;;;:::o;80208:147::-;80291:18;80304:4;80291:12;:18::i;:::-;77823:16;77834:4;77823:10;:16::i;:::-;80322:25:::1;80333:4;80339:7;80322:10;:25::i;:::-;80208:147:::0;;;:::o;90335:93::-;90393:5;90418:2;90411:9;;90335:93;:::o;124351:58::-;124388:21;124351:58;:::o;100839:83::-;100883:7;100910:4;100903:11;;100839:83;:::o;104013:115::-;104073:7;104100:20;:18;:20::i;:::-;104093:27;;104013:115;:::o;81352:218::-;81459:12;:10;:12::i;:::-;81448:23;;:7;:23;;;81440:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;81536:26;81548:4;81554:7;81536:11;:26::i;:::-;81352:218;;:::o;93209:238::-;93297:4;93314:13;93330:12;:10;:12::i;:::-;93314:28;;93353:64;93362:5;93369:7;93406:10;93378:25;93388:5;93395:7;93378:9;:25::i;:::-;:38;;;;:::i;:::-;93353:8;:64::i;:::-;93435:4;93428:11;;;93209:238;;;;:::o;107215:268::-;107313:7;107355:12;107341:11;:26;107333:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;107421:54;107440:12;:21;107453:7;107440:21;;;;;;;;;;;;;;;107463:11;107421:18;:54::i;:::-;107414:61;;107215:268;;;;:::o;125006:107::-;124318:24;77823:16;77834:4;77823:10;:16::i;:::-;125088:17:::1;125094:2;125098:6;125088:5;:17::i;:::-;125006:107:::0;;;:::o;123372:91::-;123428:27;123434:12;:10;:12::i;:::-;123448:6;123428:5;:27::i;:::-;123372:91;:::o;118894:266::-;118981:7;119002:16;119020:13;119037:55;119046:10;119058:24;:33;119083:7;119058:33;;;;;;;;;;;;;;;119037:8;:55::i;:::-;119001:91;;;;119112:11;:40;;119134:18;119144:7;119134:9;:18::i;:::-;119112:40;;;119126:5;119112:40;119105:47;;;;118894:266;;;;:::o;106589:128::-;106663:7;106690:10;:19;106701:7;106690:19;;;;;;;;;;;;;;;;;;;;;;;;;106683:26;;106589:128;;;:::o;109688:114::-;109760:34;109770:12;:10;:12::i;:::-;109784:9;109760;:34::i;:::-;109688:114;:::o;106345:151::-;106415:6;106441:47;106459:12;:21;106472:7;106459:21;;;;;;;;;;;;;;;:28;;;;106441:17;:47::i;:::-;106434:54;;106345:151;;;:::o;124207:66::-;124247:26;124207:66;:::o;90664:127::-;90738:7;90765:9;:18;90775:7;90765:18;;;;;;;;;;;;;;;;90758:25;;90664:127;;;:::o;123782:164::-;123859:46;123875:7;123884:12;:10;:12::i;:::-;123898:6;123859:15;:46::i;:::-;123916:22;123922:7;123931:6;123916:5;:22::i;:::-;123782:164;;:::o;103755:128::-;103824:7;103851:24;:7;:14;103859:5;103851:14;;;;;;;;;;;;;;;:22;:24::i;:::-;103844:31;;103755:128;;;:::o;107772:259::-;107859:7;107901:12;107887:11;:26;107879:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;107967:56;107986:23;108011:11;107967:18;:56::i;:::-;107960:63;;107772:259;;;:::o;78227:147::-;78313:4;78337:6;:12;78344:4;78337:12;;;;;;;;;;;:20;;:29;78358:7;78337:29;;;;;;;;;;;;;;;;;;;;;;;;;78330:36;;78227:147;;;;:::o;89592:104::-;89648:13;89681:7;89674:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89592:104;:::o;124917:81::-;124247:26;77823:16;77834:4;77823:10;:16::i;:::-;124979:11:::1;:9;:11::i;:::-;;124917:81:::0;:::o;119264:234::-;119336:7;119357:16;119375:13;119392:43;119401:10;119413:21;119392:8;:43::i;:::-;119356:79;;;;119455:11;:35;;119477:13;:11;:13::i;:::-;119455:35;;;119469:5;119455:35;119448:42;;;;119264:234;;;:::o;106801:212::-;106874:7;106894:11;106908:12;:21;106921:7;106908:21;;;;;;;;;;;;;;;:28;;;;106894:42;;106961:1;106954:3;:8;:51;;106969:12;:21;106982:7;106969:21;;;;;;;;;;;;;;;106997:1;106991:3;:7;;;;:::i;:::-;106969:30;;;;;;;;:::i;:::-;;;;;;;;;:36;;;;;;;;;;;;106954:51;;;106965:1;106954:51;106947:58;;;;;106801:212;;;:::o;77332:49::-;77377:4;77332:49;;;:::o;93950:436::-;94043:4;94060:13;94076:12;:10;:12::i;:::-;94060:28;;94099:24;94126:25;94136:5;94143:7;94126:9;:25::i;:::-;94099:52;;94190:15;94170:16;:35;;94162:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;94283:60;94292:5;94299:7;94327:15;94308:16;:34;94283:8;:60::i;:::-;94374:4;94367:11;;;;93950:436;;;;:::o;90997:193::-;91076:4;91093:13;91109:12;:10;:12::i;:::-;91093:28;;91132;91142:5;91149:2;91153:6;91132:9;:28::i;:::-;91178:4;91171:11;;;90997:193;;;;:::o;109884:591::-;110111:6;110092:15;:25;;110084:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;110162:14;110179:174;110207:87;105795:71;110267:9;110278:5;110285:6;110234:58;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;110224:69;;;;;;110207:16;:87::i;:::-;110309:1;110325;110341;110179:13;:174::i;:::-;110162:191;;110381:17;110391:6;110381:9;:17::i;:::-;110372:5;:26;110364:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;110439:28;110449:6;110457:9;110439;:28::i;:::-;110073:402;109884:591;;;;;;:::o;103044:645::-;103288:8;103269:15;:27;;103261:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;103343:18;102219:95;103403:5;103410:7;103419:5;103426:16;103436:5;103426:9;:16::i;:::-;103444:8;103374:79;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;103364:90;;;;;;103343:111;;103467:12;103482:28;103499:10;103482:16;:28::i;:::-;103467:43;;103523:14;103540:28;103554:4;103560:1;103563;103566;103540:13;:28::i;:::-;103523:45;;103597:5;103587:15;;:6;:15;;;103579:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;103650:31;103659:5;103666:7;103675:5;103650:8;:31::i;:::-;103250:439;;;103044:645;;;;;;;:::o;124280:62::-;124318:24;124280:62;:::o;80648:149::-;80732:18;80745:4;80732:12;:18::i;:::-;77823:16;77834:4;77823:10;:16::i;:::-;80763:26:::1;80775:4;80781:7;80763:11;:26::i;:::-;80648:149:::0;;;:::o;91253:151::-;91342:7;91369:11;:18;91381:5;91369:18;;;;;;;;;;;;;;;:27;91388:7;91369:27;;;;;;;;;;;;;;;;91362:34;;91253:151;;;;:::o;106115:150::-;106194:17;;:::i;:::-;106231:12;:21;106244:7;106231:21;;;;;;;;;;;;;;;106253:3;106231:26;;;;;;;;;;:::i;:::-;;;;;;;;;106224:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;106115:150;;;;:::o;110781:290::-;110866:28;110878:7;110887:6;110866:11;:28::i;:::-;110930:12;:10;:12::i;:::-;110913:29;;:13;:11;:13::i;:::-;:29;;110905:90;;;;;;;;;;;;:::i;:::-;;;;;;;;;111008:55;111025:23;111050:4;111056:6;111008:16;:55::i;:::-;;;110781:290;;:::o;100980:207::-;101105:5;:3;:5::i;:::-;101095:6;101073:19;:17;:19::i;:::-;:28;;;;:::i;:::-;:37;;101065:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;101151:28;101163:7;101172:6;101151:11;:28::i;:::-;100980:207;;:::o;113625:98::-;113683:7;113714:1;113710;:5;;;;:::i;:::-;113703:12;;113625:98;;;;:::o;95814:399::-;95917:1;95898:21;;:7;:21;;;95890:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;95968:49;95997:1;96001:7;96010:6;95968:20;:49::i;:::-;96046:6;96030:12;;:22;;;;;;;:::i;:::-;;;;;;;;96085:6;96063:9;:18;96073:7;96063:18;;;;;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;;;;;96128:7;96107:37;;96124:1;96107:37;;;96137:6;96107:37;;;;;;:::i;:::-;;;;;;;;96157:48;96185:1;96189:7;96198:6;96157:19;:48::i;:::-;95814:399;;:::o;2899:195::-;2956:7;2993:17;2984:26;;:5;:26;;2976:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;3080:5;3065:21;;2899:195;;;:::o;15735:190::-;15791:6;15827:16;15818:25;;:5;:25;;15810:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;15911:5;15897:20;;15735:190;;;:::o;119715:622::-;119858:44;119885:4;119891:2;119895:6;119858:26;:44::i;:::-;119935:1;119919:18;;:4;:18;;;119915:415;;119975:26;119998:2;119975:22;:26::i;:::-;120016:28;:26;:28::i;:::-;119915:415;;;120080:1;120066:16;;:2;:16;;;120062:268;;120120:28;120143:4;120120:22;:28::i;:::-;120163;:26;:28::i;:::-;120062:268;;;120249:28;120272:4;120249:22;:28::i;:::-;120292:26;120315:2;120292:22;:26::i;:::-;120062:268;119915:415;119715:622;;;:::o;111499:262::-;111641:43;111667:4;111673:2;111677:6;111641:25;:43::i;:::-;111697:56;111714:15;111724:4;111714:9;:15::i;:::-;111731:13;111741:2;111731:9;:13::i;:::-;111746:6;111697:16;:56::i;:::-;111499:262;;;:::o;99299:125::-;;;;:::o;100028:124::-;;;;:::o;113731:103::-;113794:7;113825:1;113821;:5;;;;:::i;:::-;113814:12;;113731:103;;;;:::o;63214:114::-;63279:7;63306;:14;;;63299:21;;63214:114;;;:::o;43036:157::-;43121:4;43160:25;43145:40;;;:11;:40;;;;43138:47;;43036:157;;;:::o;75140:98::-;75193:7;75220:10;75213:17;;75140:98;:::o;97575:380::-;97728:1;97711:19;;:5;:19;;;97703:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;97809:1;97790:21;;:7;:21;;;97782:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;97893:6;97863:11;:18;97875:5;97863:18;;;;;;;;;;;;;;;:27;97882:7;97863:27;;;;;;;;;;;;;;;:36;;;;97931:7;97915:32;;97924:5;97915:32;;;97940:6;97915:32;;;;;;:::i;:::-;;;;;;;;97575:380;;;:::o;98246:453::-;98381:24;98408:25;98418:5;98425:7;98408:9;:25::i;:::-;98381:52;;98468:17;98448:16;:37;98444:248;;98530:6;98510:16;:26;;98502:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;98614:51;98623:5;98630:7;98658:6;98639:16;:25;98614:8;:51::i;:::-;98444:248;98370:329;98246:453;;;:::o;94856:671::-;95003:1;94987:18;;:4;:18;;;94979:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;95080:1;95066:16;;:2;:16;;;95058:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;95135:38;95156:4;95162:2;95166:6;95135:20;:38::i;:::-;95186:19;95208:9;:15;95218:4;95208:15;;;;;;;;;;;;;;;;95186:37;;95257:6;95242:11;:21;;95234:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;95374:6;95360:11;:20;95342:9;:15;95352:4;95342:15;;;;;;;;;;;;;;;:38;;;;95419:6;95402:9;:13;95412:2;95402:13;;;;;;;;;;;;;;;;:23;;;;;;;:::i;:::-;;;;;;;;95458:2;95443:26;;95452:4;95443:26;;;95462:6;95443:26;;;;;;:::i;:::-;;;;;;;;95482:37;95502:4;95508:2;95512:6;95482:19;:37::i;:::-;94968:559;94856:671;;;:::o;78678:105::-;78745:30;78756:4;78762:12;:10;:12::i;:::-;78745:10;:30::i;:::-;78678:105;:::o;82949:238::-;83033:22;83041:4;83047:7;83033;:22::i;:::-;83028:152;;83104:4;83072:6;:12;83079:4;83072:12;;;;;;;;;;;:20;;:29;83093:7;83072:29;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;83155:12;:10;:12::i;:::-;83128:40;;83146:7;83128:40;;83140:4;83128:40;;;;;;;;;;83028:152;82949:238;;:::o;57900:314::-;57953:7;57994:12;57977:29;;57985:4;57977:29;;;:66;;;;;58027:16;58010:13;:33;57977:66;57973:234;;;58067:24;58060:31;;;;57973:234;58131:64;58153:10;58165:12;58179:15;58131:21;:64::i;:::-;58124:71;;57900:314;;:::o;83367:239::-;83451:22;83459:4;83465:7;83451;:22::i;:::-;83447:152;;;83522:5;83490:6;:12;83497:4;83490:12;;;;;;;;;;;:20;;:29;83511:7;83490:29;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;83574:12;:10;:12::i;:::-;83547:40;;83565:7;83547:40;;83559:4;83547:40;;;;;;;;;;83447:152;83367:239;;:::o;108120:1482::-;108219:7;109238:12;109253:5;:12;;;;109238:27;;109276:11;109302:236;109315:4;109309:3;:10;109302:236;;;109336:11;109350:23;109363:3;109368:4;109350:12;:23::i;:::-;109336:37;;109415:11;109392:5;109398:3;109392:10;;;;;;;;:::i;:::-;;;;;;;;;:20;;;;;;;;;;;;:34;;;109388:139;;;109454:3;109447:10;;109388:139;;;109510:1;109504:3;:7;;;;:::i;:::-;109498:13;;109388:139;109321:217;109302:236;;;109565:1;109557:4;:9;:37;;109573:5;109586:1;109579:4;:8;;;;:::i;:::-;109573:15;;;;;;;;:::i;:::-;;;;;;;;;:21;;;;;;;;;;;;109557:37;;;109569:1;109557:37;109550:44;;;;;;108120:1482;;;;:::o;125598:190::-;125735:2;125730:16;;;125739:6;125730:16;;;;;;:::i;:::-;;;;;;;;125757:23;125769:2;125773:6;125757:11;:23::i;:::-;125598:190;;:::o;125796:192::-;125915:28;125927:7;125936:6;125915:11;:28::i;:::-;125964:7;125959:21;;;125973:6;125959:21;;;;;;:::i;:::-;;;;;;;;125796:192;;:::o;120345:1619::-;120434:4;120440:7;120481:1;120468:10;:14;120460:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;120542:23;:21;:23::i;:::-;120528:10;:37;;120520:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;121738:13;121754:40;121783:10;121754:9;:13;;:28;;:40;;;;:::i;:::-;121738:56;;121820:9;:13;;:20;;;;121811:5;:29;121807:150;;121865:5;121872:1;121857:17;;;;;;;121807:150;121915:4;121921:9;:16;;121938:5;121921:23;;;;;;;;:::i;:::-;;;;;;;;;;121907:38;;;;;120345:1619;;;;;;:::o;111925:388::-;112010:23;112036:20;112046:9;112036;:20::i;:::-;112010:46;;112067:24;112094:20;112104:9;112094;:20::i;:::-;112067:47;;112149:9;112125:10;:21;112136:9;112125:21;;;;;;;;;;;;;;;;:33;;;;;;;;;;;;;;;;;;112220:9;112176:54;;112203:15;112176:54;;112192:9;112176:54;;;;;;;;;;;;112243:62;112260:15;112277:9;112288:16;112243;:62::i;:::-;111999:314;;111925:388;;:::o;118366:223::-;118413:7;118433:30;:18;:28;:30::i;:::-;118476:17;118496:23;:21;:23::i;:::-;118476:43;;118535:19;118544:9;118535:19;;;;;;:::i;:::-;;;;;;;;118572:9;118565:16;;;118366:223;:::o;59127:167::-;59204:7;59231:55;59253:20;:18;:20::i;:::-;59275:10;59231:21;:55::i;:::-;59224:62;;59127:167;;;:::o;52776:279::-;52904:7;52925:17;52944:18;52966:25;52977:4;52983:1;52986;52989;52966:10;:25::i;:::-;52924:67;;;;53002:18;53014:5;53002:11;:18::i;:::-;53038:9;53031:16;;;;52776:279;;;;;;:::o;104266:207::-;104326:15;104354:30;104387:7;:14;104395:5;104387:14;;;;;;;;;;;;;;;104354:47;;104422:15;:5;:13;:15::i;:::-;104412:25;;104448:17;:5;:15;:17::i;:::-;104343:130;104266:207;;;:::o;110582:105::-;110635:7;110662:17;110655:24;;110582:105;:::o;112972:645::-;113146:17;113165;113195:11;113209:5;:12;;;;113195:26;;113251:1;113244:3;:8;:35;;113259:5;113271:1;113265:3;:7;;;;:::i;:::-;113259:14;;;;;;;;:::i;:::-;;;;;;;;;:20;;;;;;;;;;;;113244:35;;;113255:1;113244:35;113232:47;;;;113302:20;113305:9;113316:5;113302:2;:20;;:::i;:::-;113290:32;;113345:1;113339:3;:7;:51;;;;;113378:12;113350:5;113362:1;113356:3;:7;;;;:::i;:::-;113350:14;;;;;;;;:::i;:::-;;;;;;;;;:24;;;;;;;;;;;;:40;;;113339:51;113335:275;;;113430:29;113449:9;113430:18;:29::i;:::-;113407:5;113419:1;113413:3;:7;;;;:::i;:::-;113407:14;;;;;;;;:::i;:::-;;;;;;;;;:20;;;:52;;;;;;;;;;;;;;;;;;113335:275;;;113492:5;113503:94;;;;;;;;113526:31;113544:12;113526:17;:31::i;:::-;113503:94;;;;;;113566:29;113585:9;113566:18;:29::i;:::-;113503:94;;;;;113492:106;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;113335:275;113184:433;112972:645;;;;;;:::o;125191:198::-;125337:44;125364:4;125370:2;125374:6;125337:26;:44::i;:::-;125191:198;;;:::o;125397:193::-;125539:43;125565:4;125571:2;125575:6;125539:25;:43::i;:::-;125397:193;;;:::o;121972:146::-;122040:70;122056:24;:33;122081:7;122056:33;;;;;;;;;;;;;;;122091:18;122101:7;122091:9;:18::i;:::-;122040:15;:70::i;:::-;121972:146;:::o;122126:118::-;122183:53;122199:21;122222:13;:11;:13::i;:::-;122183:15;:53::i;:::-;122126:118::o;112321:643::-;112453:3;112446:10;;:3;:10;;;;:24;;;;;112469:1;112460:6;:10;112446:24;112442:515;;;112506:1;112491:17;;:3;:17;;;112487:224;;112530:17;112549;112570:54;112587:12;:17;112600:3;112587:17;;;;;;;;;;;;;;;112606:9;112617:6;112570:16;:54::i;:::-;112529:95;;;;112669:3;112648:47;;;112674:9;112685;112648:47;;;;;;;:::i;:::-;;;;;;;;112510:201;;112487:224;112746:1;112731:17;;:3;:17;;;112727:219;;112770:17;112789;112810:49;112827:12;:17;112840:3;112827:17;;;;;;;;;;;;;;;112846:4;112852:6;112810:16;:49::i;:::-;112769:90;;;;112904:3;112883:47;;;112909:9;112920;112883:47;;;;;;;:::i;:::-;;;;;;;;112750:196;;112727:219;112442:515;112321:643;;;:::o;79073:505::-;79162:22;79170:4;79176:7;79162;:22::i;:::-;79157:414;;79350:41;79378:7;79350:41;;79388:2;79350:19;:41::i;:::-;79464:38;79492:4;79484:13;;79499:2;79464:19;:38::i;:::-;79255:270;;;;;;;;;:::i;:::-;;;;;;;;;;;;;79201:358;;;;;;;;;;;:::i;:::-;;;;;;;;79157:414;79073:505;;:::o;58222:263::-;58366:7;58414:8;58424;58434:11;58447:13;58470:4;58403:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;58393:84;;;;;;58386:91;;58222:263;;;;;:::o;64671:156::-;64733:7;64818:1;64813;64809;:5;64808:11;;;;:::i;:::-;64803:1;64799;:5;64798:21;;;;:::i;:::-;64791:28;;64671:156;;;;:::o;111165:194::-;111250:28;111262:7;111271:6;111250:11;:28::i;:::-;111291:60;111308:23;111333:9;111344:6;111291:16;:60::i;:::-;;;111165:194;;:::o;118655:127::-;118719:7;118746:28;:18;:26;:28::i;:::-;118739:35;;118655:127;:::o;73536:918::-;73625:7;73665:1;73649:5;:12;;;;:17;73645:58;;73690:1;73683:8;;;;73645:58;73715:11;73741:12;73756:5;:12;;;;73741:27;;73781:424;73794:4;73788:3;:10;73781:424;;;73815:11;73829:23;73842:3;73847:4;73829:12;:23::i;:::-;73815:37;;74086:7;74073:5;74079:3;74073:10;;;;;;;;:::i;:::-;;;;;;;;;;:20;74069:125;;;74121:3;74114:10;;74069:125;;;74177:1;74171:3;:7;;;;:::i;:::-;74165:13;;74069:125;73800:405;73781:424;;;74331:1;74325:3;:7;:36;;;;;74354:7;74336:5;74348:1;74342:3;:7;;;;:::i;:::-;74336:14;;;;;;;;:::i;:::-;;;;;;;;;;:25;74325:36;74321:126;;;74391:1;74385:3;:7;;;;:::i;:::-;74378:14;;;;;;74321:126;74432:3;74425:10;;;;73536:918;;;;;:::o;63336:127::-;63443:1;63425:7;:14;;;:19;;;;;;;;;;;63336:127;:::o;54467:196::-;54560:7;54626:15;54643:10;54597:57;;;;;;;;;:::i;:::-;;;;;;;;;;;;;54587:68;;;;;;54580:75;;54467:196;;;;:::o;51005:1632::-;51136:7;51145:12;52070:66;52065:1;52057:10;;:79;52053:163;;;52169:1;52173:30;52153:51;;;;;;52053:163;52235:2;52230:1;:7;;;;:18;;;;;52246:2;52241:1;:7;;;;52230:18;52226:102;;;52281:1;52285:30;52265:51;;;;;;52226:102;52425:14;52442:24;52452:4;52458:1;52461;52464;52442:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52425:41;;52499:1;52481:20;;:6;:20;;;52477:103;;52534:1;52538:29;52518:50;;;;;;;52477:103;52600:6;52608:20;52592:37;;;;;51005:1632;;;;;;;;:::o;46275:643::-;46353:20;46344:29;;;;;;;;:::i;:::-;;:5;:29;;;;;;;;:::i;:::-;;;46340:571;46390:7;46340:571;46451:29;46442:38;;;;;;;;:::i;:::-;;:5;:38;;;;;;;;:::i;:::-;;;46438:473;;46497:34;;;;;;;;;;:::i;:::-;;;;;;;;46438:473;46562:35;46553:44;;;;;;;;:::i;:::-;;:5;:44;;;;;;;;:::i;:::-;;;46549:362;;46614:41;;;;;;;;;;:::i;:::-;;;;;;;;46549:362;46686:30;46677:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;46673:238;;46733:44;;;;;;;;;;:::i;:::-;;;;;;;;46673:238;46808:30;46799:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;46795:116;;46855:44;;;;;;;;;;:::i;:::-;;;;;;;;46795:116;46275:643;;:::o;122252:310::-;122347:17;122367:23;:21;:23::i;:::-;122347:43;;122438:9;122405:30;122421:9;:13;;122405:15;:30::i;:::-;:42;122401:154;;;122464:9;:13;;122483:9;122464:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;122508:9;:16;;122530:12;122508:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;122401:154;122336:226;122252:310;;:::o;44931:451::-;45006:13;45032:19;45077:1;45068:6;45064:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;45054:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45032:47;;45090:15;:6;45097:1;45090:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;45116;:6;45123:1;45116:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;45147:9;45172:1;45163:6;45159:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;45147:26;;45142:135;45179:1;45175;:5;45142:135;;;45214:12;45235:3;45227:5;:11;45214:25;;;;;;;:::i;:::-;;;;;45202:6;45209:1;45202:9;;;;;;;;:::i;:::-;;;;;:37;;;;;;;;;;;45264:1;45254:11;;;;;45182:3;;;;:::i;:::-;;;45142:135;;;;45304:1;45295:5;:10;45287:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;45367:6;45353:21;;;44931:451;;;;:::o;96546:591::-;96649:1;96630:21;;:7;:21;;;96622:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;96702:49;96723:7;96740:1;96744:6;96702:20;:49::i;:::-;96764:22;96789:9;:18;96799:7;96789:18;;;;;;;;;;;;;;;;96764:43;;96844:6;96826:14;:24;;96818:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;96963:6;96946:14;:23;96925:9;:18;96935:7;96925:18;;;;;;;;;;;;;;;:44;;;;97007:6;96991:12;;:22;;;;;;;:::i;:::-;;;;;;;;97057:1;97031:37;;97040:7;97031:37;;;97061:6;97031:37;;;;;;:::i;:::-;;;;;;;;97081:48;97101:7;97118:1;97122:6;97081:19;:48::i;:::-;96611:526;96546:591;;:::o;122570:212::-;122640:7;122678:1;122664:3;:10;;;;:15;122660:115;;122703:1;122696:8;;;;122660:115;122744:3;122761:1;122748:3;:10;;;;:14;;;;:::i;:::-;122744:19;;;;;;;;:::i;:::-;;;;;;;;;;122737:26;;122570:212;;;;:::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:118::-;8670:22;8686:5;8670:22;:::i;:::-;8663:5;8660:33;8650:61;;8707:1;8704;8697:12;8650:61;8599:118;:::o;8723:135::-;8767:5;8805:6;8792:20;8783:29;;8821:31;8846:5;8821:31;:::i;:::-;8723:135;;;;:::o;8864:1053::-;8966:6;8974;8982;8990;8998;9006;9055:3;9043:9;9034:7;9030:23;9026:33;9023:120;;;9062:79;;:::i;:::-;9023:120;9182:1;9207:53;9252:7;9243:6;9232:9;9228:22;9207:53;:::i;:::-;9197:63;;9153:117;9309:2;9335:53;9380:7;9371:6;9360:9;9356:22;9335:53;:::i;:::-;9325:63;;9280:118;9437:2;9463:53;9508:7;9499:6;9488:9;9484:22;9463:53;:::i;:::-;9453:63;;9408:118;9565:2;9591:51;9634:7;9625:6;9614:9;9610:22;9591:51;:::i;:::-;9581:61;;9536:116;9691:3;9718:53;9763:7;9754:6;9743:9;9739:22;9718:53;:::i;:::-;9708:63;;9662:119;9820:3;9847:53;9892:7;9883:6;9872:9;9868:22;9847:53;:::i;:::-;9837:63;;9791:119;8864:1053;;;;;;;;:::o;9923:1199::-;10034:6;10042;10050;10058;10066;10074;10082;10131:3;10119:9;10110:7;10106:23;10102:33;10099:120;;;10138:79;;:::i;:::-;10099:120;10258:1;10283:53;10328:7;10319:6;10308:9;10304:22;10283:53;:::i;:::-;10273:63;;10229:117;10385:2;10411:53;10456:7;10447:6;10436:9;10432:22;10411:53;:::i;:::-;10401:63;;10356:118;10513:2;10539:53;10584:7;10575:6;10564:9;10560:22;10539:53;:::i;:::-;10529:63;;10484:118;10641:2;10667:53;10712:7;10703:6;10692:9;10688:22;10667:53;:::i;:::-;10657:63;;10612:118;10769:3;10796:51;10839:7;10830:6;10819:9;10815:22;10796:51;:::i;:::-;10786:61;;10740:117;10896:3;10923:53;10968:7;10959:6;10948:9;10944:22;10923:53;:::i;:::-;10913:63;;10867:119;11025:3;11052:53;11097:7;11088:6;11077:9;11073:22;11052:53;:::i;:::-;11042:63;;10996:119;9923:1199;;;;;;;;;;:::o;11128:474::-;11196:6;11204;11253:2;11241:9;11232:7;11228:23;11224:32;11221:119;;;11259:79;;:::i;:::-;11221:119;11379:1;11404:53;11449:7;11440:6;11429:9;11425:22;11404:53;:::i;:::-;11394:63;;11350:117;11506:2;11532:53;11577:7;11568:6;11557:9;11553:22;11532:53;:::i;:::-;11522:63;;11477:118;11128:474;;;;;:::o;11608:120::-;11680:23;11697:5;11680:23;:::i;:::-;11673:5;11670:34;11660:62;;11718:1;11715;11708:12;11660:62;11608:120;:::o;11734:137::-;11779:5;11817:6;11804:20;11795:29;;11833:32;11859:5;11833:32;:::i;:::-;11734:137;;;;:::o;11877:472::-;11944:6;11952;12001:2;11989:9;11980:7;11976:23;11972:32;11969:119;;;12007:79;;:::i;:::-;11969:119;12127:1;12152:53;12197:7;12188:6;12177:9;12173:22;12152:53;:::i;:::-;12142:63;;12098:117;12254:2;12280:52;12324:7;12315:6;12304:9;12300:22;12280:52;:::i;:::-;12270:62;;12225:117;11877:472;;;;;:::o;12355:105::-;12430:23;12447:5;12430:23;:::i;:::-;12425:3;12418:36;12355:105;;:::o;12466:142::-;12503:7;12543:58;12536:5;12532:70;12521:81;;12466:142;;;:::o;12614:108::-;12691:24;12709:5;12691:24;:::i;:::-;12686:3;12679:37;12614:108;;:::o;12796:517::-;12949:4;12944:3;12940:14;13041:4;13034:5;13030:16;13024:23;13060:61;13115:4;13110:3;13106:14;13092:12;13060:61;:::i;:::-;12964:167;13214:4;13207:5;13203:16;13197:23;13233:63;13290:4;13285:3;13281:14;13267:12;13233:63;:::i;:::-;13141:165;12918:395;12796:517;;:::o;13319:334::-;13468:4;13506:2;13495:9;13491:18;13483:26;;13519:127;13643:1;13632:9;13628:17;13619:6;13519:127;:::i;:::-;13319:334;;;;:::o;13659:180::-;13707:77;13704:1;13697:88;13804:4;13801:1;13794:15;13828:4;13825:1;13818:15;13845:320;13889:6;13926:1;13920:4;13916:12;13906:22;;13973:1;13967:4;13963:12;13994:18;13984:81;;14050:4;14042:6;14038:17;14028:27;;13984:81;14112:2;14104:6;14101:14;14081:18;14078:38;14075:84;;14131:18;;:::i;:::-;14075:84;13896:269;13845:320;;;:::o;14171:234::-;14311:34;14307:1;14299:6;14295:14;14288:58;14380:17;14375:2;14367:6;14363:15;14356:42;14171:234;:::o;14411:366::-;14553:3;14574:67;14638:2;14633:3;14574:67;:::i;:::-;14567:74;;14650:93;14739:3;14650:93;:::i;:::-;14768:2;14763:3;14759:12;14752:19;;14411:366;;;:::o;14783:419::-;14949:4;14987:2;14976:9;14972:18;14964:26;;15036:9;15030:4;15026:20;15022:1;15011:9;15007:17;15000:47;15064:131;15190:4;15064:131;:::i;:::-;15056:139;;14783:419;;;:::o;15208:180::-;15256:77;15253:1;15246:88;15353:4;15350:1;15343:15;15377:4;15374:1;15367:15;15394:191;15434:3;15453:20;15471:1;15453:20;:::i;:::-;15448:25;;15487:20;15505:1;15487:20;:::i;:::-;15482:25;;15530:1;15527;15523:9;15516:16;;15551:3;15548:1;15545:10;15542:36;;;15558:18;;:::i;:::-;15542:36;15394:191;;;;:::o;15591:181::-;15731:33;15727:1;15719:6;15715:14;15708:57;15591:181;:::o;15778:366::-;15920:3;15941:67;16005:2;16000:3;15941:67;:::i;:::-;15934:74;;16017:93;16106:3;16017:93;:::i;:::-;16135:2;16130:3;16126:12;16119:19;;15778:366;;;:::o;16150:419::-;16316:4;16354:2;16343:9;16339:18;16331:26;;16403:9;16397:4;16393:20;16389:1;16378:9;16374:17;16367:47;16431:131;16557:4;16431:131;:::i;:::-;16423:139;;16150:419;;;:::o;16575:194::-;16615:4;16635:20;16653:1;16635:20;:::i;:::-;16630:25;;16669:20;16687:1;16669:20;:::i;:::-;16664:25;;16713:1;16710;16706:9;16698:17;;16737:1;16731:4;16728:11;16725:37;;;16742:18;;:::i;:::-;16725:37;16575:194;;;;:::o;16775:180::-;16823:77;16820:1;16813:88;16920:4;16917:1;16910:15;16944:4;16941:1;16934:15;16961:224;17101:34;17097:1;17089:6;17085:14;17078:58;17170:7;17165:2;17157:6;17153:15;17146:32;16961:224;:::o;17191:366::-;17333:3;17354:67;17418:2;17413:3;17354:67;:::i;:::-;17347:74;;17430:93;17519:3;17430:93;:::i;:::-;17548:2;17543:3;17539:12;17532:19;;17191:366;;;:::o;17563:419::-;17729:4;17767:2;17756:9;17752:18;17744:26;;17816:9;17810:4;17806:20;17802:1;17791:9;17787:17;17780:47;17844:131;17970:4;17844:131;:::i;:::-;17836:139;;17563:419;;;:::o;17988:179::-;18128:31;18124:1;18116:6;18112:14;18105:55;17988:179;:::o;18173:366::-;18315:3;18336:67;18400:2;18395:3;18336:67;:::i;:::-;18329:74;;18412:93;18501:3;18412:93;:::i;:::-;18530:2;18525:3;18521:12;18514:19;;18173:366;;;:::o;18545:419::-;18711:4;18749:2;18738:9;18734:18;18726:26;;18798:9;18792:4;18788:20;18784:1;18773:9;18769:17;18762:47;18826:131;18952:4;18826:131;:::i;:::-;18818:139;;18545:419;;;:::o;18970:553::-;19147:4;19185:3;19174:9;19170:19;19162:27;;19199:71;19267:1;19256:9;19252:17;19243:6;19199:71;:::i;:::-;19280:72;19348:2;19337:9;19333:18;19324:6;19280:72;:::i;:::-;19362;19430:2;19419:9;19415:18;19406:6;19362:72;:::i;:::-;19444;19512:2;19501:9;19497:18;19488:6;19444:72;:::i;:::-;18970:553;;;;;;;:::o;19529:175::-;19669:27;19665:1;19657:6;19653:14;19646:51;19529:175;:::o;19710:366::-;19852:3;19873:67;19937:2;19932:3;19873:67;:::i;:::-;19866:74;;19949:93;20038:3;19949:93;:::i;:::-;20067:2;20062:3;20058:12;20051:19;;19710:366;;;:::o;20082:419::-;20248:4;20286:2;20275:9;20271:18;20263:26;;20335:9;20329:4;20325:20;20321:1;20310:9;20306:17;20299:47;20363:131;20489:4;20363:131;:::i;:::-;20355:139;;20082:419;;;:::o;20507:179::-;20647:31;20643:1;20635:6;20631:14;20624:55;20507:179;:::o;20692:366::-;20834:3;20855:67;20919:2;20914:3;20855:67;:::i;:::-;20848:74;;20931:93;21020:3;20931:93;:::i;:::-;21049:2;21044:3;21040:12;21033:19;;20692:366;;;:::o;21064:419::-;21230:4;21268:2;21257:9;21253:18;21245:26;;21317:9;21311:4;21307:20;21303:1;21292:9;21288:17;21281:47;21345:131;21471:4;21345:131;:::i;:::-;21337:139;;21064:419;;;:::o;21489:775::-;21722:4;21760:3;21749:9;21745:19;21737:27;;21774:71;21842:1;21831:9;21827:17;21818:6;21774:71;:::i;:::-;21855:72;21923:2;21912:9;21908:18;21899:6;21855:72;:::i;:::-;21937;22005:2;21994:9;21990:18;21981:6;21937:72;:::i;:::-;22019;22087:2;22076:9;22072:18;22063:6;22019:72;:::i;:::-;22101:73;22169:3;22158:9;22154:19;22145:6;22101:73;:::i;:::-;22184;22252:3;22241:9;22237:19;22228:6;22184:73;:::i;:::-;21489:775;;;;;;;;;:::o;22270:180::-;22410:32;22406:1;22398:6;22394:14;22387:56;22270:180;:::o;22456:366::-;22598:3;22619:67;22683:2;22678:3;22619:67;:::i;:::-;22612:74;;22695:93;22784:3;22695:93;:::i;:::-;22813:2;22808:3;22804:12;22797:19;;22456:366;;;:::o;22828:419::-;22994:4;23032:2;23021:9;23017:18;23009:26;;23081:9;23075:4;23071:20;23067:1;23056:9;23052:17;23045:47;23109:131;23235:4;23109:131;:::i;:::-;23101:139;;22828:419;;;:::o;23253:235::-;23393:34;23389:1;23381:6;23377:14;23370:58;23462:18;23457:2;23449:6;23445:15;23438:43;23253:235;:::o;23494:366::-;23636:3;23657:67;23721:2;23716:3;23657:67;:::i;:::-;23650:74;;23733:93;23822:3;23733:93;:::i;:::-;23851:2;23846:3;23842:12;23835:19;;23494:366;;;:::o;23866:419::-;24032:4;24070:2;24059:9;24055:18;24047:26;;24119:9;24113:4;24109:20;24105:1;24094:9;24090:17;24083:47;24147:131;24273:4;24147:131;:::i;:::-;24139:139;;23866:419;;;:::o;24291:175::-;24431:27;24427:1;24419:6;24415:14;24408:51;24291:175;:::o;24472:366::-;24614:3;24635:67;24699:2;24694:3;24635:67;:::i;:::-;24628:74;;24711:93;24800:3;24711:93;:::i;:::-;24829:2;24824:3;24820:12;24813:19;;24472:366;;;:::o;24844:419::-;25010:4;25048:2;25037:9;25033:18;25025:26;;25097:9;25091:4;25087:20;25083:1;25072:9;25068:17;25061:47;25125:131;25251:4;25125:131;:::i;:::-;25117:139;;24844:419;;;:::o;25269:181::-;25409:33;25405:1;25397:6;25393:14;25386:57;25269:181;:::o;25456:366::-;25598:3;25619:67;25683:2;25678:3;25619:67;:::i;:::-;25612:74;;25695:93;25784:3;25695:93;:::i;:::-;25813:2;25808:3;25804:12;25797:19;;25456:366;;;:::o;25828:419::-;25994:4;26032:2;26021:9;26017:18;26009:26;;26081:9;26075:4;26071:20;26067:1;26056:9;26052:17;26045:47;26109:131;26235:4;26109:131;:::i;:::-;26101:139;;25828:419;;;:::o;26253:226::-;26393:34;26389:1;26381:6;26377:14;26370:58;26462:9;26457:2;26449:6;26445:15;26438:34;26253:226;:::o;26485:366::-;26627:3;26648:67;26712:2;26707:3;26648:67;:::i;:::-;26641:74;;26724:93;26813:3;26724:93;:::i;:::-;26842:2;26837:3;26833:12;26826:19;;26485:366;;;:::o;26857:419::-;27023:4;27061:2;27050:9;27046:18;27038:26;;27110:9;27104:4;27100:20;27096:1;27085:9;27081:17;27074:47;27138:131;27264:4;27138:131;:::i;:::-;27130:139;;26857:419;;;:::o;27282:225::-;27422:34;27418:1;27410:6;27406:14;27399:58;27491:8;27486:2;27478:6;27474:15;27467:33;27282:225;:::o;27513:366::-;27655:3;27676:67;27740:2;27735:3;27676:67;:::i;:::-;27669:74;;27752:93;27841:3;27752:93;:::i;:::-;27870:2;27865:3;27861:12;27854:19;;27513:366;;;:::o;27885:419::-;28051:4;28089:2;28078:9;28074:18;28066:26;;28138:9;28132:4;28128:20;28124:1;28113:9;28109:17;28102:47;28166:131;28292:4;28166:131;:::i;:::-;28158:139;;27885:419;;;:::o;28310:223::-;28450:34;28446:1;28438:6;28434:14;28427:58;28519:6;28514:2;28506:6;28502:15;28495:31;28310:223;:::o;28539:366::-;28681:3;28702:67;28766:2;28761:3;28702:67;:::i;:::-;28695:74;;28778:93;28867:3;28778:93;:::i;:::-;28896:2;28891:3;28887:12;28880:19;;28539:366;;;:::o;28911:419::-;29077:4;29115:2;29104:9;29100:18;29092:26;;29164:9;29158:4;29154:20;29150:1;29139:9;29135:17;29128:47;29192:131;29318:4;29192:131;:::i;:::-;29184:139;;28911:419;;;:::o;29336:221::-;29476:34;29472:1;29464:6;29460:14;29453:58;29545:4;29540:2;29532:6;29528:15;29521:29;29336:221;:::o;29563:366::-;29705:3;29726:67;29790:2;29785:3;29726:67;:::i;:::-;29719:74;;29802:93;29891:3;29802:93;:::i;:::-;29920:2;29915:3;29911:12;29904:19;;29563:366;;;:::o;29935:419::-;30101:4;30139:2;30128:9;30124:18;30116:26;;30188:9;30182:4;30178:20;30174:1;30163:9;30159:17;30152:47;30216:131;30342:4;30216:131;:::i;:::-;30208:139;;29935:419;;;:::o;30360:179::-;30500:31;30496:1;30488:6;30484:14;30477:55;30360:179;:::o;30545:366::-;30687:3;30708:67;30772:2;30767:3;30708:67;:::i;:::-;30701:74;;30784:93;30873:3;30784:93;:::i;:::-;30902:2;30897:3;30893:12;30886:19;;30545:366;;;:::o;30917:419::-;31083:4;31121:2;31110:9;31106:18;31098:26;;31170:9;31164:4;31160:20;31156:1;31145:9;31141:17;31134:47;31198:131;31324:4;31198:131;:::i;:::-;31190:139;;30917:419;;;:::o;31342:224::-;31482:34;31478:1;31470:6;31466:14;31459:58;31551:7;31546:2;31538:6;31534:15;31527:32;31342:224;:::o;31572:366::-;31714:3;31735:67;31799:2;31794:3;31735:67;:::i;:::-;31728:74;;31811:93;31900:3;31811:93;:::i;:::-;31929:2;31924:3;31920:12;31913:19;;31572:366;;;:::o;31944:419::-;32110:4;32148:2;32137:9;32133:18;32125:26;;32197:9;32191:4;32187:20;32183:1;32172:9;32168:17;32161:47;32225:131;32351:4;32225:131;:::i;:::-;32217:139;;31944:419;;;:::o;32369:222::-;32509:34;32505:1;32497:6;32493:14;32486:58;32578:5;32573:2;32565:6;32561:15;32554:30;32369:222;:::o;32597:366::-;32739:3;32760:67;32824:2;32819:3;32760:67;:::i;:::-;32753:74;;32836:93;32925:3;32836:93;:::i;:::-;32954:2;32949:3;32945:12;32938:19;;32597:366;;;:::o;32969:419::-;33135:4;33173:2;33162:9;33158:18;33150:26;;33222:9;33216:4;33212:20;33208:1;33197:9;33193:17;33186:47;33250:131;33376:4;33250:131;:::i;:::-;33242:139;;32969:419;;;:::o;33394:225::-;33534:34;33530:1;33522:6;33518:14;33511:58;33603:8;33598:2;33590:6;33586:15;33579:33;33394:225;:::o;33625:366::-;33767:3;33788:67;33852:2;33847:3;33788:67;:::i;:::-;33781:74;;33864:93;33953:3;33864:93;:::i;:::-;33982:2;33977:3;33973:12;33966:19;;33625:366;;;:::o;33997:419::-;34163:4;34201:2;34190:9;34186:18;34178:26;;34250:9;34244:4;34240:20;34236:1;34225:9;34221:17;34214:47;34278:131;34404:4;34278:131;:::i;:::-;34270:139;;33997:419;;;:::o;34422:172::-;34562:24;34558:1;34550:6;34546:14;34539:48;34422:172;:::o;34600:366::-;34742:3;34763:67;34827:2;34822:3;34763:67;:::i;:::-;34756:74;;34839:93;34928:3;34839:93;:::i;:::-;34957:2;34952:3;34948:12;34941:19;;34600:366;;;:::o;34972:419::-;35138:4;35176:2;35165:9;35161:18;35153:26;;35225:9;35219:4;35215:20;35211:1;35200:9;35196:17;35189:47;35253:131;35379:4;35253:131;:::i;:::-;35245:139;;34972:419;;;:::o;35397:179::-;35537:31;35533:1;35525:6;35521:14;35514:55;35397:179;:::o;35582:366::-;35724:3;35745:67;35809:2;35804:3;35745:67;:::i;:::-;35738:74;;35821:93;35910:3;35821:93;:::i;:::-;35939:2;35934:3;35930:12;35923:19;;35582:366;;;:::o;35954:419::-;36120:4;36158:2;36147:9;36143:18;36135:26;;36207:9;36201:4;36197:20;36193:1;36182:9;36178:17;36171:47;36235:131;36361:4;36235:131;:::i;:::-;36227:139;;35954:419;;;:::o;36379:332::-;36500:4;36538:2;36527:9;36523:18;36515:26;;36551:71;36619:1;36608:9;36604:17;36595:6;36551:71;:::i;:::-;36632:72;36700:2;36689:9;36685:18;36676:6;36632:72;:::i;:::-;36379:332;;;;;:::o;36717:148::-;36819:11;36856:3;36841:18;;36717:148;;;;:::o;36871:173::-;37011:25;37007:1;36999:6;36995:14;36988:49;36871:173;:::o;37050:402::-;37210:3;37231:85;37313:2;37308:3;37231:85;:::i;:::-;37224:92;;37325:93;37414:3;37325:93;:::i;:::-;37443:2;37438:3;37434:12;37427:19;;37050:402;;;:::o;37458:390::-;37564:3;37592:39;37625:5;37592:39;:::i;:::-;37647:89;37729:6;37724:3;37647:89;:::i;:::-;37640:96;;37745:65;37803:6;37798:3;37791:4;37784:5;37780:16;37745:65;:::i;:::-;37835:6;37830:3;37826:16;37819:23;;37568:280;37458:390;;;;:::o;37854:167::-;37994:19;37990:1;37982:6;37978:14;37971:43;37854:167;:::o;38027:402::-;38187:3;38208:85;38290:2;38285:3;38208:85;:::i;:::-;38201:92;;38302:93;38391:3;38302:93;:::i;:::-;38420:2;38415:3;38411:12;38404:19;;38027:402;;;:::o;38435:967::-;38817:3;38839:148;38983:3;38839:148;:::i;:::-;38832:155;;39004:95;39095:3;39086:6;39004:95;:::i;:::-;38997:102;;39116:148;39260:3;39116:148;:::i;:::-;39109:155;;39281:95;39372:3;39363:6;39281:95;:::i;:::-;39274:102;;39393:3;39386:10;;38435:967;;;;;:::o;39408:664::-;39613:4;39651:3;39640:9;39636:19;39628:27;;39665:71;39733:1;39722:9;39718:17;39709:6;39665:71;:::i;:::-;39746:72;39814:2;39803:9;39799:18;39790:6;39746:72;:::i;:::-;39828;39896:2;39885:9;39881:18;39872:6;39828:72;:::i;:::-;39910;39978:2;39967:9;39963:18;39954:6;39910:72;:::i;:::-;39992:73;40060:3;40049:9;40045:19;40036:6;39992:73;:::i;:::-;39408:664;;;;;;;;:::o;40078:180::-;40126:77;40123:1;40116:88;40223:4;40220:1;40213:15;40247:4;40244:1;40237:15;40264:185;40304:1;40321:20;40339:1;40321:20;:::i;:::-;40316:25;;40355:20;40373:1;40355:20;:::i;:::-;40350:25;;40394:1;40384:35;;40399:18;;:::i;:::-;40384:35;40441:1;40438;40434:9;40429:14;;40264:185;;;;:::o;40455:214::-;40595:66;40591:1;40583:6;40579:14;40572:90;40455:214;:::o;40675:400::-;40835:3;40856:84;40938:1;40933:3;40856:84;:::i;:::-;40849:91;;40949:93;41038:3;40949:93;:::i;:::-;41067:1;41062:3;41058:11;41051:18;;40675:400;;;:::o;41081:79::-;41120:7;41149:5;41138:16;;41081:79;;;:::o;41166:157::-;41271:45;41291:24;41309:5;41291:24;:::i;:::-;41271:45;:::i;:::-;41266:3;41259:58;41166:157;;:::o;41329:663::-;41570:3;41592:148;41736:3;41592:148;:::i;:::-;41585:155;;41750:75;41821:3;41812:6;41750:75;:::i;:::-;41850:2;41845:3;41841:12;41834:19;;41863:75;41934:3;41925:6;41863:75;:::i;:::-;41963:2;41958:3;41954:12;41947:19;;41983:3;41976:10;;41329:663;;;;;:::o;41998:545::-;42171:4;42209:3;42198:9;42194:19;42186:27;;42223:71;42291:1;42280:9;42276:17;42267:6;42223:71;:::i;:::-;42304:68;42368:2;42357:9;42353:18;42344:6;42304:68;:::i;:::-;42382:72;42450:2;42439:9;42435:18;42426:6;42382:72;:::i;:::-;42464;42532:2;42521:9;42517:18;42508:6;42464:72;:::i;:::-;41998:545;;;;;;;:::o;42549:180::-;42597:77;42594:1;42587:88;42694:4;42691:1;42684:15;42718:4;42715:1;42708:15;42735:174;42875:26;42871:1;42863:6;42859:14;42852:50;42735:174;:::o;42915:366::-;43057:3;43078:67;43142:2;43137:3;43078:67;:::i;:::-;43071:74;;43154:93;43243:3;43154:93;:::i;:::-;43272:2;43267:3;43263:12;43256:19;;42915:366;;;:::o;43287:419::-;43453:4;43491:2;43480:9;43476:18;43468:26;;43540:9;43534:4;43530:20;43526:1;43515:9;43511:17;43504:47;43568:131;43694:4;43568:131;:::i;:::-;43560:139;;43287:419;;;:::o;43712:181::-;43852:33;43848:1;43840:6;43836:14;43829:57;43712:181;:::o;43899:366::-;44041:3;44062:67;44126:2;44121:3;44062:67;:::i;:::-;44055:74;;44138:93;44227:3;44138:93;:::i;:::-;44256:2;44251:3;44247:12;44240:19;;43899:366;;;:::o;44271:419::-;44437:4;44475:2;44464:9;44460:18;44452:26;;44524:9;44518:4;44514:20;44510:1;44499:9;44495:17;44488:47;44552:131;44678:4;44552:131;:::i;:::-;44544:139;;44271:419;;;:::o;44696:221::-;44836:34;44832:1;44824:6;44820:14;44813:58;44905:4;44900:2;44892:6;44888:15;44881:29;44696:221;:::o;44923:366::-;45065:3;45086:67;45150:2;45145:3;45086:67;:::i;:::-;45079:74;;45162:93;45251:3;45162:93;:::i;:::-;45280:2;45275:3;45271:12;45264:19;;44923:366;;;:::o;45295:419::-;45461:4;45499:2;45488:9;45484:18;45476:26;;45548:9;45542:4;45538:20;45534:1;45523:9;45519:17;45512:47;45576:131;45702:4;45576:131;:::i;:::-;45568:139;;45295:419;;;:::o;45720:221::-;45860:34;45856:1;45848:6;45844:14;45837:58;45929:4;45924:2;45916:6;45912:15;45905:29;45720:221;:::o;45947:366::-;46089:3;46110:67;46174:2;46169:3;46110:67;:::i;:::-;46103:74;;46186:93;46275:3;46186:93;:::i;:::-;46304:2;46299:3;46295:12;46288:19;;45947:366;;;:::o;46319:419::-;46485:4;46523:2;46512:9;46508:18;46500:26;;46572:9;46566:4;46562:20;46558:1;46547:9;46543:17;46536:47;46600:131;46726:4;46600:131;:::i;:::-;46592:139;;46319:419;;;:::o;46744:410::-;46784:7;46807:20;46825:1;46807:20;:::i;:::-;46802:25;;46841:20;46859:1;46841:20;:::i;:::-;46836:25;;46896:1;46893;46889:9;46918:30;46936:11;46918:30;:::i;:::-;46907:41;;47097:1;47088:7;47084:15;47081:1;47078:22;47058:1;47051:9;47031:83;47008:139;;47127:18;;:::i;:::-;47008:139;46792:362;46744:410;;;;:::o;47160:180::-;47208:77;47205:1;47198:88;47305:4;47302:1;47295:15;47329:4;47326:1;47319:15;47346:171;47385:3;47408:24;47426:5;47408:24;:::i;:::-;47399:33;;47454:4;47447:5;47444:15;47441:41;;47462:18;;:::i;:::-;47441:41;47509:1;47502:5;47498:13;47491:20;;47346:171;;;:::o;47523:182::-;47663:34;47659:1;47651:6;47647:14;47640:58;47523:182;:::o;47711:366::-;47853:3;47874:67;47938:2;47933:3;47874:67;:::i;:::-;47867:74;;47950:93;48039:3;47950:93;:::i;:::-;48068:2;48063:3;48059:12;48052:19;;47711:366;;;:::o;48083:419::-;48249:4;48287:2;48276:9;48272:18;48264:26;;48336:9;48330:4;48326:20;48322:1;48311:9;48307:17;48300:47;48364:131;48490:4;48364:131;:::i;:::-;48356:139;;48083:419;;;:::o;48508:220::-;48648:34;48644:1;48636:6;48632:14;48625:58;48717:3;48712:2;48704:6;48700:15;48693:28;48508:220;:::o;48734:366::-;48876:3;48897:67;48961:2;48956:3;48897:67;:::i;:::-;48890:74;;48973:93;49062:3;48973:93;:::i;:::-;49091:2;49086:3;49082:12;49075:19;;48734:366;;;:::o;49106:419::-;49272:4;49310:2;49299:9;49295:18;49287:26;;49359:9;49353:4;49349:20;49345:1;49334:9;49330:17;49323:47;49387:131;49513:4;49387:131;:::i;:::-;49379:139;;49106:419;;;:::o;49531:221::-;49671:34;49667:1;49659:6;49655:14;49648:58;49740:4;49735:2;49727:6;49723:15;49716:29;49531:221;:::o;49758:366::-;49900:3;49921:67;49985:2;49980:3;49921:67;:::i;:::-;49914:74;;49997:93;50086:3;49997:93;:::i;:::-;50115:2;50110:3;50106:12;50099:19;;49758:366;;;:::o;50130:419::-;50296:4;50334:2;50323:9;50319:18;50311:26;;50383:9;50377:4;50373:20;50369:1;50358:9;50354:17;50347:47;50411:131;50537:4;50411:131;:::i;:::-;50403:139;;50130:419;;;:::o
Swarm Source
ipfs://7a36d0a54338b1171d26b7b0fd45268682361cc140cbc1ff647d16db06f8c789
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.