Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
Overview
Max Total Supply
44 Bruiser
Holders
26
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
2 BruiserLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Source Code Verified (Exact Match)
Contract Name:
Bruiser
Compiler Version
v0.8.26+commit.8a97fa7a
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2024-11-19 */ // File: @openzeppelin/contracts/utils/math/SafeCast.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.20; /** * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeCast { /** * @dev Value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); /** * @dev An int value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedIntToUint(int256 value); /** * @dev Value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); /** * @dev An uint value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedUintToInt(uint256 value); /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits */ function toUint248(uint256 value) internal pure returns (uint248) { if (value > type(uint248).max) { revert SafeCastOverflowedUintDowncast(248, value); } return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits */ function toUint240(uint256 value) internal pure returns (uint240) { if (value > type(uint240).max) { revert SafeCastOverflowedUintDowncast(240, value); } return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits */ function toUint232(uint256 value) internal pure returns (uint232) { if (value > type(uint232).max) { revert SafeCastOverflowedUintDowncast(232, value); } return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { if (value > type(uint224).max) { revert SafeCastOverflowedUintDowncast(224, value); } return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits */ function toUint216(uint256 value) internal pure returns (uint216) { if (value > type(uint216).max) { revert SafeCastOverflowedUintDowncast(216, value); } return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 value) internal pure returns (uint208) { if (value > type(uint208).max) { revert SafeCastOverflowedUintDowncast(208, value); } return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits */ function toUint200(uint256 value) internal pure returns (uint200) { if (value > type(uint200).max) { revert SafeCastOverflowedUintDowncast(200, value); } return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits */ function toUint192(uint256 value) internal pure returns (uint192) { if (value > type(uint192).max) { revert SafeCastOverflowedUintDowncast(192, value); } return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits */ function toUint184(uint256 value) internal pure returns (uint184) { if (value > type(uint184).max) { revert SafeCastOverflowedUintDowncast(184, value); } return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits */ function toUint176(uint256 value) internal pure returns (uint176) { if (value > type(uint176).max) { revert SafeCastOverflowedUintDowncast(176, value); } return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits */ function toUint168(uint256 value) internal pure returns (uint168) { if (value > type(uint168).max) { revert SafeCastOverflowedUintDowncast(168, value); } return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits */ function toUint160(uint256 value) internal pure returns (uint160) { if (value > type(uint160).max) { revert SafeCastOverflowedUintDowncast(160, value); } return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits */ function toUint152(uint256 value) internal pure returns (uint152) { if (value > type(uint152).max) { revert SafeCastOverflowedUintDowncast(152, value); } return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits */ function toUint144(uint256 value) internal pure returns (uint144) { if (value > type(uint144).max) { revert SafeCastOverflowedUintDowncast(144, value); } return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits */ function toUint136(uint256 value) internal pure returns (uint136) { if (value > type(uint136).max) { revert SafeCastOverflowedUintDowncast(136, value); } return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { if (value > type(uint128).max) { revert SafeCastOverflowedUintDowncast(128, value); } return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits */ function toUint120(uint256 value) internal pure returns (uint120) { if (value > type(uint120).max) { revert SafeCastOverflowedUintDowncast(120, value); } return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits */ function toUint112(uint256 value) internal pure returns (uint112) { if (value > type(uint112).max) { revert SafeCastOverflowedUintDowncast(112, value); } return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 value) internal pure returns (uint104) { if (value > type(uint104).max) { revert SafeCastOverflowedUintDowncast(104, value); } return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { if (value > type(uint96).max) { revert SafeCastOverflowedUintDowncast(96, value); } return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits */ function toUint88(uint256 value) internal pure returns (uint88) { if (value > type(uint88).max) { revert SafeCastOverflowedUintDowncast(88, value); } return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits */ function toUint80(uint256 value) internal pure returns (uint80) { if (value > type(uint80).max) { revert SafeCastOverflowedUintDowncast(80, value); } return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits */ function toUint72(uint256 value) internal pure returns (uint72) { if (value > type(uint72).max) { revert SafeCastOverflowedUintDowncast(72, value); } return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { if (value > type(uint64).max) { revert SafeCastOverflowedUintDowncast(64, value); } return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits */ function toUint56(uint256 value) internal pure returns (uint56) { if (value > type(uint56).max) { revert SafeCastOverflowedUintDowncast(56, value); } return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits */ function toUint48(uint256 value) internal pure returns (uint48) { if (value > type(uint48).max) { revert SafeCastOverflowedUintDowncast(48, value); } return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { if (value > type(uint40).max) { revert SafeCastOverflowedUintDowncast(40, value); } return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { if (value > type(uint32).max) { revert SafeCastOverflowedUintDowncast(32, value); } return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits */ function toUint24(uint256 value) internal pure returns (uint24) { if (value > type(uint24).max) { revert SafeCastOverflowedUintDowncast(24, value); } return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { if (value > type(uint16).max) { revert SafeCastOverflowedUintDowncast(16, value); } return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits */ function toUint8(uint256 value) internal pure returns (uint8) { if (value > type(uint8).max) { revert SafeCastOverflowedUintDowncast(8, value); } return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { if (value < 0) { revert SafeCastOverflowedIntToUint(value); } return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(248, value); } } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(240, value); } } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(232, value); } } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(224, value); } } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(216, value); } } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(208, value); } } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(200, value); } } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(192, value); } } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(184, value); } } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(176, value); } } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(168, value); } } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(160, value); } } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(152, value); } } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(144, value); } } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(136, value); } } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(128, value); } } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(120, value); } } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(112, value); } } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(104, value); } } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(96, value); } } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(88, value); } } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(80, value); } } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(72, value); } } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(64, value); } } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(56, value); } } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(48, value); } } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(40, value); } } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(32, value); } } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(24, value); } } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(16, value); } } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(8, value); } } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive if (value > uint256(type(int256).max)) { revert SafeCastOverflowedUintToInt(value); } return int256(value); } /** * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump. */ function toUint(bool b) internal pure returns (uint256 u) { assembly ("memory-safe") { u := iszero(iszero(b)) } } } // File: @openzeppelin/contracts/utils/math/SignedMath.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, int256 a, int256 b) internal pure returns (int256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * int256(SafeCast.toUint(condition))); } } /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return ternary(a < b, a, b); } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // Formula from the "Bit Twiddling Hacks" by Sean Eron Anderson. // Since `n` is a signed integer, the generated bytecode will use the SAR opcode to perform the right shift, // taking advantage of the most significant (or "sign" bit) in two's complement representation. // This opcode adds new most significant bits set to the value of the previous most significant bit. As a result, // the mask will either be `bytes32(0)` (if n is positive) or `~bytes32(0)` (if n is negative). int256 mask = n >> 255; // A `bytes32(0)` mask leaves the input unchanged, while a `~bytes32(0)` mask complements it. return uint256((n + mask) ^ mask); } } } // File: @openzeppelin/contracts/utils/Panic.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol) pragma solidity ^0.8.20; /** * @dev Helper library for emitting standardized panic codes. * * ```solidity * contract Example { * using Panic for uint256; * * // Use any of the declared internal constants * function foo() { Panic.GENERIC.panic(); } * * // Alternatively * function foo() { Panic.panic(Panic.GENERIC); } * } * ``` * * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil]. * * _Available since v5.1._ */ // slither-disable-next-line unused-state library Panic { /// @dev generic / unspecified error uint256 internal constant GENERIC = 0x00; /// @dev used by the assert() builtin uint256 internal constant ASSERT = 0x01; /// @dev arithmetic underflow or overflow uint256 internal constant UNDER_OVERFLOW = 0x11; /// @dev division or modulo by zero uint256 internal constant DIVISION_BY_ZERO = 0x12; /// @dev enum conversion error uint256 internal constant ENUM_CONVERSION_ERROR = 0x21; /// @dev invalid encoding in storage uint256 internal constant STORAGE_ENCODING_ERROR = 0x22; /// @dev empty array pop uint256 internal constant EMPTY_ARRAY_POP = 0x31; /// @dev array out of bounds access uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32; /// @dev resource error (too large allocation or too large array) uint256 internal constant RESOURCE_ERROR = 0x41; /// @dev calling invalid internal function uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51; /// @dev Reverts with a panic code. Recommended to use with /// the internal constants with predefined codes. function panic(uint256 code) internal pure { assembly ("memory-safe") { mstore(0x00, 0x4e487b71) mstore(0x20, code) revert(0x1c, 0x24) } } } // File: @openzeppelin/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/Math.sol) pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an success flag (no overflow). */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow). */ function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow). */ function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a success flag (no division by zero). */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero). */ function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * SafeCast.toUint(condition)); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(a < b, a, b); } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. Panic.panic(Panic.DIVISION_BY_ZERO); } // The following calculation ensures accurate ceiling division without overflow. // Since a is non-zero, (a - 1) / b will not overflow. // The largest possible result occurs when (a - 1) / b is type(uint256).max, // but the largest value we can obtain is type(uint256).max - 1, which happens // when a = type(uint256).max and b = 1. unchecked { return SafeCast.toUint(a > 0) * ((a - 1) / b + 1); } } /** * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * * 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²⁵⁶ and mod 2²⁵⁶ - 1, then use // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2²⁵⁶ + prod0. uint256 prod0 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0. if (denominator <= prod1) { Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW)); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. uint256 twos = denominator & (0 - denominator); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2²⁵⁶ / 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²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv ≡ 1 mod 2⁴. 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⁸ inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶ inverse *= 2 - denominator * inverse; // inverse mod 2³² inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴ inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸ inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶ // 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²⁵⁶. Since the preconditions guarantee that the outcome is // less than 2²⁵⁶, 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; } } /** * @dev 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) { return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0); } /** * @dev Calculate the modular multiplicative inverse of a number in Z/nZ. * * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0. * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible. * * If the input value is not inversible, 0 is returned. * * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}. */ function invMod(uint256 a, uint256 n) internal pure returns (uint256) { unchecked { if (n == 0) return 0; // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version) // Used to compute integers x and y such that: ax + ny = gcd(a, n). // When the gcd is 1, then the inverse of a modulo n exists and it's x. // ax + ny = 1 // ax = 1 + (-y)n // ax ≡ 1 (mod n) # x is the inverse of a modulo n // If the remainder is 0 the gcd is n right away. uint256 remainder = a % n; uint256 gcd = n; // Therefore the initial coefficients are: // ax + ny = gcd(a, n) = n // 0a + 1n = n int256 x = 0; int256 y = 1; while (remainder != 0) { uint256 quotient = gcd / remainder; (gcd, remainder) = ( // The old remainder is the next gcd to try. remainder, // Compute the next remainder. // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd // where gcd is at most n (capped to type(uint256).max) gcd - remainder * quotient ); (x, y) = ( // Increment the coefficient of a. y, // Decrement the coefficient of n. // Can overflow, but the result is casted to uint256 so that the // next value of y is "wrapped around" to a value between 0 and n - 1. x - y * int256(quotient) ); } if (gcd != 1) return 0; // No inverse exists. return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative. } } /** * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`. * * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that * `a**(p-2)` is the modular multiplicative inverse of a in Fp. * * NOTE: this function does NOT check that `p` is a prime greater than `2`. */ function invModPrime(uint256 a, uint256 p) internal view returns (uint256) { unchecked { return Math.modExp(a, p - 2, p); } } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m) * * Requirements: * - modulus can't be zero * - underlying staticcall to precompile must succeed * * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make * sure the chain you're using it on supports the precompiled contract for modular exponentiation * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, * the underlying function will succeed given the lack of a revert, but the result may be incorrectly * interpreted as 0. */ function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) { (bool success, uint256 result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m). * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying * to operate modulo 0 or if the underlying precompile reverted. * * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack * of a revert, but the result may be incorrectly interpreted as 0. */ function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) { if (m == 0) return (false, 0); assembly ("memory-safe") { let ptr := mload(0x40) // | Offset | Content | Content (Hex) | // |-----------|------------|--------------------------------------------------------------------| // | 0x00:0x1f | size of b | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x20:0x3f | size of e | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x40:0x5f | size of m | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x60:0x7f | value of b | 0x<.............................................................b> | // | 0x80:0x9f | value of e | 0x<.............................................................e> | // | 0xa0:0xbf | value of m | 0x<.............................................................m> | mstore(ptr, 0x20) mstore(add(ptr, 0x20), 0x20) mstore(add(ptr, 0x40), 0x20) mstore(add(ptr, 0x60), b) mstore(add(ptr, 0x80), e) mstore(add(ptr, 0xa0), m) // Given the result < m, it's guaranteed to fit in 32 bytes, // so we can use the memory scratch space located at offset 0. success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20) result := mload(0x00) } } /** * @dev Variant of {modExp} that supports inputs of arbitrary length. */ function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) { (bool success, bytes memory result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Variant of {tryModExp} that supports inputs of arbitrary length. */ function tryModExp( bytes memory b, bytes memory e, bytes memory m ) internal view returns (bool success, bytes memory result) { if (_zeroBytes(m)) return (false, new bytes(0)); uint256 mLen = m.length; // Encode call args in result and move the free memory pointer result = abi.encodePacked(b.length, e.length, mLen, b, e, m); assembly ("memory-safe") { let dataPtr := add(result, 0x20) // Write result on top of args to avoid allocating extra memory. success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen) // Overwrite the length. // result.length > returndatasize() is guaranteed because returndatasize() == m.length mstore(result, mLen) // Set the memory pointer after the returned data. mstore(0x40, add(dataPtr, mLen)) } } /** * @dev Returns whether the provided byte array is zero. */ function _zeroBytes(bytes memory byteArray) private pure returns (bool) { for (uint256 i = 0; i < byteArray.length; ++i) { if (byteArray[i] != 0) { return false; } } return true; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * This method is based on Newton's method for computing square roots; the algorithm is restricted to only * using integer operations. */ function sqrt(uint256 a) internal pure returns (uint256) { unchecked { // Take care of easy edge cases when a == 0 or a == 1 if (a <= 1) { return a; } // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between // the current value as `ε_n = | x_n - sqrt(a) |`. // // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is // bigger than any uint256. // // By noticing that // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)` // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar // to the msb function. uint256 aa = a; uint256 xn = 1; if (aa >= (1 << 128)) { aa >>= 128; xn <<= 64; } if (aa >= (1 << 64)) { aa >>= 64; xn <<= 32; } if (aa >= (1 << 32)) { aa >>= 32; xn <<= 16; } if (aa >= (1 << 16)) { aa >>= 16; xn <<= 8; } if (aa >= (1 << 8)) { aa >>= 8; xn <<= 4; } if (aa >= (1 << 4)) { aa >>= 4; xn <<= 2; } if (aa >= (1 << 2)) { xn <<= 1; } // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1). // // We can refine our estimation by noticing that the middle of that interval minimizes the error. // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2). // This is going to be our x_0 (and ε_0) xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2) // From here, Newton's method give us: // x_{n+1} = (x_n + a / x_n) / 2 // // One should note that: // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a // = ((x_n² + a) / (2 * x_n))² - a // = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a // = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²) // = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²) // = (x_n² - a)² / (2 * x_n)² // = ((x_n² - a) / (2 * x_n))² // ≥ 0 // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n // // This gives us the proof of quadratic convergence of the sequence: // ε_{n+1} = | x_{n+1} - sqrt(a) | // = | (x_n + a / x_n) / 2 - sqrt(a) | // = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) | // = | (x_n - sqrt(a))² / (2 * x_n) | // = | ε_n² / (2 * x_n) | // = ε_n² / | (2 * x_n) | // // For the first iteration, we have a special case where x_0 is known: // ε_1 = ε_0² / | (2 * x_0) | // ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2))) // ≤ 2**(2*e-4) / (3 * 2**(e-1)) // ≤ 2**(e-3) / 3 // ≤ 2**(e-3-log2(3)) // ≤ 2**(e-4.5) // // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n: // ε_{n+1} = ε_n² / | (2 * x_n) | // ≤ (2**(e-k))² / (2 * 2**(e-1)) // ≤ 2**(2*e-2*k) / 2**e // ≤ 2**(e-2*k) xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5) -- special case, see above xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9) -- general case with k = 4.5 xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18) -- general case with k = 9 xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36) -- general case with k = 18 xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72) -- general case with k = 36 xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144) -- general case with k = 72 // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either // sqrt(a) or sqrt(a) + 1. return xn - SafeCast.toUint(xn > a / xn); } } /** * @dev Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 exp; unchecked { exp = 128 * SafeCast.toUint(value > (1 << 128) - 1); value >>= exp; result += exp; exp = 64 * SafeCast.toUint(value > (1 << 64) - 1); value >>= exp; result += exp; exp = 32 * SafeCast.toUint(value > (1 << 32) - 1); value >>= exp; result += exp; exp = 16 * SafeCast.toUint(value > (1 << 16) - 1); value >>= exp; result += exp; exp = 8 * SafeCast.toUint(value > (1 << 8) - 1); value >>= exp; result += exp; exp = 4 * SafeCast.toUint(value > (1 << 4) - 1); value >>= exp; result += exp; exp = 2 * SafeCast.toUint(value > (1 << 2) - 1); value >>= exp; result += exp; result += SafeCast.toUint(value > 1); } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 isGt; unchecked { isGt = SafeCast.toUint(value > (1 << 128) - 1); value >>= isGt * 128; result += isGt * 16; isGt = SafeCast.toUint(value > (1 << 64) - 1); value >>= isGt * 64; result += isGt * 8; isGt = SafeCast.toUint(value > (1 << 32) - 1); value >>= isGt * 32; result += isGt * 4; isGt = SafeCast.toUint(value > (1 << 16) - 1); value >>= isGt * 16; result += isGt * 2; result += SafeCast.toUint(value > (1 << 8) - 1); } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/Strings.sol) pragma solidity ^0.8.20; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; assembly ("memory-safe") { ptr := add(buffer, add(32, length)) } while (true) { ptr--; assembly ("memory-safe") { mstore8(ptr, byte(mod(value, 10), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { uint256 localValue = value; bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal * representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH); } /** * @dev Converts an `address` with fixed length of 20 bytes to its checksummed ASCII `string` hexadecimal * representation, according to EIP-55. */ function toChecksumHexString(address addr) internal pure returns (string memory) { bytes memory buffer = bytes(toHexString(addr)); // hash the hex part of buffer (skip length + 2 bytes, length 40) uint256 hashValue; assembly ("memory-safe") { hashValue := shr(96, keccak256(add(buffer, 0x22), 40)) } for (uint256 i = 41; i > 1; --i) { // possible values for buffer[i] are 48 (0) to 57 (9) and 97 (a) to 102 (f) if (hashValue & 0xf > 7 && uint8(buffer[i]) > 96) { // case shift by xoring with 0x20 buffer[i] ^= 0x20; } hashValue >>= 4; } return string(buffer); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } } // File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.20; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS } /** * @dev The signature derives the `address(0)`. */ error ECDSAInvalidSignature(); /** * @dev The signature has an invalid length. */ error ECDSAInvalidSignatureLength(uint256 length); /** * @dev The signature has an S value that is in the upper half order. */ error ECDSAInvalidSignatureS(bytes32 s); /** * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not * return address(0) without also returning an error description. Errors are documented using an enum (error type) * and a bytes32 providing additional information about the error. * * If no error is returned, then the address can be used for verification purposes. * * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] */ function tryRecover( bytes32 hash, bytes memory signature ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) { 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. assembly ("memory-safe") { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length)); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature); _throwError(error, errorArg); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[ERC-2098 short signatures] */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) { unchecked { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); // We do not check for an overflow here since the shift operation results in 0 or 1. uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs); _throwError(error, errorArg); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS, s); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature, bytes32(0)); } return (signer, RecoverError.NoError, bytes32(0)); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s); _throwError(error, errorArg); return recovered; } /** * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided. */ function _throwError(RecoverError error, bytes32 errorArg) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert ECDSAInvalidSignature(); } else if (error == RecoverError.InvalidSignatureLength) { revert ECDSAInvalidSignatureLength(uint256(errorArg)); } else if (error == RecoverError.InvalidSignatureS) { revert ECDSAInvalidSignatureS(errorArg); } } } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } } // File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/access/OwnablePermissions.sol pragma solidity ^0.8.4; abstract contract OwnablePermissions is Context { function _requireCallerIsContractOwner() internal view virtual; } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/access/OwnableBasic.sol pragma solidity ^0.8.4; abstract contract OwnableBasic is OwnablePermissions, Ownable { function _requireCallerIsContractOwner() internal view virtual override { _checkOwner(); } } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * 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[ERC 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: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/interfaces/IEOARegistry.sol pragma solidity ^0.8.4; interface IEOARegistry is IERC165 { function isVerifiedEOA(address account) external view returns (bool); } // File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/utils/TransferPolicy.sol pragma solidity ^0.8.4; enum AllowlistTypes { Operators, PermittedContractReceivers } enum ReceiverConstraints { None, NoCode, EOA } enum CallerConstraints { None, OperatorWhitelistEnableOTC, OperatorWhitelistDisableOTC } enum StakerConstraints { None, CallerIsTxOrigin, EOA } enum TransferSecurityLevels { Zero, One, Two, Three, Four, Five, Six } struct TransferSecurityPolicy { CallerConstraints callerConstraints; ReceiverConstraints receiverConstraints; } struct CollectionSecurityPolicy { TransferSecurityLevels transferSecurityLevel; uint120 operatorWhitelistId; uint120 permittedContractReceiversId; } // File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/interfaces/ITransferSecurityRegistry.sol pragma solidity ^0.8.4; interface ITransferSecurityRegistry { event AddedToAllowlist(AllowlistTypes indexed kind, uint256 indexed id, address indexed account); event CreatedAllowlist(AllowlistTypes indexed kind, uint256 indexed id, string indexed name); event ReassignedAllowlistOwnership(AllowlistTypes indexed kind, uint256 indexed id, address indexed newOwner); event RemovedFromAllowlist(AllowlistTypes indexed kind, uint256 indexed id, address indexed account); event SetAllowlist(AllowlistTypes indexed kind, address indexed collection, uint120 indexed id); event SetTransferSecurityLevel(address indexed collection, TransferSecurityLevels level); function createOperatorWhitelist(string calldata name) external returns (uint120); function createPermittedContractReceiverAllowlist(string calldata name) external returns (uint120); function reassignOwnershipOfOperatorWhitelist(uint120 id, address newOwner) external; function reassignOwnershipOfPermittedContractReceiverAllowlist(uint120 id, address newOwner) external; function renounceOwnershipOfOperatorWhitelist(uint120 id) external; function renounceOwnershipOfPermittedContractReceiverAllowlist(uint120 id) external; function setTransferSecurityLevelOfCollection(address collection, TransferSecurityLevels level) external; function setOperatorWhitelistOfCollection(address collection, uint120 id) external; function setPermittedContractReceiverAllowlistOfCollection(address collection, uint120 id) external; function addOperatorToWhitelist(uint120 id, address operator) external; function addPermittedContractReceiverToAllowlist(uint120 id, address receiver) external; function removeOperatorFromWhitelist(uint120 id, address operator) external; function removePermittedContractReceiverFromAllowlist(uint120 id, address receiver) external; function getCollectionSecurityPolicy(address collection) external view returns (CollectionSecurityPolicy memory); function getWhitelistedOperators(uint120 id) external view returns (address[] memory); function getPermittedContractReceivers(uint120 id) external view returns (address[] memory); function isOperatorWhitelisted(uint120 id, address operator) external view returns (bool); function isContractReceiverPermitted(uint120 id, address receiver) external view returns (bool); } // File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/interfaces/ITransferValidator.sol pragma solidity ^0.8.4; interface ITransferValidator { function applyCollectionTransferPolicy(address caller, address from, address to) external view; } // File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/interfaces/ICreatorTokenTransferValidator.sol pragma solidity ^0.8.4; interface ICreatorTokenTransferValidator is ITransferSecurityRegistry, ITransferValidator, IEOARegistry {} // File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/interfaces/ICreatorToken.sol pragma solidity ^0.8.4; interface ICreatorToken { event TransferValidatorUpdated(address oldValidator, address newValidator); function getTransferValidator() external view returns (ICreatorTokenTransferValidator); function getSecurityPolicy() external view returns (CollectionSecurityPolicy memory); function getWhitelistedOperators() external view returns (address[] memory); function getPermittedContractReceivers() external view returns (address[] memory); function isOperatorWhitelisted(address operator) external view returns (bool); function isContractReceiverPermitted(address receiver) external view returns (bool); function isTransferAllowed(address caller, address from, address to) external view returns (bool); } // File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/utils/TransferValidation.sol pragma solidity ^0.8.4; /** * @title TransferValidation * @author Limit Break, Inc. * @notice A mix-in that can be combined with ERC-721 contracts to provide more granular hooks. * Openzeppelin's ERC721 contract only provides hooks for before and after transfer. This allows * developers to validate or customize transfers within the context of a mint, a burn, or a transfer. */ abstract contract TransferValidation is Context { error ShouldNotMintToBurnAddress(); /// @dev Inheriting contracts should call this function in the _beforeTokenTransfer function to get more granular hooks. function _validateBeforeTransfer(address from, address to, uint256 tokenId) internal virtual { bool fromZeroAddress = from == address(0); bool toZeroAddress = to == address(0); if(fromZeroAddress && toZeroAddress) { revert ShouldNotMintToBurnAddress(); } else if(fromZeroAddress) { _preValidateMint(_msgSender(), to, tokenId, msg.value); } else if(toZeroAddress) { _preValidateBurn(_msgSender(), from, tokenId, msg.value); } else { _preValidateTransfer(_msgSender(), from, to, tokenId, msg.value); } } /// @dev Inheriting contracts should call this function in the _afterTokenTransfer function to get more granular hooks. function _validateAfterTransfer(address from, address to, uint256 tokenId) internal virtual { bool fromZeroAddress = from == address(0); bool toZeroAddress = to == address(0); if(fromZeroAddress && toZeroAddress) { revert ShouldNotMintToBurnAddress(); } else if(fromZeroAddress) { _postValidateMint(_msgSender(), to, tokenId, msg.value); } else if(toZeroAddress) { _postValidateBurn(_msgSender(), from, tokenId, msg.value); } else { _postValidateTransfer(_msgSender(), from, to, tokenId, msg.value); } } /// @dev Optional validation hook that fires before a mint function _preValidateMint(address caller, address to, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a mint function _postValidateMint(address caller, address to, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires before a burn function _preValidateBurn(address caller, address from, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a burn function _postValidateBurn(address caller, address from, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires before a transfer function _preValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a transfer function _postValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 value) internal virtual {} } // File: @openzeppelin/contracts/interfaces/IERC165.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) pragma solidity ^0.8.20; // File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/utils/CreatorTokenBase.sol pragma solidity ^0.8.4; /** * @title CreatorTokenBase * @author Limit Break, Inc. * @notice CreatorTokenBase is an abstract contract that provides basic functionality for managing token * transfer policies through an implementation of ICreatorTokenTransferValidator. This contract is intended to be used * as a base for creator-specific token contracts, enabling customizable transfer restrictions and security policies. * * <h4>Features:</h4> * <ul>Ownable: This contract can have an owner who can set and update the transfer validator.</ul> * <ul>TransferValidation: Implements the basic token transfer validation interface.</ul> * <ul>ICreatorToken: Implements the interface for creator tokens, providing view functions for token security policies.</ul> * * <h4>Benefits:</h4> * <ul>Provides a flexible and modular way to implement custom token transfer restrictions and security policies.</ul> * <ul>Allows creators to enforce policies such as whitelisted operators and permitted contract receivers.</ul> * <ul>Can be easily integrated into other token contracts as a base contract.</ul> * * <h4>Intended Usage:</h4> * <ul>Use as a base contract for creator token implementations that require advanced transfer restrictions and * security policies.</ul> * <ul>Set and update the ICreatorTokenTransferValidator implementation contract to enforce desired policies for the * creator token.</ul> */ abstract contract CreatorTokenBase is OwnablePermissions, TransferValidation, ICreatorToken { error CreatorTokenBase__InvalidTransferValidatorContract(); error CreatorTokenBase__SetTransferValidatorFirst(); address public constant DEFAULT_TRANSFER_VALIDATOR = address(0x0000721C310194CcfC01E523fc93C9cCcFa2A0Ac); TransferSecurityLevels public constant DEFAULT_TRANSFER_SECURITY_LEVEL = TransferSecurityLevels.One; uint120 public constant DEFAULT_OPERATOR_WHITELIST_ID = uint120(1); ICreatorTokenTransferValidator private transferValidator; /** * @notice Allows the contract owner to set the transfer validator to the official validator contract * and set the security policy to the recommended default settings. * @dev May be overridden to change the default behavior of an individual collection. */ function setToDefaultSecurityPolicy() public virtual { _requireCallerIsContractOwner(); setTransferValidator(DEFAULT_TRANSFER_VALIDATOR); ICreatorTokenTransferValidator(DEFAULT_TRANSFER_VALIDATOR).setTransferSecurityLevelOfCollection(address(this), DEFAULT_TRANSFER_SECURITY_LEVEL); ICreatorTokenTransferValidator(DEFAULT_TRANSFER_VALIDATOR).setOperatorWhitelistOfCollection(address(this), DEFAULT_OPERATOR_WHITELIST_ID); } /** * @notice Allows the contract owner to set the transfer validator to a custom validator contract * and set the security policy to their own custom settings. */ function setToCustomValidatorAndSecurityPolicy( address validator, TransferSecurityLevels level, uint120 operatorWhitelistId, uint120 permittedContractReceiversAllowlistId) public { _requireCallerIsContractOwner(); setTransferValidator(validator); ICreatorTokenTransferValidator(validator). setTransferSecurityLevelOfCollection(address(this), level); ICreatorTokenTransferValidator(validator). setOperatorWhitelistOfCollection(address(this), operatorWhitelistId); ICreatorTokenTransferValidator(validator). setPermittedContractReceiverAllowlistOfCollection(address(this), permittedContractReceiversAllowlistId); } /** * @notice Allows the contract owner to set the security policy to their own custom settings. * @dev Reverts if the transfer validator has not been set. */ function setToCustomSecurityPolicy( TransferSecurityLevels level, uint120 operatorWhitelistId, uint120 permittedContractReceiversAllowlistId) public { _requireCallerIsContractOwner(); ICreatorTokenTransferValidator validator = getTransferValidator(); if (address(validator) == address(0)) { revert CreatorTokenBase__SetTransferValidatorFirst(); } validator.setTransferSecurityLevelOfCollection(address(this), level); validator.setOperatorWhitelistOfCollection(address(this), operatorWhitelistId); validator.setPermittedContractReceiverAllowlistOfCollection(address(this), permittedContractReceiversAllowlistId); } /** * @notice Sets the transfer validator for the token contract. * * @dev Throws when provided validator contract is not the zero address and doesn't support * the ICreatorTokenTransferValidator interface. * @dev Throws when the caller is not the contract owner. * * @dev <h4>Postconditions:</h4> * 1. The transferValidator address is updated. * 2. The `TransferValidatorUpdated` event is emitted. * * @param transferValidator_ The address of the transfer validator contract. */ function setTransferValidator(address transferValidator_) public { _requireCallerIsContractOwner(); bool isValidTransferValidator = false; if(transferValidator_.code.length > 0) { try IERC165(transferValidator_).supportsInterface(type(ICreatorTokenTransferValidator).interfaceId) returns (bool supportsInterface) { isValidTransferValidator = supportsInterface; } catch {} } if(transferValidator_ != address(0) && !isValidTransferValidator) { revert CreatorTokenBase__InvalidTransferValidatorContract(); } emit TransferValidatorUpdated(address(transferValidator), transferValidator_); transferValidator = ICreatorTokenTransferValidator(transferValidator_); } /** * @notice Returns the transfer validator contract address for this token contract. */ function getTransferValidator() public view override returns (ICreatorTokenTransferValidator) { return transferValidator; } /** * @notice Returns the security policy for this token contract, which includes: * Transfer security level, operator whitelist id, permitted contract receiver allowlist id. */ function getSecurityPolicy() public view override returns (CollectionSecurityPolicy memory) { if (address(transferValidator) != address(0)) { return transferValidator.getCollectionSecurityPolicy(address(this)); } return CollectionSecurityPolicy({ transferSecurityLevel: TransferSecurityLevels.Zero, operatorWhitelistId: 0, permittedContractReceiversId: 0 }); } /** * @notice Returns the list of all whitelisted operators for this token contract. * @dev This can be an expensive call and should only be used in view-only functions. */ function getWhitelistedOperators() public view override returns (address[] memory) { if (address(transferValidator) != address(0)) { return transferValidator.getWhitelistedOperators( transferValidator.getCollectionSecurityPolicy(address(this)).operatorWhitelistId); } return new address[](0); } /** * @notice Returns the list of permitted contract receivers for this token contract. * @dev This can be an expensive call and should only be used in view-only functions. */ function getPermittedContractReceivers() public view override returns (address[] memory) { if (address(transferValidator) != address(0)) { return transferValidator.getPermittedContractReceivers( transferValidator.getCollectionSecurityPolicy(address(this)).permittedContractReceiversId); } return new address[](0); } /** * @notice Checks if an operator is whitelisted for this token contract. * @param operator The address of the operator to check. */ function isOperatorWhitelisted(address operator) public view override returns (bool) { if (address(transferValidator) != address(0)) { return transferValidator.isOperatorWhitelisted( transferValidator.getCollectionSecurityPolicy(address(this)).operatorWhitelistId, operator); } return false; } /** * @notice Checks if a contract receiver is permitted for this token contract. * @param receiver The address of the receiver to check. */ function isContractReceiverPermitted(address receiver) public view override returns (bool) { if (address(transferValidator) != address(0)) { return transferValidator.isContractReceiverPermitted( transferValidator.getCollectionSecurityPolicy(address(this)).permittedContractReceiversId, receiver); } return false; } /** * @notice Determines if a transfer is allowed based on the token contract's security policy. Use this function * to simulate whether or not a transfer made by the specified `caller` from the `from` address to the `to` * address would be allowed by this token's security policy. * * @notice This function only checks the security policy restrictions and does not check whether token ownership * or approvals are in place. * * @param caller The address of the simulated caller. * @param from The address of the sender. * @param to The address of the receiver. * @return True if the transfer is allowed, false otherwise. */ function isTransferAllowed(address caller, address from, address to) public view override returns (bool) { if (address(transferValidator) != address(0)) { try transferValidator.applyCollectionTransferPolicy(caller, from, to) { return true; } catch { return false; } } return true; } /** * @dev Pre-validates a token transfer, reverting if the transfer is not allowed by this token's security policy. * Inheriting contracts are responsible for overriding the _beforeTokenTransfer function, or its equivalent * and calling _validateBeforeTransfer so that checks can be properly applied during token transfers. * * @dev Throws when the transfer doesn't comply with the collection's transfer policy, if the transferValidator is * set to a non-zero address. * * @param caller The address of the caller. * @param from The address of the sender. * @param to The address of the receiver. */ function _preValidateTransfer( address caller, address from, address to, uint256 /*tokenId*/, uint256 /*value*/) internal virtual override { if (address(transferValidator) != address(0)) { transferValidator.applyCollectionTransferPolicy(caller, from, to); } } } // File: erc721a/contracts/IERC721A.sol // ERC721A Contracts v4.3.0 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); /** * `_sequentialUpTo()` must be greater than `_startTokenId()`. */ error SequentialUpToTooSmall(); /** * The `tokenId` of a sequential mint exceeds `_sequentialUpTo()`. */ error SequentialMintExceedsLimit(); /** * Spot minting requires a `tokenId` greater than `_sequentialUpTo()`. */ error SpotMintTokenIdTooSmall(); /** * Cannot mint over a token that already exists. */ error TokenAlreadyExists(); /** * The feature is not compatible with spot mints. */ error NotCompatibleWithSpotMints(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables * (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move * this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external payable; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); } // File: erc721a/contracts/ERC721A.sol // ERC721A Contracts v4.3.0 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * The `_sequentialUpTo()` function can be overriden to enable spot mints * (i.e. non-consecutive mints) for `tokenId`s greater than `_sequentialUpTo()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // The amount of tokens minted above `_sequentialUpTo()`. // We call these spot mints (i.e. non-sequential mints). uint256 private _spotMinted; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); if (_sequentialUpTo() < _startTokenId()) _revert(SequentialUpToTooSmall.selector); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the starting token ID for sequential mints. * * Override this function to change the starting token ID for sequential mints. * * Note: The value returned must never change after any tokens have been minted. */ function _startTokenId() internal view virtual returns (uint256) { return 1; } /** * @dev Returns the maximum token ID (inclusive) for sequential mints. * * Override this function to return a value less than 2**256 - 1, * but greater than `_startTokenId()`, to enable spot (non-sequential) mints. * * Note: The value returned must never change after any tokens have been minted. */ function _sequentialUpTo() internal view virtual returns (uint256) { return type(uint256).max; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256 result) { // Counter underflow is impossible as `_burnCounter` cannot be incremented // more than `_currentIndex + _spotMinted - _startTokenId()` times. unchecked { // With spot minting, the intermediate `result` can be temporarily negative, // and the computation must be unchecked. result = _currentIndex - _burnCounter - _startTokenId(); if (_sequentialUpTo() != type(uint256).max) result += _spotMinted; } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256 result) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { result = _currentIndex - _startTokenId(); if (_sequentialUpTo() != type(uint256).max) result += _spotMinted; } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } /** * @dev Returns the total number of tokens that are spot-minted. */ function _totalSpotMinted() internal view virtual returns (uint256) { return _spotMinted; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) _revert(BalanceQueryForZeroAddress.selector); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) _revert(URIQueryForNonexistentToken.selector); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Returns whether the ownership slot at `index` is initialized. * An uninitialized slot does not necessarily mean that the slot has no owner. */ function _ownershipIsInitialized(uint256 index) internal view virtual returns (bool) { return _packedOwnerships[index] != 0; } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * @dev Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256 packed) { if (_startTokenId() <= tokenId) { packed = _packedOwnerships[tokenId]; if (tokenId > _sequentialUpTo()) { if (_packedOwnershipExists(packed)) return packed; _revert(OwnerQueryForNonexistentToken.selector); } // If the data at the starting slot does not exist, start the scan. if (packed == 0) { if (tokenId >= _currentIndex) _revert(OwnerQueryForNonexistentToken.selector); // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `tokenId` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. for (;;) { unchecked { packed = _packedOwnerships[--tokenId]; } if (packed == 0) continue; if (packed & _BITMASK_BURNED == 0) return packed; // Otherwise, the token is burned, and we must revert. // This handles the case of batch burned tokens, where only the burned bit // of the starting slot is set, and remaining slots are left uninitialized. _revert(OwnerQueryForNonexistentToken.selector); } } // Otherwise, the data exists and we can skip the scan. // This is possible because we have already achieved the target condition. // This saves 2143 gas on transfers of initialized tokens. // If the token is not burned, return `packed`. Otherwise, revert. if (packed & _BITMASK_BURNED == 0) return packed; } _revert(OwnerQueryForNonexistentToken.selector); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. See {ERC721A-_approve}. * * Requirements: * * - The caller must own the token or be an approved operator. */ function approve(address to, uint256 tokenId) public payable virtual override { _approve(to, tokenId, true); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) _revert(ApprovalQueryForNonexistentToken.selector); return _tokenApprovals[tokenId].value; } /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool result) { if (_startTokenId() <= tokenId) { if (tokenId > _sequentialUpTo()) return _packedOwnershipExists(_packedOwnerships[tokenId]); if (tokenId < _currentIndex) { uint256 packed; while ((packed = _packedOwnerships[tokenId]) == 0) --tokenId; result = packed & _BITMASK_BURNED == 0; } } } /** * @dev Returns whether `packed` represents a token that exists. */ function _packedOwnershipExists(uint256 packed) private pure returns (bool result) { assembly { // The following is equivalent to `owner != address(0) && burned == false`. // Symbolically tested. result := gt(and(packed, _BITMASK_ADDRESS), and(packed, _BITMASK_BURNED)) } } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) public payable virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); // Mask `from` to the lower 160 bits, in case the upper bits somehow aren't clean. from = address(uint160(uint256(uint160(from)) & _BITMASK_ADDRESS)); if (address(uint160(prevOwnershipPacked)) != from) _revert(TransferFromIncorrectOwner.selector); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) _revert(TransferCallerNotOwnerNorApproved.selector); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS; assembly { // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. from, // `from`. toMasked, // `to`. tokenId // `tokenId`. ) } if (toMasked == 0) _revert(TransferToZeroAddress.selector); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public payable virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { _revert(TransferToNonERC721ReceiverImplementer.selector); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { _revert(TransferToNonERC721ReceiverImplementer.selector); } assembly { revert(add(32, reason), mload(reason)) } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) _revert(MintZeroQuantity.selector); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS; if (toMasked == 0) _revert(MintToZeroAddress.selector); uint256 end = startTokenId + quantity; uint256 tokenId = startTokenId; if (end - 1 > _sequentialUpTo()) _revert(SequentialMintExceedsLimit.selector); do { assembly { // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. tokenId // `tokenId`. ) } // The `!=` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. } while (++tokenId != end); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) _revert(MintToZeroAddress.selector); if (quantity == 0) _revert(MintZeroQuantity.selector); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) _revert(MintERC2309QuantityExceedsLimit.selector); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); if (startTokenId + quantity - 1 > _sequentialUpTo()) _revert(SequentialMintExceedsLimit.selector); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { _revert(TransferToNonERC721ReceiverImplementer.selector); } } while (index < end); // This prevents reentrancy to `_safeMint`. // It does not prevent reentrancy to `_safeMintSpot`. if (_currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ''); } /** * @dev Mints a single token at `tokenId`. * * Note: A spot-minted `tokenId` that has been burned can be re-minted again. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` must be greater than `_sequentialUpTo()`. * - `tokenId` must not exist. * * Emits a {Transfer} event for each mint. */ function _mintSpot(address to, uint256 tokenId) internal virtual { if (tokenId <= _sequentialUpTo()) _revert(SpotMintTokenIdTooSmall.selector); uint256 prevOwnershipPacked = _packedOwnerships[tokenId]; if (_packedOwnershipExists(prevOwnershipPacked)) _revert(TokenAlreadyExists.selector); _beforeTokenTransfers(address(0), to, tokenId, 1); // Overflows are incredibly unrealistic. // The `numberMinted` for `to` is incremented by 1, and has a max limit of 2**64 - 1. // `_spotMinted` is incremented by 1, and has a max limit of 2**256 - 1. unchecked { // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `true` (as `quantity == 1`). _packedOwnerships[tokenId] = _packOwnershipData( to, _nextInitializedFlag(1) | _nextExtraData(address(0), to, prevOwnershipPacked) ); // Updates: // - `balance += 1`. // - `numberMinted += 1`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += (1 << _BITPOS_NUMBER_MINTED) | 1; // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS; if (toMasked == 0) _revert(MintToZeroAddress.selector); assembly { // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. tokenId // `tokenId`. ) } ++_spotMinted; } _afterTokenTransfers(address(0), to, tokenId, 1); } /** * @dev Safely mints a single token at `tokenId`. * * Note: A spot-minted `tokenId` that has been burned can be re-minted again. * * Requirements: * * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}. * - `tokenId` must be greater than `_sequentialUpTo()`. * - `tokenId` must not exist. * * See {_mintSpot}. * * Emits a {Transfer} event. */ function _safeMintSpot( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mintSpot(to, tokenId); unchecked { if (to.code.length != 0) { uint256 currentSpotMinted = _spotMinted; if (!_checkContractOnERC721Received(address(0), to, tokenId, _data)) { _revert(TransferToNonERC721ReceiverImplementer.selector); } // This prevents reentrancy to `_safeMintSpot`. // It does not prevent reentrancy to `_safeMint`. if (_spotMinted != currentSpotMinted) revert(); } } } /** * @dev Equivalent to `_safeMintSpot(to, tokenId, '')`. */ function _safeMintSpot(address to, uint256 tokenId) internal virtual { _safeMintSpot(to, tokenId, ''); } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Equivalent to `_approve(to, tokenId, false)`. */ function _approve(address to, uint256 tokenId) internal virtual { _approve(to, tokenId, false); } /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - `tokenId` must exist. * * Emits an {Approval} event. */ function _approve( address to, uint256 tokenId, bool approvalCheck ) internal virtual { address owner = ownerOf(tokenId); if (approvalCheck && _msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { _revert(ApprovalCallerNotOwnerNorApproved.selector); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) _revert(TransferCallerNotOwnerNorApproved.selector); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as `_burnCounter` cannot be exceed `_currentIndex + _spotMinted` times. unchecked { _burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) _revert(OwnershipNotInitializedForExtraData.selector); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } /** * @dev For more efficient reverts. */ function _revert(bytes4 errorSelector) internal pure { assembly { mstore(0x00, errorSelector) revert(0x00, 0x04) } } } // File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/erc721c/ERC721AC.sol pragma solidity ^0.8.4; /** * @title ERC721AC * @author Limit Break, Inc. * @notice Extends Azuki's ERC721-A implementation with Creator Token functionality, which * allows the contract owner to update the transfer validation logic by managing a security policy in * an external transfer validation security policy registry. See {CreatorTokenTransferValidator}. */ abstract contract ERC721AC is ERC721A, CreatorTokenBase { constructor(string memory name_, string memory symbol_) CreatorTokenBase() ERC721A(name_, symbol_) {} function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(ICreatorToken).interfaceId || super.supportsInterface(interfaceId); } /// @dev Ties the erc721a _beforeTokenTransfers hook to more granular transfer validation logic function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual override { for (uint256 i = 0; i < quantity;) { _validateBeforeTransfer(from, to, startTokenId + i); unchecked { ++i; } } } /// @dev Ties the erc721a _afterTokenTransfer hook to more granular transfer validation logic function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual override { for (uint256 i = 0; i < quantity;) { _validateAfterTransfer(from, to, startTokenId + i); unchecked { ++i; } } } function _msgSenderERC721A() internal view virtual override returns (address) { return _msgSender(); } } // File: @openzeppelin/contracts/interfaces/IERC2981.sol // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.20; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. * * NOTE: ERC-2981 allows setting the royalty to 100% of the price. In that case all the price would be sent to the * royalty receiver and 0 tokens to the seller. Contracts dealing with royalty should consider empty transfers. */ function royaltyInfo( uint256 tokenId, uint256 salePrice ) external view returns (address receiver, uint256 royaltyAmount); } // File: @openzeppelin/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: @openzeppelin/contracts/token/common/ERC2981.sol // OpenZeppelin Contracts (last updated v5.1.0) (token/common/ERC2981.sol) pragma solidity ^0.8.20; /** * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information. * * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. * * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the * fee is specified in basis points by default. * * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the ERC. Marketplaces are expected to * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. */ abstract contract ERC2981 is IERC2981, ERC165 { struct RoyaltyInfo { address receiver; uint96 royaltyFraction; } RoyaltyInfo private _defaultRoyaltyInfo; mapping(uint256 tokenId => RoyaltyInfo) private _tokenRoyaltyInfo; /** * @dev The default royalty set is invalid (eg. (numerator / denominator) >= 1). */ error ERC2981InvalidDefaultRoyalty(uint256 numerator, uint256 denominator); /** * @dev The default royalty receiver is invalid. */ error ERC2981InvalidDefaultRoyaltyReceiver(address receiver); /** * @dev The royalty set for an specific `tokenId` is invalid (eg. (numerator / denominator) >= 1). */ error ERC2981InvalidTokenRoyalty(uint256 tokenId, uint256 numerator, uint256 denominator); /** * @dev The royalty receiver for `tokenId` is invalid. */ error ERC2981InvalidTokenRoyaltyReceiver(uint256 tokenId, address receiver); /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); } /** * @inheritdoc IERC2981 */ function royaltyInfo( uint256 tokenId, uint256 salePrice ) public view virtual returns (address receiver, uint256 amount) { RoyaltyInfo storage _royaltyInfo = _tokenRoyaltyInfo[tokenId]; address royaltyReceiver = _royaltyInfo.receiver; uint96 royaltyFraction = _royaltyInfo.royaltyFraction; if (royaltyReceiver == address(0)) { royaltyReceiver = _defaultRoyaltyInfo.receiver; royaltyFraction = _defaultRoyaltyInfo.royaltyFraction; } uint256 royaltyAmount = (salePrice * royaltyFraction) / _feeDenominator(); return (royaltyReceiver, royaltyAmount); } /** * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an * override. */ function _feeDenominator() internal pure virtual returns (uint96) { return 10000; } /** * @dev Sets the royalty information that all ids in this contract will default to. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { uint256 denominator = _feeDenominator(); if (feeNumerator > denominator) { // Royalty fee will exceed the sale price revert ERC2981InvalidDefaultRoyalty(feeNumerator, denominator); } if (receiver == address(0)) { revert ERC2981InvalidDefaultRoyaltyReceiver(address(0)); } _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Removes default royalty information. */ function _deleteDefaultRoyalty() internal virtual { delete _defaultRoyaltyInfo; } /** * @dev Sets the royalty information for a specific token id, overriding the global default. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual { uint256 denominator = _feeDenominator(); if (feeNumerator > denominator) { // Royalty fee will exceed the sale price revert ERC2981InvalidTokenRoyalty(tokenId, feeNumerator, denominator); } if (receiver == address(0)) { revert ERC2981InvalidTokenRoyaltyReceiver(tokenId, address(0)); } _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Resets royalty information for the token id back to the global default. */ function _resetTokenRoyalty(uint256 tokenId) internal virtual { delete _tokenRoyaltyInfo[tokenId]; } } // File: https://github.com/limitbreakinc/creator-token-contracts/blob/main/contracts/programmable-royalties/BasicRoyalties.sol pragma solidity ^0.8.4; /** * @title BasicRoyaltiesBase * @author Limit Break, Inc. * @dev Base functionality of an NFT mix-in contract implementing the most basic form of programmable royalties. */ abstract contract BasicRoyaltiesBase is ERC2981 { event DefaultRoyaltySet(address indexed receiver, uint96 feeNumerator); event TokenRoyaltySet(uint256 indexed tokenId, address indexed receiver, uint96 feeNumerator); function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual override { super._setDefaultRoyalty(receiver, feeNumerator); emit DefaultRoyaltySet(receiver, feeNumerator); } function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual override { super._setTokenRoyalty(tokenId, receiver, feeNumerator); emit TokenRoyaltySet(tokenId, receiver, feeNumerator); } } /** * @title BasicRoyalties * @author Limit Break, Inc. * @notice Constructable BasicRoyalties Contract implementation. */ abstract contract BasicRoyalties is BasicRoyaltiesBase { constructor(address receiver, uint96 feeNumerator) { _setDefaultRoyalty(receiver, feeNumerator); } } /** * @title BasicRoyaltiesInitializable * @author Limit Break, Inc. * @notice Initializable BasicRoyalties Contract implementation to allow for EIP-1167 clones. */ abstract contract BasicRoyaltiesInitializable is BasicRoyaltiesBase {} // File: bruiser.sol /** *Submitted for verification at Etherscan.io on 2024-04-03 */ // File: @openzeppelin/contracts/cryptography/MerkleProof.sol pragma solidity ^0.8.25; // File: @openzeppelin/contracts/utils/math/SignedMath.sol error AlreadyReservedTokens(); error CallerNotOffsetter(); error FunctionLocked(); error InsufficientValue(); error InsufficientMints(); error InsufficientSupply(); error InvalidSignature(); error NoContractMinting(); error ProvenanceHashAlreadySet(); error ProvenanceHashNotSet(); error TokenOffsetAlreadySet(); error TokenOffsetNotSet(); error WithdrawFailed(); interface Offsetable { function setOffset(uint256 randomness) external; } contract Bruiser is ERC721AC, BasicRoyalties, Ownable, OwnableBasic{ using ECDSA for bytes32; string private _baseTokenURI; string public provenanceHash; bool public operatorFilteringEnabled; string public baseExtension = ".json"; uint256 public mintPrice = 0.070 ether; uint256 public constant RESERVED = 12; uint256 startTime; bool minting; mapping(bytes4 => bool) public functionLocked; mapping(address => bool) public minter; constructor(address initialOwner, address royaltyReceiver_, uint96 royaltyFeeNumerator_, address _minter) ERC721AC("Bruiser", "Bruiser") BasicRoyalties(royaltyReceiver_, royaltyFeeNumerator_) Ownable(initialOwner){ minter[_minter] = true; } /** * @notice Modifier applied to functions that will be disabled when they're no longer needed */ modifier lockable() { if (functionLocked[msg.sig]) revert FunctionLocked(); _; } modifier onlyMinter() { require(minter[msg.sender] == true, "You're not a minter"); _; } /** * @notice Mint `RESERVED` amount of tokens to an address * @param to Address to send the reserved tokens */ function reserve(address to) external lockable onlyOwner { if (_totalMinted() >= RESERVED) revert AlreadyReservedTokens(); _mint(to, RESERVED); } function secondaryReserve(address to, uint256 quan) external onlyOwner { _mint(to, quan); } function cardMint(address to, uint256 quan) external onlyMinter { require(minting == true,"Minting is not started yet"); require(block.timestamp <= startTime + 72 hours, "Minting Times up"); _mint(to, quan); } function publicMint(address to, uint256 quantity) external payable { require(minting == true,"Minting is not started yet"); require(block.timestamp <= startTime + 72 hours, "Minting Times up"); uint256 totalCost = quantity * mintPrice; require(msg.value >= totalCost, "Ether sent is not correct."); _mint(to, quantity); if (msg.value > totalCost) { payable(msg.sender).transfer(msg.value - totalCost); } } function setDefaultRoyalty(address receiver, uint96 feeNumerator) public onlyOwner{ _requireCallerIsContractOwner(); _setDefaultRoyalty(receiver, feeNumerator); } function setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) public onlyOwner{ _requireCallerIsContractOwner(); _setTokenRoyalty(tokenId, receiver, feeNumerator); } function enableMint(bool _enable) external onlyOwner{ minting = _enable; startTime = block.timestamp; } function assignMinterRole(address _minter) external onlyOwner { minter[_minter] = true; } function revokeMinterRole(address _minter) external onlyOwner { minter[_minter] = false; } /** * @inheritdoc ERC721AC */ function supportsInterface(bytes4 interfaceId) public view override(ERC721AC, ERC2981) returns (bool) { return ERC721AC.supportsInterface(interfaceId); } /** * @notice Override ERC721AC _baseURI function to use base URI pattern */ function _baseURI() internal view virtual override returns (string memory) { return _baseTokenURI; } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require( _exists(tokenId), "ERC721Metadata: URI query for nonexistent token" ); string memory currentBaseURI = _baseURI(); return bytes(currentBaseURI).length > 0 ? string( abi.encodePacked( currentBaseURI, Strings.toString(tokenId) ) ) : ""; } /** * @notice Return the number of tokens an address has minted * @param account Address to return the number of tokens minted for */ function numberMinted(address account) external view returns (uint256) { return _numberMinted(account); } /** * @notice Lock a function so that it can no longer be called * @dev WARNING: THIS CANNOT BE UNDONE * @param id Function signature */ function lockFunction(bytes4 id) external onlyOwner { functionLocked[id] = true; } /** * @notice Set the state of the OpenSea operator filter * @param value Flag indicating if the operator filter should be applied to transfers and approvals */ function setOperatorFilteringEnabled(bool value) external lockable onlyOwner { operatorFilteringEnabled = value; } /** * @notice Set token metadata base URI * @param _newBaseURI New base URI */ function setBaseURI(string calldata _newBaseURI) external lockable onlyOwner { _baseTokenURI = _newBaseURI; } /** * @notice Set provenance hash for the collection * @param _provenanceHash New hash of the metadata */ function setProvenanceHash(string calldata _provenanceHash) external lockable onlyOwner { if (bytes(provenanceHash).length != 0) revert ProvenanceHashAlreadySet(); provenanceHash = _provenanceHash; } function setMintPrice(uint256 _price) external onlyOwner{ mintPrice = _price; } /** * @notice Withdraw all ETH sent to the contract */ function withdraw() external onlyOwner { (bool success, ) = payable(msg.sender).call{ value: address(this).balance }(""); if (!success) revert WithdrawFailed(); } function setApprovalForAll(address operator, bool approved) public override { super.setApprovalForAll(operator, approved); } function approve(address operator, uint256 tokenId) public payable override { super.approve(operator, tokenId); } function transferFrom( address from, address to, uint256 tokenId ) public payable override { super.transferFrom(from, to, tokenId); } function safeTransferFrom( address from, address to, uint256 tokenId ) public payable override { super.safeTransferFrom(from, to, tokenId); } function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public payable override { super.safeTransferFrom(from, to, tokenId, data); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"initialOwner","type":"address"},{"internalType":"address","name":"royaltyReceiver_","type":"address"},{"internalType":"uint96","name":"royaltyFeeNumerator_","type":"uint96"},{"internalType":"address","name":"_minter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyReservedTokens","type":"error"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"CreatorTokenBase__InvalidTransferValidatorContract","type":"error"},{"inputs":[],"name":"CreatorTokenBase__SetTransferValidatorFirst","type":"error"},{"inputs":[{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidDefaultRoyalty","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidDefaultRoyaltyReceiver","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidTokenRoyalty","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidTokenRoyaltyReceiver","type":"error"},{"inputs":[],"name":"FunctionLocked","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"NotCompatibleWithSpotMints","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"ProvenanceHashAlreadySet","type":"error"},{"inputs":[],"name":"SequentialMintExceedsLimit","type":"error"},{"inputs":[],"name":"SequentialUpToTooSmall","type":"error"},{"inputs":[],"name":"ShouldNotMintToBurnAddress","type":"error"},{"inputs":[],"name":"SpotMintTokenIdTooSmall","type":"error"},{"inputs":[],"name":"TokenAlreadyExists","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"WithdrawFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"DefaultRoyaltySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"TokenRoyaltySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldValidator","type":"address"},{"indexed":false,"internalType":"address","name":"newValidator","type":"address"}],"name":"TransferValidatorUpdated","type":"event"},{"inputs":[],"name":"DEFAULT_OPERATOR_WHITELIST_ID","outputs":[{"internalType":"uint120","name":"","type":"uint120"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_TRANSFER_SECURITY_LEVEL","outputs":[{"internalType":"enum TransferSecurityLevels","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_TRANSFER_VALIDATOR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESERVED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"assignMinterRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"quan","type":"uint256"}],"name":"cardMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enable","type":"bool"}],"name":"enableMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"name":"functionLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPermittedContractReceivers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSecurityPolicy","outputs":[{"components":[{"internalType":"enum TransferSecurityLevels","name":"transferSecurityLevel","type":"uint8"},{"internalType":"uint120","name":"operatorWhitelistId","type":"uint120"},{"internalType":"uint120","name":"permittedContractReceiversId","type":"uint120"}],"internalType":"struct CollectionSecurityPolicy","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTransferValidator","outputs":[{"internalType":"contract ICreatorTokenTransferValidator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWhitelistedOperators","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"isContractReceiverPermitted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"isOperatorWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"isTransferAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"id","type":"bytes4"}],"name":"lockFunction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"minter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operatorFilteringEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"provenanceHash","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"reserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"revokeMinterRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"quan","type":"uint256"}],"name":"secondaryReserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"setOperatorFilteringEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_provenanceHash","type":"string"}],"name":"setProvenanceHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum TransferSecurityLevels","name":"level","type":"uint8"},{"internalType":"uint120","name":"operatorWhitelistId","type":"uint120"},{"internalType":"uint120","name":"permittedContractReceiversAllowlistId","type":"uint120"}],"name":"setToCustomSecurityPolicy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"},{"internalType":"enum TransferSecurityLevels","name":"level","type":"uint8"},{"internalType":"uint120","name":"operatorWhitelistId","type":"uint120"},{"internalType":"uint120","name":"permittedContractReceiversAllowlistId","type":"uint120"}],"name":"setToCustomValidatorAndSecurityPolicy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setToDefaultSecurityPolicy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setTokenRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"transferValidator_","type":"address"}],"name":"setTransferValidator","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":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040526040518060400160405280600581526020017f2e6a736f6e000000000000000000000000000000000000000000000000000000815250601090816100489190610792565b5066f8b0a10e47000060115534801561005f575f80fd5b5060405161661438038061661483398181016040528101906100819190610900565b8383836040518060400160405280600781526020017f42727569736572000000000000000000000000000000000000000000000000008152506040518060400160405280600781526020017f4272756973657200000000000000000000000000000000000000000000000000815250818181600290816101019190610792565b5080600390816101119190610792565b5061012061025260201b60201c565b5f8190555061013361025260201b60201c565b61014161025a60201b60201c565b101561015e5761015d63fed8210f60e01b61028160201b60201c565b5b50505050610172828261028960201b60201c565b50505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101e4575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016101db9190610973565b60405180910390fd5b6101f3816102eb60201b60201c565b50600160155f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050505050610a1a565b5f6001905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b805f5260045ffd5b61029982826103ae60201b60201c565b8173ffffffffffffffffffffffffffffffffffffffff167f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef826040516102df919061099b565b60405180910390a25050565b5f600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600c5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f6103bd61054f60201b60201c565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff1611156104225781816040517f6f483d090000000000000000000000000000000000000000000000000000000081526004016104199291906109f3565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610492575f6040517fb6d9900a0000000000000000000000000000000000000000000000000000000081526004016104899190610973565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff16815250600a5f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b5f612710905090565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806105d357607f821691505b6020821081036105e6576105e561058f565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026106487fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261060d565b610652868361060d565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61069661069161068c8461066a565b610673565b61066a565b9050919050565b5f819050919050565b6106af8361067c565b6106c36106bb8261069d565b848454610619565b825550505050565b5f90565b6106d76106cb565b6106e28184846106a6565b505050565b5b81811015610705576106fa5f826106cf565b6001810190506106e8565b5050565b601f82111561074a5761071b816105ec565b610724846105fe565b81016020851015610733578190505b61074761073f856105fe565b8301826106e7565b50505b505050565b5f82821c905092915050565b5f61076a5f198460080261074f565b1980831691505092915050565b5f610782838361075b565b9150826002028217905092915050565b61079b82610558565b67ffffffffffffffff8111156107b4576107b3610562565b5b6107be82546105bc565b6107c9828285610709565b5f60209050601f8311600181146107fa575f84156107e8578287015190505b6107f28582610777565b865550610859565b601f198416610808866105ec565b5f5b8281101561082f5784890151825560018201915060208501945060208101905061080a565b8683101561084c5784890151610848601f89168261075b565b8355505b6001600288020188555050505b505050505050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61088e82610865565b9050919050565b61089e81610884565b81146108a8575f80fd5b50565b5f815190506108b981610895565b92915050565b5f6bffffffffffffffffffffffff82169050919050565b6108df816108bf565b81146108e9575f80fd5b50565b5f815190506108fa816108d6565b92915050565b5f805f806080858703121561091857610917610861565b5b5f610925878288016108ab565b9450506020610936878288016108ab565b9350506040610947878288016108ec565b9250506060610958878288016108ab565b91505092959194509250565b61096d81610884565b82525050565b5f6020820190506109865f830184610964565b92915050565b610995816108bf565b82525050565b5f6020820190506109ae5f83018461098c565b92915050565b5f6109ce6109c96109c4846108bf565b610673565b61066a565b9050919050565b6109de816109b4565b82525050565b6109ed8161066a565b82525050565b5f604082019050610a065f8301856109d5565b610a1360208301846109e4565b9392505050565b615bed80610a275f395ff3fe60806040526004361061034f575f3560e01c80636c3b8699116101c5578063be537f43116100f6578063dc33e68111610094578063f2fde38b1161006e578063f2fde38b14610bfc578063f4a0a52814610c24578063fb796e6c14610c4c578063fd762d9214610c765761034f565b8063dc33e68114610b5c578063e75179a414610b98578063e985e9c514610bc05761034f565b8063c6ab67a3116100d0578063c6ab67a314610ab0578063c87b56dd14610ada578063ce6df2b914610b16578063d007af5c14610b325761034f565b8063be537f4314610a34578063c668286214610a5e578063c68b330514610a885761034f565b8063a22cb46511610163578063b366d6131161013d578063b366d6131461098c578063b7c0b8e8146109b4578063b88d4fde146109dc578063bbadfe76146109f85761034f565b8063a22cb46514610912578063a9fc664e1461093a578063aa592f25146109625761034f565b806374d0101d1161019f57806374d0101d1461085a5780638da5cb5b1461088257806395d89b41146108ac5780639d645a44146108d65761034f565b80636c3b8699146107f257806370a0823114610808578063715018a6146108445761034f565b80632e8da8291161029f57806355f804b31161023d5780636134716211610217578063613471621461073c5780636352211e146107645780636817c76c146107a057806369e2f0fb146107ca5761034f565b806355f804b3146106c25780635944c753146106ea5780635d4c1d46146107125761034f565b80633dd08c38116102795780633dd08c381461061857806342842e0e14610654578063495c8bf9146106705780634f9d2c0c1461069a5761034f565b80632e8da8291461059e57806334531828146105da5780633ccfd60b146106025761034f565b8063098144d41161030c5780631b25b077116102e65780631b25b077146104df5780631c33b3281461051b57806323b872dd146105455780632a55205a146105615761034f565b8063098144d414610463578063109695231461048d57806318160ddd146104b55761034f565b8063014635461461035357806301ffc9a71461037d57806304634d8d146103b957806306fdde03146103e1578063081812fc1461040b578063095ea7b314610447575b5f80fd5b34801561035e575f80fd5b50610367610c9e565b60405161037491906144fa565b60405180910390f35b348015610388575f80fd5b506103a3600480360381019061039e9190614579565b610cb4565b6040516103b091906145be565b60405180910390f35b3480156103c4575f80fd5b506103df60048036038101906103da9190614642565b610cc5565b005b3480156103ec575f80fd5b506103f5610ce3565b60405161040291906146f0565b60405180910390f35b348015610416575f80fd5b50610431600480360381019061042c9190614743565b610d73565b60405161043e91906144fa565b60405180910390f35b610461600480360381019061045c919061476e565b610dcc565b005b34801561046e575f80fd5b50610477610dda565b6040516104849190614807565b60405180910390f35b348015610498575f80fd5b506104b360048036038101906104ae9190614881565b610e02565b005b3480156104c0575f80fd5b506104c9610f1d565b6040516104d691906148db565b60405180910390f35b3480156104ea575f80fd5b50610505600480360381019061050091906148f4565b610f68565b60405161051291906145be565b60405180910390f35b348015610526575f80fd5b5061052f611063565b60405161053c91906149b7565b60405180910390f35b61055f600480360381019061055a91906149d0565b611068565b005b34801561056c575f80fd5b5061058760048036038101906105829190614a20565b611078565b604051610595929190614a5e565b60405180910390f35b3480156105a9575f80fd5b506105c460048036038101906105bf9190614a85565b61119a565b6040516105d191906145be565b60405180910390f35b3480156105e5575f80fd5b5061060060048036038101906105fb9190614579565b611336565b005b34801561060d575f80fd5b506106166113a8565b005b348015610623575f80fd5b5061063e60048036038101906106399190614a85565b611452565b60405161064b91906145be565b60405180910390f35b61066e600480360381019061066991906149d0565b61146f565b005b34801561067b575f80fd5b5061068461147f565b6040516106919190614b67565b60405180910390f35b3480156106a5575f80fd5b506106c060048036038101906106bb919061476e565b611663565b005b3480156106cd575f80fd5b506106e860048036038101906106e39190614881565b6117a9565b005b3480156106f5575f80fd5b50610710600480360381019061070b9190614b87565b61187d565b005b34801561071d575f80fd5b5061072661189d565b6040516107339190614c00565b60405180910390f35b348015610747575f80fd5b50610762600480360381019061075d9190614c66565b6118a2565b005b34801561076f575f80fd5b5061078a60048036038101906107859190614743565b611a58565b60405161079791906144fa565b60405180910390f35b3480156107ab575f80fd5b506107b4611a69565b6040516107c191906148db565b60405180910390f35b3480156107d5575f80fd5b506107f060048036038101906107eb9190614a85565b611a6f565b005b3480156107fd575f80fd5b50610806611ace565b005b348015610813575f80fd5b5061082e60048036038101906108299190614a85565b611be9565b60405161083b91906148db565b60405180910390f35b34801561084f575f80fd5b50610858611c7d565b005b348015610865575f80fd5b50610880600480360381019061087b919061476e565b611c90565b005b34801561088d575f80fd5b50610896611ca6565b6040516108a391906144fa565b60405180910390f35b3480156108b7575f80fd5b506108c0611cce565b6040516108cd91906146f0565b60405180910390f35b3480156108e1575f80fd5b506108fc60048036038101906108f79190614a85565b611d5e565b60405161090991906145be565b60405180910390f35b34801561091d575f80fd5b5061093860048036038101906109339190614ce0565b611efa565b005b348015610945575f80fd5b50610960600480360381019061095b9190614a85565b611f08565b005b34801561096d575f80fd5b506109766120bd565b60405161098391906148db565b60405180910390f35b348015610997575f80fd5b506109b260048036038101906109ad9190614a85565b6120c2565b005b3480156109bf575f80fd5b506109da60048036038101906109d59190614d1e565b612122565b005b6109f660048036038101906109f19190614e71565b6121fc565b005b348015610a03575f80fd5b50610a1e6004803603810190610a199190614579565b61220e565b604051610a2b91906145be565b60405180910390f35b348015610a3f575f80fd5b50610a4861222b565b604051610a559190614f4f565b60405180910390f35b348015610a69575f80fd5b50610a7261237c565b604051610a7f91906146f0565b60405180910390f35b348015610a93575f80fd5b50610aae6004803603810190610aa99190614d1e565b612408565b005b348015610abb575f80fd5b50610ac4612433565b604051610ad191906146f0565b60405180910390f35b348015610ae5575f80fd5b50610b006004803603810190610afb9190614743565b6124bf565b604051610b0d91906146f0565b60405180910390f35b610b306004803603810190610b2b919061476e565b612563565b005b348015610b3d575f80fd5b50610b466126c6565b604051610b539190614b67565b60405180910390f35b348015610b67575f80fd5b50610b826004803603810190610b7d9190614a85565b6128aa565b604051610b8f91906148db565b60405180910390f35b348015610ba3575f80fd5b50610bbe6004803603810190610bb99190614a85565b6128bb565b005b348015610bcb575f80fd5b50610be66004803603810190610be19190614f68565b6129c8565b604051610bf391906145be565b60405180910390f35b348015610c07575f80fd5b50610c226004803603810190610c1d9190614a85565b612a56565b005b348015610c2f575f80fd5b50610c4a6004803603810190610c459190614743565b612ada565b005b348015610c57575f80fd5b50610c60612aec565b604051610c6d91906145be565b60405180910390f35b348015610c81575f80fd5b50610c9c6004803603810190610c979190614fa6565b612afe565b005b71721c310194ccfc01e523fc93c9cccfa2a0ac81565b5f610cbe82612c4d565b9050919050565b610ccd612cc6565b610cd5612d4d565b610cdf8282612d57565b5050565b606060028054610cf290615037565b80601f0160208091040260200160405190810160405280929190818152602001828054610d1e90615037565b8015610d695780601f10610d4057610100808354040283529160200191610d69565b820191905f5260205f20905b815481529060010190602001808311610d4c57829003601f168201915b5050505050905090565b5f610d7d82612db3565b610d9257610d9163cf4700e460e01b612e56565b5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610dd68282612e5e565b5050565b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60145f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff1615610eb8576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ec0612cc6565b5f600e8054610ece90615037565b905014610f07576040517f19e24c1100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181600e9182610f18929190615205565b505050565b5f610f26612e6e565b6001545f54030390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610f58612e76565b14610f6557600854810190505b90565b5f8073ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146110575760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663285fb8c88585856040518463ffffffff1660e01b815260040161101b939291906152d2565b5f6040518083038186803b158015611031575f80fd5b505afa925050508015611042575060015b61104e575f905061105c565b6001905061105c565b600190505b9392505050565b600181565b611073838383612e9d565b505050565b5f805f600b5f8681526020019081526020015f2090505f815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f825f0160149054906101000a90046bffffffffffffffffffffffff1690505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361114c57600a5f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169150600a5f0160149054906101000a90046bffffffffffffffffffffffff1690505b5f611155613148565b6bffffffffffffffffffffffff16826bffffffffffffffffffffffff168861117d9190615334565b61118791906153a2565b9050828195509550505050509250929050565b5f8073ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461132d5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d72dde5e60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b815260040161128691906144fa565b606060405180830381865afa1580156112a1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112c5919061545f565b60200151846040518363ffffffff1660e01b81526004016112e792919061548a565b602060405180830381865afa158015611302573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061132691906154c5565b9050611331565b5f90505b919050565b61133e612cc6565b600160145f837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b6113b0612cc6565b5f3373ffffffffffffffffffffffffffffffffffffffff16476040516113d59061551d565b5f6040518083038185875af1925050503d805f811461140f576040519150601f19603f3d011682016040523d82523d5f602084013e611414565b606091505b505090508061144f576040517f750b219c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b6015602052805f5260405f205f915054906101000a900460ff1681565b61147a838383613151565b505050565b60605f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146116145760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633fe5df9960095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b815260040161156c91906144fa565b606060405180830381865afa158015611587573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115ab919061545f565b602001516040518263ffffffff1660e01b81526004016115cb9190614c00565b5f60405180830381865afa1580156115e5573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061160d9190615605565b9050611660565b5f67ffffffffffffffff81111561162e5761162d614d4d565b5b60405190808252806020026020018201604052801561165c5781602001602082028036833780820191505090505b5090505b90565b6001151560155f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff161515146116f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ea90615696565b60405180910390fd5b6001151560135f9054906101000a900460ff16151514611748576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161173f906156fe565b60405180910390fd5b6203f480601254611759919061571c565b42111561179b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161179290615799565b60405180910390fd5b6117a58282613170565b5050565b60145f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff161561185f576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611867612cc6565b8181600d9182611878929190615205565b505050565b611885612cc6565b61188d612d4d565b6118988383836132e4565b505050565b600181565b6118aa612d4d565b5f6118b3610dda565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361191a576040517f39ffc7ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663da0194c030866040518363ffffffff1660e01b81526004016119559291906157b7565b5f604051808303815f87803b15801561196c575f80fd5b505af115801561197e573d5f803e3d5ffd5b505050508073ffffffffffffffffffffffffffffffffffffffff16632304aa0230856040518363ffffffff1660e01b81526004016119bd9291906157de565b5f604051808303815f87803b1580156119d4575f80fd5b505af11580156119e6573d5f803e3d5ffd5b505050508073ffffffffffffffffffffffffffffffffffffffff16638d74431430846040518363ffffffff1660e01b8152600401611a259291906157de565b5f604051808303815f87803b158015611a3c575f80fd5b505af1158015611a4e573d5f803e3d5ffd5b5050505050505050565b5f611a6282613343565b9050919050565b60115481565b611a77612cc6565b5f60155f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b611ad6612d4d565b611af171721c310194ccfc01e523fc93c9cccfa2a0ac611f08565b71721c310194ccfc01e523fc93c9cccfa2a0ac73ffffffffffffffffffffffffffffffffffffffff1663da0194c03060016040518363ffffffff1660e01b8152600401611b3f9291906157b7565b5f604051808303815f87803b158015611b56575f80fd5b505af1158015611b68573d5f803e3d5ffd5b5050505071721c310194ccfc01e523fc93c9cccfa2a0ac73ffffffffffffffffffffffffffffffffffffffff16632304aa023060016040518363ffffffff1660e01b8152600401611bba9291906157de565b5f604051808303815f87803b158015611bd1575f80fd5b505af1158015611be3573d5f803e3d5ffd5b50505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611c2e57611c2d638f4eb60460e01b612e56565b5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b611c85612cc6565b611c8e5f613452565b565b611c98612cc6565b611ca28282613170565b5050565b5f600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054611cdd90615037565b80601f0160208091040260200160405190810160405280929190818152602001828054611d0990615037565b8015611d545780601f10611d2b57610100808354040283529160200191611d54565b820191905f5260205f20905b815481529060010190602001808311611d3757829003601f168201915b5050505050905090565b5f8073ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611ef15760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639445f53060095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b8152600401611e4a91906144fa565b606060405180830381865afa158015611e65573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e89919061545f565b60400151846040518363ffffffff1660e01b8152600401611eab92919061548a565b602060405180830381865afa158015611ec6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611eea91906154c5565b9050611ef5565b5f90505b919050565b611f048282613515565b5050565b611f10612d4d565b5f808273ffffffffffffffffffffffffffffffffffffffff163b1115611fae578173ffffffffffffffffffffffffffffffffffffffff166301ffc9a75f6040518263ffffffff1660e01b8152600401611f699190615814565b602060405180830381865afa925050508015611fa357506040513d601f19601f82011682018060405250810190611fa091906154c5565b60015b15611fad57809150505b5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611fe8575080155b1561201f576040517f32483afb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff168360405161207192919061582d565b60405180910390a18160095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600c81565b6120ca612cc6565b600160155f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b60145f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff16156121d8576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6121e0612cc6565b80600f5f6101000a81548160ff02191690831515021790555050565b6122088484848461361b565b50505050565b6014602052805f5260405f205f915054906101000a900460ff1681565b612233614469565b5f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146123275760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b81526004016122e191906144fa565b606060405180830381865afa1580156122fc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612320919061545f565b9050612379565b60405180606001604052805f600681111561234557612344614944565b5b81526020015f6effffffffffffffffffffffffffffff1681526020015f6effffffffffffffffffffffffffffff1681525090505b90565b6010805461238990615037565b80601f01602080910402602001604051908101604052809291908181526020018280546123b590615037565b80156124005780601f106123d757610100808354040283529160200191612400565b820191905f5260205f20905b8154815290600101906020018083116123e357829003601f168201915b505050505081565b612410612cc6565b8060135f6101000a81548160ff0219169083151502179055504260128190555050565b600e805461244090615037565b80601f016020809104026020016040519081016040528092919081815260200182805461246c90615037565b80156124b75780601f1061248e576101008083540402835291602001916124b7565b820191905f5260205f20905b81548152906001019060200180831161249a57829003601f168201915b505050505081565b60606124ca82612db3565b612509576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612500906158c4565b60405180910390fd5b5f61251261366c565b90505f8151116125305760405180602001604052805f81525061255b565b8061253a846136fc565b60405160200161254b92919061591c565b6040516020818303038152906040525b915050919050565b6001151560135f9054906101000a900460ff161515146125b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125af906156fe565b60405180910390fd5b6203f4806012546125c9919061571c565b42111561260b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161260290615799565b60405180910390fd5b5f6011548261261a9190615334565b90508034101561265f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161265690615989565b60405180910390fd5b6126698383613170565b803411156126c1573373ffffffffffffffffffffffffffffffffffffffff166108fc823461269791906159a7565b90811502906040515f60405180830381858888f193505050501580156126bf573d5f803e3d5ffd5b505b505050565b60605f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461285b5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166317e94a6c60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b81526004016127b391906144fa565b606060405180830381865afa1580156127ce573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127f2919061545f565b604001516040518263ffffffff1660e01b81526004016128129190614c00565b5f60405180830381865afa15801561282c573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906128549190615605565b90506128a7565b5f67ffffffffffffffff81111561287557612874614d4d565b5b6040519080825280602002602001820160405280156128a35781602001602082028036833780820191505090505b5090505b90565b5f6128b4826137c6565b9050919050565b60145f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff1615612971576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612979612cc6565b600c61298361381a565b106129ba576040517f1f0f14ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129c581600c613170565b50565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b612a5e612cc6565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612ace575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401612ac591906144fa565b60405180910390fd5b612ad781613452565b50565b612ae2612cc6565b8060118190555050565b600f5f9054906101000a900460ff1681565b612b06612d4d565b612b0f84611f08565b8373ffffffffffffffffffffffffffffffffffffffff1663da0194c030856040518363ffffffff1660e01b8152600401612b4a9291906157b7565b5f604051808303815f87803b158015612b61575f80fd5b505af1158015612b73573d5f803e3d5ffd5b505050508373ffffffffffffffffffffffffffffffffffffffff16632304aa0230846040518363ffffffff1660e01b8152600401612bb29291906157de565b5f604051808303815f87803b158015612bc9575f80fd5b505af1158015612bdb573d5f803e3d5ffd5b505050508373ffffffffffffffffffffffffffffffffffffffff16638d74431430836040518363ffffffff1660e01b8152600401612c1a9291906157de565b5f604051808303815f87803b158015612c31575f80fd5b505af1158015612c43573d5f803e3d5ffd5b5050505050505050565b5f7f86455d28000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612cbf5750612cbe82613861565b5b9050919050565b612cce6138f2565b73ffffffffffffffffffffffffffffffffffffffff16612cec611ca6565b73ffffffffffffffffffffffffffffffffffffffff1614612d4b57612d0f6138f2565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401612d4291906144fa565b60405180910390fd5b565b612d55612cc6565b565b612d6182826138f9565b8173ffffffffffffffffffffffffffffffffffffffff167f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef82604051612da791906159e9565b60405180910390a25050565b5f81612dbd612e6e565b11612e5057612dca612e76565b821115612df257612deb60045f8481526020019081526020015f2054613a94565b9050612e51565b5f54821015612e4f575f5b5f60045f8581526020019081526020015f205491508103612e295782612e2290615a02565b9250612dfd565b5f7c01000000000000000000000000000000000000000000000000000000008216149150505b5b5b919050565b805f5260045ffd5b612e6a82826001613ad4565b5050565b5f6001905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b5f612ea782613343565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612f1c57612f1b63a114810060e01b612e56565b5b5f80612f2784613bfe565b91509150612f3d8187612f38613c21565b613c2f565b612f6857612f5286612f4d613c21565b6129c8565b612f6757612f666359c896be60e01b612e56565b5b5b612f758686866001613c72565b8015612f7f575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f81546001019190508190555061304785613023888887613ca4565b7c020000000000000000000000000000000000000000000000000000000017613ccb565b60045f8681526020019081526020015f20819055505f7c02000000000000000000000000000000000000000000000000000000008416036130c3575f6001850190505f60045f8381526020019081526020015f2054036130c1575f5481146130c0578360045f8381526020019081526020015f20819055505b5b505b5f73ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45f81036131325761313163ea553b3460e01b612e56565b5b61313f8787876001613cf5565b50505050505050565b5f612710905090565b61316b83838360405180602001604052805f8152506121fc565b505050565b5f805490505f820361318d5761318c63b562e8dd60e01b612e56565b5b6131995f848385613c72565b6131b7836131a85f865f613ca4565b6131b185613d27565b17613ccb565b60045f8381526020019081526020015f2081905550600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505f73ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161690505f810361326857613267632e07630060e01b612e56565b5b5f83830190505f83905061327a612e76565b600183031115613295576132946381647e3a60e01b612e56565b5b5b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a481816001019150810361329657815f819055505050506132df5f848385613cf5565b505050565b6132ef838383613d36565b8173ffffffffffffffffffffffffffffffffffffffff16837f7f5b076c952c0ec86e5425963c1326dd0f03a3595c19f81d765e8ff559a6e33c8360405161333691906159e9565b60405180910390a3505050565b5f8161334d612e6e565b1161343c5760045f8381526020019081526020015f2054905061336e612e76565b8211156133935761337e81613a94565b61344d5761339263df2d9b4260e01b612e56565b5b5f8103613414575f5482106133b3576133b263df2d9b4260e01b612e56565b5b5b60045f836001900393508381526020019081526020015f205490505f81031561340f575f7c01000000000000000000000000000000000000000000000000000000008216031561344d5761340e63df2d9b4260e01b612e56565b5b6133b4565b5f7c01000000000000000000000000000000000000000000000000000000008216031561344d575b61344c63df2d9b4260e01b612e56565b5b919050565b5f600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600c5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8060075f613521613c21565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166135ca613c21565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161360f91906145be565b60405180910390a35050565b613626848484611068565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146136665761365084848484613ee5565b6136655761366463d1a57ed660e01b612e56565b5b5b50505050565b6060600d805461367b90615037565b80601f01602080910402602001604051908101604052809291908181526020018280546136a790615037565b80156136f25780601f106136c9576101008083540402835291602001916136f2565b820191905f5260205f20905b8154815290600101906020018083116136d557829003601f168201915b5050505050905090565b60605f600161370a8461400f565b0190505f8167ffffffffffffffff81111561372857613727614d4d565b5b6040519080825280601f01601f19166020018201604052801561375a5781602001600182028036833780820191505090505b5090505f82602001820190505b6001156137bb578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816137b0576137af615375565b5b0494505f8503613767575b819350505050919050565b5f67ffffffffffffffff604060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054901c169050919050565b5f613823612e6e565b5f540390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff613851612e76565b1461385e57600854810190505b90565b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806138bb57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806138eb5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b5f33905090565b5f613902613148565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff1611156139675781816040517f6f483d0900000000000000000000000000000000000000000000000000000000815260040161395e929190615a59565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036139d7575f6040517fb6d9900a0000000000000000000000000000000000000000000000000000000081526004016139ce91906144fa565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff16815250600a5f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b5f7c0100000000000000000000000000000000000000000000000000000000821673ffffffffffffffffffffffffffffffffffffffff8316119050919050565b5f613ade83611a58565b9050818015613b2057508073ffffffffffffffffffffffffffffffffffffffff16613b07613c21565b73ffffffffffffffffffffffffffffffffffffffff1614155b15613b4c57613b3681613b31613c21565b6129c8565b613b4b57613b4a63cfb3b94260e01b612e56565b5b5b8360065f8581526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f613c2a6138f2565b905090565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b5f5b81811015613c9d57613c9285858386613c8d919061571c565b614160565b806001019050613c74565b5050505050565b5f8060e883901c905060e8613cba86868461425e565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b5f5b81811015613d2057613d1585858386613d10919061571c565b614266565b806001019050613cf7565b5050505050565b5f6001821460e11b9050919050565b5f613d3f613148565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff161115613da6578382826040517fdfd1fc1b000000000000000000000000000000000000000000000000000000008152600401613d9d93929190615a80565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603613e1857835f6040517f969f0852000000000000000000000000000000000000000000000000000000008152600401613e0f929190615ab5565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff16815250600b5f8681526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555090505050505050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613f0a613c21565b8786866040518563ffffffff1660e01b8152600401613f2c9493929190615b2e565b6020604051808303815f875af1925050508015613f6757506040513d601f19601f82011682018060405250810190613f649190615b8c565b60015b613fbc573d805f8114613f95576040519150601f19603f3d011682016040523d82523d5f602084013e613f9a565b606091505b505f815103613fb457613fb363d1a57ed660e01b612e56565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061406b577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161406157614060615375565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106140a8576d04ee2d6d415b85acef8100000000838161409e5761409d615375565b5b0492506020810190505b662386f26fc1000083106140d757662386f26fc1000083816140cd576140cc615375565b5b0492506010810190505b6305f5e1008310614100576305f5e10083816140f6576140f5615375565b5b0492506008810190505b612710831061412557612710838161411b5761411a615375565b5b0492506004810190505b60648310614148576064838161413e5761413d615375565b5b0492506002810190505b600a8310614157576001810190505b80915050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490505f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490508180156141ce5750805b15614205576040517f5cbd944100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81156142235761421e6142166138f2565b858534614364565b614257565b80156142415761423c6142346138f2565b86853461436a565b614256565b61425561424c6138f2565b86868634614370565b5b5b5050505050565b5f9392505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490505f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490508180156142d45750805b1561430b576040517f5cbd944100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81156143295761432461431c6138f2565b858534614456565b61435d565b80156143475761434261433a6138f2565b86853461445c565b61435c565b61435b6143526138f2565b86868634614462565b5b5b5050505050565b50505050565b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461444f5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663285fb8c88686866040518463ffffffff1660e01b8152600401614422939291906152d2565b5f6040518083038186803b158015614438575f80fd5b505afa15801561444a573d5f803e3d5ffd5b505050505b5050505050565b50505050565b50505050565b5050505050565b60405180606001604052805f600681111561448757614486614944565b5b81526020015f6effffffffffffffffffffffffffffff1681526020015f6effffffffffffffffffffffffffffff1681525090565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6144e4826144bb565b9050919050565b6144f4816144da565b82525050565b5f60208201905061450d5f8301846144eb565b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61455881614524565b8114614562575f80fd5b50565b5f813590506145738161454f565b92915050565b5f6020828403121561458e5761458d61451c565b5b5f61459b84828501614565565b91505092915050565b5f8115159050919050565b6145b8816145a4565b82525050565b5f6020820190506145d15f8301846145af565b92915050565b6145e0816144da565b81146145ea575f80fd5b50565b5f813590506145fb816145d7565b92915050565b5f6bffffffffffffffffffffffff82169050919050565b61462181614601565b811461462b575f80fd5b50565b5f8135905061463c81614618565b92915050565b5f80604083850312156146585761465761451c565b5b5f614665858286016145ed565b92505060206146768582860161462e565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6146c282614680565b6146cc818561468a565b93506146dc81856020860161469a565b6146e5816146a8565b840191505092915050565b5f6020820190508181035f83015261470881846146b8565b905092915050565b5f819050919050565b61472281614710565b811461472c575f80fd5b50565b5f8135905061473d81614719565b92915050565b5f602082840312156147585761475761451c565b5b5f6147658482850161472f565b91505092915050565b5f80604083850312156147845761478361451c565b5b5f614791858286016145ed565b92505060206147a28582860161472f565b9150509250929050565b5f819050919050565b5f6147cf6147ca6147c5846144bb565b6147ac565b6144bb565b9050919050565b5f6147e0826147b5565b9050919050565b5f6147f1826147d6565b9050919050565b614801816147e7565b82525050565b5f60208201905061481a5f8301846147f8565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261484157614840614820565b5b8235905067ffffffffffffffff81111561485e5761485d614824565b5b60208301915083600182028301111561487a57614879614828565b5b9250929050565b5f80602083850312156148975761489661451c565b5b5f83013567ffffffffffffffff8111156148b4576148b3614520565b5b6148c08582860161482c565b92509250509250929050565b6148d581614710565b82525050565b5f6020820190506148ee5f8301846148cc565b92915050565b5f805f6060848603121561490b5761490a61451c565b5b5f614918868287016145ed565b9350506020614929868287016145ed565b925050604061493a868287016145ed565b9150509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b6007811061498257614981614944565b5b50565b5f81905061499282614971565b919050565b5f6149a182614985565b9050919050565b6149b181614997565b82525050565b5f6020820190506149ca5f8301846149a8565b92915050565b5f805f606084860312156149e7576149e661451c565b5b5f6149f4868287016145ed565b9350506020614a05868287016145ed565b9250506040614a168682870161472f565b9150509250925092565b5f8060408385031215614a3657614a3561451c565b5b5f614a438582860161472f565b9250506020614a548582860161472f565b9150509250929050565b5f604082019050614a715f8301856144eb565b614a7e60208301846148cc565b9392505050565b5f60208284031215614a9a57614a9961451c565b5b5f614aa7848285016145ed565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b614ae2816144da565b82525050565b5f614af38383614ad9565b60208301905092915050565b5f602082019050919050565b5f614b1582614ab0565b614b1f8185614aba565b9350614b2a83614aca565b805f5b83811015614b5a578151614b418882614ae8565b9750614b4c83614aff565b925050600181019050614b2d565b5085935050505092915050565b5f6020820190508181035f830152614b7f8184614b0b565b905092915050565b5f805f60608486031215614b9e57614b9d61451c565b5b5f614bab8682870161472f565b9350506020614bbc868287016145ed565b9250506040614bcd8682870161462e565b9150509250925092565b5f6effffffffffffffffffffffffffffff82169050919050565b614bfa81614bd7565b82525050565b5f602082019050614c135f830184614bf1565b92915050565b60078110614c25575f80fd5b50565b5f81359050614c3681614c19565b92915050565b614c4581614bd7565b8114614c4f575f80fd5b50565b5f81359050614c6081614c3c565b92915050565b5f805f60608486031215614c7d57614c7c61451c565b5b5f614c8a86828701614c28565b9350506020614c9b86828701614c52565b9250506040614cac86828701614c52565b9150509250925092565b614cbf816145a4565b8114614cc9575f80fd5b50565b5f81359050614cda81614cb6565b92915050565b5f8060408385031215614cf657614cf561451c565b5b5f614d03858286016145ed565b9250506020614d1485828601614ccc565b9150509250929050565b5f60208284031215614d3357614d3261451c565b5b5f614d4084828501614ccc565b91505092915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b614d83826146a8565b810181811067ffffffffffffffff82111715614da257614da1614d4d565b5b80604052505050565b5f614db4614513565b9050614dc08282614d7a565b919050565b5f67ffffffffffffffff821115614ddf57614dde614d4d565b5b614de8826146a8565b9050602081019050919050565b828183375f83830152505050565b5f614e15614e1084614dc5565b614dab565b905082815260208101848484011115614e3157614e30614d49565b5b614e3c848285614df5565b509392505050565b5f82601f830112614e5857614e57614820565b5b8135614e68848260208601614e03565b91505092915050565b5f805f8060808587031215614e8957614e8861451c565b5b5f614e96878288016145ed565b9450506020614ea7878288016145ed565b9350506040614eb88782880161472f565b925050606085013567ffffffffffffffff811115614ed957614ed8614520565b5b614ee587828801614e44565b91505092959194509250565b614efa81614997565b82525050565b614f0981614bd7565b82525050565b606082015f820151614f235f850182614ef1565b506020820151614f366020850182614f00565b506040820151614f496040850182614f00565b50505050565b5f606082019050614f625f830184614f0f565b92915050565b5f8060408385031215614f7e57614f7d61451c565b5b5f614f8b858286016145ed565b9250506020614f9c858286016145ed565b9150509250929050565b5f805f8060808587031215614fbe57614fbd61451c565b5b5f614fcb878288016145ed565b9450506020614fdc87828801614c28565b9350506040614fed87828801614c52565b9250506060614ffe87828801614c52565b91505092959194509250565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061504e57607f821691505b6020821081036150615761506061500a565b5b50919050565b5f82905092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026150cd7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82615092565b6150d78683615092565b95508019841693508086168417925050509392505050565b5f6151096151046150ff84614710565b6147ac565b614710565b9050919050565b5f819050919050565b615122836150ef565b61513661512e82615110565b84845461509e565b825550505050565b5f90565b61514a61513e565b615155818484615119565b505050565b5b818110156151785761516d5f82615142565b60018101905061515b565b5050565b601f8211156151bd5761518e81615071565b61519784615083565b810160208510156151a6578190505b6151ba6151b285615083565b83018261515a565b50505b505050565b5f82821c905092915050565b5f6151dd5f19846008026151c2565b1980831691505092915050565b5f6151f583836151ce565b9150826002028217905092915050565b61520f8383615067565b67ffffffffffffffff81111561522857615227614d4d565b5b6152328254615037565b61523d82828561517c565b5f601f83116001811461526a575f8415615258578287013590505b61526285826151ea565b8655506152c9565b601f19841661527886615071565b5f5b8281101561529f5784890135825560018201915060208501945060208101905061527a565b868310156152bc57848901356152b8601f8916826151ce565b8355505b6001600288020188555050505b50505050505050565b5f6060820190506152e55f8301866144eb565b6152f260208301856144eb565b6152ff60408301846144eb565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61533e82614710565b915061534983614710565b925082820261535781614710565b9150828204841483151761536e5761536d615307565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6153ac82614710565b91506153b783614710565b9250826153c7576153c6615375565b5b828204905092915050565b5f80fd5b5f815190506153e481614c19565b92915050565b5f815190506153f881614c3c565b92915050565b5f60608284031215615413576154126153d2565b5b61541d6060614dab565b90505f61542c848285016153d6565b5f83015250602061543f848285016153ea565b6020830152506040615453848285016153ea565b60408301525092915050565b5f606082840312156154745761547361451c565b5b5f615481848285016153fe565b91505092915050565b5f60408201905061549d5f830185614bf1565b6154aa60208301846144eb565b9392505050565b5f815190506154bf81614cb6565b92915050565b5f602082840312156154da576154d961451c565b5b5f6154e7848285016154b1565b91505092915050565b5f81905092915050565b50565b5f6155085f836154f0565b9150615513826154fa565b5f82019050919050565b5f615527826154fd565b9150819050919050565b5f67ffffffffffffffff82111561554b5761554a614d4d565b5b602082029050602081019050919050565b5f8151905061556a816145d7565b92915050565b5f61558261557d84615531565b614dab565b905080838252602082019050602084028301858111156155a5576155a4614828565b5b835b818110156155ce57806155ba888261555c565b8452602084019350506020810190506155a7565b5050509392505050565b5f82601f8301126155ec576155eb614820565b5b81516155fc848260208601615570565b91505092915050565b5f6020828403121561561a5761561961451c565b5b5f82015167ffffffffffffffff81111561563757615636614520565b5b615643848285016155d8565b91505092915050565b7f596f75277265206e6f742061206d696e746572000000000000000000000000005f82015250565b5f61568060138361468a565b915061568b8261564c565b602082019050919050565b5f6020820190508181035f8301526156ad81615674565b9050919050565b7f4d696e74696e67206973206e6f742073746172746564207965740000000000005f82015250565b5f6156e8601a8361468a565b91506156f3826156b4565b602082019050919050565b5f6020820190508181035f830152615715816156dc565b9050919050565b5f61572682614710565b915061573183614710565b925082820190508082111561574957615748615307565b5b92915050565b7f4d696e74696e672054696d6573207570000000000000000000000000000000005f82015250565b5f61578360108361468a565b915061578e8261574f565b602082019050919050565b5f6020820190508181035f8301526157b081615777565b9050919050565b5f6040820190506157ca5f8301856144eb565b6157d760208301846149a8565b9392505050565b5f6040820190506157f15f8301856144eb565b6157fe6020830184614bf1565b9392505050565b61580e81614524565b82525050565b5f6020820190506158275f830184615805565b92915050565b5f6040820190506158405f8301856144eb565b61584d60208301846144eb565b9392505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f5f8201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b5f6158ae602f8361468a565b91506158b982615854565b604082019050919050565b5f6020820190508181035f8301526158db816158a2565b9050919050565b5f81905092915050565b5f6158f682614680565b61590081856158e2565b935061591081856020860161469a565b80840191505092915050565b5f61592782856158ec565b915061593382846158ec565b91508190509392505050565b7f45746865722073656e74206973206e6f7420636f72726563742e0000000000005f82015250565b5f615973601a8361468a565b915061597e8261593f565b602082019050919050565b5f6020820190508181035f8301526159a081615967565b9050919050565b5f6159b182614710565b91506159bc83614710565b92508282039050818111156159d4576159d3615307565b5b92915050565b6159e381614601565b82525050565b5f6020820190506159fc5f8301846159da565b92915050565b5f615a0c82614710565b91505f8203615a1e57615a1d615307565b5b600182039050919050565b5f615a43615a3e615a3984614601565b6147ac565b614710565b9050919050565b615a5381615a29565b82525050565b5f604082019050615a6c5f830185615a4a565b615a7960208301846148cc565b9392505050565b5f606082019050615a935f8301866148cc565b615aa06020830185615a4a565b615aad60408301846148cc565b949350505050565b5f604082019050615ac85f8301856148cc565b615ad560208301846144eb565b9392505050565b5f81519050919050565b5f82825260208201905092915050565b5f615b0082615adc565b615b0a8185615ae6565b9350615b1a81856020860161469a565b615b23816146a8565b840191505092915050565b5f608082019050615b415f8301876144eb565b615b4e60208301866144eb565b615b5b60408301856148cc565b8181036060830152615b6d8184615af6565b905095945050505050565b5f81519050615b868161454f565b92915050565b5f60208284031215615ba157615ba061451c565b5b5f615bae84828501615b78565b9150509291505056fea2646970667358221220a3a1b43c38efa8d75ff9019a44c19fe687dd278e6a1faef7bfa1281bca6f66b764736f6c634300081a003300000000000000000000000059de7273191e6bf1907d614e94ecfbe8e5fb73180000000000000000000000000116991b4edf3d88a9db4850b2c9fc5a326b14b500000000000000000000000000000000000000000000000000000000000001f40000000000000000000000003bdc72443bd7fe4ab1ecbbfe04389e3b4197941b
Deployed Bytecode
0x60806040526004361061034f575f3560e01c80636c3b8699116101c5578063be537f43116100f6578063dc33e68111610094578063f2fde38b1161006e578063f2fde38b14610bfc578063f4a0a52814610c24578063fb796e6c14610c4c578063fd762d9214610c765761034f565b8063dc33e68114610b5c578063e75179a414610b98578063e985e9c514610bc05761034f565b8063c6ab67a3116100d0578063c6ab67a314610ab0578063c87b56dd14610ada578063ce6df2b914610b16578063d007af5c14610b325761034f565b8063be537f4314610a34578063c668286214610a5e578063c68b330514610a885761034f565b8063a22cb46511610163578063b366d6131161013d578063b366d6131461098c578063b7c0b8e8146109b4578063b88d4fde146109dc578063bbadfe76146109f85761034f565b8063a22cb46514610912578063a9fc664e1461093a578063aa592f25146109625761034f565b806374d0101d1161019f57806374d0101d1461085a5780638da5cb5b1461088257806395d89b41146108ac5780639d645a44146108d65761034f565b80636c3b8699146107f257806370a0823114610808578063715018a6146108445761034f565b80632e8da8291161029f57806355f804b31161023d5780636134716211610217578063613471621461073c5780636352211e146107645780636817c76c146107a057806369e2f0fb146107ca5761034f565b806355f804b3146106c25780635944c753146106ea5780635d4c1d46146107125761034f565b80633dd08c38116102795780633dd08c381461061857806342842e0e14610654578063495c8bf9146106705780634f9d2c0c1461069a5761034f565b80632e8da8291461059e57806334531828146105da5780633ccfd60b146106025761034f565b8063098144d41161030c5780631b25b077116102e65780631b25b077146104df5780631c33b3281461051b57806323b872dd146105455780632a55205a146105615761034f565b8063098144d414610463578063109695231461048d57806318160ddd146104b55761034f565b8063014635461461035357806301ffc9a71461037d57806304634d8d146103b957806306fdde03146103e1578063081812fc1461040b578063095ea7b314610447575b5f80fd5b34801561035e575f80fd5b50610367610c9e565b60405161037491906144fa565b60405180910390f35b348015610388575f80fd5b506103a3600480360381019061039e9190614579565b610cb4565b6040516103b091906145be565b60405180910390f35b3480156103c4575f80fd5b506103df60048036038101906103da9190614642565b610cc5565b005b3480156103ec575f80fd5b506103f5610ce3565b60405161040291906146f0565b60405180910390f35b348015610416575f80fd5b50610431600480360381019061042c9190614743565b610d73565b60405161043e91906144fa565b60405180910390f35b610461600480360381019061045c919061476e565b610dcc565b005b34801561046e575f80fd5b50610477610dda565b6040516104849190614807565b60405180910390f35b348015610498575f80fd5b506104b360048036038101906104ae9190614881565b610e02565b005b3480156104c0575f80fd5b506104c9610f1d565b6040516104d691906148db565b60405180910390f35b3480156104ea575f80fd5b50610505600480360381019061050091906148f4565b610f68565b60405161051291906145be565b60405180910390f35b348015610526575f80fd5b5061052f611063565b60405161053c91906149b7565b60405180910390f35b61055f600480360381019061055a91906149d0565b611068565b005b34801561056c575f80fd5b5061058760048036038101906105829190614a20565b611078565b604051610595929190614a5e565b60405180910390f35b3480156105a9575f80fd5b506105c460048036038101906105bf9190614a85565b61119a565b6040516105d191906145be565b60405180910390f35b3480156105e5575f80fd5b5061060060048036038101906105fb9190614579565b611336565b005b34801561060d575f80fd5b506106166113a8565b005b348015610623575f80fd5b5061063e60048036038101906106399190614a85565b611452565b60405161064b91906145be565b60405180910390f35b61066e600480360381019061066991906149d0565b61146f565b005b34801561067b575f80fd5b5061068461147f565b6040516106919190614b67565b60405180910390f35b3480156106a5575f80fd5b506106c060048036038101906106bb919061476e565b611663565b005b3480156106cd575f80fd5b506106e860048036038101906106e39190614881565b6117a9565b005b3480156106f5575f80fd5b50610710600480360381019061070b9190614b87565b61187d565b005b34801561071d575f80fd5b5061072661189d565b6040516107339190614c00565b60405180910390f35b348015610747575f80fd5b50610762600480360381019061075d9190614c66565b6118a2565b005b34801561076f575f80fd5b5061078a60048036038101906107859190614743565b611a58565b60405161079791906144fa565b60405180910390f35b3480156107ab575f80fd5b506107b4611a69565b6040516107c191906148db565b60405180910390f35b3480156107d5575f80fd5b506107f060048036038101906107eb9190614a85565b611a6f565b005b3480156107fd575f80fd5b50610806611ace565b005b348015610813575f80fd5b5061082e60048036038101906108299190614a85565b611be9565b60405161083b91906148db565b60405180910390f35b34801561084f575f80fd5b50610858611c7d565b005b348015610865575f80fd5b50610880600480360381019061087b919061476e565b611c90565b005b34801561088d575f80fd5b50610896611ca6565b6040516108a391906144fa565b60405180910390f35b3480156108b7575f80fd5b506108c0611cce565b6040516108cd91906146f0565b60405180910390f35b3480156108e1575f80fd5b506108fc60048036038101906108f79190614a85565b611d5e565b60405161090991906145be565b60405180910390f35b34801561091d575f80fd5b5061093860048036038101906109339190614ce0565b611efa565b005b348015610945575f80fd5b50610960600480360381019061095b9190614a85565b611f08565b005b34801561096d575f80fd5b506109766120bd565b60405161098391906148db565b60405180910390f35b348015610997575f80fd5b506109b260048036038101906109ad9190614a85565b6120c2565b005b3480156109bf575f80fd5b506109da60048036038101906109d59190614d1e565b612122565b005b6109f660048036038101906109f19190614e71565b6121fc565b005b348015610a03575f80fd5b50610a1e6004803603810190610a199190614579565b61220e565b604051610a2b91906145be565b60405180910390f35b348015610a3f575f80fd5b50610a4861222b565b604051610a559190614f4f565b60405180910390f35b348015610a69575f80fd5b50610a7261237c565b604051610a7f91906146f0565b60405180910390f35b348015610a93575f80fd5b50610aae6004803603810190610aa99190614d1e565b612408565b005b348015610abb575f80fd5b50610ac4612433565b604051610ad191906146f0565b60405180910390f35b348015610ae5575f80fd5b50610b006004803603810190610afb9190614743565b6124bf565b604051610b0d91906146f0565b60405180910390f35b610b306004803603810190610b2b919061476e565b612563565b005b348015610b3d575f80fd5b50610b466126c6565b604051610b539190614b67565b60405180910390f35b348015610b67575f80fd5b50610b826004803603810190610b7d9190614a85565b6128aa565b604051610b8f91906148db565b60405180910390f35b348015610ba3575f80fd5b50610bbe6004803603810190610bb99190614a85565b6128bb565b005b348015610bcb575f80fd5b50610be66004803603810190610be19190614f68565b6129c8565b604051610bf391906145be565b60405180910390f35b348015610c07575f80fd5b50610c226004803603810190610c1d9190614a85565b612a56565b005b348015610c2f575f80fd5b50610c4a6004803603810190610c459190614743565b612ada565b005b348015610c57575f80fd5b50610c60612aec565b604051610c6d91906145be565b60405180910390f35b348015610c81575f80fd5b50610c9c6004803603810190610c979190614fa6565b612afe565b005b71721c310194ccfc01e523fc93c9cccfa2a0ac81565b5f610cbe82612c4d565b9050919050565b610ccd612cc6565b610cd5612d4d565b610cdf8282612d57565b5050565b606060028054610cf290615037565b80601f0160208091040260200160405190810160405280929190818152602001828054610d1e90615037565b8015610d695780601f10610d4057610100808354040283529160200191610d69565b820191905f5260205f20905b815481529060010190602001808311610d4c57829003601f168201915b5050505050905090565b5f610d7d82612db3565b610d9257610d9163cf4700e460e01b612e56565b5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610dd68282612e5e565b5050565b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60145f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff1615610eb8576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ec0612cc6565b5f600e8054610ece90615037565b905014610f07576040517f19e24c1100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181600e9182610f18929190615205565b505050565b5f610f26612e6e565b6001545f54030390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610f58612e76565b14610f6557600854810190505b90565b5f8073ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146110575760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663285fb8c88585856040518463ffffffff1660e01b815260040161101b939291906152d2565b5f6040518083038186803b158015611031575f80fd5b505afa925050508015611042575060015b61104e575f905061105c565b6001905061105c565b600190505b9392505050565b600181565b611073838383612e9d565b505050565b5f805f600b5f8681526020019081526020015f2090505f815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f825f0160149054906101000a90046bffffffffffffffffffffffff1690505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361114c57600a5f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169150600a5f0160149054906101000a90046bffffffffffffffffffffffff1690505b5f611155613148565b6bffffffffffffffffffffffff16826bffffffffffffffffffffffff168861117d9190615334565b61118791906153a2565b9050828195509550505050509250929050565b5f8073ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461132d5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d72dde5e60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b815260040161128691906144fa565b606060405180830381865afa1580156112a1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112c5919061545f565b60200151846040518363ffffffff1660e01b81526004016112e792919061548a565b602060405180830381865afa158015611302573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061132691906154c5565b9050611331565b5f90505b919050565b61133e612cc6565b600160145f837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b6113b0612cc6565b5f3373ffffffffffffffffffffffffffffffffffffffff16476040516113d59061551d565b5f6040518083038185875af1925050503d805f811461140f576040519150601f19603f3d011682016040523d82523d5f602084013e611414565b606091505b505090508061144f576040517f750b219c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b6015602052805f5260405f205f915054906101000a900460ff1681565b61147a838383613151565b505050565b60605f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146116145760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633fe5df9960095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b815260040161156c91906144fa565b606060405180830381865afa158015611587573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115ab919061545f565b602001516040518263ffffffff1660e01b81526004016115cb9190614c00565b5f60405180830381865afa1580156115e5573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061160d9190615605565b9050611660565b5f67ffffffffffffffff81111561162e5761162d614d4d565b5b60405190808252806020026020018201604052801561165c5781602001602082028036833780820191505090505b5090505b90565b6001151560155f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff161515146116f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ea90615696565b60405180910390fd5b6001151560135f9054906101000a900460ff16151514611748576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161173f906156fe565b60405180910390fd5b6203f480601254611759919061571c565b42111561179b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161179290615799565b60405180910390fd5b6117a58282613170565b5050565b60145f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff161561185f576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611867612cc6565b8181600d9182611878929190615205565b505050565b611885612cc6565b61188d612d4d565b6118988383836132e4565b505050565b600181565b6118aa612d4d565b5f6118b3610dda565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361191a576040517f39ffc7ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663da0194c030866040518363ffffffff1660e01b81526004016119559291906157b7565b5f604051808303815f87803b15801561196c575f80fd5b505af115801561197e573d5f803e3d5ffd5b505050508073ffffffffffffffffffffffffffffffffffffffff16632304aa0230856040518363ffffffff1660e01b81526004016119bd9291906157de565b5f604051808303815f87803b1580156119d4575f80fd5b505af11580156119e6573d5f803e3d5ffd5b505050508073ffffffffffffffffffffffffffffffffffffffff16638d74431430846040518363ffffffff1660e01b8152600401611a259291906157de565b5f604051808303815f87803b158015611a3c575f80fd5b505af1158015611a4e573d5f803e3d5ffd5b5050505050505050565b5f611a6282613343565b9050919050565b60115481565b611a77612cc6565b5f60155f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b611ad6612d4d565b611af171721c310194ccfc01e523fc93c9cccfa2a0ac611f08565b71721c310194ccfc01e523fc93c9cccfa2a0ac73ffffffffffffffffffffffffffffffffffffffff1663da0194c03060016040518363ffffffff1660e01b8152600401611b3f9291906157b7565b5f604051808303815f87803b158015611b56575f80fd5b505af1158015611b68573d5f803e3d5ffd5b5050505071721c310194ccfc01e523fc93c9cccfa2a0ac73ffffffffffffffffffffffffffffffffffffffff16632304aa023060016040518363ffffffff1660e01b8152600401611bba9291906157de565b5f604051808303815f87803b158015611bd1575f80fd5b505af1158015611be3573d5f803e3d5ffd5b50505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611c2e57611c2d638f4eb60460e01b612e56565b5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b611c85612cc6565b611c8e5f613452565b565b611c98612cc6565b611ca28282613170565b5050565b5f600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054611cdd90615037565b80601f0160208091040260200160405190810160405280929190818152602001828054611d0990615037565b8015611d545780601f10611d2b57610100808354040283529160200191611d54565b820191905f5260205f20905b815481529060010190602001808311611d3757829003601f168201915b5050505050905090565b5f8073ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611ef15760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639445f53060095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b8152600401611e4a91906144fa565b606060405180830381865afa158015611e65573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e89919061545f565b60400151846040518363ffffffff1660e01b8152600401611eab92919061548a565b602060405180830381865afa158015611ec6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611eea91906154c5565b9050611ef5565b5f90505b919050565b611f048282613515565b5050565b611f10612d4d565b5f808273ffffffffffffffffffffffffffffffffffffffff163b1115611fae578173ffffffffffffffffffffffffffffffffffffffff166301ffc9a75f6040518263ffffffff1660e01b8152600401611f699190615814565b602060405180830381865afa925050508015611fa357506040513d601f19601f82011682018060405250810190611fa091906154c5565b60015b15611fad57809150505b5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611fe8575080155b1561201f576040517f32483afb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff168360405161207192919061582d565b60405180910390a18160095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600c81565b6120ca612cc6565b600160155f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b60145f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff16156121d8576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6121e0612cc6565b80600f5f6101000a81548160ff02191690831515021790555050565b6122088484848461361b565b50505050565b6014602052805f5260405f205f915054906101000a900460ff1681565b612233614469565b5f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146123275760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b81526004016122e191906144fa565b606060405180830381865afa1580156122fc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612320919061545f565b9050612379565b60405180606001604052805f600681111561234557612344614944565b5b81526020015f6effffffffffffffffffffffffffffff1681526020015f6effffffffffffffffffffffffffffff1681525090505b90565b6010805461238990615037565b80601f01602080910402602001604051908101604052809291908181526020018280546123b590615037565b80156124005780601f106123d757610100808354040283529160200191612400565b820191905f5260205f20905b8154815290600101906020018083116123e357829003601f168201915b505050505081565b612410612cc6565b8060135f6101000a81548160ff0219169083151502179055504260128190555050565b600e805461244090615037565b80601f016020809104026020016040519081016040528092919081815260200182805461246c90615037565b80156124b75780601f1061248e576101008083540402835291602001916124b7565b820191905f5260205f20905b81548152906001019060200180831161249a57829003601f168201915b505050505081565b60606124ca82612db3565b612509576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612500906158c4565b60405180910390fd5b5f61251261366c565b90505f8151116125305760405180602001604052805f81525061255b565b8061253a846136fc565b60405160200161254b92919061591c565b6040516020818303038152906040525b915050919050565b6001151560135f9054906101000a900460ff161515146125b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125af906156fe565b60405180910390fd5b6203f4806012546125c9919061571c565b42111561260b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161260290615799565b60405180910390fd5b5f6011548261261a9190615334565b90508034101561265f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161265690615989565b60405180910390fd5b6126698383613170565b803411156126c1573373ffffffffffffffffffffffffffffffffffffffff166108fc823461269791906159a7565b90811502906040515f60405180830381858888f193505050501580156126bf573d5f803e3d5ffd5b505b505050565b60605f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461285b5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166317e94a6c60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b81526004016127b391906144fa565b606060405180830381865afa1580156127ce573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127f2919061545f565b604001516040518263ffffffff1660e01b81526004016128129190614c00565b5f60405180830381865afa15801561282c573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906128549190615605565b90506128a7565b5f67ffffffffffffffff81111561287557612874614d4d565b5b6040519080825280602002602001820160405280156128a35781602001602082028036833780820191505090505b5090505b90565b5f6128b4826137c6565b9050919050565b60145f80357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020015f205f9054906101000a900460ff1615612971576040517f8bf9b99f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612979612cc6565b600c61298361381a565b106129ba576040517f1f0f14ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129c581600c613170565b50565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b612a5e612cc6565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612ace575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401612ac591906144fa565b60405180910390fd5b612ad781613452565b50565b612ae2612cc6565b8060118190555050565b600f5f9054906101000a900460ff1681565b612b06612d4d565b612b0f84611f08565b8373ffffffffffffffffffffffffffffffffffffffff1663da0194c030856040518363ffffffff1660e01b8152600401612b4a9291906157b7565b5f604051808303815f87803b158015612b61575f80fd5b505af1158015612b73573d5f803e3d5ffd5b505050508373ffffffffffffffffffffffffffffffffffffffff16632304aa0230846040518363ffffffff1660e01b8152600401612bb29291906157de565b5f604051808303815f87803b158015612bc9575f80fd5b505af1158015612bdb573d5f803e3d5ffd5b505050508373ffffffffffffffffffffffffffffffffffffffff16638d74431430836040518363ffffffff1660e01b8152600401612c1a9291906157de565b5f604051808303815f87803b158015612c31575f80fd5b505af1158015612c43573d5f803e3d5ffd5b5050505050505050565b5f7f86455d28000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612cbf5750612cbe82613861565b5b9050919050565b612cce6138f2565b73ffffffffffffffffffffffffffffffffffffffff16612cec611ca6565b73ffffffffffffffffffffffffffffffffffffffff1614612d4b57612d0f6138f2565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401612d4291906144fa565b60405180910390fd5b565b612d55612cc6565b565b612d6182826138f9565b8173ffffffffffffffffffffffffffffffffffffffff167f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef82604051612da791906159e9565b60405180910390a25050565b5f81612dbd612e6e565b11612e5057612dca612e76565b821115612df257612deb60045f8481526020019081526020015f2054613a94565b9050612e51565b5f54821015612e4f575f5b5f60045f8581526020019081526020015f205491508103612e295782612e2290615a02565b9250612dfd565b5f7c01000000000000000000000000000000000000000000000000000000008216149150505b5b5b919050565b805f5260045ffd5b612e6a82826001613ad4565b5050565b5f6001905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b5f612ea782613343565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612f1c57612f1b63a114810060e01b612e56565b5b5f80612f2784613bfe565b91509150612f3d8187612f38613c21565b613c2f565b612f6857612f5286612f4d613c21565b6129c8565b612f6757612f666359c896be60e01b612e56565b5b5b612f758686866001613c72565b8015612f7f575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f81546001019190508190555061304785613023888887613ca4565b7c020000000000000000000000000000000000000000000000000000000017613ccb565b60045f8681526020019081526020015f20819055505f7c02000000000000000000000000000000000000000000000000000000008416036130c3575f6001850190505f60045f8381526020019081526020015f2054036130c1575f5481146130c0578360045f8381526020019081526020015f20819055505b5b505b5f73ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45f81036131325761313163ea553b3460e01b612e56565b5b61313f8787876001613cf5565b50505050505050565b5f612710905090565b61316b83838360405180602001604052805f8152506121fc565b505050565b5f805490505f820361318d5761318c63b562e8dd60e01b612e56565b5b6131995f848385613c72565b6131b7836131a85f865f613ca4565b6131b185613d27565b17613ccb565b60045f8381526020019081526020015f2081905550600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505f73ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161690505f810361326857613267632e07630060e01b612e56565b5b5f83830190505f83905061327a612e76565b600183031115613295576132946381647e3a60e01b612e56565b5b5b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a481816001019150810361329657815f819055505050506132df5f848385613cf5565b505050565b6132ef838383613d36565b8173ffffffffffffffffffffffffffffffffffffffff16837f7f5b076c952c0ec86e5425963c1326dd0f03a3595c19f81d765e8ff559a6e33c8360405161333691906159e9565b60405180910390a3505050565b5f8161334d612e6e565b1161343c5760045f8381526020019081526020015f2054905061336e612e76565b8211156133935761337e81613a94565b61344d5761339263df2d9b4260e01b612e56565b5b5f8103613414575f5482106133b3576133b263df2d9b4260e01b612e56565b5b5b60045f836001900393508381526020019081526020015f205490505f81031561340f575f7c01000000000000000000000000000000000000000000000000000000008216031561344d5761340e63df2d9b4260e01b612e56565b5b6133b4565b5f7c01000000000000000000000000000000000000000000000000000000008216031561344d575b61344c63df2d9b4260e01b612e56565b5b919050565b5f600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600c5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8060075f613521613c21565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166135ca613c21565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161360f91906145be565b60405180910390a35050565b613626848484611068565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146136665761365084848484613ee5565b6136655761366463d1a57ed660e01b612e56565b5b5b50505050565b6060600d805461367b90615037565b80601f01602080910402602001604051908101604052809291908181526020018280546136a790615037565b80156136f25780601f106136c9576101008083540402835291602001916136f2565b820191905f5260205f20905b8154815290600101906020018083116136d557829003601f168201915b5050505050905090565b60605f600161370a8461400f565b0190505f8167ffffffffffffffff81111561372857613727614d4d565b5b6040519080825280601f01601f19166020018201604052801561375a5781602001600182028036833780820191505090505b5090505f82602001820190505b6001156137bb578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816137b0576137af615375565b5b0494505f8503613767575b819350505050919050565b5f67ffffffffffffffff604060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054901c169050919050565b5f613823612e6e565b5f540390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff613851612e76565b1461385e57600854810190505b90565b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806138bb57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806138eb5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b5f33905090565b5f613902613148565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff1611156139675781816040517f6f483d0900000000000000000000000000000000000000000000000000000000815260040161395e929190615a59565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036139d7575f6040517fb6d9900a0000000000000000000000000000000000000000000000000000000081526004016139ce91906144fa565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff16815250600a5f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b5f7c0100000000000000000000000000000000000000000000000000000000821673ffffffffffffffffffffffffffffffffffffffff8316119050919050565b5f613ade83611a58565b9050818015613b2057508073ffffffffffffffffffffffffffffffffffffffff16613b07613c21565b73ffffffffffffffffffffffffffffffffffffffff1614155b15613b4c57613b3681613b31613c21565b6129c8565b613b4b57613b4a63cfb3b94260e01b612e56565b5b5b8360065f8581526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f613c2a6138f2565b905090565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b5f5b81811015613c9d57613c9285858386613c8d919061571c565b614160565b806001019050613c74565b5050505050565b5f8060e883901c905060e8613cba86868461425e565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b5f5b81811015613d2057613d1585858386613d10919061571c565b614266565b806001019050613cf7565b5050505050565b5f6001821460e11b9050919050565b5f613d3f613148565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff161115613da6578382826040517fdfd1fc1b000000000000000000000000000000000000000000000000000000008152600401613d9d93929190615a80565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603613e1857835f6040517f969f0852000000000000000000000000000000000000000000000000000000008152600401613e0f929190615ab5565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff16815250600b5f8681526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555090505050505050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613f0a613c21565b8786866040518563ffffffff1660e01b8152600401613f2c9493929190615b2e565b6020604051808303815f875af1925050508015613f6757506040513d601f19601f82011682018060405250810190613f649190615b8c565b60015b613fbc573d805f8114613f95576040519150601f19603f3d011682016040523d82523d5f602084013e613f9a565b606091505b505f815103613fb457613fb363d1a57ed660e01b612e56565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061406b577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161406157614060615375565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106140a8576d04ee2d6d415b85acef8100000000838161409e5761409d615375565b5b0492506020810190505b662386f26fc1000083106140d757662386f26fc1000083816140cd576140cc615375565b5b0492506010810190505b6305f5e1008310614100576305f5e10083816140f6576140f5615375565b5b0492506008810190505b612710831061412557612710838161411b5761411a615375565b5b0492506004810190505b60648310614148576064838161413e5761413d615375565b5b0492506002810190505b600a8310614157576001810190505b80915050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490505f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490508180156141ce5750805b15614205576040517f5cbd944100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81156142235761421e6142166138f2565b858534614364565b614257565b80156142415761423c6142346138f2565b86853461436a565b614256565b61425561424c6138f2565b86868634614370565b5b5b5050505050565b5f9392505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490505f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490508180156142d45750805b1561430b576040517f5cbd944100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81156143295761432461431c6138f2565b858534614456565b61435d565b80156143475761434261433a6138f2565b86853461445c565b61435c565b61435b6143526138f2565b86868634614462565b5b5b5050505050565b50505050565b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461444f5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663285fb8c88686866040518463ffffffff1660e01b8152600401614422939291906152d2565b5f6040518083038186803b158015614438575f80fd5b505afa15801561444a573d5f803e3d5ffd5b505050505b5050505050565b50505050565b50505050565b5050505050565b60405180606001604052805f600681111561448757614486614944565b5b81526020015f6effffffffffffffffffffffffffffff1681526020015f6effffffffffffffffffffffffffffff1681525090565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6144e4826144bb565b9050919050565b6144f4816144da565b82525050565b5f60208201905061450d5f8301846144eb565b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61455881614524565b8114614562575f80fd5b50565b5f813590506145738161454f565b92915050565b5f6020828403121561458e5761458d61451c565b5b5f61459b84828501614565565b91505092915050565b5f8115159050919050565b6145b8816145a4565b82525050565b5f6020820190506145d15f8301846145af565b92915050565b6145e0816144da565b81146145ea575f80fd5b50565b5f813590506145fb816145d7565b92915050565b5f6bffffffffffffffffffffffff82169050919050565b61462181614601565b811461462b575f80fd5b50565b5f8135905061463c81614618565b92915050565b5f80604083850312156146585761465761451c565b5b5f614665858286016145ed565b92505060206146768582860161462e565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6146c282614680565b6146cc818561468a565b93506146dc81856020860161469a565b6146e5816146a8565b840191505092915050565b5f6020820190508181035f83015261470881846146b8565b905092915050565b5f819050919050565b61472281614710565b811461472c575f80fd5b50565b5f8135905061473d81614719565b92915050565b5f602082840312156147585761475761451c565b5b5f6147658482850161472f565b91505092915050565b5f80604083850312156147845761478361451c565b5b5f614791858286016145ed565b92505060206147a28582860161472f565b9150509250929050565b5f819050919050565b5f6147cf6147ca6147c5846144bb565b6147ac565b6144bb565b9050919050565b5f6147e0826147b5565b9050919050565b5f6147f1826147d6565b9050919050565b614801816147e7565b82525050565b5f60208201905061481a5f8301846147f8565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261484157614840614820565b5b8235905067ffffffffffffffff81111561485e5761485d614824565b5b60208301915083600182028301111561487a57614879614828565b5b9250929050565b5f80602083850312156148975761489661451c565b5b5f83013567ffffffffffffffff8111156148b4576148b3614520565b5b6148c08582860161482c565b92509250509250929050565b6148d581614710565b82525050565b5f6020820190506148ee5f8301846148cc565b92915050565b5f805f6060848603121561490b5761490a61451c565b5b5f614918868287016145ed565b9350506020614929868287016145ed565b925050604061493a868287016145ed565b9150509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b6007811061498257614981614944565b5b50565b5f81905061499282614971565b919050565b5f6149a182614985565b9050919050565b6149b181614997565b82525050565b5f6020820190506149ca5f8301846149a8565b92915050565b5f805f606084860312156149e7576149e661451c565b5b5f6149f4868287016145ed565b9350506020614a05868287016145ed565b9250506040614a168682870161472f565b9150509250925092565b5f8060408385031215614a3657614a3561451c565b5b5f614a438582860161472f565b9250506020614a548582860161472f565b9150509250929050565b5f604082019050614a715f8301856144eb565b614a7e60208301846148cc565b9392505050565b5f60208284031215614a9a57614a9961451c565b5b5f614aa7848285016145ed565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b614ae2816144da565b82525050565b5f614af38383614ad9565b60208301905092915050565b5f602082019050919050565b5f614b1582614ab0565b614b1f8185614aba565b9350614b2a83614aca565b805f5b83811015614b5a578151614b418882614ae8565b9750614b4c83614aff565b925050600181019050614b2d565b5085935050505092915050565b5f6020820190508181035f830152614b7f8184614b0b565b905092915050565b5f805f60608486031215614b9e57614b9d61451c565b5b5f614bab8682870161472f565b9350506020614bbc868287016145ed565b9250506040614bcd8682870161462e565b9150509250925092565b5f6effffffffffffffffffffffffffffff82169050919050565b614bfa81614bd7565b82525050565b5f602082019050614c135f830184614bf1565b92915050565b60078110614c25575f80fd5b50565b5f81359050614c3681614c19565b92915050565b614c4581614bd7565b8114614c4f575f80fd5b50565b5f81359050614c6081614c3c565b92915050565b5f805f60608486031215614c7d57614c7c61451c565b5b5f614c8a86828701614c28565b9350506020614c9b86828701614c52565b9250506040614cac86828701614c52565b9150509250925092565b614cbf816145a4565b8114614cc9575f80fd5b50565b5f81359050614cda81614cb6565b92915050565b5f8060408385031215614cf657614cf561451c565b5b5f614d03858286016145ed565b9250506020614d1485828601614ccc565b9150509250929050565b5f60208284031215614d3357614d3261451c565b5b5f614d4084828501614ccc565b91505092915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b614d83826146a8565b810181811067ffffffffffffffff82111715614da257614da1614d4d565b5b80604052505050565b5f614db4614513565b9050614dc08282614d7a565b919050565b5f67ffffffffffffffff821115614ddf57614dde614d4d565b5b614de8826146a8565b9050602081019050919050565b828183375f83830152505050565b5f614e15614e1084614dc5565b614dab565b905082815260208101848484011115614e3157614e30614d49565b5b614e3c848285614df5565b509392505050565b5f82601f830112614e5857614e57614820565b5b8135614e68848260208601614e03565b91505092915050565b5f805f8060808587031215614e8957614e8861451c565b5b5f614e96878288016145ed565b9450506020614ea7878288016145ed565b9350506040614eb88782880161472f565b925050606085013567ffffffffffffffff811115614ed957614ed8614520565b5b614ee587828801614e44565b91505092959194509250565b614efa81614997565b82525050565b614f0981614bd7565b82525050565b606082015f820151614f235f850182614ef1565b506020820151614f366020850182614f00565b506040820151614f496040850182614f00565b50505050565b5f606082019050614f625f830184614f0f565b92915050565b5f8060408385031215614f7e57614f7d61451c565b5b5f614f8b858286016145ed565b9250506020614f9c858286016145ed565b9150509250929050565b5f805f8060808587031215614fbe57614fbd61451c565b5b5f614fcb878288016145ed565b9450506020614fdc87828801614c28565b9350506040614fed87828801614c52565b9250506060614ffe87828801614c52565b91505092959194509250565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061504e57607f821691505b6020821081036150615761506061500a565b5b50919050565b5f82905092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026150cd7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82615092565b6150d78683615092565b95508019841693508086168417925050509392505050565b5f6151096151046150ff84614710565b6147ac565b614710565b9050919050565b5f819050919050565b615122836150ef565b61513661512e82615110565b84845461509e565b825550505050565b5f90565b61514a61513e565b615155818484615119565b505050565b5b818110156151785761516d5f82615142565b60018101905061515b565b5050565b601f8211156151bd5761518e81615071565b61519784615083565b810160208510156151a6578190505b6151ba6151b285615083565b83018261515a565b50505b505050565b5f82821c905092915050565b5f6151dd5f19846008026151c2565b1980831691505092915050565b5f6151f583836151ce565b9150826002028217905092915050565b61520f8383615067565b67ffffffffffffffff81111561522857615227614d4d565b5b6152328254615037565b61523d82828561517c565b5f601f83116001811461526a575f8415615258578287013590505b61526285826151ea565b8655506152c9565b601f19841661527886615071565b5f5b8281101561529f5784890135825560018201915060208501945060208101905061527a565b868310156152bc57848901356152b8601f8916826151ce565b8355505b6001600288020188555050505b50505050505050565b5f6060820190506152e55f8301866144eb565b6152f260208301856144eb565b6152ff60408301846144eb565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61533e82614710565b915061534983614710565b925082820261535781614710565b9150828204841483151761536e5761536d615307565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6153ac82614710565b91506153b783614710565b9250826153c7576153c6615375565b5b828204905092915050565b5f80fd5b5f815190506153e481614c19565b92915050565b5f815190506153f881614c3c565b92915050565b5f60608284031215615413576154126153d2565b5b61541d6060614dab565b90505f61542c848285016153d6565b5f83015250602061543f848285016153ea565b6020830152506040615453848285016153ea565b60408301525092915050565b5f606082840312156154745761547361451c565b5b5f615481848285016153fe565b91505092915050565b5f60408201905061549d5f830185614bf1565b6154aa60208301846144eb565b9392505050565b5f815190506154bf81614cb6565b92915050565b5f602082840312156154da576154d961451c565b5b5f6154e7848285016154b1565b91505092915050565b5f81905092915050565b50565b5f6155085f836154f0565b9150615513826154fa565b5f82019050919050565b5f615527826154fd565b9150819050919050565b5f67ffffffffffffffff82111561554b5761554a614d4d565b5b602082029050602081019050919050565b5f8151905061556a816145d7565b92915050565b5f61558261557d84615531565b614dab565b905080838252602082019050602084028301858111156155a5576155a4614828565b5b835b818110156155ce57806155ba888261555c565b8452602084019350506020810190506155a7565b5050509392505050565b5f82601f8301126155ec576155eb614820565b5b81516155fc848260208601615570565b91505092915050565b5f6020828403121561561a5761561961451c565b5b5f82015167ffffffffffffffff81111561563757615636614520565b5b615643848285016155d8565b91505092915050565b7f596f75277265206e6f742061206d696e746572000000000000000000000000005f82015250565b5f61568060138361468a565b915061568b8261564c565b602082019050919050565b5f6020820190508181035f8301526156ad81615674565b9050919050565b7f4d696e74696e67206973206e6f742073746172746564207965740000000000005f82015250565b5f6156e8601a8361468a565b91506156f3826156b4565b602082019050919050565b5f6020820190508181035f830152615715816156dc565b9050919050565b5f61572682614710565b915061573183614710565b925082820190508082111561574957615748615307565b5b92915050565b7f4d696e74696e672054696d6573207570000000000000000000000000000000005f82015250565b5f61578360108361468a565b915061578e8261574f565b602082019050919050565b5f6020820190508181035f8301526157b081615777565b9050919050565b5f6040820190506157ca5f8301856144eb565b6157d760208301846149a8565b9392505050565b5f6040820190506157f15f8301856144eb565b6157fe6020830184614bf1565b9392505050565b61580e81614524565b82525050565b5f6020820190506158275f830184615805565b92915050565b5f6040820190506158405f8301856144eb565b61584d60208301846144eb565b9392505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f5f8201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b5f6158ae602f8361468a565b91506158b982615854565b604082019050919050565b5f6020820190508181035f8301526158db816158a2565b9050919050565b5f81905092915050565b5f6158f682614680565b61590081856158e2565b935061591081856020860161469a565b80840191505092915050565b5f61592782856158ec565b915061593382846158ec565b91508190509392505050565b7f45746865722073656e74206973206e6f7420636f72726563742e0000000000005f82015250565b5f615973601a8361468a565b915061597e8261593f565b602082019050919050565b5f6020820190508181035f8301526159a081615967565b9050919050565b5f6159b182614710565b91506159bc83614710565b92508282039050818111156159d4576159d3615307565b5b92915050565b6159e381614601565b82525050565b5f6020820190506159fc5f8301846159da565b92915050565b5f615a0c82614710565b91505f8203615a1e57615a1d615307565b5b600182039050919050565b5f615a43615a3e615a3984614601565b6147ac565b614710565b9050919050565b615a5381615a29565b82525050565b5f604082019050615a6c5f830185615a4a565b615a7960208301846148cc565b9392505050565b5f606082019050615a935f8301866148cc565b615aa06020830185615a4a565b615aad60408301846148cc565b949350505050565b5f604082019050615ac85f8301856148cc565b615ad560208301846144eb565b9392505050565b5f81519050919050565b5f82825260208201905092915050565b5f615b0082615adc565b615b0a8185615ae6565b9350615b1a81856020860161469a565b615b23816146a8565b840191505092915050565b5f608082019050615b415f8301876144eb565b615b4e60208301866144eb565b615b5b60408301856148cc565b8181036060830152615b6d8184615af6565b905095945050505050565b5f81519050615b868161454f565b92915050565b5f60208284031215615ba157615ba061451c565b5b5f615bae84828501615b78565b9150509291505056fea2646970667358221220a3a1b43c38efa8d75ff9019a44c19fe687dd278e6a1faef7bfa1281bca6f66b764736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000059de7273191e6bf1907d614e94ecfbe8e5fb73180000000000000000000000000116991b4edf3d88a9db4850b2c9fc5a326b14b500000000000000000000000000000000000000000000000000000000000001f40000000000000000000000003bdc72443bd7fe4ab1ecbbfe04389e3b4197941b
-----Decoded View---------------
Arg [0] : initialOwner (address): 0x59dE7273191E6bf1907d614e94eCFbe8e5FB7318
Arg [1] : royaltyReceiver_ (address): 0x0116991B4eDF3D88a9Db4850b2C9FC5a326b14b5
Arg [2] : royaltyFeeNumerator_ (uint96): 500
Arg [3] : _minter (address): 0x3bDC72443bD7fE4Ab1EcbBFE04389e3B4197941B
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000059de7273191e6bf1907d614e94ecfbe8e5fb7318
Arg [1] : 0000000000000000000000000116991b4edf3d88a9db4850b2c9fc5a326b14b5
Arg [2] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [3] : 0000000000000000000000003bdc72443bd7fe4ab1ecbbfe04389e3b4197941b
Deployed Bytecode Sourcemap
180236:7195:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97924:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;183357:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;182543:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;129165:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;136405:227;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;186555:159;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;102450:137;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;185717:269;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;124367:573;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;106234:387;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98035:99;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;186724:211;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;174810:673;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;104579:357;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;184869:96;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;186167:207;;;;;;;;;;;;;:::i;:::-;;180683:38;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;186945:219;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103466:358;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;181799:242;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;185425:155;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;182736:207;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;98141:66;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100190:727;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;130567:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;180499:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;183196:104;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;98581:464;;;;;;;;;;;;;:::i;:::-;;126091:242;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85456:103;;;;;;;;;;;;;:::i;:::-;;181681:106;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;84781:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;129341:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105108:378;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;186384:161;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101517:818;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;180544:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;183085:103;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;185157:160;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;187175:253;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;180631:45;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102804:455;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;180455:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;182951:126;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;180377:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;183802:609;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;182049:486;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;104034:379;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;184576:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;181501:168;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137363:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85714:220;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;185994:93;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;180412:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99248:749;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;97924:104;97985:42;97924:104;:::o;183357:221::-;183489:4;183531:39;183558:11;183531:26;:39::i;:::-;183511:59;;183357:221;;;:::o;182543:185::-;84667:13;:11;:13::i;:::-;182636:31:::1;:29;:31::i;:::-;182678:42;182697:8;182707:12;182678:18;:42::i;:::-;182543:185:::0;;:::o;129165:100::-;129219:13;129252:5;129245:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;129165:100;:::o;136405:227::-;136481:7;136506:16;136514:7;136506;:16::i;:::-;136501:73;;136524:50;136532:41;;;136524:7;:50::i;:::-;136501:73;136594:15;:24;136610:7;136594:24;;;;;;;;;;;:30;;;;;;;;;;;;136587:37;;136405:227;;;:::o;186555:159::-;186674:32;186688:8;186698:7;186674:13;:32::i;:::-;186555:159;;:::o;102450:137::-;102512:30;102562:17;;;;;;;;;;;102555:24;;102450:137;:::o;185717:269::-;181161:14;:23;181176:7;;;;181161:23;;;;;;;;;;;;;;;;;;;;;;;;;;;181157:52;;;181193:16;;;;;;;;;;;;;;181157:52;84667:13:::1;:11;:13::i;:::-;185884:1:::2;185858:14;185852:28;;;;;:::i;:::-;;;:33;185848:85;;185907:26;;;;;;;;;;;;;;185848:85;185963:15;;185946:14;:32;;;;;;;:::i;:::-;;185717:269:::0;;:::o;124367:573::-;124428:14;124826:15;:13;:15::i;:::-;124811:12;;124795:13;;:28;:46;124786:55;;124881:17;124860;:15;:17::i;:::-;:38;124856:65;;124910:11;;124900:21;;;;124856:65;124367:573;:::o;106234:387::-;106333:4;106392:1;106354:40;;106362:17;;;;;;;;;;;106354:40;;;106350:242;;106415:17;;;;;;;;;;;:47;;;106463:6;106471:4;106477:2;106415:65;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;106411:170;;106560:5;106553:12;;;;106411:170;106507:4;106500:11;;;;106350:242;106609:4;106602:11;;106234:387;;;;;;:::o;98035:99::-;98108:26;98035:99;:::o;186724:211::-;186890:37;186909:4;186915:2;186919:7;186890:18;:37::i;:::-;186724:211;;;:::o;174810:673::-;174921:16;174939:14;174966:32;175001:17;:26;175019:7;175001:26;;;;;;;;;;;174966:61;;175038:23;175064:12;:21;;;;;;;;;;;;175038:47;;175096:22;175121:12;:28;;;;;;;;;;;;175096:53;;175193:1;175166:29;;:15;:29;;;175162:176;;175230:19;:28;;;;;;;;;;;;175212:46;;175291:19;:35;;;;;;;;;;;;175273:53;;175162:176;175350:21;175406:17;:15;:17::i;:::-;175374:49;;175387:15;175375:27;;:9;:27;;;;:::i;:::-;175374:49;;;;:::i;:::-;175350:73;;175444:15;175461:13;175436:39;;;;;;;;174810:673;;;;;:::o;104579:357::-;104658:4;104717:1;104679:40;;104687:17;;;;;;;;;;;104679:40;;;104675:229;;104743:17;;;;;;;;;;;:39;;;104801:17;;;;;;;;;;;:45;;;104855:4;104801:60;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:80;;;104883:8;104743:149;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;104736:156;;;;104675:229;104923:5;104916:12;;104579:357;;;;:::o;184869:96::-;84667:13;:11;:13::i;:::-;184953:4:::1;184932:14;:18;184947:2;184932:18;;;;;;;;;;;;;;;;;;:25;;;;;;;;;;;;;;;;;;184869:96:::0;:::o;186167:207::-;84667:13;:11;:13::i;:::-;186218:12:::1;186244:10;186236:24;;186282:21;186236:82;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;186217:101;;;186334:7;186329:37;;186350:16;;;;;;;;;;;;;;186329:37;186206:168;186167:207::o:0;180683:38::-;;;;;;;;;;;;;;;;;;;;;;:::o;186945:219::-;187115:41;187138:4;187144:2;187148:7;187115:22;:41::i;:::-;186945:219;;;:::o;103466:358::-;103531:16;103602:1;103564:40;;103572:17;;;;;;;;;;;103564:40;;;103560:221;;103628:17;;;;;;;;;;;:41;;;103688:17;;;;;;;;;;;:45;;;103742:4;103688:60;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:80;;;103628:141;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;103621:148;;;;103560:221;103814:1;103800:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;103793:23;;103466:358;;:::o;181799:242::-;181300:4;181278:26;;:6;:18;181285:10;181278:18;;;;;;;;;;;;;;;;;;;;;;;;;:26;;;181270:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;181894:4:::1;181883:15;;:7;;;;;;;;;;;:15;;;181875:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;181978:8;181966:9;;:20;;;;:::i;:::-;181947:15;:39;;181939:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;182018:15;182024:2;182028:4;182018:5;:15::i;:::-;181799:242:::0;;:::o;185425:155::-;181161:14;:23;181176:7;;;;181161:23;;;;;;;;;;;;;;;;;;;;;;;;;;;181157:52;;;181193:16;;;;;;;;;;;;;;181157:52;84667:13:::1;:11;:13::i;:::-;185561:11:::2;;185545:13;:27;;;;;;;:::i;:::-;;185425:155:::0;;:::o;182736:207::-;84667:13;:11;:13::i;:::-;182844:31:::1;:29;:31::i;:::-;182886:49;182903:7;182912:8;182922:12;182886:16;:49::i;:::-;182736:207:::0;;;:::o;98141:66::-;98205:1;98141:66;:::o;100190:727::-;100379:31;:29;:31::i;:::-;100423:40;100466:22;:20;:22::i;:::-;100423:65;;100533:1;100503:32;;100511:9;100503:32;;;100499:117;;100559:45;;;;;;;;;;;;;;100499:117;100628:9;:46;;;100683:4;100690:5;100628:68;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;100707:9;:42;;;100758:4;100765:19;100707:78;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;100796:9;:59;;;100864:4;100871:37;100796:113;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;100368:549;100190:727;;;:::o;130567:152::-;130639:7;130682:27;130701:7;130682:18;:27::i;:::-;130659:52;;130567:152;;;:::o;180499:38::-;;;;:::o;183196:104::-;84667:13;:11;:13::i;:::-;183287:5:::1;183269:6;:15;183276:7;183269:15;;;;;;;;;;;;;;;;:23;;;;;;;;;;;;;;;;;;183196:104:::0;:::o;98581:464::-;98645:31;:29;:31::i;:::-;98687:48;97985:42;98687:20;:48::i;:::-;97985:42;98746:95;;;98850:4;98108:26;98746:143;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97985:42;98900:91;;;99000:4;98205:1;98900:137;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;98581:464::o;126091:242::-;126163:7;126204:1;126187:19;;:5;:19;;;126183:69;;126208:44;126216:35;;;126208:7;:44::i;:::-;126183:69;118851:13;126270:18;:25;126289:5;126270:25;;;;;;;;;;;;;;;;:55;126263:62;;126091:242;;;:::o;85456:103::-;84667:13;:11;:13::i;:::-;85521:30:::1;85548:1;85521:18;:30::i;:::-;85456:103::o:0;181681:106::-;84667:13;:11;:13::i;:::-;181764:15:::1;181770:2;181774:4;181764:5;:15::i;:::-;181681:106:::0;;:::o;84781:87::-;84827:7;84854:6;;;;;;;;;;;84847:13;;84781:87;:::o;129341:104::-;129397:13;129430:7;129423:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;129341:104;:::o;105108:378::-;105193:4;105252:1;105214:40;;105222:17;;;;;;;;;;;105214:40;;;105210:244;;105278:17;;;;;;;;;;;:45;;;105342:17;;;;;;;;;;;:45;;;105396:4;105342:60;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:89;;;105433:8;105278:164;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;105271:171;;;;105210:244;105473:5;105466:12;;105108:378;;;;:::o;186384:161::-;186494:43;186518:8;186528;186494:23;:43::i;:::-;186384:161;;:::o;101517:818::-;101593:31;:29;:31::i;:::-;101637:29;101723:1;101690:18;:30;;;:34;101687:304;;;101753:18;101745:45;;;101791:48;101745:95;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;101741:239;;;101938:17;101911:44;;101859:112;101741:239;101687:304;102036:1;102006:32;;:18;:32;;;;:61;;;;;102043:24;102042:25;102006:61;102003:152;;;102091:52;;;;;;;;;;;;;;102003:152;102172:72;102205:17;;;;;;;;;;;102225:18;102172:72;;;;;;;:::i;:::-;;;;;;;;102308:18;102257:17;;:70;;;;;;;;;;;;;;;;;;101582:753;101517:818;:::o;180544:37::-;180579:2;180544:37;:::o;183085:103::-;84667:13;:11;:13::i;:::-;183176:4:::1;183158:6;:15;183165:7;183158:15;;;;;;;;;;;;;;;;:22;;;;;;;;;;;;;;;;;;183085:103:::0;:::o;185157:160::-;181161:14;:23;181176:7;;;;181161:23;;;;;;;;;;;;;;;;;;;;;;;;;;;181157:52;;;181193:16;;;;;;;;;;;;;;181157:52;84667:13:::1;:11;:13::i;:::-;185304:5:::2;185277:24;;:32;;;;;;;;;;;;;;;;;;185157:160:::0;:::o;187175:253::-;187373:47;187396:4;187402:2;187406:7;187415:4;187373:22;:47::i;:::-;187175:253;;;;:::o;180631:45::-;;;;;;;;;;;;;;;;;;;;;;:::o;102804:455::-;102863:31;;:::i;:::-;102949:1;102911:40;;102919:17;;;;;;;;;;;102911:40;;;102907:140;;102975:17;;;;;;;;;;;:45;;;103029:4;102975:60;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;102968:67;;;;102907:140;103066:185;;;;;;;;103129:27;103066:185;;;;;;;;:::i;:::-;;;;;;103192:1;103066:185;;;;;;103238:1;103066:185;;;;;103059:192;;102804:455;;:::o;180455:37::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;182951:126::-;84667:13;:11;:13::i;:::-;183024:7:::1;183014;;:17;;;;;;;;;;;;;;;;;;183054:15;183042:9;:27;;;;182951:126:::0;:::o;180377:28::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;183802:609::-;183920:13;183973:16;183981:7;183973;:16::i;:::-;183951:113;;;;;;;;;;;;:::i;:::-;;;;;;;;;184077:28;184108:10;:8;:10::i;:::-;184077:41;;184180:1;184155:14;184149:28;:32;:254;;;;;;;;;;;;;;;;;184273:14;184314:25;184331:7;184314:16;:25::i;:::-;184230:132;;;;;;;;;:::i;:::-;;;;;;;;;;;;;184149:254;184129:274;;;183802:609;;;:::o;182049:486::-;182146:4;182135:15;;:7;;;;;;;;;;;:15;;;182127:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;182230:8;182218:9;;:20;;;;:::i;:::-;182199:15;:39;;182191:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;182270:17;182301:9;;182290:8;:20;;;;:::i;:::-;182270:40;;182342:9;182329;:22;;182321:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;182393:19;182399:2;182403:8;182393:5;:19::i;:::-;182439:9;182427;:21;182423:105;;;182473:10;182465:28;;:51;182506:9;182494;:21;;;;:::i;:::-;182465:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;182423:105;182116:419;182049:486;;:::o;104034:379::-;104105:16;104176:1;104138:40;;104146:17;;;;;;;;;;;104138:40;;;104134:236;;104202:17;;;;;;;;;;;:47;;;104268:17;;;;;;;;;;;:45;;;104322:4;104268:60;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:89;;;104202:156;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;104195:163;;;;104134:236;104403:1;104389:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104382:23;;104034:379;;:::o;184576:119::-;184638:7;184665:22;184679:7;184665:13;:22::i;:::-;184658:29;;184576:119;;;:::o;181501:168::-;181161:14;:23;181176:7;;;;181161:23;;;;;;;;;;;;;;;;;;;;;;;;;;;181157:52;;;181193:16;;;;;;;;;;;;;;181157:52;84667:13:::1;:11;:13::i;:::-;180579:2:::2;181573:14;:12;:14::i;:::-;:26;181569:62;;181608:23;;;;;;;;;;;;;;181569:62;181642:19;181648:2;180579;181642:5;:19::i;:::-;181501:168:::0;:::o;137363:164::-;137460:4;137484:18;:25;137503:5;137484:25;;;;;;;;;;;;;;;:35;137510:8;137484:35;;;;;;;;;;;;;;;;;;;;;;;;;137477:42;;137363:164;;;;:::o;85714:220::-;84667:13;:11;:13::i;:::-;85819:1:::1;85799:22;;:8;:22;;::::0;85795:93:::1;;85873:1;85845:31;;;;;;;;;;;:::i;:::-;;;;;;;;85795:93;85898:28;85917:8;85898:18;:28::i;:::-;85714:220:::0;:::o;185994:93::-;84667:13;:11;:13::i;:::-;186073:6:::1;186061:9;:18;;;;185994:93:::0;:::o;180412:36::-;;;;;;;;;;;;;:::o;99248:749::-;99478:31;:29;:31::i;:::-;99522;99543:9;99522:20;:31::i;:::-;99597:9;99566:92;;;99667:4;99674:5;99566:114;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99724:9;99693:88;;;99790:4;99797:19;99693:124;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99861:9;99830:105;;;99944:4;99951:37;99830:159;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99248:749;;;;:::o;169154:203::-;169239:4;169278:31;169263:46;;;:11;:46;;;;:86;;;;169313:36;169337:11;169313:23;:36::i;:::-;169263:86;169256:93;;169154:203;;;:::o;84946:166::-;85017:12;:10;:12::i;:::-;85006:23;;:7;:5;:7::i;:::-;:23;;;85002:103;;85080:12;:10;:12::i;:::-;85053:40;;;;;;;;;;;:::i;:::-;;;;;;;;85002:103;84946:166::o;86509:104::-;86592:13;:11;:13::i;:::-;86509:104::o;178470:217::-;178574:48;178599:8;178609:12;178574:24;:48::i;:::-;178656:8;178638:41;;;178666:12;178638:41;;;;;;:::i;:::-;;;;;;;;178470:217;;:::o;137785:475::-;137850:11;137897:7;137878:15;:13;:15::i;:::-;:26;137874:379;;137935:17;:15;:17::i;:::-;137925:7;:27;137921:90;;;137961:50;137984:17;:26;138002:7;137984:26;;;;;;;;;;;;137961:22;:50::i;:::-;137954:57;;;;137921:90;138042:13;;138032:7;:23;138028:214;;;138076:14;138109:60;138157:1;138126:17;:26;138144:7;138126:26;;;;;;;;;;;;138117:35;;;138116:42;138109:60;;138160:9;;;;:::i;:::-;;;138109:60;;;138225:1;119627:8;138197:6;:24;:29;138188:38;;138057:185;138028:214;137874:379;137785:475;;;;:::o;168294:165::-;168395:13;168389:4;168382:27;168436:4;168430;168423:18;136122:124;136211:27;136220:2;136224:7;136233:4;136211:8;:27::i;:::-;136122:124;;:::o;123415:92::-;123471:7;123498:1;123491:8;;123415:92;:::o;123865:110::-;123923:7;123950:17;123943:24;;123865:110;:::o;140677:3523::-;140819:27;140849;140868:7;140849:18;:27::i;:::-;140819:57;;120309:14;141020:4;141004:22;;:41;140981:66;;141105:4;141064:45;;141080:19;141064:45;;;141060:95;;141111:44;141119:35;;;141111:7;:44::i;:::-;141060:95;141169:27;141198:23;141225:35;141252:7;141225:26;:35::i;:::-;141168:92;;;;141360:68;141385:15;141402:4;141408:19;:17;:19::i;:::-;141360:24;:68::i;:::-;141355:189;;141448:43;141465:4;141471:19;:17;:19::i;:::-;141448:16;:43::i;:::-;141443:101;;141493:51;141501:42;;;141493:7;:51::i;:::-;141443:101;141355:189;141557:43;141579:4;141585:2;141589:7;141598:1;141557:21;:43::i;:::-;141693:15;141690:160;;;141833:1;141812:19;141805:30;141690:160;142230:18;:24;142249:4;142230:24;;;;;;;;;;;;;;;;142228:26;;;;;;;;;;;;142299:18;:22;142318:2;142299:22;;;;;;;;;;;;;;;;142297:24;;;;;;;;;;;142621:146;142658:2;142707:45;142722:4;142728:2;142732:19;142707:14;:45::i;:::-;119907:8;142679:73;142621:18;:146::i;:::-;142592:17;:26;142610:7;142592:26;;;;;;;;;;;:175;;;;142938:1;119907:8;142887:19;:47;:52;142883:627;;142960:19;142992:1;142982:7;:11;142960:33;;143149:1;143115:17;:30;143133:11;143115:30;;;;;;;;;;;;:35;143111:384;;143253:13;;143238:11;:28;143234:242;;143433:19;143400:17;:30;143418:11;143400:30;;;;;;;;;;;:52;;;;143234:242;143111:384;142941:569;142883:627;143623:16;120309:14;143658:2;143642:20;;:39;143623:58;;144022:7;143986:8;143952:4;143894:25;143839:1;143782;143759:299;144095:1;144083:8;:13;144079:58;;144098:39;144106:30;;;144098:7;:39::i;:::-;144079:58;144150:42;144171:4;144177:2;144181:7;144190:1;144150:20;:42::i;:::-;140808:3392;;;;140677:3523;;;:::o;175765:97::-;175823:6;175849:5;175842:12;;175765:97;:::o;144296:193::-;144442:39;144459:4;144465:2;144469:7;144442:39;;;;;;;;;;;;:16;:39::i;:::-;144296:193;;;:::o;148740:2399::-;148813:20;148836:13;;148813:36;;148876:1;148864:8;:13;148860:53;;148879:34;148887:25;;;148879:7;:34::i;:::-;148860:53;148926:61;148956:1;148960:2;148964:12;148978:8;148926:21;:61::i;:::-;149460:139;149497:2;149551:33;149574:1;149578:2;149582:1;149551:14;:33::i;:::-;149518:30;149539:8;149518:20;:30::i;:::-;:66;149460:18;:139::i;:::-;149426:17;:31;149444:12;149426:31;;;;;;;;;;;:173;;;;149886:1;118989:2;149856:1;:26;;149855:32;149843:8;:45;149817:18;:22;149836:2;149817:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;149999:16;120309:14;150034:2;150018:20;;:39;149999:58;;150090:1;150078:8;:13;150074:54;;150093:35;150101:26;;;150093:7;:35::i;:::-;150074:54;150145:11;150174:8;150159:12;:23;150145:37;;150197:15;150215:12;150197:30;;150258:17;:15;:17::i;:::-;150254:1;150248:3;:7;:27;150244:77;;;150277:44;150285:35;;;150277:7;:44::i;:::-;150244:77;150338:676;150757:7;150713:8;150668:1;150602:25;150539:1;150474;150443:358;151009:3;150996:9;;;;;;:16;150338:676;;151046:3;151030:13;:19;;;;149175:1886;;;151071:60;151100:1;151104:2;151108:12;151122:8;151071:20;:60::i;:::-;148802:2337;148740:2399;;:::o;178695:246::-;178814:55;178837:7;178846:8;178856:12;178814:22;:55::i;:::-;178910:8;178885:48;;178901:7;178885:48;178920:12;178885:48;;;;;;:::i;:::-;;;;;;;;178695:246;;;:::o;132052:2213::-;132119:14;132169:7;132150:15;:13;:15::i;:::-;:26;132146:2054;;132202:17;:26;132220:7;132202:26;;;;;;;;;;;;132193:35;;132259:17;:15;:17::i;:::-;132249:7;:27;132245:183;;;132301:30;132324:6;132301:22;:30::i;:::-;132333:13;132297:49;132365:47;132373:38;;;132365:7;:47::i;:::-;132245:183;132539:1;132529:6;:11;132525:1292;;132576:13;;132565:7;:24;132561:77;;132591:47;132599:38;;;132591:7;:47::i;:::-;132561:77;133195:607;133273:17;:28;133291:9;;;;;;;133273:28;;;;;;;;;;;;133264:37;;133361:1;133351:6;:11;133347:25;133364:8;133347:25;133427:1;119627:8;133399:6;:24;:29;133395:48;133430:13;133395:48;133735:47;133743:38;;;133735:7;:47::i;:::-;133195:607;;;132525:1292;134172:1;119627:8;134144:6;:24;:29;134140:48;134175:13;134140:48;132146:2054;134210:47;134218:38;;;134210:7;:47::i;:::-;132052:2213;;;;:::o;86094:191::-;86168:16;86187:6;;;;;;;;;;;86168:25;;86213:8;86204:6;;:17;;;;;;;;;;;;;;;;;;86268:8;86237:40;;86258:8;86237:40;;;;;;;;;;;;86157:128;86094:191;:::o;136972:234::-;137119:8;137067:18;:39;137086:19;:17;:19::i;:::-;137067:39;;;;;;;;;;;;;;;:49;137107:8;137067:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;137179:8;137143:55;;137158:19;:17;:19::i;:::-;137143:55;;;137189:8;137143:55;;;;;;:::i;:::-;;;;;;;;136972:234;;:::o;145087:416::-;145262:31;145275:4;145281:2;145285:7;145262:12;:31::i;:::-;145326:1;145308:2;:14;;;:19;145304:192;;145347:56;145378:4;145384:2;145388:7;145397:5;145347:30;:56::i;:::-;145342:154;;145424:56;145432:47;;;145424:7;:56::i;:::-;145342:154;145304:192;145087:416;;;;:::o;183680:114::-;183740:13;183773;183766:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;183680:114;:::o;70399:650::-;70455:13;70506:14;70543:1;70523:17;70534:5;70523:10;:17::i;:::-;:21;70506:38;;70559:20;70593:6;70582:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70559:41;;70615:11;70712:6;70708:2;70704:15;70696:6;70692:28;70685:35;;70749:254;70756:4;70749:254;;;70781:5;;;;;;;;70887:10;70882:2;70875:5;70871:14;70866:32;70861:3;70853:46;70945:2;70936:11;;;;;;:::i;:::-;;;;;70979:1;70970:5;:10;70749:254;70966:21;70749:254;71024:6;71017:13;;;;;70399:650;;;:::o;126415:178::-;126476:7;118851:13;118989:2;126504:18;:25;126523:5;126504:25;;;;;;;;;;;;;;;;:50;;126503:82;126496:89;;126415:178;;;:::o;125038:385::-;125093:14;125309:15;:13;:15::i;:::-;125293:13;;:31;125284:40;;125364:17;125343;:15;:17::i;:::-;:38;125339:65;;125393:11;;125383:21;;;;125339:65;125038:385;:::o;128263:639::-;128348:4;128687:10;128672:25;;:11;:25;;;;:102;;;;128764:10;128749:25;;:11;:25;;;;128672:102;:179;;;;128841:10;128826:25;;:11;:25;;;;128672:179;128652:199;;128263:639;;;:::o;82515:98::-;82568:7;82595:10;82588:17;;82515:98;:::o;176133:518::-;176228:19;176250:17;:15;:17::i;:::-;176228:39;;;;176297:11;176282:12;:26;;;176278:176;;;176416:12;176430:11;176387:55;;;;;;;;;;;;:::i;:::-;;;;;;;;176278:176;176488:1;176468:22;;:8;:22;;;176464:110;;176559:1;176514:48;;;;;;;;;;;:::i;:::-;;;;;;;;176464:110;176608:35;;;;;;;;176620:8;176608:35;;;;;;176630:12;176608:35;;;;;176586:19;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;176217:434;176133:518;;:::o;138356:335::-;138426:11;138656:15;138648:6;138644:28;138625:16;138617:6;138613:29;138610:63;138600:73;;138356:335;;;:::o;159709:474::-;159838:13;159854:16;159862:7;159854;:16::i;:::-;159838:32;;159887:13;:45;;;;;159927:5;159904:28;;:19;:17;:19::i;:::-;:28;;;;159887:45;159883:201;;;159952:44;159969:5;159976:19;:17;:19::i;:::-;159952:16;:44::i;:::-;159947:137;;160017:51;160025:42;;;160017:7;:51::i;:::-;159947:137;159883:201;160129:2;160096:15;:24;160112:7;160096:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;160167:7;160163:2;160147:28;;160156:5;160147:28;;;;;;;;;;;;159827:356;159709:474;;;:::o;139572:485::-;139674:27;139703:23;139744:38;139785:15;:24;139801:7;139785:24;;;;;;;;;;;139744:65;;139962:18;139939:41;;140019:19;140013:26;139994:45;;139924:126;139572:485;;;:::o;170297:116::-;170366:7;170393:12;:10;:12::i;:::-;170386:19;;170297:116;:::o;138800:659::-;138949:11;139114:16;139107:5;139103:28;139094:37;;139274:16;139263:9;139259:32;139246:45;;139424:15;139413:9;139410:30;139402:5;139391:9;139388:20;139385:56;139375:66;;138800:659;;;;;:::o;169466:359::-;169648:9;169643:175;169667:8;169663:1;:12;169643:175;;;169693:51;169717:4;169723:2;169742:1;169727:12;:16;;;;:::i;:::-;169693:23;:51::i;:::-;169788:3;;;;;169643:175;;;;169466:359;;;;:::o;165584:311::-;165719:7;165739:16;120031:3;165765:19;:41;;165739:68;;120031:3;165833:31;165844:4;165850:2;165854:9;165833:10;:31::i;:::-;165825:40;;:62;;165818:69;;;165584:311;;;;;:::o;134813:450::-;134893:14;135061:16;135054:5;135050:28;135041:37;;135238:5;135224:11;135199:23;135195:41;135192:52;135185:5;135182:63;135172:73;;134813:450;;;;:::o;169932:357::-;170113:9;170108:174;170132:8;170128:1;:12;170108:174;;;170158:50;170181:4;170187:2;170206:1;170191:12;:16;;;;:::i;:::-;170158:22;:50::i;:::-;170252:3;;;;;170108:174;;;;169932:357;;;;:::o;135365:324::-;135435:14;135668:1;135658:8;135655:15;135629:24;135625:46;135615:56;;135365:324;;;:::o;177102:554::-;177212:19;177234:17;:15;:17::i;:::-;177212:39;;;;177281:11;177266:12;:26;;;177262:183;;;177398:7;177407:12;177421:11;177371:62;;;;;;;;;;;;;:::i;:::-;;;;;;;;177262:183;177479:1;177459:22;;:8;:22;;;177455:117;;177540:7;177557:1;177505:55;;;;;;;;;;;;:::i;:::-;;;;;;;;177455:117;177613:35;;;;;;;;177625:8;177613:35;;;;;;177635:12;177613:35;;;;;177584:17;:26;177602:7;177584:26;;;;;;;;;;;:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;177201:455;177102:554;;;:::o;147587:691::-;147750:4;147796:2;147771:45;;;147817:19;:17;:19::i;:::-;147838:4;147844:7;147853:5;147771:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;147767:504;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;148071:1;148054:6;:13;:18;148050:115;;148093:56;148101:47;;;148093:7;:56::i;:::-;148050:115;148237:6;148231:13;148222:6;148218:2;148214:15;148207:38;147767:504;147940:54;;;147930:64;;;:6;:64;;;;147923:71;;;147587:691;;;;;;:::o;66716:948::-;66769:7;66789:14;66806:1;66789:18;;66856:8;66847:5;:17;66843:106;;66894:8;66885:17;;;;;;:::i;:::-;;;;;66931:2;66921:12;;;;66843:106;66976:8;66967:5;:17;66963:106;;67014:8;67005:17;;;;;;:::i;:::-;;;;;67051:2;67041:12;;;;66963:106;67096:8;67087:5;:17;67083:106;;67134:8;67125:17;;;;;;:::i;:::-;;;;;67171:2;67161:12;;;;67083:106;67216:7;67207:5;:16;67203:103;;67253:7;67244:16;;;;;;:::i;:::-;;;;;67289:1;67279:11;;;;67203:103;67333:7;67324:5;:16;67320:103;;67370:7;67361:16;;;;;;:::i;:::-;;;;;67406:1;67396:11;;;;67320:103;67450:7;67441:5;:16;67437:103;;67487:7;67478:16;;;;;;:::i;:::-;;;;;67523:1;67513:11;;;;67437:103;67567:7;67558:5;:16;67554:68;;67605:1;67595:11;;;;67554:68;67650:6;67643:13;;;66716:948;;;:::o;93447:623::-;93551:20;93590:1;93574:18;;:4;:18;;;93551:41;;93603:18;93638:1;93624:16;;:2;:16;;;93603:37;;93656:15;:32;;;;;93675:13;93656:32;93653:410;;;93712:28;;;;;;;;;;;;;;93653:410;93761:15;93758:305;;;93793:54;93810:12;:10;:12::i;:::-;93824:2;93828:7;93837:9;93793:16;:54::i;:::-;93758:305;;;93868:13;93865:198;;;93898:56;93915:12;:10;:12::i;:::-;93929:4;93935:7;93944:9;93898:16;:56::i;:::-;93865:198;;;93987:64;94008:12;:10;:12::i;:::-;94022:4;94028:2;94032:7;94041:9;93987:20;:64::i;:::-;93865:198;93758:305;93540:530;;93447:623;;;:::o;165285:147::-;165422:6;165285:147;;;;;:::o;94203:625::-;94306:20;94345:1;94329:18;;:4;:18;;;94306:41;;94358:18;94393:1;94379:16;;:2;:16;;;94358:37;;94411:15;:32;;;;;94430:13;94411:32;94408:413;;;94467:28;;;;;;;;;;;;;;94408:413;94516:15;94513:308;;;94548:55;94566:12;:10;:12::i;:::-;94580:2;94584:7;94593:9;94548:17;:55::i;:::-;94513:308;;;94624:13;94621:200;;;94654:57;94672:12;:10;:12::i;:::-;94686:4;94692:7;94701:9;94654:17;:57::i;:::-;94621:200;;;94744:65;94766:12;:10;:12::i;:::-;94780:4;94786:2;94790:7;94799:9;94744:21;:65::i;:::-;94621:200;94513:308;94295:533;;94203:625;;;:::o;94900:105::-;;;;;:::o;95254:107::-;;;;;:::o;107324:344::-;107565:1;107527:40;;107535:17;;;;;;;;;;;107527:40;;;107523:138;;107584:17;;;;;;;;;;;:47;;;107632:6;107640:4;107646:2;107584:65;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;107523:138;107324:344;;;;;:::o;95076:106::-;;;;;:::o;95432:108::-;;;;;:::o;95814:124::-;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;:::o;7:126:1:-;44:7;84:42;77:5;73:54;62:65;;7:126;;;:::o;139:96::-;176:7;205:24;223:5;205:24;:::i;:::-;194:35;;139:96;;;:::o;241:118::-;328:24;346:5;328:24;:::i;:::-;323:3;316:37;241:118;;:::o;365:222::-;458:4;496:2;485:9;481:18;473:26;;509:71;577:1;566:9;562:17;553:6;509:71;:::i;:::-;365:222;;;;:::o;593:75::-;626:6;659:2;653:9;643:19;;593:75;:::o;674:117::-;783:1;780;773:12;797:117;906:1;903;896:12;920:149;956:7;996:66;989:5;985:78;974:89;;920:149;;;:::o;1075:120::-;1147:23;1164:5;1147:23;:::i;:::-;1140:5;1137:34;1127:62;;1185:1;1182;1175:12;1127:62;1075:120;:::o;1201:137::-;1246:5;1284:6;1271:20;1262:29;;1300:32;1326:5;1300:32;:::i;:::-;1201:137;;;;:::o;1344:327::-;1402:6;1451:2;1439:9;1430:7;1426:23;1422:32;1419:119;;;1457:79;;:::i;:::-;1419:119;1577:1;1602:52;1646:7;1637:6;1626:9;1622:22;1602:52;:::i;:::-;1592:62;;1548:116;1344:327;;;;:::o;1677:90::-;1711:7;1754:5;1747:13;1740:21;1729:32;;1677:90;;;:::o;1773:109::-;1854:21;1869:5;1854:21;:::i;:::-;1849:3;1842:34;1773:109;;:::o;1888:210::-;1975:4;2013:2;2002:9;1998:18;1990:26;;2026:65;2088:1;2077:9;2073:17;2064:6;2026:65;:::i;:::-;1888:210;;;;:::o;2104:122::-;2177:24;2195:5;2177:24;:::i;:::-;2170:5;2167:35;2157:63;;2216:1;2213;2206:12;2157:63;2104:122;:::o;2232:139::-;2278:5;2316:6;2303:20;2294:29;;2332:33;2359:5;2332:33;:::i;:::-;2232:139;;;;:::o;2377:109::-;2413:7;2453:26;2446:5;2442:38;2431:49;;2377:109;;;:::o;2492:120::-;2564:23;2581:5;2564:23;:::i;:::-;2557:5;2554:34;2544:62;;2602:1;2599;2592:12;2544:62;2492:120;:::o;2618:137::-;2663:5;2701:6;2688:20;2679:29;;2717:32;2743:5;2717:32;:::i;:::-;2618:137;;;;:::o;2761:472::-;2828:6;2836;2885:2;2873:9;2864:7;2860:23;2856:32;2853:119;;;2891:79;;:::i;:::-;2853:119;3011:1;3036:53;3081:7;3072:6;3061:9;3057:22;3036:53;:::i;:::-;3026:63;;2982:117;3138:2;3164:52;3208:7;3199:6;3188:9;3184:22;3164:52;:::i;:::-;3154:62;;3109:117;2761:472;;;;;:::o;3239:99::-;3291:6;3325:5;3319:12;3309:22;;3239:99;;;:::o;3344:169::-;3428:11;3462:6;3457:3;3450:19;3502:4;3497:3;3493:14;3478:29;;3344:169;;;;:::o;3519:139::-;3608:6;3603:3;3598;3592:23;3649:1;3640:6;3635:3;3631:16;3624:27;3519:139;;;:::o;3664:102::-;3705:6;3756:2;3752:7;3747:2;3740:5;3736:14;3732:28;3722:38;;3664:102;;;:::o;3772:377::-;3860:3;3888:39;3921:5;3888:39;:::i;:::-;3943:71;4007:6;4002:3;3943:71;:::i;:::-;3936:78;;4023:65;4081:6;4076:3;4069:4;4062:5;4058:16;4023:65;:::i;:::-;4113:29;4135:6;4113:29;:::i;:::-;4108:3;4104:39;4097:46;;3864:285;3772:377;;;;:::o;4155:313::-;4268:4;4306:2;4295:9;4291:18;4283:26;;4355:9;4349:4;4345:20;4341:1;4330:9;4326:17;4319:47;4383:78;4456:4;4447:6;4383:78;:::i;:::-;4375:86;;4155:313;;;;:::o;4474:77::-;4511:7;4540:5;4529:16;;4474:77;;;:::o;4557:122::-;4630:24;4648:5;4630:24;:::i;:::-;4623:5;4620:35;4610:63;;4669:1;4666;4659:12;4610:63;4557:122;:::o;4685:139::-;4731:5;4769:6;4756:20;4747:29;;4785:33;4812:5;4785:33;:::i;:::-;4685:139;;;;:::o;4830:329::-;4889:6;4938:2;4926:9;4917:7;4913:23;4909:32;4906:119;;;4944:79;;:::i;:::-;4906:119;5064:1;5089:53;5134:7;5125:6;5114:9;5110:22;5089:53;:::i;:::-;5079:63;;5035:117;4830:329;;;;:::o;5165:474::-;5233:6;5241;5290:2;5278:9;5269:7;5265:23;5261:32;5258:119;;;5296:79;;:::i;:::-;5258:119;5416:1;5441:53;5486:7;5477:6;5466:9;5462:22;5441:53;:::i;:::-;5431:63;;5387:117;5543:2;5569:53;5614:7;5605:6;5594:9;5590:22;5569:53;:::i;:::-;5559:63;;5514:118;5165:474;;;;;:::o;5645:60::-;5673:3;5694:5;5687:12;;5645:60;;;:::o;5711:142::-;5761:9;5794:53;5812:34;5821:24;5839:5;5821:24;:::i;:::-;5812:34;:::i;:::-;5794:53;:::i;:::-;5781:66;;5711:142;;;:::o;5859:126::-;5909:9;5942:37;5973:5;5942:37;:::i;:::-;5929:50;;5859:126;;;:::o;5991:165::-;6080:9;6113:37;6144:5;6113:37;:::i;:::-;6100:50;;5991:165;;;:::o;6162:209::-;6288:76;6358:5;6288:76;:::i;:::-;6283:3;6276:89;6162:209;;:::o;6377:300::-;6509:4;6547:2;6536:9;6532:18;6524:26;;6560:110;6667:1;6656:9;6652:17;6643:6;6560:110;:::i;:::-;6377:300;;;;:::o;6683:117::-;6792:1;6789;6782:12;6806:117;6915:1;6912;6905:12;6929:117;7038:1;7035;7028:12;7066:553;7124:8;7134:6;7184:3;7177:4;7169:6;7165:17;7161:27;7151:122;;7192:79;;:::i;:::-;7151:122;7305:6;7292:20;7282:30;;7335:18;7327:6;7324:30;7321:117;;;7357:79;;:::i;:::-;7321:117;7471:4;7463:6;7459:17;7447:29;;7525:3;7517:4;7509:6;7505:17;7495:8;7491:32;7488:41;7485:128;;;7532:79;;:::i;:::-;7485:128;7066:553;;;;;:::o;7625:529::-;7696:6;7704;7753:2;7741:9;7732:7;7728:23;7724:32;7721:119;;;7759:79;;:::i;:::-;7721:119;7907:1;7896:9;7892:17;7879:31;7937:18;7929:6;7926:30;7923:117;;;7959:79;;:::i;:::-;7923:117;8072:65;8129:7;8120:6;8109:9;8105:22;8072:65;:::i;:::-;8054:83;;;;7850:297;7625:529;;;;;:::o;8160:118::-;8247:24;8265:5;8247:24;:::i;:::-;8242:3;8235:37;8160:118;;:::o;8284:222::-;8377:4;8415:2;8404:9;8400:18;8392:26;;8428:71;8496:1;8485:9;8481:17;8472:6;8428:71;:::i;:::-;8284:222;;;;:::o;8512:619::-;8589:6;8597;8605;8654:2;8642:9;8633:7;8629:23;8625:32;8622:119;;;8660:79;;:::i;:::-;8622:119;8780:1;8805:53;8850:7;8841:6;8830:9;8826:22;8805:53;:::i;:::-;8795:63;;8751:117;8907:2;8933:53;8978:7;8969:6;8958:9;8954:22;8933:53;:::i;:::-;8923:63;;8878:118;9035:2;9061:53;9106:7;9097:6;9086:9;9082:22;9061:53;:::i;:::-;9051:63;;9006:118;8512:619;;;;;:::o;9137:180::-;9185:77;9182:1;9175:88;9282:4;9279:1;9272:15;9306:4;9303:1;9296:15;9323:132;9423:1;9416:5;9413:12;9403:46;;9429:18;;:::i;:::-;9403:46;9323:132;:::o;9461:165::-;9525:7;9554:5;9543:16;;9560:60;9614:5;9560:60;:::i;:::-;9461:165;;;:::o;9632:::-;9707:9;9740:51;9785:5;9740:51;:::i;:::-;9727:64;;9632:165;;;:::o;9803:181::-;9915:62;9971:5;9915:62;:::i;:::-;9910:3;9903:75;9803:181;;:::o;9990:272::-;10108:4;10146:2;10135:9;10131:18;10123:26;;10159:96;10252:1;10241:9;10237:17;10228:6;10159:96;:::i;:::-;9990:272;;;;:::o;10268:619::-;10345:6;10353;10361;10410:2;10398:9;10389:7;10385:23;10381:32;10378:119;;;10416:79;;:::i;:::-;10378:119;10536:1;10561:53;10606:7;10597:6;10586:9;10582:22;10561:53;:::i;:::-;10551:63;;10507:117;10663:2;10689:53;10734:7;10725:6;10714:9;10710:22;10689:53;:::i;:::-;10679:63;;10634:118;10791:2;10817:53;10862:7;10853:6;10842:9;10838:22;10817:53;:::i;:::-;10807:63;;10762:118;10268:619;;;;;:::o;10893:474::-;10961:6;10969;11018:2;11006:9;10997:7;10993:23;10989:32;10986:119;;;11024:79;;:::i;:::-;10986:119;11144:1;11169:53;11214:7;11205:6;11194:9;11190:22;11169:53;:::i;:::-;11159:63;;11115:117;11271:2;11297:53;11342:7;11333:6;11322:9;11318:22;11297:53;:::i;:::-;11287:63;;11242:118;10893:474;;;;;:::o;11373:332::-;11494:4;11532:2;11521:9;11517:18;11509:26;;11545:71;11613:1;11602:9;11598:17;11589:6;11545:71;:::i;:::-;11626:72;11694:2;11683:9;11679:18;11670:6;11626:72;:::i;:::-;11373:332;;;;;:::o;11711:329::-;11770:6;11819:2;11807:9;11798:7;11794:23;11790:32;11787:119;;;11825:79;;:::i;:::-;11787:119;11945:1;11970:53;12015:7;12006:6;11995:9;11991:22;11970:53;:::i;:::-;11960:63;;11916:117;11711:329;;;;:::o;12046:114::-;12113:6;12147:5;12141:12;12131:22;;12046:114;;;:::o;12166:184::-;12265:11;12299:6;12294:3;12287:19;12339:4;12334:3;12330:14;12315:29;;12166:184;;;;:::o;12356:132::-;12423:4;12446:3;12438:11;;12476:4;12471:3;12467:14;12459:22;;12356:132;;;:::o;12494:108::-;12571:24;12589:5;12571:24;:::i;:::-;12566:3;12559:37;12494:108;;:::o;12608:179::-;12677:10;12698:46;12740:3;12732:6;12698:46;:::i;:::-;12776:4;12771:3;12767:14;12753:28;;12608:179;;;;:::o;12793:113::-;12863:4;12895;12890:3;12886:14;12878:22;;12793:113;;;:::o;12942:732::-;13061:3;13090:54;13138:5;13090:54;:::i;:::-;13160:86;13239:6;13234:3;13160:86;:::i;:::-;13153:93;;13270:56;13320:5;13270:56;:::i;:::-;13349:7;13380:1;13365:284;13390:6;13387:1;13384:13;13365:284;;;13466:6;13460:13;13493:63;13552:3;13537:13;13493:63;:::i;:::-;13486:70;;13579:60;13632:6;13579:60;:::i;:::-;13569:70;;13425:224;13412:1;13409;13405:9;13400:14;;13365:284;;;13369:14;13665:3;13658:10;;13066:608;;;12942:732;;;;:::o;13680:373::-;13823:4;13861:2;13850:9;13846:18;13838:26;;13910:9;13904:4;13900:20;13896:1;13885:9;13881:17;13874:47;13938:108;14041:4;14032:6;13938:108;:::i;:::-;13930:116;;13680:373;;;;:::o;14059:617::-;14135:6;14143;14151;14200:2;14188:9;14179:7;14175:23;14171:32;14168:119;;;14206:79;;:::i;:::-;14168:119;14326:1;14351:53;14396:7;14387:6;14376:9;14372:22;14351:53;:::i;:::-;14341:63;;14297:117;14453:2;14479:53;14524:7;14515:6;14504:9;14500:22;14479:53;:::i;:::-;14469:63;;14424:118;14581:2;14607:52;14651:7;14642:6;14631:9;14627:22;14607:52;:::i;:::-;14597:62;;14552:117;14059:617;;;;;:::o;14682:116::-;14719:7;14759:32;14752:5;14748:44;14737:55;;14682:116;;;:::o;14804:118::-;14891:24;14909:5;14891:24;:::i;:::-;14886:3;14879:37;14804:118;;:::o;14928:222::-;15021:4;15059:2;15048:9;15044:18;15036:26;;15072:71;15140:1;15129:9;15125:17;15116:6;15072:71;:::i;:::-;14928:222;;;;:::o;15156:126::-;15256:1;15249:5;15246:12;15236:40;;15272:1;15269;15262:12;15236:40;15156:126;:::o;15288:193::-;15361:5;15399:6;15386:20;15377:29;;15415:60;15469:5;15415:60;:::i;:::-;15288:193;;;;:::o;15487:122::-;15560:24;15578:5;15560:24;:::i;:::-;15553:5;15550:35;15540:63;;15599:1;15596;15589:12;15540:63;15487:122;:::o;15615:139::-;15661:5;15699:6;15686:20;15677:29;;15715:33;15742:5;15715:33;:::i;:::-;15615:139;;;;:::o;15760:673::-;15864:6;15872;15880;15929:2;15917:9;15908:7;15904:23;15900:32;15897:119;;;15935:79;;:::i;:::-;15897:119;16055:1;16080:80;16152:7;16143:6;16132:9;16128:22;16080:80;:::i;:::-;16070:90;;16026:144;16209:2;16235:53;16280:7;16271:6;16260:9;16256:22;16235:53;:::i;:::-;16225:63;;16180:118;16337:2;16363:53;16408:7;16399:6;16388:9;16384:22;16363:53;:::i;:::-;16353:63;;16308:118;15760:673;;;;;:::o;16439:116::-;16509:21;16524:5;16509:21;:::i;:::-;16502:5;16499:32;16489:60;;16545:1;16542;16535:12;16489:60;16439:116;:::o;16561:133::-;16604:5;16642:6;16629:20;16620:29;;16658:30;16682:5;16658:30;:::i;:::-;16561:133;;;;:::o;16700:468::-;16765:6;16773;16822:2;16810:9;16801:7;16797:23;16793:32;16790:119;;;16828:79;;:::i;:::-;16790:119;16948:1;16973:53;17018:7;17009:6;16998:9;16994:22;16973:53;:::i;:::-;16963:63;;16919:117;17075:2;17101:50;17143:7;17134:6;17123:9;17119:22;17101:50;:::i;:::-;17091:60;;17046:115;16700:468;;;;;:::o;17174:323::-;17230:6;17279:2;17267:9;17258:7;17254:23;17250:32;17247:119;;;17285:79;;:::i;:::-;17247:119;17405:1;17430:50;17472:7;17463:6;17452:9;17448:22;17430:50;:::i;:::-;17420:60;;17376:114;17174:323;;;;:::o;17503:117::-;17612:1;17609;17602:12;17626:180;17674:77;17671:1;17664:88;17771:4;17768:1;17761:15;17795:4;17792:1;17785:15;17812:281;17895:27;17917:4;17895:27;:::i;:::-;17887:6;17883:40;18025:6;18013:10;18010:22;17989:18;17977:10;17974:34;17971:62;17968:88;;;18036:18;;:::i;:::-;17968:88;18076:10;18072:2;18065:22;17855:238;17812:281;;:::o;18099:129::-;18133:6;18160:20;;:::i;:::-;18150:30;;18189:33;18217:4;18209:6;18189:33;:::i;:::-;18099:129;;;:::o;18234:307::-;18295:4;18385:18;18377:6;18374:30;18371:56;;;18407:18;;:::i;:::-;18371:56;18445:29;18467:6;18445:29;:::i;:::-;18437:37;;18529:4;18523;18519:15;18511:23;;18234:307;;;:::o;18547:148::-;18645:6;18640:3;18635;18622:30;18686:1;18677:6;18672:3;18668:16;18661:27;18547:148;;;:::o;18701:423::-;18778:5;18803:65;18819:48;18860:6;18819:48;:::i;:::-;18803:65;:::i;:::-;18794:74;;18891:6;18884:5;18877:21;18929:4;18922:5;18918:16;18967:3;18958:6;18953:3;18949:16;18946:25;18943:112;;;18974:79;;:::i;:::-;18943:112;19064:54;19111:6;19106:3;19101;19064:54;:::i;:::-;18784:340;18701:423;;;;;:::o;19143:338::-;19198:5;19247:3;19240:4;19232:6;19228:17;19224:27;19214:122;;19255:79;;:::i;:::-;19214:122;19372:6;19359:20;19397:78;19471:3;19463:6;19456:4;19448:6;19444:17;19397:78;:::i;:::-;19388:87;;19204:277;19143:338;;;;:::o;19487:943::-;19582:6;19590;19598;19606;19655:3;19643:9;19634:7;19630:23;19626:33;19623:120;;;19662:79;;:::i;:::-;19623:120;19782:1;19807:53;19852:7;19843:6;19832:9;19828:22;19807:53;:::i;:::-;19797:63;;19753:117;19909:2;19935:53;19980:7;19971:6;19960:9;19956:22;19935:53;:::i;:::-;19925:63;;19880:118;20037:2;20063:53;20108:7;20099:6;20088:9;20084:22;20063:53;:::i;:::-;20053:63;;20008:118;20193:2;20182:9;20178:18;20165:32;20224:18;20216:6;20213:30;20210:117;;;20246:79;;:::i;:::-;20210:117;20351:62;20405:7;20396:6;20385:9;20381:22;20351:62;:::i;:::-;20341:72;;20136:287;19487:943;;;;;;;:::o;20436:171::-;20538:62;20594:5;20538:62;:::i;:::-;20533:3;20526:75;20436:171;;:::o;20613:108::-;20690:24;20708:5;20690:24;:::i;:::-;20685:3;20678:37;20613:108;;:::o;20801:796::-;20982:4;20977:3;20973:14;21086:4;21079:5;21075:16;21069:23;21105:88;21187:4;21182:3;21178:14;21164:12;21105:88;:::i;:::-;20997:206;21300:4;21293:5;21289:16;21283:23;21319:63;21376:4;21371:3;21367:14;21353:12;21319:63;:::i;:::-;21213:179;21498:4;21491:5;21487:16;21481:23;21517:63;21574:4;21569:3;21565:14;21551:12;21517:63;:::i;:::-;21402:188;20951:646;20801:796;;:::o;21603:390::-;21780:4;21818:2;21807:9;21803:18;21795:26;;21831:155;21983:1;21972:9;21968:17;21959:6;21831:155;:::i;:::-;21603:390;;;;:::o;21999:474::-;22067:6;22075;22124:2;22112:9;22103:7;22099:23;22095:32;22092:119;;;22130:79;;:::i;:::-;22092:119;22250:1;22275:53;22320:7;22311:6;22300:9;22296:22;22275:53;:::i;:::-;22265:63;;22221:117;22377:2;22403:53;22448:7;22439:6;22428:9;22424:22;22403:53;:::i;:::-;22393:63;;22348:118;21999:474;;;;;:::o;22479:819::-;22592:6;22600;22608;22616;22665:3;22653:9;22644:7;22640:23;22636:33;22633:120;;;22672:79;;:::i;:::-;22633:120;22792:1;22817:53;22862:7;22853:6;22842:9;22838:22;22817:53;:::i;:::-;22807:63;;22763:117;22919:2;22945:80;23017:7;23008:6;22997:9;22993:22;22945:80;:::i;:::-;22935:90;;22890:145;23074:2;23100:53;23145:7;23136:6;23125:9;23121:22;23100:53;:::i;:::-;23090:63;;23045:118;23202:2;23228:53;23273:7;23264:6;23253:9;23249:22;23228:53;:::i;:::-;23218:63;;23173:118;22479:819;;;;;;;:::o;23304:180::-;23352:77;23349:1;23342:88;23449:4;23446:1;23439:15;23473:4;23470:1;23463:15;23490:320;23534:6;23571:1;23565:4;23561:12;23551:22;;23618:1;23612:4;23608:12;23639:18;23629:81;;23695:4;23687:6;23683:17;23673:27;;23629:81;23757:2;23749:6;23746:14;23726:18;23723:38;23720:84;;23776:18;;:::i;:::-;23720:84;23541:269;23490:320;;;:::o;23816:97::-;23875:6;23903:3;23893:13;;23816:97;;;;:::o;23919:141::-;23968:4;23991:3;23983:11;;24014:3;24011:1;24004:14;24048:4;24045:1;24035:18;24027:26;;23919:141;;;:::o;24066:93::-;24103:6;24150:2;24145;24138:5;24134:14;24130:23;24120:33;;24066:93;;;:::o;24165:107::-;24209:8;24259:5;24253:4;24249:16;24228:37;;24165:107;;;;:::o;24278:393::-;24347:6;24397:1;24385:10;24381:18;24420:97;24450:66;24439:9;24420:97;:::i;:::-;24538:39;24568:8;24557:9;24538:39;:::i;:::-;24526:51;;24610:4;24606:9;24599:5;24595:21;24586:30;;24659:4;24649:8;24645:19;24638:5;24635:30;24625:40;;24354:317;;24278:393;;;;;:::o;24677:142::-;24727:9;24760:53;24778:34;24787:24;24805:5;24787:24;:::i;:::-;24778:34;:::i;:::-;24760:53;:::i;:::-;24747:66;;24677:142;;;:::o;24825:75::-;24868:3;24889:5;24882:12;;24825:75;;;:::o;24906:269::-;25016:39;25047:7;25016:39;:::i;:::-;25077:91;25126:41;25150:16;25126:41;:::i;:::-;25118:6;25111:4;25105:11;25077:91;:::i;:::-;25071:4;25064:105;24982:193;24906:269;;;:::o;25181:73::-;25226:3;25181:73;:::o;25260:189::-;25337:32;;:::i;:::-;25378:65;25436:6;25428;25422:4;25378:65;:::i;:::-;25313:136;25260:189;;:::o;25455:186::-;25515:120;25532:3;25525:5;25522:14;25515:120;;;25586:39;25623:1;25616:5;25586:39;:::i;:::-;25559:1;25552:5;25548:13;25539:22;;25515:120;;;25455:186;;:::o;25647:543::-;25748:2;25743:3;25740:11;25737:446;;;25782:38;25814:5;25782:38;:::i;:::-;25866:29;25884:10;25866:29;:::i;:::-;25856:8;25852:44;26049:2;26037:10;26034:18;26031:49;;;26070:8;26055:23;;26031:49;26093:80;26149:22;26167:3;26149:22;:::i;:::-;26139:8;26135:37;26122:11;26093:80;:::i;:::-;25752:431;;25737:446;25647:543;;;:::o;26196:117::-;26250:8;26300:5;26294:4;26290:16;26269:37;;26196:117;;;;:::o;26319:169::-;26363:6;26396:51;26444:1;26440:6;26432:5;26429:1;26425:13;26396:51;:::i;:::-;26392:56;26477:4;26471;26467:15;26457:25;;26370:118;26319:169;;;;:::o;26493:295::-;26569:4;26715:29;26740:3;26734:4;26715:29;:::i;:::-;26707:37;;26777:3;26774:1;26770:11;26764:4;26761:21;26753:29;;26493:295;;;;:::o;26793:1403::-;26917:44;26957:3;26952;26917:44;:::i;:::-;27026:18;27018:6;27015:30;27012:56;;;27048:18;;:::i;:::-;27012:56;27092:38;27124:4;27118:11;27092:38;:::i;:::-;27177:67;27237:6;27229;27223:4;27177:67;:::i;:::-;27271:1;27300:2;27292:6;27289:14;27317:1;27312:632;;;;27988:1;28005:6;28002:84;;;28061:9;28056:3;28052:19;28039:33;28030:42;;28002:84;28112:67;28172:6;28165:5;28112:67;:::i;:::-;28106:4;28099:81;27961:229;27282:908;;27312:632;27364:4;27360:9;27352:6;27348:22;27398:37;27430:4;27398:37;:::i;:::-;27457:1;27471:215;27485:7;27482:1;27479:14;27471:215;;;27571:9;27566:3;27562:19;27549:33;27541:6;27534:49;27622:1;27614:6;27610:14;27600:24;;27669:2;27658:9;27654:18;27641:31;;27508:4;27505:1;27501:12;27496:17;;27471:215;;;27714:6;27705:7;27702:19;27699:186;;;27779:9;27774:3;27770:19;27757:33;27822:48;27864:4;27856:6;27852:17;27841:9;27822:48;:::i;:::-;27814:6;27807:64;27722:163;27699:186;27931:1;27927;27919:6;27915:14;27911:22;27905:4;27898:36;27319:625;;;27282:908;;26892:1304;;;26793:1403;;;:::o;28202:442::-;28351:4;28389:2;28378:9;28374:18;28366:26;;28402:71;28470:1;28459:9;28455:17;28446:6;28402:71;:::i;:::-;28483:72;28551:2;28540:9;28536:18;28527:6;28483:72;:::i;:::-;28565;28633:2;28622:9;28618:18;28609:6;28565:72;:::i;:::-;28202:442;;;;;;:::o;28650:180::-;28698:77;28695:1;28688:88;28795:4;28792:1;28785:15;28819:4;28816:1;28809:15;28836:410;28876:7;28899:20;28917:1;28899:20;:::i;:::-;28894:25;;28933:20;28951:1;28933:20;:::i;:::-;28928:25;;28988:1;28985;28981:9;29010:30;29028:11;29010:30;:::i;:::-;28999:41;;29189:1;29180:7;29176:15;29173:1;29170:22;29150:1;29143:9;29123:83;29100:139;;29219:18;;:::i;:::-;29100:139;28884:362;28836:410;;;;:::o;29252:180::-;29300:77;29297:1;29290:88;29397:4;29394:1;29387:15;29421:4;29418:1;29411:15;29438:185;29478:1;29495:20;29513:1;29495:20;:::i;:::-;29490:25;;29529:20;29547:1;29529:20;:::i;:::-;29524:25;;29568:1;29558:35;;29573:18;;:::i;:::-;29558:35;29615:1;29612;29608:9;29603:14;;29438:185;;;;:::o;29629:117::-;29738:1;29735;29728:12;29875:197;29959:5;29990:6;29984:13;29975:22;;30006:60;30060:5;30006:60;:::i;:::-;29875:197;;;;:::o;30078:143::-;30135:5;30166:6;30160:13;30151:22;;30182:33;30209:5;30182:33;:::i;:::-;30078:143;;;;:::o;30266:879::-;30368:5;30412:4;30400:9;30395:3;30391:19;30387:30;30384:117;;;30420:79;;:::i;:::-;30384:117;30519:21;30535:4;30519:21;:::i;:::-;30510:30;;30616:1;30656:87;30739:3;30730:6;30719:9;30715:22;30656:87;:::i;:::-;30649:4;30642:5;30638:16;30631:113;30550:205;30829:2;30870:60;30926:3;30917:6;30906:9;30902:22;30870:60;:::i;:::-;30863:4;30856:5;30852:16;30845:86;30765:177;31025:2;31066:60;31122:3;31113:6;31102:9;31098:22;31066:60;:::i;:::-;31059:4;31052:5;31048:16;31041:86;30952:186;30266:879;;;;:::o;31151:435::-;31263:6;31312:2;31300:9;31291:7;31287:23;31283:32;31280:119;;;31318:79;;:::i;:::-;31280:119;31438:1;31463:106;31561:7;31552:6;31541:9;31537:22;31463:106;:::i;:::-;31453:116;;31409:170;31151:435;;;;:::o;31592:332::-;31713:4;31751:2;31740:9;31736:18;31728:26;;31764:71;31832:1;31821:9;31817:17;31808:6;31764:71;:::i;:::-;31845:72;31913:2;31902:9;31898:18;31889:6;31845:72;:::i;:::-;31592:332;;;;;:::o;31930:137::-;31984:5;32015:6;32009:13;32000:22;;32031:30;32055:5;32031:30;:::i;:::-;31930:137;;;;:::o;32073:345::-;32140:6;32189:2;32177:9;32168:7;32164:23;32160:32;32157:119;;;32195:79;;:::i;:::-;32157:119;32315:1;32340:61;32393:7;32384:6;32373:9;32369:22;32340:61;:::i;:::-;32330:71;;32286:125;32073:345;;;;:::o;32424:147::-;32525:11;32562:3;32547:18;;32424:147;;;;:::o;32577:114::-;;:::o;32697:398::-;32856:3;32877:83;32958:1;32953:3;32877:83;:::i;:::-;32870:90;;32969:93;33058:3;32969:93;:::i;:::-;33087:1;33082:3;33078:11;33071:18;;32697:398;;;:::o;33101:379::-;33285:3;33307:147;33450:3;33307:147;:::i;:::-;33300:154;;33471:3;33464:10;;33101:379;;;:::o;33486:311::-;33563:4;33653:18;33645:6;33642:30;33639:56;;;33675:18;;:::i;:::-;33639:56;33725:4;33717:6;33713:17;33705:25;;33785:4;33779;33775:15;33767:23;;33486:311;;;:::o;33803:143::-;33860:5;33891:6;33885:13;33876:22;;33907:33;33934:5;33907:33;:::i;:::-;33803:143;;;;:::o;33969:732::-;34076:5;34101:81;34117:64;34174:6;34117:64;:::i;:::-;34101:81;:::i;:::-;34092:90;;34202:5;34231:6;34224:5;34217:21;34265:4;34258:5;34254:16;34247:23;;34318:4;34310:6;34306:17;34298:6;34294:30;34347:3;34339:6;34336:15;34333:122;;;34366:79;;:::i;:::-;34333:122;34481:6;34464:231;34498:6;34493:3;34490:15;34464:231;;;34573:3;34602:48;34646:3;34634:10;34602:48;:::i;:::-;34597:3;34590:61;34680:4;34675:3;34671:14;34664:21;;34540:155;34524:4;34519:3;34515:14;34508:21;;34464:231;;;34468:21;34082:619;;33969:732;;;;;:::o;34724:385::-;34806:5;34855:3;34848:4;34840:6;34836:17;34832:27;34822:122;;34863:79;;:::i;:::-;34822:122;34973:6;34967:13;34998:105;35099:3;35091:6;35084:4;35076:6;35072:17;34998:105;:::i;:::-;34989:114;;34812:297;34724:385;;;;:::o;35115:554::-;35210:6;35259:2;35247:9;35238:7;35234:23;35230:32;35227:119;;;35265:79;;:::i;:::-;35227:119;35406:1;35395:9;35391:17;35385:24;35436:18;35428:6;35425:30;35422:117;;;35458:79;;:::i;:::-;35422:117;35563:89;35644:7;35635:6;35624:9;35620:22;35563:89;:::i;:::-;35553:99;;35356:306;35115:554;;;;:::o;35675:169::-;35815:21;35811:1;35803:6;35799:14;35792:45;35675:169;:::o;35850:366::-;35992:3;36013:67;36077:2;36072:3;36013:67;:::i;:::-;36006:74;;36089:93;36178:3;36089:93;:::i;:::-;36207:2;36202:3;36198:12;36191:19;;35850:366;;;:::o;36222:419::-;36388:4;36426:2;36415:9;36411:18;36403:26;;36475:9;36469:4;36465:20;36461:1;36450:9;36446:17;36439:47;36503:131;36629:4;36503:131;:::i;:::-;36495:139;;36222:419;;;:::o;36647:176::-;36787:28;36783:1;36775:6;36771:14;36764:52;36647:176;:::o;36829:366::-;36971:3;36992:67;37056:2;37051:3;36992:67;:::i;:::-;36985:74;;37068:93;37157:3;37068:93;:::i;:::-;37186:2;37181:3;37177:12;37170:19;;36829:366;;;:::o;37201:419::-;37367:4;37405:2;37394:9;37390:18;37382:26;;37454:9;37448:4;37444:20;37440:1;37429:9;37425:17;37418:47;37482:131;37608:4;37482:131;:::i;:::-;37474:139;;37201:419;;;:::o;37626:191::-;37666:3;37685:20;37703:1;37685:20;:::i;:::-;37680:25;;37719:20;37737:1;37719:20;:::i;:::-;37714:25;;37762:1;37759;37755:9;37748:16;;37783:3;37780:1;37777:10;37774:36;;;37790:18;;:::i;:::-;37774:36;37626:191;;;;:::o;37823:166::-;37963:18;37959:1;37951:6;37947:14;37940:42;37823:166;:::o;37995:366::-;38137:3;38158:67;38222:2;38217:3;38158:67;:::i;:::-;38151:74;;38234:93;38323:3;38234:93;:::i;:::-;38352:2;38347:3;38343:12;38336:19;;37995:366;;;:::o;38367:419::-;38533:4;38571:2;38560:9;38556:18;38548:26;;38620:9;38614:4;38610:20;38606:1;38595:9;38591:17;38584:47;38648:131;38774:4;38648:131;:::i;:::-;38640:139;;38367:419;;;:::o;38792:382::-;38938:4;38976:2;38965:9;38961:18;38953:26;;38989:71;39057:1;39046:9;39042:17;39033:6;38989:71;:::i;:::-;39070:97;39163:2;39152:9;39148:18;39139:6;39070:97;:::i;:::-;38792:382;;;;;:::o;39180:332::-;39301:4;39339:2;39328:9;39324:18;39316:26;;39352:71;39420:1;39409:9;39405:17;39396:6;39352:71;:::i;:::-;39433:72;39501:2;39490:9;39486:18;39477:6;39433:72;:::i;:::-;39180:332;;;;;:::o;39518:115::-;39603:23;39620:5;39603:23;:::i;:::-;39598:3;39591:36;39518:115;;:::o;39639:218::-;39730:4;39768:2;39757:9;39753:18;39745:26;;39781:69;39847:1;39836:9;39832:17;39823:6;39781:69;:::i;:::-;39639:218;;;;:::o;39863:332::-;39984:4;40022:2;40011:9;40007:18;39999:26;;40035:71;40103:1;40092:9;40088:17;40079:6;40035:71;:::i;:::-;40116:72;40184:2;40173:9;40169:18;40160:6;40116:72;:::i;:::-;39863:332;;;;;:::o;40201:234::-;40341:34;40337:1;40329:6;40325:14;40318:58;40410:17;40405:2;40397:6;40393:15;40386:42;40201:234;:::o;40441:366::-;40583:3;40604:67;40668:2;40663:3;40604:67;:::i;:::-;40597:74;;40680:93;40769:3;40680:93;:::i;:::-;40798:2;40793:3;40789:12;40782:19;;40441:366;;;:::o;40813:419::-;40979:4;41017:2;41006:9;41002:18;40994:26;;41066:9;41060:4;41056:20;41052:1;41041:9;41037:17;41030:47;41094:131;41220:4;41094:131;:::i;:::-;41086:139;;40813:419;;;:::o;41238:148::-;41340:11;41377:3;41362:18;;41238:148;;;;:::o;41392:390::-;41498:3;41526:39;41559:5;41526:39;:::i;:::-;41581:89;41663:6;41658:3;41581:89;:::i;:::-;41574:96;;41679:65;41737:6;41732:3;41725:4;41718:5;41714:16;41679:65;:::i;:::-;41769:6;41764:3;41760:16;41753:23;;41502:280;41392:390;;;;:::o;41788:435::-;41968:3;41990:95;42081:3;42072:6;41990:95;:::i;:::-;41983:102;;42102:95;42193:3;42184:6;42102:95;:::i;:::-;42095:102;;42214:3;42207:10;;41788:435;;;;;:::o;42229:176::-;42369:28;42365:1;42357:6;42353:14;42346:52;42229:176;:::o;42411:366::-;42553:3;42574:67;42638:2;42633:3;42574:67;:::i;:::-;42567:74;;42650:93;42739:3;42650:93;:::i;:::-;42768:2;42763:3;42759:12;42752:19;;42411:366;;;:::o;42783:419::-;42949:4;42987:2;42976:9;42972:18;42964:26;;43036:9;43030:4;43026:20;43022:1;43011:9;43007:17;43000:47;43064:131;43190:4;43064:131;:::i;:::-;43056:139;;42783:419;;;:::o;43208:194::-;43248:4;43268:20;43286:1;43268:20;:::i;:::-;43263:25;;43302:20;43320:1;43302:20;:::i;:::-;43297:25;;43346:1;43343;43339:9;43331:17;;43370:1;43364:4;43361:11;43358:37;;;43375:18;;:::i;:::-;43358:37;43208:194;;;;:::o;43408:115::-;43493:23;43510:5;43493:23;:::i;:::-;43488:3;43481:36;43408:115;;:::o;43529:218::-;43620:4;43658:2;43647:9;43643:18;43635:26;;43671:69;43737:1;43726:9;43722:17;43713:6;43671:69;:::i;:::-;43529:218;;;;:::o;43753:171::-;43792:3;43815:24;43833:5;43815:24;:::i;:::-;43806:33;;43861:4;43854:5;43851:15;43848:41;;43869:18;;:::i;:::-;43848:41;43916:1;43909:5;43905:13;43898:20;;43753:171;;;:::o;43930:140::-;43979:9;44012:52;44030:33;44039:23;44056:5;44039:23;:::i;:::-;44030:33;:::i;:::-;44012:52;:::i;:::-;43999:65;;43930:140;;;:::o;44076:129::-;44162:36;44192:5;44162:36;:::i;:::-;44157:3;44150:49;44076:129;;:::o;44211:330::-;44331:4;44369:2;44358:9;44354:18;44346:26;;44382:70;44449:1;44438:9;44434:17;44425:6;44382:70;:::i;:::-;44462:72;44530:2;44519:9;44515:18;44506:6;44462:72;:::i;:::-;44211:330;;;;;:::o;44547:440::-;44695:4;44733:2;44722:9;44718:18;44710:26;;44746:71;44814:1;44803:9;44799:17;44790:6;44746:71;:::i;:::-;44827;44894:2;44883:9;44879:18;44870:6;44827:71;:::i;:::-;44908:72;44976:2;44965:9;44961:18;44952:6;44908:72;:::i;:::-;44547:440;;;;;;:::o;44993:332::-;45114:4;45152:2;45141:9;45137:18;45129:26;;45165:71;45233:1;45222:9;45218:17;45209:6;45165:71;:::i;:::-;45246:72;45314:2;45303:9;45299:18;45290:6;45246:72;:::i;:::-;44993:332;;;;;:::o;45331:98::-;45382:6;45416:5;45410:12;45400:22;;45331:98;;;:::o;45435:168::-;45518:11;45552:6;45547:3;45540:19;45592:4;45587:3;45583:14;45568:29;;45435:168;;;;:::o;45609:373::-;45695:3;45723:38;45755:5;45723:38;:::i;:::-;45777:70;45840:6;45835:3;45777:70;:::i;:::-;45770:77;;45856:65;45914:6;45909:3;45902:4;45895:5;45891:16;45856:65;:::i;:::-;45946:29;45968:6;45946:29;:::i;:::-;45941:3;45937:39;45930:46;;45699:283;45609:373;;;;:::o;45988:640::-;46183:4;46221:3;46210:9;46206:19;46198:27;;46235:71;46303:1;46292:9;46288:17;46279:6;46235:71;:::i;:::-;46316:72;46384:2;46373:9;46369:18;46360:6;46316:72;:::i;:::-;46398;46466:2;46455:9;46451:18;46442:6;46398:72;:::i;:::-;46517:9;46511:4;46507:20;46502:2;46491:9;46487:18;46480:48;46545:76;46616:4;46607:6;46545:76;:::i;:::-;46537:84;;45988:640;;;;;;;:::o;46634:141::-;46690:5;46721:6;46715:13;46706:22;;46737:32;46763:5;46737:32;:::i;:::-;46634:141;;;;:::o;46781:349::-;46850:6;46899:2;46887:9;46878:7;46874:23;46870:32;46867:119;;;46905:79;;:::i;:::-;46867:119;47025:1;47050:63;47105:7;47096:6;47085:9;47081:22;47050:63;:::i;:::-;47040:73;;46996:127;46781:349;;;;:::o
Swarm Source
ipfs://a3a1b43c38efa8d75ff9019a44c19fe687dd278e6a1faef7bfa1281bca6f66b7
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.