Overview
POL Balance
0 POL
POL Value
$0.00Token Holdings
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 10,196 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Face Image D... | 65433414 | 14 secs ago | IN | 0 POL | 0.04370622 | ||||
Mint With Certif... | 65433410 | 22 secs ago | IN | 0 POL | 0.40586907 | ||||
Set Back Image D... | 65433234 | 6 mins ago | IN | 0 POL | 0.00481839 | ||||
Set Back Image D... | 65433229 | 6 mins ago | IN | 0 POL | 0.04414406 | ||||
Set Face Image D... | 65433224 | 6 mins ago | IN | 0 POL | 0.00481699 | ||||
Set Face Image D... | 65433220 | 7 mins ago | IN | 0 POL | 0.04458978 | ||||
Mint With Certif... | 65433214 | 7 mins ago | IN | 0 POL | 0.40646013 | ||||
Set Face Image D... | 65432631 | 28 mins ago | IN | 0 POL | 0.0593955 | ||||
Mint With Certif... | 65432625 | 28 mins ago | IN | 0 POL | 0.4205986 | ||||
Set Face Image D... | 65432461 | 34 mins ago | IN | 0 POL | 0.00481699 | ||||
Set Face Image D... | 65432455 | 34 mins ago | IN | 0 POL | 0.05346139 | ||||
Mint With Certif... | 65432450 | 34 mins ago | IN | 0 POL | 0.47313654 | ||||
Set Back Image D... | 65432110 | 46 mins ago | IN | 0 POL | 0.00481839 | ||||
Set Back Image D... | 65432106 | 46 mins ago | IN | 0 POL | 0.05227703 | ||||
Set Face Image D... | 65432102 | 46 mins ago | IN | 0 POL | 0.00559393 | ||||
Set Face Image D... | 65432098 | 46 mins ago | IN | 0 POL | 0.06074339 | ||||
Mint With Certif... | 65432094 | 47 mins ago | IN | 0 POL | 0.41966327 | ||||
Update | 65431962 | 52 mins ago | IN | 0 POL | 0.0501642 | ||||
Set Back Image D... | 65431940 | 53 mins ago | IN | 0 POL | 0.00481839 | ||||
Set Back Image D... | 65431937 | 53 mins ago | IN | 0 POL | 0.05227703 | ||||
Set Face Image D... | 65431933 | 53 mins ago | IN | 0 POL | 0.00544311 | ||||
Set Face Image D... | 65431928 | 53 mins ago | IN | 0 POL | 0.04232578 | ||||
Mint With Certif... | 65431924 | 53 mins ago | IN | 0 POL | 0.41883808 | ||||
Set Back Image D... | 65431869 | 55 mins ago | IN | 0 POL | 0.00497382 | ||||
Set Back Image D... | 65431865 | 55 mins ago | IN | 0 POL | 0.05126407 |
Latest 25 internal transactions (View All)
Loading...
Loading
Contract Name:
WTCNFT
Compiler Version
v0.7.0+commit.9e61f92b
Contract Source Code (Solidity)
/** *Submitted for verification at polygonscan.com on 2023-02-10 */ // SPDX-License-Identifier: UNLICENSED // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.7/contracts/utils/Strings.sol pragma solidity ^0.7.0; /** * @dev String operations. */ library Strings { /** * @dev Converts a `uint256` to its ASCII `string` representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); uint256 index = digits - 1; temp = value; while (temp != 0) { buffer[index--] = bytes1(uint8(48 + temp % 10)); temp /= 10; } return string(buffer); } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.7/contracts/utils/EnumerableMap.sol pragma solidity ^0.7.0; /** * @dev Library for managing an enumerable variant of Solidity's * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] * type. * * Maps have the following properties: * * - Entries are added, removed, and checked for existence in constant time * (O(1)). * - Entries are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableMap for EnumerableMap.UintToAddressMap; * * // Declare a set state variable * EnumerableMap.UintToAddressMap private myMap; * } * ``` * * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are * supported. */ library EnumerableMap { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Map type with // bytes32 keys and values. // The Map implementation uses private functions, and user-facing // implementations (such as Uint256ToAddressMap) are just wrappers around // the underlying Map. // This means that we can only create new EnumerableMaps for types that fit // in bytes32. struct MapEntry { bytes32 _key; bytes32 _value; } struct Map { // Storage of map keys and values MapEntry[] _entries; // Position of the entry defined by a key in the `entries` array, plus 1 // because index 0 means a key is not in the map. mapping (bytes32 => uint256) _indexes; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) { // We read and store the key's index to prevent multiple reads from the same storage slot uint256 keyIndex = map._indexes[key]; if (keyIndex == 0) { // Equivalent to !contains(map, key) map._entries.push(MapEntry({ _key: key, _value: value })); // The entry is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value map._indexes[key] = map._entries.length; return true; } else { map._entries[keyIndex - 1]._value = value; return false; } } /** * @dev Removes a key-value pair from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function _remove(Map storage map, bytes32 key) private returns (bool) { // We read and store the key's index to prevent multiple reads from the same storage slot uint256 keyIndex = map._indexes[key]; if (keyIndex != 0) { // Equivalent to contains(map, key) // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one // in the array, and then remove the last entry (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = keyIndex - 1; uint256 lastIndex = map._entries.length - 1; // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. MapEntry storage lastEntry = map._entries[lastIndex]; // Move the last entry to the index where the entry to delete is map._entries[toDeleteIndex] = lastEntry; // Update the index for the moved entry map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved entry was stored map._entries.pop(); // Delete the index for the deleted slot delete map._indexes[key]; return true; } else { return false; } } /** * @dev Returns true if the key is in the map. O(1). */ function _contains(Map storage map, bytes32 key) private view returns (bool) { return map._indexes[key] != 0; } /** * @dev Returns the number of key-value pairs in the map. O(1). */ function _length(Map storage map) private view returns (uint256) { return map._entries.length; } /** * @dev Returns the key-value pair stored at position `index` in the map. O(1). * * Note that there are no guarantees on the ordering of entries inside the * array, and it may change when more entries are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) { require(map._entries.length > index, "EnumerableMap: index out of bounds"); MapEntry storage entry = map._entries[index]; return (entry._key, entry._value); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) { uint256 keyIndex = map._indexes[key]; if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key) return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function _get(Map storage map, bytes32 key) private view returns (bytes32) { uint256 keyIndex = map._indexes[key]; require(keyIndex != 0, "EnumerableMap: nonexistent key"); // Equivalent to contains(map, key) return map._entries[keyIndex - 1]._value; // All indexes are 1-based } /** * @dev Same as {_get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {_tryGet}. */ function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) { uint256 keyIndex = map._indexes[key]; require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key) return map._entries[keyIndex - 1]._value; // All indexes are 1-based } // UintToAddressMap struct UintToAddressMap { Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) { return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { return _remove(map._inner, bytes32(key)); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { return _contains(map._inner, bytes32(key)); } /** * @dev Returns the number of elements in the map. O(1). */ function length(UintToAddressMap storage map) internal view returns (uint256) { return _length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { (bytes32 key, bytes32 value) = _at(map._inner, index); return (uint256(key), address(uint160(uint256(value)))); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. * * _Available since v3.4._ */ function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) { (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key)); return (success, address(uint160(uint256(value)))); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key))))); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage)))); } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.7/contracts/token/ERC721/IERC721Receiver.sol pragma solidity ^0.7.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.7/contracts/introspection/IERC165.sol pragma solidity ^0.7.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.7/contracts/introspection/ERC165.sol pragma solidity ^0.7.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts may inherit from this and call {_registerInterface} to declare * their support of an interface. */ abstract contract ERC165 is IERC165 { /* * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7 */ bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /** * @dev Mapping of interface ids to whether or not it's supported. */ mapping(bytes4 => bool) private _supportedInterfaces; constructor () { // Derived contracts need only register support for their own interfaces, // we register support for ERC165 itself here _registerInterface(_INTERFACE_ID_ERC165); } /** * @dev See {IERC165-supportsInterface}. * * Time complexity O(1), guaranteed to always use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return _supportedInterfaces[interfaceId]; } /** * @dev Registers the contract as an implementer of the interface defined by * `interfaceId`. Support of the actual ERC165 interface is automatic and * registering its interface id is not required. * * See {IERC165-supportsInterface}. * * Requirements: * * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). */ function _registerInterface(bytes4 interfaceId) internal virtual { require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); _supportedInterfaces[interfaceId] = true; } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.7/contracts/token/ERC721/IERC721.sol pragma solidity ^0.7.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @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) external; /** * @dev Transfers `tokenId` token 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; /** * @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; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @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 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); /** * @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 calldata data) external; } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.7/contracts/token/ERC721/IERC721Enumerable.sol pragma solidity ^0.7.0; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.7/contracts/token/ERC721/IERC721Metadata.sol pragma solidity ^0.7.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @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); } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.7/contracts/math/SafeMath.sol pragma solidity ^0.7.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when 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 SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.7/contracts/utils/Counters.sol pragma solidity ^0.7.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath} * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never * directly accessed. */ library Counters { using SafeMath for uint256; struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { // The {SafeMath} overflow check can be skipped here, see the comment at the top counter._value += 1; } function decrement(Counter storage counter) internal { counter._value = counter._value.sub(1); } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.7/contracts/utils/Context.sol pragma solidity >=0.6.0 <0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN 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 payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.7/contracts/utils/Pausable.sol pragma solidity ^0.7.0; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor () { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.7/contracts/utils/Address.sol pragma solidity ^0.7.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.7/contracts/utils/EnumerableSet.sol pragma solidity ^0.7.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.7/contracts/token/ERC721/ERC721.sol pragma solidity ^0.7.0; /** * @title ERC721 Non-Fungible Token Standard basic implementation * @dev see https://eips.ethereum.org/EIPS/eip-721 */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable { using SafeMath for uint256; using Address for address; using EnumerableSet for EnumerableSet.UintSet; using EnumerableMap for EnumerableMap.UintToAddressMap; using Strings for uint256; // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; // Mapping from holder address to their (enumerable) set of owned tokens mapping (address => EnumerableSet.UintSet) private _holderTokens; // Enumerable mapping from token ids to their owners EnumerableMap.UintToAddressMap private _tokenOwners; // Mapping from token ID to approved address mapping (uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping (address => mapping (address => bool)) private _operatorApprovals; // Token name string private _name; // Token symbol string private _symbol; // Optional mapping for token URIs mapping (uint256 => string) private _tokenURIs; // Base URI string private _baseURI; /* * bytes4(keccak256('balanceOf(address)')) == 0x70a08231 * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3 * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465 * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5 * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde * * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^ * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd */ bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; /* * bytes4(keccak256('name()')) == 0x06fdde03 * bytes4(keccak256('symbol()')) == 0x95d89b41 * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd * * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f */ bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f; /* * bytes4(keccak256('totalSupply()')) == 0x18160ddd * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59 * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7 * * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63 */ bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor (string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(_INTERFACE_ID_ERC721); _registerInterface(_INTERFACE_ID_ERC721_METADATA); _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _holderTokens[owner].length(); } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token"); } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory _tokenURI = _tokenURIs[tokenId]; string memory base = baseURI(); // If there is no base URI, return the token URI. if (bytes(base).length == 0) { return _tokenURI; } // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked). if (bytes(_tokenURI).length > 0) { return string(abi.encodePacked(base, _tokenURI)); } // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI. return string(abi.encodePacked(base, tokenId.toString())); } /** * @dev Returns the base URI set via {_setBaseURI}. This will be * automatically added as a prefix in {tokenURI} to each token's URI, or * to the token ID if no specific URI is set for that token ID. */ function baseURI() public view virtual returns (string memory) { return _baseURI; } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { return _holderTokens[owner].at(index); } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds return _tokenOwners.length(); } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { (uint256 tokenId, ) = _tokenOwners.at(index); return tokenId; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { require(operator != _msgSender(), "ERC721: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransfer(from, to, tokenId, _data); } /** * @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. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @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 (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _tokenOwners.contains(tokenId); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: d* * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual { _mint(to, tokenId); require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _holderTokens[to].add(tokenId); _tokenOwners.set(tokenId, to); emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); // internal owner _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); // Clear metadata (if any) if (bytes(_tokenURIs[tokenId]).length != 0) { delete _tokenURIs[tokenId]; } _holderTokens[owner].remove(tokenId); _tokenOwners.remove(tokenId); emit Transfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); // internal owner require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _holderTokens[from].remove(tokenId); _holderTokens[to].add(tokenId); _tokenOwners.set(tokenId, to); emit Transfer(from, to, tokenId); } /** * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token"); _tokenURIs[tokenId] = _tokenURI; } /** * @dev Internal function to set the base URI for all token IDs. It is * automatically added as a prefix to the value returned in {tokenURI}, * or to the token ID if {tokenURI} is empty. */ function _setBaseURI(string memory baseURI_) internal virtual { _baseURI = baseURI_; } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) private returns (bool) { if (!to.isContract()) { return true; } bytes memory returndata = to.functionCall(abi.encodeWithSelector( IERC721Receiver(to).onERC721Received.selector, _msgSender(), from, tokenId, _data ), "ERC721: transfer to non ERC721Receiver implementer"); bytes4 retval = abi.decode(returndata, (bytes4)); return (retval == _ERC721_RECEIVED); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * 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, ``from``'s `tokenId` will be burned. * - `from` cannot be the zero address. * - `to` cannot be the zero address. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.7/contracts/token/ERC721/ERC721Pausable.sol pragma solidity ^0.7.0; /** * @dev ERC721 token with pausable token transfers, minting and burning. * * Useful for scenarios such as preventing trades until the end of an evaluation * period, or having an emergency switch for freezing all token transfers in the * event of a large bug. */ abstract contract ERC721Pausable is ERC721, Pausable { /** * @dev See {ERC721-_beforeTokenTransfer}. * * Requirements: * * - the contract must not be paused. */ function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override { super._beforeTokenTransfer(from, to, tokenId); require(!paused(), "ERC721Pausable: token transfer while paused"); } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.7/contracts/token/ERC721/ERC721Burnable.sol pragma solidity ^0.7.0; /** * @title ERC721 Burnable Token * @dev ERC721 Token that can be irreversibly burned (destroyed). */ abstract contract ERC721Burnable is Context, ERC721 { /** * @dev Burns `tokenId`. See {ERC721-_burn}. * * Requirements: * * - The caller must own `tokenId` or be an approved operator. */ function burn(uint256 tokenId) public virtual { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved"); _burn(tokenId); } } // File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.7/contracts/access/AccessControl.sol pragma solidity ^0.7.0; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context { using EnumerableSet for EnumerableSet.AddressSet; using Address for address; struct RoleData { EnumerableSet.AddressSet members; bytes32 adminRole; } mapping (bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view returns (bool) { return _roles[role].members.contains(account); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view returns (uint256) { return _roles[role].members.length(); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view returns (address) { return _roles[role].members.at(index); } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant"); _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke"); _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { emit RoleAdminChanged(role, _roles[role].adminRole, adminRole); _roles[role].adminRole = adminRole; } function _grantRole(bytes32 role, address account) private { if (_roles[role].members.add(account)) { emit RoleGranted(role, account, _msgSender()); } } function _revokeRole(bytes32 role, address account) private { if (_roles[role].members.remove(account)) { emit RoleRevoked(role, account, _msgSender()); } } } // File: contracts/WTC-NFT.sol pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; /** * @dev {ERC721} token, including: * * - ability for holders to burn (destroy) their tokens * - a minter role that allows for token minting (creation) * - a pauser role that allows to stop all token transfers * - token ID and URI autogeneration * * This contract uses {AccessControl} to lock permissioned functions using the * different roles - head to its documentation for details. * * The account that deploys the contract will be granted the minter and pauser * roles, as well as the default admin role, which will let it grant both minter * and pauser roles to other accounts. */ contract WTCNFTBase is Context, AccessControl, ERC721Burnable, ERC721Pausable { address public contractOwner; bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); /** * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the * account that deploys the contract. * * Token URIs will be autogenerated based on `baseURI` and their token IDs. * See {ERC721-tokenURI}. */ constructor(string memory name, string memory symbol, string memory baseURI) ERC721(name, symbol) { contractOwner = _msgSender(); _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); _setupRole(MINTER_ROLE, _msgSender()); _setupRole(PAUSER_ROLE, _msgSender()); _setBaseURI(baseURI); } /** * @dev Pauses all token transfers. * * See {ERC721Pausable} and {Pausable-_pause}. * * Requirements: * * - the caller must have the `PAUSER_ROLE`. */ function pause() public virtual { require(hasRole(PAUSER_ROLE, _msgSender()), "WTCNFTBase: must have pauser role to pause"); _pause(); } /** * @dev Unpauses all token transfers. * * See {ERC721Pausable} and {Pausable-_unpause}. * * Requirements: * * - the caller must have the `PAUSER_ROLE`. */ function unpause() public virtual { require(hasRole(PAUSER_ROLE, _msgSender()), "WTCNFTBase: must have pauser role to unpause"); _unpause(); } function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override(ERC721, ERC721Pausable) { super._beforeTokenTransfer(from, to, tokenId); } /** * @dev It updates `baseURI`. * * Requirements: * * - the caller must have the `MINTER_ROLE`. */ function updateBaseURI(string memory baseURI) public { require(hasRole(MINTER_ROLE, _msgSender()), "WTC: must have minter role to update baseURI"); _setBaseURI(baseURI); } /** * @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, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev Returns whether `str` is equal to `str2`. * */ function compareString(string memory str, string memory str2) internal view virtual returns (bool) { if (keccak256(abi.encodePacked(str)) == keccak256(abi.encodePacked(str2))) { return true; } return false; } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApproved(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "WTCNFTBase: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender)); } /** * @dev Returns the ammount of decimals. * * Unlike ERC20, ERC721 lacks a decimals field, since each token is distinct and cannot be partitioned. * */ function decimals() public pure returns (uint8) { return uint8(0); } } /** * @dev {WTCNFT} token, including: * * - ability for holders to access their tokens * - each token is linked to certificate data * - ability for holders to transfer their tokens * - only a user with minter role is able to mint a token * - only a user with minter role or approved is able to update a token * - only a user with minter role or approved is able to burn a token * */ contract WTCNFT is WTCNFTBase { using Counters for Counters.Counter; struct Certificate { string certificateCardId; string watchBrand; string watchModel; string watchReference; string watchYear; ImageStorage faceImage; ImageStorage backImage; string pdfDigest; string jsonDigest; string jsonString; } event CertificateUpdate(uint256 indexed tokenId, string indexed certificateCardId, string pdfDigest, string jsonDigest, string jsonString); event CertificateDeleted(uint256 indexed tokenId, string indexed certificateCardId, string pdfDigest, string jsonDigest, string jsonString); event ImageData(uint256 indexed tokenId, string indexed certificateCardId, string indexed imageName, uint256 imagePartIndex, string imageData); event OwnershipReset(uint256 indexed tokenId, address indexed from, address indexed to); mapping(uint256 => Certificate) private certificates; Counters.Counter private _tokenIdTracker; constructor() WTCNFTBase("Watch Certificate", "WTC", "https://api.watchcertificate.org/api/v1/certificates/nft/") { } /** * @dev Creates a new token for `to` and set tokenURI with `certificateCardId`. Its token ID will be automatically * assigned (and available on the emitted {IERC721-Transfer} event), and the token * URI autogenerated based on the base URI passed at construction. * * See {ERC721-_mint}. * * Requirements: * * - `certificateCardId` must exist. * - the caller must have the `MINTER_ROLE`. */ function mintWithCertificateCardId(address to, string memory certificateCardId, string memory watchBrand, string memory watchModel, string memory watchReference, string memory watchYear, string memory pdfDigest, string memory jsonDigest, string memory jsonString) public { require(bytes(certificateCardId).length > 0, "WTC: certificateCardId should not be empty"); require(!isCertificateWithCertificateCardIdExists(certificateCardId), "WTC: certificateCardId must be unique"); require(hasRole(MINTER_ROLE, _msgSender()), "WTC: must have minter role to mint"); _tokenIdTracker.increment(); uint256 newTokenId = _tokenIdTracker.current(); _mint(to, newTokenId); _setTokenURI(newTokenId, certificateCardId); certificates[newTokenId].certificateCardId = certificateCardId; certificates[newTokenId].watchBrand = watchBrand; certificates[newTokenId].watchModel = watchModel; certificates[newTokenId].watchReference = watchReference; certificates[newTokenId].watchYear = watchYear; certificates[newTokenId].pdfDigest = pdfDigest; certificates[newTokenId].jsonDigest = jsonDigest; certificates[newTokenId].jsonString = jsonString; emit CertificateUpdate(newTokenId, certificates[newTokenId].certificateCardId, certificates[newTokenId].pdfDigest, certificates[newTokenId].jsonDigest, certificates[newTokenId].jsonString); } /** * @dev Updates an existing token for `tokenId`. * CertificateUpdate event is triggered on success * * Requirements: * * - `tokenId` must exist. * - the caller must have the `MINTER_ROLE`. */ function update(uint256 tokenId, string memory pdfDigest, string memory jsonDigest, string memory jsonString) public { require(_exists(tokenId), "WTC: tokenId must exist to update certificate"); //solhint-disable-next-line max-line-length require(_isApproved(_msgSender(), tokenId) || hasRole(MINTER_ROLE, _msgSender()), "WTC: must have minter role or be approved to update"); certificates[tokenId].pdfDigest = pdfDigest; certificates[tokenId].jsonDigest = jsonDigest; certificates[tokenId].jsonString = jsonString; emit CertificateUpdate(tokenId, certificates[tokenId].certificateCardId, certificates[tokenId].pdfDigest, certificates[tokenId].jsonDigest, certificates[tokenId].jsonString); } /** * @dev Deletes an existing token for `tokenId`. * * See {ERC721-_burn}. * * Requirements: * * - `tokenId` must exist. * - the caller must have the `MINTER_ROLE` or be the owner or be approved. */ function burn(uint256 tokenId) override public virtual { require(_exists(tokenId), "WTC: tokenId must exist to burn certificate"); //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId) || hasRole(MINTER_ROLE, _msgSender()), "WTC: must have minter role or be the owner or be approved to burn"); Certificate memory certificate = certificates[tokenId]; delete certificates[tokenId]; emit CertificateDeleted(tokenId, certificate.certificateCardId, certificate.pdfDigest, certificate.jsonDigest, certificate.jsonString); _burn(tokenId); } /** * @dev Check certificate for `certificateCardId` exists. * * Requirements: * * - `certificateCardId` must exist. */ function isCertificateWithCertificateCardIdExists(string memory certificateCardId) public view returns (bool) { require(bytes(certificateCardId).length > 0, "WTC: certificateCardId should not be empty"); uint256 tokenId = 1; while (tokenId <= _tokenIdTracker.current()) { if (compareString(certificates[tokenId].certificateCardId, certificateCardId)) { return true; } tokenId++; } return false; } /** * @dev Return `tokenId` for `certificateCardId`. * * Requirements: * * - `certificateCardId` must exist. */ function tokenIdWithCertificateCardId(string memory certificateCardId) public view returns (uint256) { require(bytes(certificateCardId).length > 0, "WTC: certificateCardId should not be empty"); uint256 tokenId = 1; while (tokenId <= _tokenIdTracker.current()) { if (compareString(certificates[tokenId].certificateCardId, certificateCardId)) { return tokenId; } tokenId++; } require(false, "WTC: tokenId with certificateCardId not found"); } /** * @dev Return `pdfDigest` for `certificateCardId`. * * Requirements: * * - `certificateCardId` must exist. */ function pdfDigestWithCertificateCardId(string memory certificateCardId) public view returns (string memory) { require(bytes(certificateCardId).length > 0, "WTC: certificateCardId should not be empty"); uint256 tokenId = 1; while (tokenId <= _tokenIdTracker.current()) { if (compareString(certificates[tokenId].certificateCardId, certificateCardId)) { return certificates[tokenId].pdfDigest; } tokenId++; } require(false, "WTC: digest with certificateCardId not found"); } /** * @dev Return `pdfDigest` for `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function pdfDigestWithTokenId(uint256 tokenId) public view returns (string memory) { require(_exists(tokenId), "WTC: tokenId must exist to get certificate digest"); return certificates[tokenId].pdfDigest; } /** * @dev Return `certifcate` for `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function certificateWithTokenId(uint256 tokenId) public view returns (Certificate memory) { require(_exists(tokenId), "WTC: tokenId must exist to get certificate"); return certificates[tokenId]; } // --- IMAGES // ------ FACE IMAGE /** * @dev Updates face image data for an existing token with `tokenId`. * ImageData event is triggered on success * * Requirements: * * - `tokenId` must exist. * - the caller is approved must have the `MINTER_ROLE`. */ function setFaceImageData(uint256 tokenId, string calldata imageName, uint256 imagePartIndex, string calldata imageData) public { require(_isApproved(_msgSender(), tokenId) || hasRole(MINTER_ROLE, _msgSender()), "WTC: must have minter role or be approved to set face image data"); require(_exists(tokenId), "WTC: tokenId must exist to set face image data"); ImageStorage faceImage = new ImageStorage(); if (imagePartIndex == 0) { // INFO: reinitialize image certificates[tokenId].faceImage = faceImage; } emit ImageData(tokenId, certificates[tokenId].certificateCardId, imageName, imagePartIndex, imageData); } /** * @dev Updates face image data transaction hash for an existing token with `tokenId`. * * Requirements: * * - `tokenId` must exist. * - the caller is approved must have the `MINTER_ROLE`. */ function setFaceImageDataTxHash(uint256 tokenId, string memory txHash) public { require(_isApproved(_msgSender(), tokenId) || hasRole(MINTER_ROLE, _msgSender()), "WTC: must have minter role or be approved to set face image data tx hash"); require(_exists(tokenId), "WTC: tokenId must exist to set face image data tx hash"); certificates[tokenId].faceImage.setTxHashImageData(txHash); } /** * @dev Get face image data transaction hash for an existing token with `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function getFaceImageDataTxHash(uint256 tokenId, uint256 imagePartIndex) public view returns (string memory) { require(_exists(tokenId), "WTC: tokenId must exist to get face image data tx hash"); Certificate memory certificate = certificates[tokenId]; ImageStorage faceImage = certificate.faceImage; string memory txHashImageData = faceImage.txHashImageData(imagePartIndex); return txHashImageData; } // ------ BACK IMAGE /** * @dev Updates back image data for an existing token with `tokenId`. * ImageData event is triggered on success * * Requirements: * * - `tokenId` must exist. * - the caller is approved must have the `MINTER_ROLE`. */ function setBackImageData(uint256 tokenId, string calldata imageName, uint256 imagePartIndex, string calldata imageData) public { require(_isApproved(_msgSender(), tokenId) || hasRole(MINTER_ROLE, _msgSender()), "WTC: must have minter role or be approved to set back image data"); require(_exists(tokenId), "WTC: tokenId must exist to set back image data"); ImageStorage backImage = new ImageStorage(); if (imagePartIndex == 0) { // INFO: reinitialize image certificates[tokenId].backImage = backImage; } emit ImageData(tokenId, certificates[tokenId].certificateCardId, imageName, imagePartIndex, imageData); } /** * @dev Updates back image data transaction hash for an existing token with `tokenId`. * * Requirements: * * - `tokenId` must exist. * - the caller is approved must have the `MINTER_ROLE`. */ function setBackImageDataTxHash(uint256 tokenId, string memory txHash) public { require(_isApproved(_msgSender(), tokenId) || hasRole(MINTER_ROLE, _msgSender()), "WTC: must have minter role or be approved to set back image data tx hash"); require(_exists(tokenId), "WTC: tokenId must exist to set back image data tx hash"); certificates[tokenId].backImage.setTxHashImageData(txHash); } /** * @dev Get back image data transaction hash for an existing token with `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function getBackImageDataTxHash(uint256 tokenId, uint256 imagePartIndex) public view returns (string memory) { require(_exists(tokenId), "WTC: tokenId must exist to get back image data tx hash"); Certificate memory certificate = certificates[tokenId]; ImageStorage backImage = certificate.backImage; string memory txHashImageData = backImage.txHashImageData(imagePartIndex); return txHashImageData; } // --- RESET OWNERSHIP /** * @dev reset ownership * */ function resetOwnership(uint256 tokenId) public { require(_exists(tokenId), "WTC: tokenId must exist to reset NFT ownership"); require(_isApproved(_msgSender(), tokenId) || hasRole(MINTER_ROLE, _msgSender()), "WTC: must have minter role or be approved to reset NFT ownership"); address from = ERC721.ownerOf(tokenId); address to = contractOwner; require(from != to, "WTC: from and to address are the same, ownership should not be reset"); _transfer(from, to, tokenId); emit OwnershipReset(tokenId, from, to); } } /** * @dev {ImageStorage} thanks to OpenGem, including: * * - ability to store image using events * */ contract ImageStorage { string[] public txHashImageData; function setTxHashImageData(string memory txHash) public { txHashImageData.push(txHash); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"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":"tokenId","type":"uint256"},{"indexed":true,"internalType":"string","name":"certificateCardId","type":"string"},{"indexed":false,"internalType":"string","name":"pdfDigest","type":"string"},{"indexed":false,"internalType":"string","name":"jsonDigest","type":"string"},{"indexed":false,"internalType":"string","name":"jsonString","type":"string"}],"name":"CertificateDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"string","name":"certificateCardId","type":"string"},{"indexed":false,"internalType":"string","name":"pdfDigest","type":"string"},{"indexed":false,"internalType":"string","name":"jsonDigest","type":"string"},{"indexed":false,"internalType":"string","name":"jsonString","type":"string"}],"name":"CertificateUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"string","name":"certificateCardId","type":"string"},{"indexed":true,"internalType":"string","name":"imageName","type":"string"},{"indexed":false,"internalType":"uint256","name":"imagePartIndex","type":"uint256"},{"indexed":false,"internalType":"string","name":"imageData","type":"string"}],"name":"ImageData","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipReset","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","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":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"certificateWithTokenId","outputs":[{"components":[{"internalType":"string","name":"certificateCardId","type":"string"},{"internalType":"string","name":"watchBrand","type":"string"},{"internalType":"string","name":"watchModel","type":"string"},{"internalType":"string","name":"watchReference","type":"string"},{"internalType":"string","name":"watchYear","type":"string"},{"internalType":"contract ImageStorage","name":"faceImage","type":"address"},{"internalType":"contract ImageStorage","name":"backImage","type":"address"},{"internalType":"string","name":"pdfDigest","type":"string"},{"internalType":"string","name":"jsonDigest","type":"string"},{"internalType":"string","name":"jsonString","type":"string"}],"internalType":"struct WTCNFT.Certificate","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"imagePartIndex","type":"uint256"}],"name":"getBackImageDataTxHash","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"imagePartIndex","type":"uint256"}],"name":"getFaceImageDataTxHash","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"certificateCardId","type":"string"}],"name":"isCertificateWithCertificateCardIdExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"certificateCardId","type":"string"},{"internalType":"string","name":"watchBrand","type":"string"},{"internalType":"string","name":"watchModel","type":"string"},{"internalType":"string","name":"watchReference","type":"string"},{"internalType":"string","name":"watchYear","type":"string"},{"internalType":"string","name":"pdfDigest","type":"string"},{"internalType":"string","name":"jsonDigest","type":"string"},{"internalType":"string","name":"jsonString","type":"string"}],"name":"mintWithCertificateCardId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"certificateCardId","type":"string"}],"name":"pdfDigestWithCertificateCardId","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"pdfDigestWithTokenId","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"resetOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","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":"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":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"imageName","type":"string"},{"internalType":"uint256","name":"imagePartIndex","type":"uint256"},{"internalType":"string","name":"imageData","type":"string"}],"name":"setBackImageData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"txHash","type":"string"}],"name":"setBackImageDataTxHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"imageName","type":"string"},{"internalType":"uint256","name":"imagePartIndex","type":"uint256"},{"internalType":"string","name":"imageData","type":"string"}],"name":"setFaceImageData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"txHash","type":"string"}],"name":"setFaceImageDataTxHash","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":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"certificateCardId","type":"string"}],"name":"tokenIdWithCertificateCardId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"","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":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"pdfDigest","type":"string"},{"internalType":"string","name":"jsonDigest","type":"string"},{"internalType":"string","name":"jsonString","type":"string"}],"name":"update","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"updateBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405180604001604052806011815260200170576174636820436572746966696361746560781b8152506040518060400160405280600381526020016257544360e81b815250604051806060016040528060398152602001620061df603991398282620000866301ffc9a760e01b620001ad565b81516200009b90600790602085019062000334565b508051620000b190600890602084019062000334565b50620000c46380ac58cd60e01b620001ad565b620000d6635b5e139f60e01b620001ad565b620000e863780e9d6360e01b620001ad565b5050600b805460ff19169055620000fe6200020b565b600b80546001600160a01b039290921661010002610100600160a81b03199092169190911790556200013b6000620001356200020b565b6200020f565b6200016a7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6620001356200020b565b620001997f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a620001356200020b565b620001a4816200021f565b50505062000407565b6001600160e01b03198082161415620001e35760405162461bcd60e51b8152600401620001da90620003d0565b60405180910390fd5b6001600160e01b0319166000908152600160208190526040909120805460ff19169091179055565b3390565b6200021b828262000234565b5050565b80516200021b90600a90602084019062000334565b600082815260208181526040909120620002599183906200315e620002ad821b17901c565b156200021b57620002696200020b565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000620002c4836001600160a01b038416620002cd565b90505b92915050565b6000620002db83836200031c565b6200031357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620002c7565b506000620002c7565b60009081526001919091016020526040902054151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200037757805160ff1916838001178555620003a7565b82800160010185558215620003a7579182015b82811115620003a75782518255916020019190600101906200038a565b50620003b5929150620003b9565b5090565b5b80821115620003b55760008155600101620003ba565b6020808252601c908201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604082015260600190565b615dc880620004176000396000f3fe608060405234801561001057600080fd5b50600436106102a05760003560e01c80636522bff111610167578063a22cb465116100ce578063ce606ee011610087578063ce606ee0146105b9578063d5391393146105c1578063d547741f146105c9578063e63ab1e9146105dc578063e985e9c5146105e4578063eb7898b2146105f7576102a0565b8063a22cb4651461053a578063b86525001461054d578063b88d4fde14610560578063c46ba90f14610573578063c87b56dd14610593578063ca15c873146105a6576102a0565b80638456cb59116101205780638456cb59146104e95780639010d07c146104f157806391d1485414610504578063931688cb1461051757806395d89b411461052a578063a217fddf14610532576102a0565b80636522bff1146104825780636c0360eb146104955780636ca2f5ef1461049d5780636d8685ab146104b057806370a08231146104c35780637f95447e146104d6576102a0565b8063313ce5671161020b5780635158f090116101c45780635158f0901461041b57806353950fdf1461042e5780635948c1bc146104415780635c975abb146104545780635eb637591461045c5780636352211e1461046f576102a0565b8063313ce567146103b257806336568abe146103c75780633f4ba83a146103da57806342842e0e146103e257806342966c68146103f55780634f6ccce714610408576102a0565b806321a9fd991161025d57806321a9fd991461034057806323b872dd14610353578063248a9ca3146103665780632ce19dd6146103795780632f2ff15d1461038c5780632f745c591461039f576102a0565b806301ffc9a7146102a557806306fdde03146102ce578063081812fc146102e3578063095ea7b3146103035780630f8c7d3a1461031857806318160ddd1461032b575b600080fd5b6102b86102b3366004614414565b61060a565b6040516102c59190614811565b60405180910390f35b6102d661062d565b6040516102c59190614825565b6102f66102f13660046143b7565b6106c3565b6040516102c591906147c0565b61031661031136600461438d565b61070f565b005b6103166103263660046144f2565b6107a7565b6103336108f7565b6040516102c5919061481c565b6102d661034e3660046143f3565b610908565b610316610361366004614161565b610ebb565b6103336103743660046143b7565b610ef3565b6102d661038736600461444c565b610f08565b61031661039a3660046143cf565b6110a7565b6103336103ad36600461438d565b6110ef565b6103ba611118565b6040516102c591906158dd565b6103166103d53660046143cf565b61111d565b61031661115f565b6103166103f0366004614161565b6111b1565b6103166104033660046143b7565b6111cc565b6103336104163660046143b7565b611835565b61033361042936600461444c565b61184b565b61031661043c366004614572565b611917565b6102d661044f3660046143b7565b6119ff565b6102b8611ac8565b6102d661046a3660046143f3565b611ad1565b6102f661047d3660046143b7565b612024565b6103166104903660046145b7565b61204c565b6102d66121af565b6103166104ab3660046143b7565b612210565b6103166104be366004614572565b612316565b6103336104d1366004614112565b6123c2565b6103166104e4366004614244565b61240b565b610316612663565b6102f66104ff3660046143f3565b6126b3565b6102b86105123660046143cf565b6126cb565b61031661052536600461444c565b6126e3565b6102d6612725565b610333612786565b610316610548366004614209565b61278b565b61031661055b3660046144f2565b612859565b61031661056e3660046141a1565b612931565b6105866105813660046143b7565b612970565b6040516102c59190615791565b6102d66105a13660046143b7565b612e8f565b6103336105b43660046143b7565b612fd5565b6102f6612fec565b610333613000565b6103166105d73660046143cf565b613012565b61033361304c565b6102b86105f236600461412d565b613070565b6102b861060536600461444c565b61309e565b6001600160e01b0319811660009081526001602052604090205460ff165b919050565b60078054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106b95780601f1061068e576101008083540402835291602001916106b9565b820191906000526020600020905b81548152906001019060200180831161069c57829003601f168201915b5050505050905090565b60006106ce82613173565b6106f35760405162461bcd60e51b81526004016106ea906151d0565b60405180910390fd5b506000908152600560205260409020546001600160a01b031690565b600061071a82612024565b9050806001600160a01b0316836001600160a01b0316141561074e5760405162461bcd60e51b81526004016106ea90615433565b806001600160a01b0316610760613180565b6001600160a01b0316148061077c575061077c816105f2613180565b6107985760405162461bcd60e51b81526004016106ea90614f32565b6107a28383613184565b505050565b6107b86107b2613180565b876131f2565b806107d857506107d8600080516020615d73833981519152610512613180565b6107f45760405162461bcd60e51b81526004016106ea906152b9565b6107fd86613173565b6108195760405162461bcd60e51b81526004016106ea90614ee4565b600060405161082790613f1f565b604051809103906000f080158015610843573d6000803e3d6000fd5b50905083610876576000878152600c6020526040902060060180546001600160a01b0319166001600160a01b0383161790555b8585604051610886929190614711565b6040805191829003822060008a8152600c6020529190912090916108aa9190614750565b6040518091039020887fc974d5c20c92f16ef296fd9eebe00dd8e662f6562dc69af3c89244ea70db4a328787876040516108e6939291906158a7565b60405180910390a450505050505050565b6000610903600361325b565b905090565b606061091383613173565b61092f5760405162461bcd60e51b81526004016106ea906148aa565b610937613f2c565b6000848152600c60209081526040918290208251815460026001821615610100026000190190911604601f8101849004909302810161016090810190945261014081018381529093919284928491908401828280156109d75780601f106109ac576101008083540402835291602001916109d7565b820191906000526020600020905b8154815290600101906020018083116109ba57829003601f168201915b50505050508152602001600182018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a795780601f10610a4e57610100808354040283529160200191610a79565b820191906000526020600020905b815481529060010190602001808311610a5c57829003601f168201915b5050509183525050600282810180546040805160206001841615610100026000190190931694909404601f81018390048302850183019091528084529381019390830182828015610b0b5780601f10610ae057610100808354040283529160200191610b0b565b820191906000526020600020905b815481529060010190602001808311610aee57829003601f168201915b505050918352505060038201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015610b9f5780601f10610b7457610100808354040283529160200191610b9f565b820191906000526020600020905b815481529060010190602001808311610b8257829003601f168201915b505050918352505060048201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015610c335780601f10610c0857610100808354040283529160200191610c33565b820191906000526020600020905b815481529060010190602001808311610c1657829003601f168201915b505050918352505060058201546001600160a01b039081166020808401919091526006840154909116604080840191909152600784018054825160026101006001841615026000190190921691909104601f810185900485028201850190935282815260609094019392909190830182828015610cf15780601f10610cc657610100808354040283529160200191610cf1565b820191906000526020600020905b815481529060010190602001808311610cd457829003601f168201915b505050918352505060088201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015610d855780601f10610d5a57610100808354040283529160200191610d85565b820191906000526020600020905b815481529060010190602001808311610d6857829003601f168201915b505050918352505060098201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015610e195780601f10610dee57610100808354040283529160200191610e19565b820191906000526020600020905b815481529060010190602001808311610dfc57829003601f168201915b5050509190925250505060c081015160405163703bd4dd60e11b8152919250906060906001600160a01b0383169063e077a9ba90610e5b90889060040161481c565b60006040518083038186803b158015610e7357600080fd5b505afa158015610e87573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610eaf919081019061447f565b93505050505b92915050565b610ecc610ec6613180565b82613266565b610ee85760405162461bcd60e51b81526004016106ea906154be565b6107a28383836132d8565b60009081526020819052604090206002015490565b60606000825111610f2b5760405162461bcd60e51b81526004016106ea90615474565b60015b610f38600d6133e6565b811161108f576000818152600c602090815260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452610fdf9392830182828015610fd45780601f10610fa957610100808354040283529160200191610fd4565b820191906000526020600020905b815481529060010190602001808311610fb757829003601f168201915b5050505050846133ea565b15611087576000818152600c602090815260409182902060070180548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452909183018282801561107a5780601f1061104f5761010080835404028352916020019161107a565b820191906000526020600020905b81548152906001019060200180831161105d57829003601f168201915b5050505050915050610628565b600101610f2e565b60405162461bcd60e51b81526004016106ea90614c8e565b6000828152602081905260409020600201546110c590610512613180565b6110e15760405162461bcd60e51b81526004016106ea9061498d565b6110eb8282613448565b5050565b6001600160a01b038216600090815260026020526040812061111190836134b1565b9392505050565b600090565b611125613180565b6001600160a01b0316816001600160a01b0316146111555760405162461bcd60e51b81526004016106ea90615742565b6110eb82826134bd565b61118b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610512613180565b6111a75760405162461bcd60e51b81526004016106ea906156a0565b6111af613526565b565b6107a283838360405180602001604052806000815250612931565b6111d581613173565b6111f15760405162461bcd60e51b81526004016106ea90614fd9565b6111fc610ec6613180565b8061121c575061121c600080516020615d73833981519152610512613180565b6112385760405162461bcd60e51b81526004016106ea90615546565b611240613f2c565b6000828152600c60209081526040918290208251815460026001821615610100026000190190911604601f8101849004909302810161016090810190945261014081018381529093919284928491908401828280156112e05780601f106112b5576101008083540402835291602001916112e0565b820191906000526020600020905b8154815290600101906020018083116112c357829003601f168201915b50505050508152602001600182018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156113825780601f1061135757610100808354040283529160200191611382565b820191906000526020600020905b81548152906001019060200180831161136557829003601f168201915b5050509183525050600282810180546040805160206001841615610100026000190190931694909404601f810183900483028501830190915280845293810193908301828280156114145780601f106113e957610100808354040283529160200191611414565b820191906000526020600020905b8154815290600101906020018083116113f757829003601f168201915b505050918352505060038201805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529382019392918301828280156114a85780601f1061147d576101008083540402835291602001916114a8565b820191906000526020600020905b81548152906001019060200180831161148b57829003601f168201915b505050918352505060048201805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815293820193929183018282801561153c5780601f106115115761010080835404028352916020019161153c565b820191906000526020600020905b81548152906001019060200180831161151f57829003601f168201915b505050918352505060058201546001600160a01b039081166020808401919091526006840154909116604080840191909152600784018054825160026101006001841615026000190190921691909104601f8101859004850282018501909352828152606090940193929091908301828280156115fa5780601f106115cf576101008083540402835291602001916115fa565b820191906000526020600020905b8154815290600101906020018083116115dd57829003601f168201915b505050918352505060088201805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815293820193929183018282801561168e5780601f106116635761010080835404028352916020019161168e565b820191906000526020600020905b81548152906001019060200180831161167157829003601f168201915b505050918352505060098201805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529382019392918301828280156117225780601f106116f757610100808354040283529160200191611722565b820191906000526020600020905b81548152906001019060200180831161170557829003601f168201915b505050919092525050506000838152600c602052604081209192506117478282613f91565b611755600183016000613f91565b611763600283016000613f91565b611771600383016000613f91565b61177f600483016000613f91565b6005820180546001600160a01b031990811690915560068301805490911690556117ad600783016000613f91565b6117bb600883016000613f91565b6117c9600983016000613f91565b505080516040516117da91906146f5565b6040518091039020827fce800f051025c107d292d462ffc77996c1b95849dc9b7e85142408293b6912e68360e0015184610100015185610120015160405161182493929190614838565b60405180910390a36110eb82613594565b600080611843600384613661565b509392505050565b60008082511161186d5760405162461bcd60e51b81526004016106ea90615474565b60015b61187a600d6133e6565b81116118ff576000818152600c602090815260409182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084526118eb9392830182828015610fd45780601f10610fa957610100808354040283529160200191610fd4565b156118f7579050610628565b600101611870565b60405162461bcd60e51b81526004016106ea9061559b565b611928611922613180565b836131f2565b806119485750611948600080516020615d73833981519152610512613180565b6119645760405162461bcd60e51b81526004016106ea906150af565b61196d82613173565b6119895760405162461bcd60e51b81526004016106ea90614b21565b6000828152600c602052604090819020600501549051636b8b476560e01b81526001600160a01b0390911690636b8b4765906119c9908490600401614825565b600060405180830381600087803b1580156119e357600080fd5b505af11580156119f7573d6000803e3d6000fd5b505050505050565b6060611a0a82613173565b611a265760405162461bcd60e51b81526004016106ea90615268565b6000828152600c602090815260409182902060070180548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084529091830182828015611abc5780601f10611a9157610100808354040283529160200191611abc565b820191906000526020600020905b815481529060010190602001808311611a9f57829003601f168201915b50505050509050919050565b600b5460ff1690565b6060611adc83613173565b611af85760405162461bcd60e51b81526004016106ea90614d7b565b611b00613f2c565b6000848152600c60209081526040918290208251815460026001821615610100026000190190911604601f810184900490930281016101609081019094526101408101838152909391928492849190840182828015611ba05780601f10611b7557610100808354040283529160200191611ba0565b820191906000526020600020905b815481529060010190602001808311611b8357829003601f168201915b50505050508152602001600182018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611c425780601f10611c1757610100808354040283529160200191611c42565b820191906000526020600020905b815481529060010190602001808311611c2557829003601f168201915b5050509183525050600282810180546040805160206001841615610100026000190190931694909404601f81018390048302850183019091528084529381019390830182828015611cd45780601f10611ca957610100808354040283529160200191611cd4565b820191906000526020600020905b815481529060010190602001808311611cb757829003601f168201915b505050918352505060038201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015611d685780601f10611d3d57610100808354040283529160200191611d68565b820191906000526020600020905b815481529060010190602001808311611d4b57829003601f168201915b505050918352505060048201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015611dfc5780601f10611dd157610100808354040283529160200191611dfc565b820191906000526020600020905b815481529060010190602001808311611ddf57829003601f168201915b505050918352505060058201546001600160a01b039081166020808401919091526006840154909116604080840191909152600784018054825160026101006001841615026000190190921691909104601f810185900485028201850190935282815260609094019392909190830182828015611eba5780601f10611e8f57610100808354040283529160200191611eba565b820191906000526020600020905b815481529060010190602001808311611e9d57829003601f168201915b505050918352505060088201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015611f4e5780601f10611f2357610100808354040283529160200191611f4e565b820191906000526020600020905b815481529060010190602001808311611f3157829003601f168201915b505050918352505060098201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015611fe25780601f10611fb757610100808354040283529160200191611fe2565b820191906000526020600020905b815481529060010190602001808311611fc557829003601f168201915b5050509190925250505060a081015160405163703bd4dd60e11b8152919250906060906001600160a01b0383169063e077a9ba90610e5b90889060040161481c565b6000610eb582604051806060016040528060298152602001615d4a602991396003919061367f565b61205584613173565b6120715760405162461bcd60e51b81526004016106ea90614e6d565b61208261207c613180565b856131f2565b806120a257506120a2600080516020615d73833981519152610512613180565b6120be5760405162461bcd60e51b81526004016106ea90615024565b6000848152600c6020908152604090912084516120e392600790920191860190613fd5565b506000848152600c60209081526040909120835161210992600890920191850190613fd5565b506000848152600c60209081526040909120825161212f92600990920191840190613fd5565b506000848152600c602052604090819020905161214c9190614750565b604080519182900382206000878152600c60205291909120909186917facab8395a3b1066446f4c6edfa3690bc95345549a14e41e5319563e2fec842a5916121a1916007810191600882019160090190614871565b60405180910390a350505050565b600a8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106b95780601f1061068e576101008083540402835291602001916106b9565b61221981613173565b6122355760405162461bcd60e51b81526004016106ea906155e8565b612246612240613180565b826131f2565b806122665750612266600080516020615d73833981519152610512613180565b6122825760405162461bcd60e51b81526004016106ea90614b77565b600061228d82612024565b600b549091506001600160a01b0361010090910481169082168114156122c55760405162461bcd60e51b81526004016106ea90615636565b6122d08282856132d8565b806001600160a01b0316826001600160a01b0316847fed5804d8e0554bb1dda62035b632546a9ab024b92985e9a6a4dff2cd2bbcb08d60405160405180910390a4505050565b612321611922613180565b806123415750612341600080516020615d73833981519152610512613180565b61235d5760405162461bcd60e51b81526004016106ea90614cda565b61236682613173565b6123825760405162461bcd60e51b81526004016106ea906156ec565b6000828152600c602052604090819020600601549051636b8b476560e01b81526001600160a01b0390911690636b8b4765906119c9908490600401614825565b60006001600160a01b0382166123ea5760405162461bcd60e51b81526004016106ea90614f8f565b6001600160a01b0382166000908152600260205260409020610eb59061325b565b600088511161242c5760405162461bcd60e51b81526004016106ea90615474565b6124358861309e565b156124525760405162461bcd60e51b81526004016106ea90614d36565b61246c600080516020615d73833981519152610512613180565b6124885760405162461bcd60e51b81526004016106ea906149dc565b612492600d61368c565b600061249e600d6133e6565b90506124aa8a82613695565b6124b4818a613759565b6000818152600c602090815260409091208a516124d3928c0190613fd5565b506000818152600c6020908152604090912089516124f9926001909201918b0190613fd5565b506000818152600c60209081526040909120885161251f926002909201918a0190613fd5565b506000818152600c60209081526040909120875161254592600390920191890190613fd5565b506000818152600c60209081526040909120865161256b92600490920191880190613fd5565b506000818152600c60209081526040909120855161259192600790920191870190613fd5565b506000818152600c6020908152604090912084516125b792600890920191860190613fd5565b506000818152600c6020908152604090912083516125dd92600990920191850190613fd5565b506000818152600c60205260409081902090516125fa9190614750565b604080519182900382206000848152600c60205291909120909183917facab8395a3b1066446f4c6edfa3690bc95345549a14e41e5319563e2fec842a59161264f916007810191600882019160090190614871565b60405180910390a350505050505050505050565b61268f7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610512613180565b6126ab5760405162461bcd60e51b81526004016106ea90615065565b6111af61379d565b600082815260208190526040812061111190836134b1565b600082815260208190526040812061111190836137f8565b6126fd600080516020615d73833981519152610512613180565b6127195760405162461bcd60e51b81526004016106ea906153e7565b6127228161380d565b50565b60088054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106b95780601f1061068e576101008083540402835291602001916106b9565b600081565b612793613180565b6001600160a01b0316826001600160a01b031614156127c45760405162461bcd60e51b81526004016106ea90614c57565b80600660006127d1613180565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155612815613180565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161284d9190614811565b60405180910390a35050565b6128646107b2613180565b806128845750612884600080516020615d73833981519152610512613180565b6128a05760405162461bcd60e51b81526004016106ea90614a4c565b6128a986613173565b6128c55760405162461bcd60e51b81526004016106ea90615182565b60006040516128d390613f1f565b604051809103906000f0801580156128ef573d6000803e3d6000fd5b50905083610876576000878152600c60205260409081902060050180546001600160a01b0319166001600160a01b038416179055516108869087908790614711565b61294261293c613180565b83613266565b61295e5760405162461bcd60e51b81526004016106ea906154be565b61296a84848484613820565b50505050565b612978613f2c565b61298182613173565b61299d5760405162461bcd60e51b81526004016106ea90615305565b6000828152600c60209081526040918290208251815460026001821615610100026000190190911604601f810184900490930281016101609081019094526101408101838152909391928492849190840182828015612a3d5780601f10612a1257610100808354040283529160200191612a3d565b820191906000526020600020905b815481529060010190602001808311612a2057829003601f168201915b50505050508152602001600182018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015612adf5780601f10612ab457610100808354040283529160200191612adf565b820191906000526020600020905b815481529060010190602001808311612ac257829003601f168201915b5050509183525050600282810180546040805160206001841615610100026000190190931694909404601f81018390048302850183019091528084529381019390830182828015612b715780601f10612b4657610100808354040283529160200191612b71565b820191906000526020600020905b815481529060010190602001808311612b5457829003601f168201915b505050918352505060038201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015612c055780601f10612bda57610100808354040283529160200191612c05565b820191906000526020600020905b815481529060010190602001808311612be857829003601f168201915b505050918352505060048201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015612c995780601f10612c6e57610100808354040283529160200191612c99565b820191906000526020600020905b815481529060010190602001808311612c7c57829003601f168201915b505050918352505060058201546001600160a01b039081166020808401919091526006840154909116604080840191909152600784018054825160026101006001841615026000190190921691909104601f810185900485028201850190935282815260609094019392909190830182828015612d575780601f10612d2c57610100808354040283529160200191612d57565b820191906000526020600020905b815481529060010190602001808311612d3a57829003601f168201915b505050918352505060088201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015612deb5780601f10612dc057610100808354040283529160200191612deb565b820191906000526020600020905b815481529060010190602001808311612dce57829003601f168201915b505050918352505060098201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015612e7f5780601f10612e5457610100808354040283529160200191612e7f565b820191906000526020600020905b815481529060010190602001808311612e6257829003601f168201915b5050505050815250509050919050565b6060612e9a82613173565b612eb65760405162461bcd60e51b81526004016106ea90615398565b60008281526009602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845260609392830182828015612f4b5780601f10612f2057610100808354040283529160200191612f4b565b820191906000526020600020905b815481529060010190602001808311612f2e57829003601f168201915b505050505090506060612f5c6121af565b9050805160001415612f7057509050610628565b815115612fa2578082604051602001612f8a929190614721565b60405160208183030381529060405292505050610628565b80612fac85613853565b604051602001612fbd929190614721565b60405160208183030381529060405292505050919050565b6000818152602081905260408120610eb59061325b565b600b5461010090046001600160a01b031681565b600080516020615d7383398151915281565b60008281526020819052604090206002015461303090610512613180565b6111555760405162461bcd60e51b81526004016106ea90614e1d565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b6000808251116130c05760405162461bcd60e51b81526004016106ea90615474565b60015b6130cd600d6133e6565b8111613155576000818152600c602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845261313e9392830182828015610fd45780601f10610fa957610100808354040283529160200191610fd4565b1561314d576001915050610628565b6001016130c3565b50600092915050565b6000611111836001600160a01b03841661392e565b6000610eb5600383613978565b3390565b600081815260056020526040902080546001600160a01b0319166001600160a01b03841690811790915581906131b982612024565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006131fd82613173565b6132195760405162461bcd60e51b81526004016106ea90614bc3565b600061322483612024565b9050836001600160a01b0316613239846106c3565b6001600160a01b0316148061325357506132538185613070565b949350505050565b6000610eb5826133e6565b600061327182613173565b61328d5760405162461bcd60e51b81526004016106ea90614dd1565b600061329883612024565b9050806001600160a01b0316846001600160a01b031614806132c85750836001600160a01b0316613239846106c3565b8061325357506132538185613070565b826001600160a01b03166132eb82612024565b6001600160a01b0316146133115760405162461bcd60e51b81526004016106ea9061534f565b6001600160a01b0382166133375760405162461bcd60e51b81526004016106ea90614c13565b613342838383613984565b61334d600082613184565b6001600160a01b038316600090815260026020526040902061336f908261398f565b506001600160a01b0382166000908152600260205260409020613392908261399b565b5061339f600382846139a7565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b5490565b6000816040516020016133fd91906146f5565b604051602081830303815290604052805190602001208360405160200161342491906146f5565b60405160208183030381529060405280519060200120141561315557506001610eb5565b6000828152602081905260409020613460908261315e565b156110eb5761346d613180565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600061111183836139bd565b60008281526020819052604090206134d59082613a02565b156110eb576134e2613180565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b61352e611ac8565b61354a5760405162461bcd60e51b81526004016106ea90614a1e565b600b805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61357d613180565b60405161358a91906147c0565b60405180910390a1565b600061359f82612024565b90506135ad81600084613984565b6135b8600083613184565b60008281526009602052604090205460026000196101006001841615020190911604156135f65760008281526009602052604081206135f691613f91565b6001600160a01b0381166000908152600260205260409020613618908361398f565b50613624600383613a17565b5060405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60008080806136708686613a23565b909450925050505b9250929050565b6000613253848484613a7f565b80546001019055565b6001600160a01b0382166136bb5760405162461bcd60e51b81526004016106ea9061514d565b6136c481613173565b156136e15760405162461bcd60e51b81526004016106ea90614aea565b6136ed60008383613984565b6001600160a01b038216600090815260026020526040902061370f908261399b565b5061371c600382846139a7565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b61376282613173565b61377e5760405162461bcd60e51b81526004016106ea9061521c565b600082815260096020908152604090912082516107a292840190613fd5565b6137a5611ac8565b156137c25760405162461bcd60e51b81526004016106ea90614eba565b600b805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861357d613180565b6000611111836001600160a01b038416613ade565b80516110eb90600a906020840190613fd5565b61382b8484846132d8565b61383784848484613af6565b61296a5760405162461bcd60e51b81526004016106ea90614a98565b60608161387857506040805180820190915260018152600360fc1b6020820152610628565b8160005b811561389057600101600a8204915061387c565b60608167ffffffffffffffff811180156138a957600080fd5b506040519080825280601f01601f1916602001820160405280156138d4576020820181803683370190505b50859350905060001982015b831561392557600a840660300160f81b8282806001900393508151811061390357fe5b60200101906001600160f81b031916908160001a905350600a840493506138e0565b50949350505050565b600061393a8383613ade565b61397057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610eb5565b506000610eb5565b60006111118383613ade565b6107a2838383613bd5565b60006111118383613c05565b6000611111838361392e565b600061325384846001600160a01b038516613ccb565b815460009082106139e05760405162461bcd60e51b81526004016106ea90614900565b8260000182815481106139ef57fe5b9060005260206000200154905092915050565b6000611111836001600160a01b038416613c05565b60006111118383613d62565b815460009081908310613a485760405162461bcd60e51b81526004016106ea9061510b565b6000846000018481548110613a5957fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008281526001840160205260408120548281613aaf5760405162461bcd60e51b81526004016106ea9190614825565b50846000016001820381548110613ac257fe5b9060005260206000209060020201600101549150509392505050565b60009081526001919091016020526040902054151590565b6000613b0a846001600160a01b0316613e36565b613b1657506001613253565b6060613b9e630a85bd0160e11b613b2b613180565b888787604051602401613b4194939291906147d4565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001615cf8603291396001600160a01b0388169190613e3c565b9050600081806020019051810190613bb69190614430565b6001600160e01b031916630a85bd0160e11b1492505050949350505050565b613be08383836107a2565b613be8611ac8565b156107a25760405162461bcd60e51b81526004016106ea90614942565b60008181526001830160205260408120548015613cc15783546000198083019190810190600090879083908110613c3857fe5b9060005260206000200154905080876000018481548110613c5557fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080613c8557fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610eb5565b6000915050610eb5565b600082815260018401602052604081205480613d30575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055611111565b82856000016001830381548110613d4357fe5b9060005260206000209060020201600101819055506000915050611111565b60008181526001830160205260408120548015613cc15783546000198083019190810190600090879083908110613d9557fe5b9060005260206000209060020201905080876000018481548110613db557fe5b600091825260208083208454600290930201918255600193840154918401919091558354825289830190526040902090840190558654879080613df457fe5b6000828152602080822060026000199094019384020182815560019081018390559290935588815289820190925260408220919091559450610eb59350505050565b3b151590565b6060613253848460008585613e5085613e36565b613e6c5760405162461bcd60e51b81526004016106ea9061550f565b60006060866001600160a01b03168587604051613e8991906146f5565b60006040518083038185875af1925050503d8060008114613ec6576040519150601f19603f3d011682016040523d82523d6000602084013e613ecb565b606091505b5091509150613edb828286613ee6565b979650505050505050565b60608315613ef5575081611111565b825115613f055782518084602001fd5b8160405162461bcd60e51b81526004016106ea9190614825565b61035e8061599a83390190565b604051806101400160405280606081526020016060815260200160608152602001606081526020016060815260200160006001600160a01b0316815260200160006001600160a01b031681526020016060815260200160608152602001606081525090565b50805460018160011615610100020316600290046000825580601f10613fb75750612722565b601f0160209004906000526020600020908101906127229190614053565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061401657805160ff1916838001178555614043565b82800160010185558215614043579182015b82811115614043578251825591602001919060010190614028565b5061404f929150614053565b5090565b5b8082111561404f5760008155600101614054565b80356001600160a01b0381168114610eb557600080fd5b600082601f83011261408f578081fd5b81356140a261409d82615912565b6158eb565b91508082528360208285010111156140b957600080fd5b8060208401602084013760009082016020015292915050565b60008083601f8401126140e3578182fd5b50813567ffffffffffffffff8111156140fa578182fd5b60208301915083602082850101111561367857600080fd5b600060208284031215614123578081fd5b6111118383614068565b6000806040838503121561413f578081fd5b6141498484614068565b91506141588460208501614068565b90509250929050565b600080600060608486031215614175578081fd5b83356141808161596e565b925060208401356141908161596e565b929592945050506040919091013590565b600080600080608085870312156141b6578081fd5b6141c08686614068565b93506141cf8660208701614068565b925060408501359150606085013567ffffffffffffffff8111156141f1578182fd5b6141fd8782880161407f565b91505092959194509250565b6000806040838503121561421b578182fd5b6142258484614068565b915060208301358015158114614239578182fd5b809150509250929050565b60008060008060008060008060006101208a8c031215614262578485fd5b61426c8b8b614068565b985060208a013567ffffffffffffffff80821115614288578687fd5b6142948d838e0161407f565b995060408c01359150808211156142a9578687fd5b6142b58d838e0161407f565b985060608c01359150808211156142ca578687fd5b6142d68d838e0161407f565b975060808c01359150808211156142eb578687fd5b6142f78d838e0161407f565b965060a08c013591508082111561430c578586fd5b6143188d838e0161407f565b955060c08c013591508082111561432d578485fd5b6143398d838e0161407f565b945060e08c013591508082111561434e578384fd5b61435a8d838e0161407f565b93506101008c0135915080821115614370578283fd5b5061437d8c828d0161407f565b9150509295985092959850929598565b6000806040838503121561439f578182fd5b6143a98484614068565b946020939093013593505050565b6000602082840312156143c8578081fd5b5035919050565b600080604083850312156143e1578182fd5b8235915060208301356142398161596e565b60008060408385031215614405578182fd5b50508035926020909101359150565b600060208284031215614425578081fd5b813561111181615983565b600060208284031215614441578081fd5b815161111181615983565b60006020828403121561445d578081fd5b813567ffffffffffffffff811115614473578182fd5b6132538482850161407f565b600060208284031215614490578081fd5b815167ffffffffffffffff8111156144a6578182fd5b8201601f810184136144b6578182fd5b80516144c461409d82615912565b8181528560208385010111156144d8578384fd5b6144e9826020830160208601615942565b95945050505050565b6000806000806000806080878903121561450a578384fd5b86359550602087013567ffffffffffffffff80821115614528578586fd5b6145348a838b016140d2565b9097509550604089013594506060890135915080821115614553578384fd5b5061456089828a016140d2565b979a9699509497509295939492505050565b60008060408385031215614584578182fd5b82359150602083013567ffffffffffffffff8111156145a1578182fd5b6145ad8582860161407f565b9150509250929050565b600080600080608085870312156145cc578182fd5b84359350602085013567ffffffffffffffff808211156145ea578384fd5b6145f68883890161407f565b9450604087013591508082111561460b578384fd5b6146178883890161407f565b9350606087013591508082111561462c578283fd5b506141fd8782880161407f565b60008151808452614651816020860160208601615942565b601f01601f19169290920160200192915050565b6001600160a01b03169052565b6000815460018082166000811461469057600181146146ae576146ec565b60028304607f16865260ff19831660208701526040860193506146ec565b600283048087526146be86615936565b60005b828110156146e25781546020828b01015284820191506020810190506146c1565b8801602001955050505b50505092915050565b60008251614707818460208701615942565b9190910192915050565b6000828483379101908152919050565b60008351614733818460208801615942565b835190830190614747818360208801615942565b01949350505050565b600080835460018082166000811461476f5760018114614786576147b5565b60ff198316865260028304607f16860193506147b5565b600283048786526020808720875b838110156147ad5781548a820152908501908201614794565b505050860193505b509195945050505050565b6001600160a01b0391909116815260200190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061480790830184614639565b9695505050505050565b901515815260200190565b90815260200190565b6000602082526111116020830184614639565b60006060825261484b6060830186614639565b828103602084015261485d8186614639565b905082810360408401526148078185614639565b6000606082526148846060830186614672565b82810360208401526148968186614672565b905082810360408401526148078185614672565b60208082526036908201527f5754433a20746f6b656e4964206d75737420657869737420746f2067657420626040820152750c2c6d640d2dac2ceca40c8c2e8c240e8f040d0c2e6d60531b606082015260800190565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252602b908201527f4552433732315061757361626c653a20746f6b656e207472616e73666572207760408201526a1a1a5b19481c185d5cd95960aa1b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b60208082526022908201527f5754433a206d7573742068617665206d696e74657220726f6c6520746f206d696040820152611b9d60f21b606082015260800190565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b60208082526040908201819052600080516020615d2a833981519152908201527f20617070726f76656420746f20736574206661636520696d6167652064617461606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b60208082526036908201527f5754433a20746f6b656e4964206d75737420657869737420746f2073657420666040820152750c2c6ca40d2dac2ceca40c8c2e8c240e8f040d0c2e6d60531b606082015260800190565b60208082526040908201819052600080516020615d2a833981519152908201527f20617070726f76656420746f207265736574204e4654206f776e657273686970606082015260800190565b60208082526030908201527f5754434e4654426173653a206f70657261746f7220717565727920666f72206e60408201526f37b732bc34b9ba32b73a103a37b5b2b760811b606082015260800190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b6020808252602c908201527f5754433a2064696765737420776974682063657274696669636174654361726460408201526b1259081b9bdd08199bdd5b9960a21b606082015260800190565b6020808252604890820152600080516020615d2a83398151915260408201527f20617070726f76656420746f20736574206261636b20696d6167652064617461606082015267040e8f040d0c2e6d60c31b608082015260a00190565b60208082526025908201527f5754433a206365727469666963617465436172644964206d75737420626520756040820152646e6971756560d81b606082015260800190565b60208082526036908201527f5754433a20746f6b656e4964206d75737420657869737420746f2067657420666040820152750c2c6ca40d2dac2ceca40c8c2e8c240e8f040d0c2e6d60531b606082015260800190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b6020808252602d908201527f5754433a20746f6b656e4964206d75737420657869737420746f20757064617460408201526c6520636572746966696361746560981b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252602e908201527f5754433a20746f6b656e4964206d75737420657869737420746f20736574206260408201526d61636b20696d616765206461746160901b606082015260800190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602b908201527f5754433a20746f6b656e4964206d75737420657869737420746f206275726e2060408201526a636572746966696361746560a81b606082015260800190565b6020808252603390820152600080516020615d2a83398151915260408201527220617070726f76656420746f2075706461746560681b606082015260800190565b6020808252602a908201527f5754434e4654426173653a206d75737420686176652070617573657220726f6c6040820152696520746f20706175736560b01b606082015260800190565b6020808252604890820152600080516020615d2a83398151915260408201527f20617070726f76656420746f20736574206661636520696d6167652064617461606082015267040e8f040d0c2e6d60c31b608082015260a00190565b60208082526022908201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602e908201527f5754433a20746f6b656e4964206d75737420657869737420746f20736574206660408201526d61636520696d616765206461746160901b606082015260800190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252602c908201527f4552433732314d657461646174613a2055524920736574206f66206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526031908201527f5754433a20746f6b656e4964206d75737420657869737420746f206765742063604082015270195c9d1a599a58d85d1948191a59d95cdd607a1b606082015260800190565b60208082526040908201819052600080516020615d2a833981519152908201527f20617070726f76656420746f20736574206261636b20696d6167652064617461606082015260800190565b6020808252602a908201527f5754433a20746f6b656e4964206d75737420657869737420746f2067657420636040820152696572746966696361746560b01b606082015260800190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b6020808252602f908201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60408201526e3732bc34b9ba32b73a103a37b5b2b760891b606082015260800190565b6020808252602c908201527f5754433a206d7573742068617665206d696e74657220726f6c6520746f20757060408201526b64617465206261736555524960a01b606082015260800190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b6020808252602a908201527f5754433a2063657274696669636174654361726449642073686f756c64206e6f6040820152697420626520656d70747960b01b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252604190820152600080516020615d2a83398151915260408201527f20746865206f776e6572206f7220626520617070726f76656420746f206275726060820152603760f91b608082015260a00190565b6020808252602d908201527f5754433a20746f6b656e4964207769746820636572746966696361746543617260408201526c191259081b9bdd08199bdd5b99609a1b606082015260800190565b6020808252602e908201527f5754433a20746f6b656e4964206d75737420657869737420746f20726573657460408201526d0204e4654206f776e6572736869760941b606082015260800190565b60208082526044908201527f5754433a2066726f6d20616e6420746f2061646472657373206172652074686560408201527f2073616d652c206f776e6572736869702073686f756c64206e6f742062652072606082015263195cd95d60e21b608082015260a00190565b6020808252602c908201527f5754434e4654426173653a206d75737420686176652070617573657220726f6c60408201526b6520746f20756e706175736560a01b606082015260800190565b60208082526036908201527f5754433a20746f6b656e4964206d75737420657869737420746f2073657420626040820152750c2c6d640d2dac2ceca40c8c2e8c240e8f040d0c2e6d60531b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b60006020825282516101408060208501526157b0610160850183614639565b91506020850151601f19808685030160408701526157ce8483614639565b935060408701519150808685030160608701526157eb8483614639565b935060608701519150808685030160808701526158088483614639565b935060808701519150808685030160a08701526158258483614639565b935060a0870151915061583b60c0870183614665565b60c0870151915061584f60e0870183614665565b60e0870151915061010081878603018188015261586c8584614639565b94508088015192505061012081878603018188015261588b8584614639565b9088015187820390920184880152935090506148078382614639565b60008482526040602083015282604083015282846060840137818301606090810191909152601f909201601f1916010192915050565b60ff91909116815260200190565b60405181810167ffffffffffffffff8111828210171561590a57600080fd5b604052919050565b600067ffffffffffffffff821115615928578081fd5b50601f01601f191660200190565b60009081526020902090565b60005b8381101561595d578181015183820152602001615945565b8381111561296a5750506000910152565b6001600160a01b038116811461272257600080fd5b6001600160e01b03198116811461272257600080fdfe608060405234801561001057600080fd5b5061033e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80636b8b47651461003b578063e077a9ba14610050575b600080fd5b61004e6100493660046101f6565b610079565b005b61006361005e366004610291565b6100bd565b60405161007091906102a9565b60405180910390f35b6000805460018101825590805281516100b9917f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56301906020840190610163565b5050565b600081815481106100ca57fe5b600091825260209182902001805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529350909183018282801561015b5780601f106101305761010080835404028352916020019161015b565b820191906000526020600020905b81548152906001019060200180831161013e57829003601f168201915b505050505081565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106101a457805160ff19168380011785556101d1565b828001600101855582156101d1579182015b828111156101d15782518255916020019190600101906101b6565b506101dd9291506101e1565b5090565b5b808211156101dd57600081556001016101e2565b600060208284031215610207578081fd5b813567ffffffffffffffff8082111561021e578283fd5b818401915084601f830112610231578283fd5b81358181111561023f578384fd5b604051601f8201601f19168101602001838111828210171561025f578586fd5b604052818152838201602001871015610276578485fd5b6102878260208301602087016102fc565b9695505050505050565b6000602082840312156102a2578081fd5b5035919050565b6000602080835283518082850152825b818110156102d5578581018301518582016040015282016102b9565b818111156102e65783604083870101525b50601f01601f1916929092016040019392505050565b8281833750600091015256fea2646970667358221220c7148bdaacf8688f2bf16e267c998ff438a032272d9c4f415297bffe3251e52a64736f6c634300070000334552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465725754433a206d7573742068617665206d696e74657220726f6c65206f722062654552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6a2646970667358221220bb2928fe012e6f6e6a9bdf2e5827c6c96e6ecba38657377283c88a5f58766b0364736f6c6343000700003368747470733a2f2f6170692e776174636863657274696669636174652e6f72672f6170692f76312f6365727469666963617465732f6e66742f
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102a05760003560e01c80636522bff111610167578063a22cb465116100ce578063ce606ee011610087578063ce606ee0146105b9578063d5391393146105c1578063d547741f146105c9578063e63ab1e9146105dc578063e985e9c5146105e4578063eb7898b2146105f7576102a0565b8063a22cb4651461053a578063b86525001461054d578063b88d4fde14610560578063c46ba90f14610573578063c87b56dd14610593578063ca15c873146105a6576102a0565b80638456cb59116101205780638456cb59146104e95780639010d07c146104f157806391d1485414610504578063931688cb1461051757806395d89b411461052a578063a217fddf14610532576102a0565b80636522bff1146104825780636c0360eb146104955780636ca2f5ef1461049d5780636d8685ab146104b057806370a08231146104c35780637f95447e146104d6576102a0565b8063313ce5671161020b5780635158f090116101c45780635158f0901461041b57806353950fdf1461042e5780635948c1bc146104415780635c975abb146104545780635eb637591461045c5780636352211e1461046f576102a0565b8063313ce567146103b257806336568abe146103c75780633f4ba83a146103da57806342842e0e146103e257806342966c68146103f55780634f6ccce714610408576102a0565b806321a9fd991161025d57806321a9fd991461034057806323b872dd14610353578063248a9ca3146103665780632ce19dd6146103795780632f2ff15d1461038c5780632f745c591461039f576102a0565b806301ffc9a7146102a557806306fdde03146102ce578063081812fc146102e3578063095ea7b3146103035780630f8c7d3a1461031857806318160ddd1461032b575b600080fd5b6102b86102b3366004614414565b61060a565b6040516102c59190614811565b60405180910390f35b6102d661062d565b6040516102c59190614825565b6102f66102f13660046143b7565b6106c3565b6040516102c591906147c0565b61031661031136600461438d565b61070f565b005b6103166103263660046144f2565b6107a7565b6103336108f7565b6040516102c5919061481c565b6102d661034e3660046143f3565b610908565b610316610361366004614161565b610ebb565b6103336103743660046143b7565b610ef3565b6102d661038736600461444c565b610f08565b61031661039a3660046143cf565b6110a7565b6103336103ad36600461438d565b6110ef565b6103ba611118565b6040516102c591906158dd565b6103166103d53660046143cf565b61111d565b61031661115f565b6103166103f0366004614161565b6111b1565b6103166104033660046143b7565b6111cc565b6103336104163660046143b7565b611835565b61033361042936600461444c565b61184b565b61031661043c366004614572565b611917565b6102d661044f3660046143b7565b6119ff565b6102b8611ac8565b6102d661046a3660046143f3565b611ad1565b6102f661047d3660046143b7565b612024565b6103166104903660046145b7565b61204c565b6102d66121af565b6103166104ab3660046143b7565b612210565b6103166104be366004614572565b612316565b6103336104d1366004614112565b6123c2565b6103166104e4366004614244565b61240b565b610316612663565b6102f66104ff3660046143f3565b6126b3565b6102b86105123660046143cf565b6126cb565b61031661052536600461444c565b6126e3565b6102d6612725565b610333612786565b610316610548366004614209565b61278b565b61031661055b3660046144f2565b612859565b61031661056e3660046141a1565b612931565b6105866105813660046143b7565b612970565b6040516102c59190615791565b6102d66105a13660046143b7565b612e8f565b6103336105b43660046143b7565b612fd5565b6102f6612fec565b610333613000565b6103166105d73660046143cf565b613012565b61033361304c565b6102b86105f236600461412d565b613070565b6102b861060536600461444c565b61309e565b6001600160e01b0319811660009081526001602052604090205460ff165b919050565b60078054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106b95780601f1061068e576101008083540402835291602001916106b9565b820191906000526020600020905b81548152906001019060200180831161069c57829003601f168201915b5050505050905090565b60006106ce82613173565b6106f35760405162461bcd60e51b81526004016106ea906151d0565b60405180910390fd5b506000908152600560205260409020546001600160a01b031690565b600061071a82612024565b9050806001600160a01b0316836001600160a01b0316141561074e5760405162461bcd60e51b81526004016106ea90615433565b806001600160a01b0316610760613180565b6001600160a01b0316148061077c575061077c816105f2613180565b6107985760405162461bcd60e51b81526004016106ea90614f32565b6107a28383613184565b505050565b6107b86107b2613180565b876131f2565b806107d857506107d8600080516020615d73833981519152610512613180565b6107f45760405162461bcd60e51b81526004016106ea906152b9565b6107fd86613173565b6108195760405162461bcd60e51b81526004016106ea90614ee4565b600060405161082790613f1f565b604051809103906000f080158015610843573d6000803e3d6000fd5b50905083610876576000878152600c6020526040902060060180546001600160a01b0319166001600160a01b0383161790555b8585604051610886929190614711565b6040805191829003822060008a8152600c6020529190912090916108aa9190614750565b6040518091039020887fc974d5c20c92f16ef296fd9eebe00dd8e662f6562dc69af3c89244ea70db4a328787876040516108e6939291906158a7565b60405180910390a450505050505050565b6000610903600361325b565b905090565b606061091383613173565b61092f5760405162461bcd60e51b81526004016106ea906148aa565b610937613f2c565b6000848152600c60209081526040918290208251815460026001821615610100026000190190911604601f8101849004909302810161016090810190945261014081018381529093919284928491908401828280156109d75780601f106109ac576101008083540402835291602001916109d7565b820191906000526020600020905b8154815290600101906020018083116109ba57829003601f168201915b50505050508152602001600182018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a795780601f10610a4e57610100808354040283529160200191610a79565b820191906000526020600020905b815481529060010190602001808311610a5c57829003601f168201915b5050509183525050600282810180546040805160206001841615610100026000190190931694909404601f81018390048302850183019091528084529381019390830182828015610b0b5780601f10610ae057610100808354040283529160200191610b0b565b820191906000526020600020905b815481529060010190602001808311610aee57829003601f168201915b505050918352505060038201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015610b9f5780601f10610b7457610100808354040283529160200191610b9f565b820191906000526020600020905b815481529060010190602001808311610b8257829003601f168201915b505050918352505060048201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015610c335780601f10610c0857610100808354040283529160200191610c33565b820191906000526020600020905b815481529060010190602001808311610c1657829003601f168201915b505050918352505060058201546001600160a01b039081166020808401919091526006840154909116604080840191909152600784018054825160026101006001841615026000190190921691909104601f810185900485028201850190935282815260609094019392909190830182828015610cf15780601f10610cc657610100808354040283529160200191610cf1565b820191906000526020600020905b815481529060010190602001808311610cd457829003601f168201915b505050918352505060088201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015610d855780601f10610d5a57610100808354040283529160200191610d85565b820191906000526020600020905b815481529060010190602001808311610d6857829003601f168201915b505050918352505060098201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015610e195780601f10610dee57610100808354040283529160200191610e19565b820191906000526020600020905b815481529060010190602001808311610dfc57829003601f168201915b5050509190925250505060c081015160405163703bd4dd60e11b8152919250906060906001600160a01b0383169063e077a9ba90610e5b90889060040161481c565b60006040518083038186803b158015610e7357600080fd5b505afa158015610e87573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610eaf919081019061447f565b93505050505b92915050565b610ecc610ec6613180565b82613266565b610ee85760405162461bcd60e51b81526004016106ea906154be565b6107a28383836132d8565b60009081526020819052604090206002015490565b60606000825111610f2b5760405162461bcd60e51b81526004016106ea90615474565b60015b610f38600d6133e6565b811161108f576000818152600c602090815260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452610fdf9392830182828015610fd45780601f10610fa957610100808354040283529160200191610fd4565b820191906000526020600020905b815481529060010190602001808311610fb757829003601f168201915b5050505050846133ea565b15611087576000818152600c602090815260409182902060070180548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452909183018282801561107a5780601f1061104f5761010080835404028352916020019161107a565b820191906000526020600020905b81548152906001019060200180831161105d57829003601f168201915b5050505050915050610628565b600101610f2e565b60405162461bcd60e51b81526004016106ea90614c8e565b6000828152602081905260409020600201546110c590610512613180565b6110e15760405162461bcd60e51b81526004016106ea9061498d565b6110eb8282613448565b5050565b6001600160a01b038216600090815260026020526040812061111190836134b1565b9392505050565b600090565b611125613180565b6001600160a01b0316816001600160a01b0316146111555760405162461bcd60e51b81526004016106ea90615742565b6110eb82826134bd565b61118b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610512613180565b6111a75760405162461bcd60e51b81526004016106ea906156a0565b6111af613526565b565b6107a283838360405180602001604052806000815250612931565b6111d581613173565b6111f15760405162461bcd60e51b81526004016106ea90614fd9565b6111fc610ec6613180565b8061121c575061121c600080516020615d73833981519152610512613180565b6112385760405162461bcd60e51b81526004016106ea90615546565b611240613f2c565b6000828152600c60209081526040918290208251815460026001821615610100026000190190911604601f8101849004909302810161016090810190945261014081018381529093919284928491908401828280156112e05780601f106112b5576101008083540402835291602001916112e0565b820191906000526020600020905b8154815290600101906020018083116112c357829003601f168201915b50505050508152602001600182018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156113825780601f1061135757610100808354040283529160200191611382565b820191906000526020600020905b81548152906001019060200180831161136557829003601f168201915b5050509183525050600282810180546040805160206001841615610100026000190190931694909404601f810183900483028501830190915280845293810193908301828280156114145780601f106113e957610100808354040283529160200191611414565b820191906000526020600020905b8154815290600101906020018083116113f757829003601f168201915b505050918352505060038201805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529382019392918301828280156114a85780601f1061147d576101008083540402835291602001916114a8565b820191906000526020600020905b81548152906001019060200180831161148b57829003601f168201915b505050918352505060048201805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815293820193929183018282801561153c5780601f106115115761010080835404028352916020019161153c565b820191906000526020600020905b81548152906001019060200180831161151f57829003601f168201915b505050918352505060058201546001600160a01b039081166020808401919091526006840154909116604080840191909152600784018054825160026101006001841615026000190190921691909104601f8101859004850282018501909352828152606090940193929091908301828280156115fa5780601f106115cf576101008083540402835291602001916115fa565b820191906000526020600020905b8154815290600101906020018083116115dd57829003601f168201915b505050918352505060088201805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815293820193929183018282801561168e5780601f106116635761010080835404028352916020019161168e565b820191906000526020600020905b81548152906001019060200180831161167157829003601f168201915b505050918352505060098201805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529382019392918301828280156117225780601f106116f757610100808354040283529160200191611722565b820191906000526020600020905b81548152906001019060200180831161170557829003601f168201915b505050919092525050506000838152600c602052604081209192506117478282613f91565b611755600183016000613f91565b611763600283016000613f91565b611771600383016000613f91565b61177f600483016000613f91565b6005820180546001600160a01b031990811690915560068301805490911690556117ad600783016000613f91565b6117bb600883016000613f91565b6117c9600983016000613f91565b505080516040516117da91906146f5565b6040518091039020827fce800f051025c107d292d462ffc77996c1b95849dc9b7e85142408293b6912e68360e0015184610100015185610120015160405161182493929190614838565b60405180910390a36110eb82613594565b600080611843600384613661565b509392505050565b60008082511161186d5760405162461bcd60e51b81526004016106ea90615474565b60015b61187a600d6133e6565b81116118ff576000818152600c602090815260409182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084526118eb9392830182828015610fd45780601f10610fa957610100808354040283529160200191610fd4565b156118f7579050610628565b600101611870565b60405162461bcd60e51b81526004016106ea9061559b565b611928611922613180565b836131f2565b806119485750611948600080516020615d73833981519152610512613180565b6119645760405162461bcd60e51b81526004016106ea906150af565b61196d82613173565b6119895760405162461bcd60e51b81526004016106ea90614b21565b6000828152600c602052604090819020600501549051636b8b476560e01b81526001600160a01b0390911690636b8b4765906119c9908490600401614825565b600060405180830381600087803b1580156119e357600080fd5b505af11580156119f7573d6000803e3d6000fd5b505050505050565b6060611a0a82613173565b611a265760405162461bcd60e51b81526004016106ea90615268565b6000828152600c602090815260409182902060070180548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084529091830182828015611abc5780601f10611a9157610100808354040283529160200191611abc565b820191906000526020600020905b815481529060010190602001808311611a9f57829003601f168201915b50505050509050919050565b600b5460ff1690565b6060611adc83613173565b611af85760405162461bcd60e51b81526004016106ea90614d7b565b611b00613f2c565b6000848152600c60209081526040918290208251815460026001821615610100026000190190911604601f810184900490930281016101609081019094526101408101838152909391928492849190840182828015611ba05780601f10611b7557610100808354040283529160200191611ba0565b820191906000526020600020905b815481529060010190602001808311611b8357829003601f168201915b50505050508152602001600182018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611c425780601f10611c1757610100808354040283529160200191611c42565b820191906000526020600020905b815481529060010190602001808311611c2557829003601f168201915b5050509183525050600282810180546040805160206001841615610100026000190190931694909404601f81018390048302850183019091528084529381019390830182828015611cd45780601f10611ca957610100808354040283529160200191611cd4565b820191906000526020600020905b815481529060010190602001808311611cb757829003601f168201915b505050918352505060038201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015611d685780601f10611d3d57610100808354040283529160200191611d68565b820191906000526020600020905b815481529060010190602001808311611d4b57829003601f168201915b505050918352505060048201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015611dfc5780601f10611dd157610100808354040283529160200191611dfc565b820191906000526020600020905b815481529060010190602001808311611ddf57829003601f168201915b505050918352505060058201546001600160a01b039081166020808401919091526006840154909116604080840191909152600784018054825160026101006001841615026000190190921691909104601f810185900485028201850190935282815260609094019392909190830182828015611eba5780601f10611e8f57610100808354040283529160200191611eba565b820191906000526020600020905b815481529060010190602001808311611e9d57829003601f168201915b505050918352505060088201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015611f4e5780601f10611f2357610100808354040283529160200191611f4e565b820191906000526020600020905b815481529060010190602001808311611f3157829003601f168201915b505050918352505060098201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015611fe25780601f10611fb757610100808354040283529160200191611fe2565b820191906000526020600020905b815481529060010190602001808311611fc557829003601f168201915b5050509190925250505060a081015160405163703bd4dd60e11b8152919250906060906001600160a01b0383169063e077a9ba90610e5b90889060040161481c565b6000610eb582604051806060016040528060298152602001615d4a602991396003919061367f565b61205584613173565b6120715760405162461bcd60e51b81526004016106ea90614e6d565b61208261207c613180565b856131f2565b806120a257506120a2600080516020615d73833981519152610512613180565b6120be5760405162461bcd60e51b81526004016106ea90615024565b6000848152600c6020908152604090912084516120e392600790920191860190613fd5565b506000848152600c60209081526040909120835161210992600890920191850190613fd5565b506000848152600c60209081526040909120825161212f92600990920191840190613fd5565b506000848152600c602052604090819020905161214c9190614750565b604080519182900382206000878152600c60205291909120909186917facab8395a3b1066446f4c6edfa3690bc95345549a14e41e5319563e2fec842a5916121a1916007810191600882019160090190614871565b60405180910390a350505050565b600a8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106b95780601f1061068e576101008083540402835291602001916106b9565b61221981613173565b6122355760405162461bcd60e51b81526004016106ea906155e8565b612246612240613180565b826131f2565b806122665750612266600080516020615d73833981519152610512613180565b6122825760405162461bcd60e51b81526004016106ea90614b77565b600061228d82612024565b600b549091506001600160a01b0361010090910481169082168114156122c55760405162461bcd60e51b81526004016106ea90615636565b6122d08282856132d8565b806001600160a01b0316826001600160a01b0316847fed5804d8e0554bb1dda62035b632546a9ab024b92985e9a6a4dff2cd2bbcb08d60405160405180910390a4505050565b612321611922613180565b806123415750612341600080516020615d73833981519152610512613180565b61235d5760405162461bcd60e51b81526004016106ea90614cda565b61236682613173565b6123825760405162461bcd60e51b81526004016106ea906156ec565b6000828152600c602052604090819020600601549051636b8b476560e01b81526001600160a01b0390911690636b8b4765906119c9908490600401614825565b60006001600160a01b0382166123ea5760405162461bcd60e51b81526004016106ea90614f8f565b6001600160a01b0382166000908152600260205260409020610eb59061325b565b600088511161242c5760405162461bcd60e51b81526004016106ea90615474565b6124358861309e565b156124525760405162461bcd60e51b81526004016106ea90614d36565b61246c600080516020615d73833981519152610512613180565b6124885760405162461bcd60e51b81526004016106ea906149dc565b612492600d61368c565b600061249e600d6133e6565b90506124aa8a82613695565b6124b4818a613759565b6000818152600c602090815260409091208a516124d3928c0190613fd5565b506000818152600c6020908152604090912089516124f9926001909201918b0190613fd5565b506000818152600c60209081526040909120885161251f926002909201918a0190613fd5565b506000818152600c60209081526040909120875161254592600390920191890190613fd5565b506000818152600c60209081526040909120865161256b92600490920191880190613fd5565b506000818152600c60209081526040909120855161259192600790920191870190613fd5565b506000818152600c6020908152604090912084516125b792600890920191860190613fd5565b506000818152600c6020908152604090912083516125dd92600990920191850190613fd5565b506000818152600c60205260409081902090516125fa9190614750565b604080519182900382206000848152600c60205291909120909183917facab8395a3b1066446f4c6edfa3690bc95345549a14e41e5319563e2fec842a59161264f916007810191600882019160090190614871565b60405180910390a350505050505050505050565b61268f7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610512613180565b6126ab5760405162461bcd60e51b81526004016106ea90615065565b6111af61379d565b600082815260208190526040812061111190836134b1565b600082815260208190526040812061111190836137f8565b6126fd600080516020615d73833981519152610512613180565b6127195760405162461bcd60e51b81526004016106ea906153e7565b6127228161380d565b50565b60088054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106b95780601f1061068e576101008083540402835291602001916106b9565b600081565b612793613180565b6001600160a01b0316826001600160a01b031614156127c45760405162461bcd60e51b81526004016106ea90614c57565b80600660006127d1613180565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155612815613180565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161284d9190614811565b60405180910390a35050565b6128646107b2613180565b806128845750612884600080516020615d73833981519152610512613180565b6128a05760405162461bcd60e51b81526004016106ea90614a4c565b6128a986613173565b6128c55760405162461bcd60e51b81526004016106ea90615182565b60006040516128d390613f1f565b604051809103906000f0801580156128ef573d6000803e3d6000fd5b50905083610876576000878152600c60205260409081902060050180546001600160a01b0319166001600160a01b038416179055516108869087908790614711565b61294261293c613180565b83613266565b61295e5760405162461bcd60e51b81526004016106ea906154be565b61296a84848484613820565b50505050565b612978613f2c565b61298182613173565b61299d5760405162461bcd60e51b81526004016106ea90615305565b6000828152600c60209081526040918290208251815460026001821615610100026000190190911604601f810184900490930281016101609081019094526101408101838152909391928492849190840182828015612a3d5780601f10612a1257610100808354040283529160200191612a3d565b820191906000526020600020905b815481529060010190602001808311612a2057829003601f168201915b50505050508152602001600182018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015612adf5780601f10612ab457610100808354040283529160200191612adf565b820191906000526020600020905b815481529060010190602001808311612ac257829003601f168201915b5050509183525050600282810180546040805160206001841615610100026000190190931694909404601f81018390048302850183019091528084529381019390830182828015612b715780601f10612b4657610100808354040283529160200191612b71565b820191906000526020600020905b815481529060010190602001808311612b5457829003601f168201915b505050918352505060038201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015612c055780601f10612bda57610100808354040283529160200191612c05565b820191906000526020600020905b815481529060010190602001808311612be857829003601f168201915b505050918352505060048201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015612c995780601f10612c6e57610100808354040283529160200191612c99565b820191906000526020600020905b815481529060010190602001808311612c7c57829003601f168201915b505050918352505060058201546001600160a01b039081166020808401919091526006840154909116604080840191909152600784018054825160026101006001841615026000190190921691909104601f810185900485028201850190935282815260609094019392909190830182828015612d575780601f10612d2c57610100808354040283529160200191612d57565b820191906000526020600020905b815481529060010190602001808311612d3a57829003601f168201915b505050918352505060088201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015612deb5780601f10612dc057610100808354040283529160200191612deb565b820191906000526020600020905b815481529060010190602001808311612dce57829003601f168201915b505050918352505060098201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015612e7f5780601f10612e5457610100808354040283529160200191612e7f565b820191906000526020600020905b815481529060010190602001808311612e6257829003601f168201915b5050505050815250509050919050565b6060612e9a82613173565b612eb65760405162461bcd60e51b81526004016106ea90615398565b60008281526009602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845260609392830182828015612f4b5780601f10612f2057610100808354040283529160200191612f4b565b820191906000526020600020905b815481529060010190602001808311612f2e57829003601f168201915b505050505090506060612f5c6121af565b9050805160001415612f7057509050610628565b815115612fa2578082604051602001612f8a929190614721565b60405160208183030381529060405292505050610628565b80612fac85613853565b604051602001612fbd929190614721565b60405160208183030381529060405292505050919050565b6000818152602081905260408120610eb59061325b565b600b5461010090046001600160a01b031681565b600080516020615d7383398151915281565b60008281526020819052604090206002015461303090610512613180565b6111555760405162461bcd60e51b81526004016106ea90614e1d565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b6000808251116130c05760405162461bcd60e51b81526004016106ea90615474565b60015b6130cd600d6133e6565b8111613155576000818152600c602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845261313e9392830182828015610fd45780601f10610fa957610100808354040283529160200191610fd4565b1561314d576001915050610628565b6001016130c3565b50600092915050565b6000611111836001600160a01b03841661392e565b6000610eb5600383613978565b3390565b600081815260056020526040902080546001600160a01b0319166001600160a01b03841690811790915581906131b982612024565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006131fd82613173565b6132195760405162461bcd60e51b81526004016106ea90614bc3565b600061322483612024565b9050836001600160a01b0316613239846106c3565b6001600160a01b0316148061325357506132538185613070565b949350505050565b6000610eb5826133e6565b600061327182613173565b61328d5760405162461bcd60e51b81526004016106ea90614dd1565b600061329883612024565b9050806001600160a01b0316846001600160a01b031614806132c85750836001600160a01b0316613239846106c3565b8061325357506132538185613070565b826001600160a01b03166132eb82612024565b6001600160a01b0316146133115760405162461bcd60e51b81526004016106ea9061534f565b6001600160a01b0382166133375760405162461bcd60e51b81526004016106ea90614c13565b613342838383613984565b61334d600082613184565b6001600160a01b038316600090815260026020526040902061336f908261398f565b506001600160a01b0382166000908152600260205260409020613392908261399b565b5061339f600382846139a7565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b5490565b6000816040516020016133fd91906146f5565b604051602081830303815290604052805190602001208360405160200161342491906146f5565b60405160208183030381529060405280519060200120141561315557506001610eb5565b6000828152602081905260409020613460908261315e565b156110eb5761346d613180565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600061111183836139bd565b60008281526020819052604090206134d59082613a02565b156110eb576134e2613180565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b61352e611ac8565b61354a5760405162461bcd60e51b81526004016106ea90614a1e565b600b805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61357d613180565b60405161358a91906147c0565b60405180910390a1565b600061359f82612024565b90506135ad81600084613984565b6135b8600083613184565b60008281526009602052604090205460026000196101006001841615020190911604156135f65760008281526009602052604081206135f691613f91565b6001600160a01b0381166000908152600260205260409020613618908361398f565b50613624600383613a17565b5060405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60008080806136708686613a23565b909450925050505b9250929050565b6000613253848484613a7f565b80546001019055565b6001600160a01b0382166136bb5760405162461bcd60e51b81526004016106ea9061514d565b6136c481613173565b156136e15760405162461bcd60e51b81526004016106ea90614aea565b6136ed60008383613984565b6001600160a01b038216600090815260026020526040902061370f908261399b565b5061371c600382846139a7565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b61376282613173565b61377e5760405162461bcd60e51b81526004016106ea9061521c565b600082815260096020908152604090912082516107a292840190613fd5565b6137a5611ac8565b156137c25760405162461bcd60e51b81526004016106ea90614eba565b600b805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861357d613180565b6000611111836001600160a01b038416613ade565b80516110eb90600a906020840190613fd5565b61382b8484846132d8565b61383784848484613af6565b61296a5760405162461bcd60e51b81526004016106ea90614a98565b60608161387857506040805180820190915260018152600360fc1b6020820152610628565b8160005b811561389057600101600a8204915061387c565b60608167ffffffffffffffff811180156138a957600080fd5b506040519080825280601f01601f1916602001820160405280156138d4576020820181803683370190505b50859350905060001982015b831561392557600a840660300160f81b8282806001900393508151811061390357fe5b60200101906001600160f81b031916908160001a905350600a840493506138e0565b50949350505050565b600061393a8383613ade565b61397057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610eb5565b506000610eb5565b60006111118383613ade565b6107a2838383613bd5565b60006111118383613c05565b6000611111838361392e565b600061325384846001600160a01b038516613ccb565b815460009082106139e05760405162461bcd60e51b81526004016106ea90614900565b8260000182815481106139ef57fe5b9060005260206000200154905092915050565b6000611111836001600160a01b038416613c05565b60006111118383613d62565b815460009081908310613a485760405162461bcd60e51b81526004016106ea9061510b565b6000846000018481548110613a5957fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008281526001840160205260408120548281613aaf5760405162461bcd60e51b81526004016106ea9190614825565b50846000016001820381548110613ac257fe5b9060005260206000209060020201600101549150509392505050565b60009081526001919091016020526040902054151590565b6000613b0a846001600160a01b0316613e36565b613b1657506001613253565b6060613b9e630a85bd0160e11b613b2b613180565b888787604051602401613b4194939291906147d4565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001615cf8603291396001600160a01b0388169190613e3c565b9050600081806020019051810190613bb69190614430565b6001600160e01b031916630a85bd0160e11b1492505050949350505050565b613be08383836107a2565b613be8611ac8565b156107a25760405162461bcd60e51b81526004016106ea90614942565b60008181526001830160205260408120548015613cc15783546000198083019190810190600090879083908110613c3857fe5b9060005260206000200154905080876000018481548110613c5557fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080613c8557fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610eb5565b6000915050610eb5565b600082815260018401602052604081205480613d30575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055611111565b82856000016001830381548110613d4357fe5b9060005260206000209060020201600101819055506000915050611111565b60008181526001830160205260408120548015613cc15783546000198083019190810190600090879083908110613d9557fe5b9060005260206000209060020201905080876000018481548110613db557fe5b600091825260208083208454600290930201918255600193840154918401919091558354825289830190526040902090840190558654879080613df457fe5b6000828152602080822060026000199094019384020182815560019081018390559290935588815289820190925260408220919091559450610eb59350505050565b3b151590565b6060613253848460008585613e5085613e36565b613e6c5760405162461bcd60e51b81526004016106ea9061550f565b60006060866001600160a01b03168587604051613e8991906146f5565b60006040518083038185875af1925050503d8060008114613ec6576040519150601f19603f3d011682016040523d82523d6000602084013e613ecb565b606091505b5091509150613edb828286613ee6565b979650505050505050565b60608315613ef5575081611111565b825115613f055782518084602001fd5b8160405162461bcd60e51b81526004016106ea9190614825565b61035e8061599a83390190565b604051806101400160405280606081526020016060815260200160608152602001606081526020016060815260200160006001600160a01b0316815260200160006001600160a01b031681526020016060815260200160608152602001606081525090565b50805460018160011615610100020316600290046000825580601f10613fb75750612722565b601f0160209004906000526020600020908101906127229190614053565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061401657805160ff1916838001178555614043565b82800160010185558215614043579182015b82811115614043578251825591602001919060010190614028565b5061404f929150614053565b5090565b5b8082111561404f5760008155600101614054565b80356001600160a01b0381168114610eb557600080fd5b600082601f83011261408f578081fd5b81356140a261409d82615912565b6158eb565b91508082528360208285010111156140b957600080fd5b8060208401602084013760009082016020015292915050565b60008083601f8401126140e3578182fd5b50813567ffffffffffffffff8111156140fa578182fd5b60208301915083602082850101111561367857600080fd5b600060208284031215614123578081fd5b6111118383614068565b6000806040838503121561413f578081fd5b6141498484614068565b91506141588460208501614068565b90509250929050565b600080600060608486031215614175578081fd5b83356141808161596e565b925060208401356141908161596e565b929592945050506040919091013590565b600080600080608085870312156141b6578081fd5b6141c08686614068565b93506141cf8660208701614068565b925060408501359150606085013567ffffffffffffffff8111156141f1578182fd5b6141fd8782880161407f565b91505092959194509250565b6000806040838503121561421b578182fd5b6142258484614068565b915060208301358015158114614239578182fd5b809150509250929050565b60008060008060008060008060006101208a8c031215614262578485fd5b61426c8b8b614068565b985060208a013567ffffffffffffffff80821115614288578687fd5b6142948d838e0161407f565b995060408c01359150808211156142a9578687fd5b6142b58d838e0161407f565b985060608c01359150808211156142ca578687fd5b6142d68d838e0161407f565b975060808c01359150808211156142eb578687fd5b6142f78d838e0161407f565b965060a08c013591508082111561430c578586fd5b6143188d838e0161407f565b955060c08c013591508082111561432d578485fd5b6143398d838e0161407f565b945060e08c013591508082111561434e578384fd5b61435a8d838e0161407f565b93506101008c0135915080821115614370578283fd5b5061437d8c828d0161407f565b9150509295985092959850929598565b6000806040838503121561439f578182fd5b6143a98484614068565b946020939093013593505050565b6000602082840312156143c8578081fd5b5035919050565b600080604083850312156143e1578182fd5b8235915060208301356142398161596e565b60008060408385031215614405578182fd5b50508035926020909101359150565b600060208284031215614425578081fd5b813561111181615983565b600060208284031215614441578081fd5b815161111181615983565b60006020828403121561445d578081fd5b813567ffffffffffffffff811115614473578182fd5b6132538482850161407f565b600060208284031215614490578081fd5b815167ffffffffffffffff8111156144a6578182fd5b8201601f810184136144b6578182fd5b80516144c461409d82615912565b8181528560208385010111156144d8578384fd5b6144e9826020830160208601615942565b95945050505050565b6000806000806000806080878903121561450a578384fd5b86359550602087013567ffffffffffffffff80821115614528578586fd5b6145348a838b016140d2565b9097509550604089013594506060890135915080821115614553578384fd5b5061456089828a016140d2565b979a9699509497509295939492505050565b60008060408385031215614584578182fd5b82359150602083013567ffffffffffffffff8111156145a1578182fd5b6145ad8582860161407f565b9150509250929050565b600080600080608085870312156145cc578182fd5b84359350602085013567ffffffffffffffff808211156145ea578384fd5b6145f68883890161407f565b9450604087013591508082111561460b578384fd5b6146178883890161407f565b9350606087013591508082111561462c578283fd5b506141fd8782880161407f565b60008151808452614651816020860160208601615942565b601f01601f19169290920160200192915050565b6001600160a01b03169052565b6000815460018082166000811461469057600181146146ae576146ec565b60028304607f16865260ff19831660208701526040860193506146ec565b600283048087526146be86615936565b60005b828110156146e25781546020828b01015284820191506020810190506146c1565b8801602001955050505b50505092915050565b60008251614707818460208701615942565b9190910192915050565b6000828483379101908152919050565b60008351614733818460208801615942565b835190830190614747818360208801615942565b01949350505050565b600080835460018082166000811461476f5760018114614786576147b5565b60ff198316865260028304607f16860193506147b5565b600283048786526020808720875b838110156147ad5781548a820152908501908201614794565b505050860193505b509195945050505050565b6001600160a01b0391909116815260200190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061480790830184614639565b9695505050505050565b901515815260200190565b90815260200190565b6000602082526111116020830184614639565b60006060825261484b6060830186614639565b828103602084015261485d8186614639565b905082810360408401526148078185614639565b6000606082526148846060830186614672565b82810360208401526148968186614672565b905082810360408401526148078185614672565b60208082526036908201527f5754433a20746f6b656e4964206d75737420657869737420746f2067657420626040820152750c2c6d640d2dac2ceca40c8c2e8c240e8f040d0c2e6d60531b606082015260800190565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252602b908201527f4552433732315061757361626c653a20746f6b656e207472616e73666572207760408201526a1a1a5b19481c185d5cd95960aa1b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b60208082526022908201527f5754433a206d7573742068617665206d696e74657220726f6c6520746f206d696040820152611b9d60f21b606082015260800190565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b60208082526040908201819052600080516020615d2a833981519152908201527f20617070726f76656420746f20736574206661636520696d6167652064617461606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b60208082526036908201527f5754433a20746f6b656e4964206d75737420657869737420746f2073657420666040820152750c2c6ca40d2dac2ceca40c8c2e8c240e8f040d0c2e6d60531b606082015260800190565b60208082526040908201819052600080516020615d2a833981519152908201527f20617070726f76656420746f207265736574204e4654206f776e657273686970606082015260800190565b60208082526030908201527f5754434e4654426173653a206f70657261746f7220717565727920666f72206e60408201526f37b732bc34b9ba32b73a103a37b5b2b760811b606082015260800190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b6020808252602c908201527f5754433a2064696765737420776974682063657274696669636174654361726460408201526b1259081b9bdd08199bdd5b9960a21b606082015260800190565b6020808252604890820152600080516020615d2a83398151915260408201527f20617070726f76656420746f20736574206261636b20696d6167652064617461606082015267040e8f040d0c2e6d60c31b608082015260a00190565b60208082526025908201527f5754433a206365727469666963617465436172644964206d75737420626520756040820152646e6971756560d81b606082015260800190565b60208082526036908201527f5754433a20746f6b656e4964206d75737420657869737420746f2067657420666040820152750c2c6ca40d2dac2ceca40c8c2e8c240e8f040d0c2e6d60531b606082015260800190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b6020808252602d908201527f5754433a20746f6b656e4964206d75737420657869737420746f20757064617460408201526c6520636572746966696361746560981b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252602e908201527f5754433a20746f6b656e4964206d75737420657869737420746f20736574206260408201526d61636b20696d616765206461746160901b606082015260800190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b6020808252602b908201527f5754433a20746f6b656e4964206d75737420657869737420746f206275726e2060408201526a636572746966696361746560a81b606082015260800190565b6020808252603390820152600080516020615d2a83398151915260408201527220617070726f76656420746f2075706461746560681b606082015260800190565b6020808252602a908201527f5754434e4654426173653a206d75737420686176652070617573657220726f6c6040820152696520746f20706175736560b01b606082015260800190565b6020808252604890820152600080516020615d2a83398151915260408201527f20617070726f76656420746f20736574206661636520696d6167652064617461606082015267040e8f040d0c2e6d60c31b608082015260a00190565b60208082526022908201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602e908201527f5754433a20746f6b656e4964206d75737420657869737420746f20736574206660408201526d61636520696d616765206461746160901b606082015260800190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252602c908201527f4552433732314d657461646174613a2055524920736574206f66206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526031908201527f5754433a20746f6b656e4964206d75737420657869737420746f206765742063604082015270195c9d1a599a58d85d1948191a59d95cdd607a1b606082015260800190565b60208082526040908201819052600080516020615d2a833981519152908201527f20617070726f76656420746f20736574206261636b20696d6167652064617461606082015260800190565b6020808252602a908201527f5754433a20746f6b656e4964206d75737420657869737420746f2067657420636040820152696572746966696361746560b01b606082015260800190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b6020808252602f908201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60408201526e3732bc34b9ba32b73a103a37b5b2b760891b606082015260800190565b6020808252602c908201527f5754433a206d7573742068617665206d696e74657220726f6c6520746f20757060408201526b64617465206261736555524960a01b606082015260800190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b6020808252602a908201527f5754433a2063657274696669636174654361726449642073686f756c64206e6f6040820152697420626520656d70747960b01b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252604190820152600080516020615d2a83398151915260408201527f20746865206f776e6572206f7220626520617070726f76656420746f206275726060820152603760f91b608082015260a00190565b6020808252602d908201527f5754433a20746f6b656e4964207769746820636572746966696361746543617260408201526c191259081b9bdd08199bdd5b99609a1b606082015260800190565b6020808252602e908201527f5754433a20746f6b656e4964206d75737420657869737420746f20726573657460408201526d0204e4654206f776e6572736869760941b606082015260800190565b60208082526044908201527f5754433a2066726f6d20616e6420746f2061646472657373206172652074686560408201527f2073616d652c206f776e6572736869702073686f756c64206e6f742062652072606082015263195cd95d60e21b608082015260a00190565b6020808252602c908201527f5754434e4654426173653a206d75737420686176652070617573657220726f6c60408201526b6520746f20756e706175736560a01b606082015260800190565b60208082526036908201527f5754433a20746f6b656e4964206d75737420657869737420746f2073657420626040820152750c2c6d640d2dac2ceca40c8c2e8c240e8f040d0c2e6d60531b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b60006020825282516101408060208501526157b0610160850183614639565b91506020850151601f19808685030160408701526157ce8483614639565b935060408701519150808685030160608701526157eb8483614639565b935060608701519150808685030160808701526158088483614639565b935060808701519150808685030160a08701526158258483614639565b935060a0870151915061583b60c0870183614665565b60c0870151915061584f60e0870183614665565b60e0870151915061010081878603018188015261586c8584614639565b94508088015192505061012081878603018188015261588b8584614639565b9088015187820390920184880152935090506148078382614639565b60008482526040602083015282604083015282846060840137818301606090810191909152601f909201601f1916010192915050565b60ff91909116815260200190565b60405181810167ffffffffffffffff8111828210171561590a57600080fd5b604052919050565b600067ffffffffffffffff821115615928578081fd5b50601f01601f191660200190565b60009081526020902090565b60005b8381101561595d578181015183820152602001615945565b8381111561296a5750506000910152565b6001600160a01b038116811461272257600080fd5b6001600160e01b03198116811461272257600080fdfe608060405234801561001057600080fd5b5061033e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80636b8b47651461003b578063e077a9ba14610050575b600080fd5b61004e6100493660046101f6565b610079565b005b61006361005e366004610291565b6100bd565b60405161007091906102a9565b60405180910390f35b6000805460018101825590805281516100b9917f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56301906020840190610163565b5050565b600081815481106100ca57fe5b600091825260209182902001805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529350909183018282801561015b5780601f106101305761010080835404028352916020019161015b565b820191906000526020600020905b81548152906001019060200180831161013e57829003601f168201915b505050505081565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106101a457805160ff19168380011785556101d1565b828001600101855582156101d1579182015b828111156101d15782518255916020019190600101906101b6565b506101dd9291506101e1565b5090565b5b808211156101dd57600081556001016101e2565b600060208284031215610207578081fd5b813567ffffffffffffffff8082111561021e578283fd5b818401915084601f830112610231578283fd5b81358181111561023f578384fd5b604051601f8201601f19168101602001838111828210171561025f578586fd5b604052818152838201602001871015610276578485fd5b6102878260208301602087016102fc565b9695505050505050565b6000602082840312156102a2578081fd5b5035919050565b6000602080835283518082850152825b818110156102d5578581018301518582016040015282016102b9565b818111156102e65783604083870101525b50601f01601f1916929092016040019392505050565b8281833750600091015256fea2646970667358221220c7148bdaacf8688f2bf16e267c998ff438a032272d9c4f415297bffe3251e52a64736f6c634300070000334552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465725754433a206d7573742068617665206d696e74657220726f6c65206f722062654552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6a2646970667358221220bb2928fe012e6f6e6a9bdf2e5827c6c96e6ecba38657377283c88a5f58766b0364736f6c63430007000033
Deployed Bytecode Sourcemap
83032:13247:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14080:150;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56066:100;;;:::i;:::-;;;;;;;:::i;58852:221::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;58382:404::-;;;;;;:::i;:::-;;:::i;:::-;;93595:697;;;;;;:::i;:::-;;:::i;57860:211::-;;;:::i;:::-;;;;;;;:::i;95146:452::-;;;;;;:::i;:::-;;:::i;59742:305::-;;;;;;:::i;:::-;;:::i;75040:114::-;;;;;;:::i;:::-;;:::i;89635:580::-;;;;;;:::i;:::-;;:::i;75416:227::-;;;;;;:::i;:::-;;:::i;57622:162::-;;;;;;:::i;:::-;;:::i;82532:82::-;;;:::i;:::-;;;;;;;:::i;76625:209::-;;;;;;:::i;:::-;;:::i;80446:165::-;;;:::i;60118:151::-;;;;;;:::i;:::-;;:::i;87435:650::-;;;;;;:::i;:::-;;:::i;58148:172::-;;;;;;:::i;:::-;;:::i;88919:549::-;;;;;;:::i;:::-;;:::i;92233:417::-;;;;;;:::i;:::-;;:::i;90359:231::-;;;;;;:::i;:::-;;:::i;32701:86::-;;;:::i;92834:452::-;;;;;;:::i;:::-;;:::i;55822:177::-;;;;;;:::i;:::-;;:::i;86404:760::-;;;;;;:::i;:::-;;:::i;57441:97::-;;;:::i;95696:580::-;;;;;;:::i;:::-;;:::i;94545:417::-;;;;;;:::i;:::-;;:::i;55539:221::-;;;;;;:::i;:::-;;:::i;84683:1465::-;;;;;;:::i;:::-;;:::i;80068:159::-;;;:::i;74713:138::-;;;;;;:::i;:::-;;:::i;73674:139::-;;;;;;:::i;:::-;;:::i;80955:196::-;;;;;;:::i;:::-;;:::i;56235:104::-;;;:::i;72419:49::-;;;:::i;59145:295::-;;;;;;:::i;:::-;;:::i;91283:697::-;;;;;;:::i;:::-;;:::i;60340:285::-;;;;;;:::i;:::-;;:::i;90734:221::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;56410:792::-;;;;;;:::i;:::-;;:::i;73987:127::-;;;;;;:::i;:::-;;:::i;79081:28::-;;;:::i;79118:62::-;;;:::i;75888:230::-;;;;;;:::i;:::-;;:::i;79187:62::-;;;:::i;59511:164::-;;;;;;:::i;:::-;;:::i;88254:504::-;;;;;;:::i;:::-;;:::i;14080:150::-;-1:-1:-1;;;;;;14189:33:0;;14165:4;14189:33;;;:20;:33;;;;;;;;14080:150;;;;:::o;56066:100::-;56153:5;56146:12;;;;;;;;-1:-1:-1;;56146:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56120:13;;56146:12;;56153:5;;56146:12;;56153:5;56146:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56066:100;:::o;58852:221::-;58928:7;58956:16;58964:7;58956;:16::i;:::-;58948:73;;;;-1:-1:-1;;;58948:73:0;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;59041:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;59041:24:0;;58852:221::o;58382:404::-;58463:13;58479:23;58494:7;58479:14;:23::i;:::-;58463:39;;58527:5;-1:-1:-1;;;;;58521:11:0;:2;-1:-1:-1;;;;;58521:11:0;;;58513:57;;;;-1:-1:-1;;;58513:57:0;;;;;;;:::i;:::-;58607:5;-1:-1:-1;;;;;58591:21:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;58591:21:0;;:69;;;;58616:44;58640:5;58647:12;:10;:12::i;58616:44::-;58583:161;;;;-1:-1:-1;;;58583:161:0;;;;;;;:::i;:::-;58757:21;58766:2;58770:7;58757:8;:21::i;:::-;58382:404;;;:::o;93595:697::-;93742:34;93754:12;:10;:12::i;:::-;93768:7;93742:11;:34::i;:::-;:72;;;;93780:34;-1:-1:-1;;;;;;;;;;;93801:12:0;:10;:12::i;93780:34::-;93734:149;;;;-1:-1:-1;;;93734:149:0;;;;;;;:::i;:::-;93902:16;93910:7;93902;:16::i;:::-;93894:75;;;;-1:-1:-1;;;93894:75:0;;;;;;;:::i;:::-;93980:22;94005:18;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;93980:43:0;-1:-1:-1;94040:19:0;94036:136;;94117:21;;;;:12;:21;;;;;:31;;:43;;-1:-1:-1;;;;;;94117:43:0;-1:-1:-1;;;;;94117:43:0;;;;;94036:136;94247:9;;94187:97;;;;;;;:::i;:::-;;;;;;;;;;94206:21;;;;:12;:21;;;;;;94187:97;;;;94206:21;94187:97;:::i;:::-;;;;;;;;94197:7;94187:97;94258:14;94274:9;;94187:97;;;;;;;;:::i;:::-;;;;;;;;93595:697;;;;;;;:::o;57860:211::-;57921:7;58042:21;:12;:19;:21::i;:::-;58035:28;;57860:211;:::o;95146:452::-;95240:13;95274:16;95282:7;95274;:16::i;:::-;95266:83;;;;-1:-1:-1;;;95266:83:0;;;;;;;:::i;:::-;95360:30;;:::i;:::-;95393:21;;;;:12;:21;;;;;;;;;95360:54;;;;;;;;;;;-1:-1:-1;;95360:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95393:21;;95360:54;;95393:21;;95360:54;;;95393:21;95360:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;95360:54:0;;;-1:-1:-1;;95360:54:0;;;;;;;;;;;;;;;;-1:-1:-1;;95360:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;95360:54:0;;;-1:-1:-1;;95360:54:0;;;;;;;;;;;;;;;;-1:-1:-1;;95360:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;95360:54:0;;;-1:-1:-1;;95360:54:0;;;;;;;;;;;;;;;;-1:-1:-1;;95360:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;95360:54:0;;;-1:-1:-1;;95360:54:0;;;;-1:-1:-1;;;;;95360:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;95360:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;95360:54:0;;;-1:-1:-1;;95360:54:0;;;;;;;;;;;;;;;;-1:-1:-1;;95360:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;95360:54:0;;;-1:-1:-1;;95360:54:0;;;;;;;;;;;;;;;;-1:-1:-1;;95360:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;95360:54:0;;;;-1:-1:-1;;;95450:21:0;;;;95514:41;;-1:-1:-1;;;95514:41:0;;95360:54;;-1:-1:-1;95450:21:0;95482:29;;-1:-1:-1;;;;;95514:25:0;;;;;:41;;95540:14;;95514:41;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;95514:41:0;;;;;;;;;;;;:::i;:::-;95482:73;-1:-1:-1;;;;95146:452:0;;;;;:::o;59742:305::-;59903:41;59922:12;:10;:12::i;:::-;59936:7;59903:18;:41::i;:::-;59895:103;;;;-1:-1:-1;;;59895:103:0;;;;;;;:::i;:::-;60011:28;60021:4;60027:2;60031:7;60011:9;:28::i;75040:114::-;75097:7;75124:12;;;;;;;;;;:22;;;;75040:114::o;89635:580::-;89729:13;89797:1;89769:17;89763:31;:35;89755:90;;;;-1:-1:-1;;;89755:90:0;;;;;;;:::i;:::-;89874:1;89888:247;89906:25;:15;:23;:25::i;:::-;89895:7;:36;89888:247;;89966:21;;;;:12;:21;;;;;;;;;89952:73;;;;;;-1:-1:-1;;89952:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89966:21;89952:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90007:17;89952:13;:73::i;:::-;89948:152;;;90053:21;;;;:12;:21;;;;;;;;;:31;;90046:38;;;;;;-1:-1:-1;;90046:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90053:31;;90046:38;;90053:31;90046:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89948:152;90114:9;;89888:247;;;90145:62;;-1:-1:-1;;;90145:62:0;;;;;;;:::i;75416:227::-;75508:6;:12;;;;;;;;;;:22;;;75500:45;;75532:12;:10;:12::i;75500:45::-;75492:105;;;;-1:-1:-1;;;75492:105:0;;;;;;;:::i;:::-;75610:25;75621:4;75627:7;75610:10;:25::i;:::-;75416:227;;:::o;57622:162::-;-1:-1:-1;;;;;57746:20:0;;57719:7;57746:20;;;:13;:20;;;;;:30;;57770:5;57746:23;:30::i;:::-;57739:37;57622:162;-1:-1:-1;;;57622:162:0:o;82532:82::-;82573:5;82532:82;:::o;76625:209::-;76723:12;:10;:12::i;:::-;-1:-1:-1;;;;;76712:23:0;:7;-1:-1:-1;;;;;76712:23:0;;76704:83;;;;-1:-1:-1;;;76704:83:0;;;;;;;:::i;:::-;76800:26;76812:4;76818:7;76800:11;:26::i;80446:165::-;80499:34;79225:24;80520:12;:10;:12::i;80499:34::-;80491:91;;;;-1:-1:-1;;;80491:91:0;;;;;;;:::i;:::-;80593:10;:8;:10::i;:::-;80446:165::o;60118:151::-;60222:39;60239:4;60245:2;60249:7;60222:39;;;;;;;;;;;;:16;:39::i;87435:650::-;87509:16;87517:7;87509;:16::i;:::-;87501:72;;;;-1:-1:-1;;;87501:72:0;;;;;;;:::i;:::-;87645:41;87664:12;:10;:12::i;87645:41::-;:79;;;;87690:34;-1:-1:-1;;;;;;;;;;;87711:12:0;:10;:12::i;87690:34::-;87637:157;;;;-1:-1:-1;;;87637:157:0;;;;;;;:::i;:::-;87805:30;;:::i;:::-;87838:21;;;;:12;:21;;;;;;;;;87805:54;;;;;;;;;;;-1:-1:-1;;87805:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87838:21;;87805:54;;87838:21;;87805:54;;;87838:21;87805:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;87805:54:0;;;-1:-1:-1;;87805:54:0;;;;;;;;;;;;;;;;-1:-1:-1;;87805:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;87805:54:0;;;-1:-1:-1;;87805:54:0;;;;;;;;;;;;;;;;-1:-1:-1;;87805:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;87805:54:0;;;-1:-1:-1;;87805:54:0;;;;;;;;;;;;;;;;-1:-1:-1;;87805:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;87805:54:0;;;-1:-1:-1;;87805:54:0;;;;-1:-1:-1;;;;;87805:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;87805:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;87805:54:0;;;-1:-1:-1;;87805:54:0;;;;;;;;;;;;;;;;-1:-1:-1;;87805:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;87805:54:0;;;-1:-1:-1;;87805:54:0;;;;;;;;;;;;;;;;-1:-1:-1;;87805:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;87805:54:0;;;;-1:-1:-1;;;87879:21:0;;;;:12;:21;;;;;87805:54;;-1:-1:-1;87872:28:0;87879:21;;87872:28;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;;87872:28:0;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;-1:-1:-1;;87951:29:0;;87923:129;;;;87951:29;87923:129;:::i;:::-;;;;;;;;87942:7;87923:129;87982:11;:21;;;88005:11;:22;;;88029:11;:22;;;87923:129;;;;;;;;:::i;:::-;;;;;;;;88063:14;88069:7;88063:5;:14::i;58148:172::-;58223:7;;58265:22;:12;58281:5;58265:15;:22::i;:::-;-1:-1:-1;58243:44:0;58148:172;-1:-1:-1;;;58148:172:0:o;88919:549::-;89011:7;89073:1;89045:17;89039:31;:35;89031:90;;;;-1:-1:-1;;;89031:90:0;;;;;;;:::i;:::-;89150:1;89164:223;89182:25;:15;:23;:25::i;:::-;89171:7;:36;89164:223;;89242:21;;;;:12;:21;;;;;;;;;89228:73;;;;;;-1:-1:-1;;89228:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89242:21;89228:73;;;;;;;;;;;;;;;;;;;;;;;;;89224:128;;;89329:7;-1:-1:-1;89322:14:0;;89224:128;89366:9;;89164:223;;;89397:63;;-1:-1:-1;;;89397:63:0;;;;;;;:::i;92233:417::-;92330:34;92342:12;:10;:12::i;:::-;92356:7;92330:11;:34::i;:::-;:72;;;;92368:34;-1:-1:-1;;;;;;;;;;;92389:12:0;:10;:12::i;92368:34::-;92322:157;;;;-1:-1:-1;;;92322:157:0;;;;;;;:::i;:::-;92498:16;92506:7;92498;:16::i;:::-;92490:83;;;;-1:-1:-1;;;92490:83:0;;;;;;;:::i;:::-;92584:21;;;;:12;:21;;;;;;;:31;;;:58;;-1:-1:-1;;;92584:58:0;;-1:-1:-1;;;;;92584:31:0;;;;:50;;:58;;92635:6;;92584:58;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92233:417;;:::o;90359:231::-;90427:13;90461:16;90469:7;90461;:16::i;:::-;90453:78;;;;-1:-1:-1;;;90453:78:0;;;;;;;:::i;:::-;90551:21;;;;:12;:21;;;;;;;;;:31;;90544:38;;;;;;-1:-1:-1;;90544:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90551:31;;90544:38;;90551:31;90544:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90359:231;;;:::o;32701:86::-;32772:7;;;;32701:86;:::o;92834:452::-;92928:13;92962:16;92970:7;92962;:16::i;:::-;92954:83;;;;-1:-1:-1;;;92954:83:0;;;;;;;:::i;:::-;93048:30;;:::i;:::-;93081:21;;;;:12;:21;;;;;;;;;93048:54;;;;;;;;;;;-1:-1:-1;;93048:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93081:21;;93048:54;;93081:21;;93048:54;;;93081:21;93048:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;93048:54:0;;;-1:-1:-1;;93048:54:0;;;;;;;;;;;;;;;;-1:-1:-1;;93048:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;93048:54:0;;;-1:-1:-1;;93048:54:0;;;;;;;;;;;;;;;;-1:-1:-1;;93048:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;93048:54:0;;;-1:-1:-1;;93048:54:0;;;;;;;;;;;;;;;;-1:-1:-1;;93048:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;93048:54:0;;;-1:-1:-1;;93048:54:0;;;;-1:-1:-1;;;;;93048:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;93048:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;93048:54:0;;;-1:-1:-1;;93048:54:0;;;;;;;;;;;;;;;;-1:-1:-1;;93048:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;93048:54:0;;;-1:-1:-1;;93048:54:0;;;;;;;;;;;;;;;;-1:-1:-1;;93048:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;93048:54:0;;;;-1:-1:-1;;;93138:21:0;;;;93202:41;;-1:-1:-1;;;93202:41:0;;93048:54;;-1:-1:-1;93138:21:0;93170:29;;-1:-1:-1;;;;;93202:25:0;;;;;:41;;93228:14;;93202:41;;;:::i;55822:177::-;55894:7;55921:70;55938:7;55921:70;;;;;;;;;;;;;;;;;:12;;:70;:16;:70::i;86404:760::-;86540:16;86548:7;86540;:16::i;:::-;86532:74;;;;-1:-1:-1;;;86532:74:0;;;;;;;:::i;:::-;86678:34;86690:12;:10;:12::i;:::-;86704:7;86678:11;:34::i;:::-;:72;;;;86716:34;-1:-1:-1;;;;;;;;;;;86737:12:0;:10;:12::i;86716:34::-;86670:136;;;;-1:-1:-1;;;86670:136:0;;;;;;;:::i;:::-;86817:21;;;;:12;:21;;;;;;;;:43;;;;:31;;;;;:43;;;;:::i;:::-;-1:-1:-1;86871:21:0;;;;:12;:21;;;;;;;;:45;;;;:32;;;;;:45;;;;:::i;:::-;-1:-1:-1;86927:21:0;;;;:12;:21;;;;;;;;:45;;;;:32;;;;;:45;;;;:::i;:::-;-1:-1:-1;87015:21:0;;;;:12;:21;;;;;;;86988:168;;;;87015:21;86988:168;:::i;:::-;;;;;;;;;;87056:21;;;;:12;:21;;;;;;86988:168;;87006:7;;86988:168;;;;87056:31;;;;87089:32;;;;87123;;;86988:168;:::i;:::-;;;;;;;;86404:760;;;;:::o;57441:97::-;57522:8;57515:15;;;;;;;;-1:-1:-1;;57515:15:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57489:13;;57515:15;;57522:8;;57515:15;;57522:8;57515:15;;;;;;;;;;;;;;;;;;;;;;;;95696:580;95763:16;95771:7;95763;:16::i;:::-;95755:75;;;;-1:-1:-1;;;95755:75:0;;;;;;;:::i;:::-;95849:34;95861:12;:10;:12::i;:::-;95875:7;95849:11;:34::i;:::-;:72;;;;95887:34;-1:-1:-1;;;;;;;;;;;95908:12:0;:10;:12::i;95887:34::-;95841:149;;;;-1:-1:-1;;;95841:149:0;;;;;;;:::i;:::-;96001:12;96016:23;96031:7;96016:14;:23::i;:::-;96063:13;;96001:38;;-1:-1:-1;;;;;;96063:13:0;;;;;;;96095:10;;;;;96087:91;;;;-1:-1:-1;;;96087:91:0;;;;;;;:::i;:::-;96191:28;96201:4;96207:2;96211:7;96191:9;:28::i;:::-;96265:2;-1:-1:-1;;;;;96235:33:0;96259:4;-1:-1:-1;;;;;96235:33:0;96250:7;96235:33;;;;;;;;;;95696:580;;;:::o;94545:417::-;94642:34;94654:12;:10;:12::i;94642:34::-;:72;;;;94680:34;-1:-1:-1;;;;;;;;;;;94701:12:0;:10;:12::i;94680:34::-;94634:157;;;;-1:-1:-1;;;94634:157:0;;;;;;;:::i;:::-;94810:16;94818:7;94810;:16::i;:::-;94802:83;;;;-1:-1:-1;;;94802:83:0;;;;;;;:::i;:::-;94896:21;;;;:12;:21;;;;;;;:31;;;:58;;-1:-1:-1;;;94896:58:0;;-1:-1:-1;;;;;94896:31:0;;;;:50;;:58;;94947:6;;94896:58;;;:::i;55539:221::-;55611:7;-1:-1:-1;;;;;55639:19:0;;55631:74;;;;-1:-1:-1;;;55631:74:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;55723:20:0;;;;;;:13;:20;;;;;:29;;:27;:29::i;84683:1465::-;85007:1;84979:17;84973:31;:35;84965:90;;;;-1:-1:-1;;;84965:90:0;;;;;;;:::i;:::-;85075:59;85116:17;85075:40;:59::i;:::-;85074:60;85066:110;;;;-1:-1:-1;;;85066:110:0;;;;;;;:::i;:::-;85195:34;-1:-1:-1;;;;;;;;;;;85216:12:0;:10;:12::i;85195:34::-;85187:81;;;;-1:-1:-1;;;85187:81:0;;;;;;;:::i;:::-;85279:27;:15;:25;:27::i;:::-;85317:18;85338:25;:15;:23;:25::i;:::-;85317:46;;85376:21;85382:2;85386:10;85376:5;:21::i;:::-;85408:43;85421:10;85433:17;85408:12;:43::i;:::-;85462:24;;;;:12;:24;;;;;;;;:62;;;;;;;;:::i;:::-;-1:-1:-1;85535:24:0;;;;:12;:24;;;;;;;;:48;;;;:35;;;;;:48;;;;:::i;:::-;-1:-1:-1;85594:24:0;;;;:12;:24;;;;;;;;:48;;;;:35;;;;;:48;;;;:::i;:::-;-1:-1:-1;85653:24:0;;;;:12;:24;;;;;;;;:56;;;;:39;;;;;:56;;;;:::i;:::-;-1:-1:-1;85720:24:0;;;;:12;:24;;;;;;;;:46;;;;:34;;;;;:46;;;;:::i;:::-;-1:-1:-1;85777:24:0;;;;:12;:24;;;;;;;;:46;;;;:34;;;;;:46;;;;:::i;:::-;-1:-1:-1;85834:24:0;;;;:12;:24;;;;;;;;:48;;;;:35;;;;;:48;;;;:::i;:::-;-1:-1:-1;85893:24:0;;;;:12;:24;;;;;;;;:48;;;;:35;;;;;:48;;;;:::i;:::-;-1:-1:-1;85987:24:0;;;;:12;:24;;;;;;;85957:183;;;;85987:24;85957:183;:::i;:::-;;;;;;;;;;86031:24;;;;:12;:24;;;;;;85957:183;;85975:10;;85957:183;;;;86031:34;;;;86067:35;;;;86104;;;85957:183;:::i;:::-;;;;;;;;84683:1465;;;;;;;;;;:::o;80068:159::-;80119:34;79225:24;80140:12;:10;:12::i;80119:34::-;80111:89;;;;-1:-1:-1;;;80111:89:0;;;;;;;:::i;:::-;80211:8;:6;:8::i;74713:138::-;74786:7;74813:12;;;;;;;;;;:30;;74837:5;74813:23;:30::i;73674:139::-;73743:4;73767:12;;;;;;;;;;:38;;73797:7;73767:29;:38::i;80955:196::-;81027:34;-1:-1:-1;;;;;;;;;;;81048:12:0;:10;:12::i;81027:34::-;81019:91;;;;-1:-1:-1;;;81019:91:0;;;;;;;:::i;:::-;81123:20;81135:7;81123:11;:20::i;:::-;80955:196;:::o;56235:104::-;56324:7;56317:14;;;;;;;;-1:-1:-1;;56317:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56291:13;;56317:14;;56324:7;;56317:14;;56324:7;56317:14;;;;;;;;;;;;;;;;;;;;;;;;72419:49;72464:4;72419:49;:::o;59145:295::-;59260:12;:10;:12::i;:::-;-1:-1:-1;;;;;59248:24:0;:8;-1:-1:-1;;;;;59248:24:0;;;59240:62;;;;-1:-1:-1;;;59240:62:0;;;;;;;:::i;:::-;59360:8;59315:18;:32;59334:12;:10;:12::i;:::-;-1:-1:-1;;;;;59315:32:0;;;;;;;;;;;;;;;;;-1:-1:-1;59315:32:0;;;:42;;;;;;;;;;;;:53;;-1:-1:-1;;59315:53:0;;;;;;;;;;;59399:12;:10;:12::i;:::-;-1:-1:-1;;;;;59384:48:0;;59423:8;59384:48;;;;;;:::i;:::-;;;;;;;;59145:295;;:::o;91283:697::-;91430:34;91442:12;:10;:12::i;91430:34::-;:72;;;;91468:34;-1:-1:-1;;;;;;;;;;;91489:12:0;:10;:12::i;91468:34::-;91422:149;;;;-1:-1:-1;;;91422:149:0;;;;;;;:::i;:::-;91590:16;91598:7;91590;:16::i;:::-;91582:75;;;;-1:-1:-1;;;91582:75:0;;;;;;;:::i;:::-;91668:22;91693:18;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;91668:43:0;-1:-1:-1;91728:19:0;91724:136;;91805:21;;;;:12;:21;;;;;;;:31;;:43;;-1:-1:-1;;;;;;91805:43:0;-1:-1:-1;;;;;91805:43:0;;;;;91875:97;;;91935:9;;;;91875:97;:::i;60340:285::-;60472:41;60491:12;:10;:12::i;:::-;60505:7;60472:18;:41::i;:::-;60464:103;;;;-1:-1:-1;;;60464:103:0;;;;;;;:::i;:::-;60578:39;60592:4;60598:2;60602:7;60611:5;60578:13;:39::i;:::-;60340:285;;;;:::o;90734:221::-;90804:18;;:::i;:::-;90843:16;90851:7;90843;:16::i;:::-;90835:71;;;;-1:-1:-1;;;90835:71:0;;;;;;;:::i;:::-;90926:21;;;;:12;:21;;;;;;;;;90919:28;;;;;;;;;;;-1:-1:-1;;90919:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90926:21;;90919:28;;90926:21;;90919:28;;;90926:21;90919:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;90919:28:0;;;-1:-1:-1;;90919:28:0;;;;;;;;;;;;;;;;-1:-1:-1;;90919:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;90919:28:0;;;-1:-1:-1;;90919:28:0;;;;;;;;;;;;;;;;-1:-1:-1;;90919:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;90919:28:0;;;-1:-1:-1;;90919:28:0;;;;;;;;;;;;;;;;-1:-1:-1;;90919:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;90919:28:0;;;-1:-1:-1;;90919:28:0;;;;-1:-1:-1;;;;;90919:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;90919:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;90919:28:0;;;-1:-1:-1;;90919:28:0;;;;;;;;;;;;;;;;-1:-1:-1;;90919:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;90919:28:0;;;-1:-1:-1;;90919:28:0;;;;;;;;;;;;;;;;-1:-1:-1;;90919:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90734:221;;;:::o;56410:792::-;56483:13;56517:16;56525:7;56517;:16::i;:::-;56509:76;;;;-1:-1:-1;;;56509:76:0;;;;;;;:::i;:::-;56624:19;;;;:10;:19;;;;;;;;;56598:45;;;;;;-1:-1:-1;;56598:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:23;;:45;;;56624:19;56598:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56654:18;56675:9;:7;:9::i;:::-;56654:30;;56766:4;56760:18;56782:1;56760:23;56756:72;;;-1:-1:-1;56807:9:0;-1:-1:-1;56800:16:0;;56756:72;56932:23;;:27;56928:108;;57007:4;57013:9;56990:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;56976:48;;;;;;56928:108;57168:4;57174:18;:7;:16;:18::i;:::-;57151:42;;;;;;;;;:::i;:::-;;;;;;;;;;;;;57137:57;;;;56410:792;;;:::o;73987:127::-;74050:7;74077:12;;;;;;;;;;:29;;:27;:29::i;79081:28::-;;;;;;-1:-1:-1;;;;;79081:28:0;;:::o;79118:62::-;-1:-1:-1;;;;;;;;;;;79118:62:0;:::o;75888:230::-;75981:6;:12;;;;;;;;;;:22;;;75973:45;;76005:12;:10;:12::i;75973:45::-;75965:106;;;;-1:-1:-1;;;75965:106:0;;;;;;;:::i;79187:62::-;79225:24;79187:62;:::o;59511:164::-;-1:-1:-1;;;;;59632:25:0;;;59608:4;59632:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;59511:164::o;88254:504::-;88358:4;88417:1;88389:17;88383:31;:35;88375:90;;;;-1:-1:-1;;;88375:90:0;;;;;;;:::i;:::-;88494:1;88508:220;88526:25;:15;:23;:25::i;:::-;88515:7;:36;88508:220;;88586:21;;;;:12;:21;;;;;;;;;88572:73;;;;;;-1:-1:-1;;88572:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88586:21;88572:73;;;;;;;;;;;;;;;;;;;;;;;;;88568:125;;;88673:4;88666:11;;;;;88568:125;88707:9;;88508:220;;;-1:-1:-1;88745:5:0;;88254:504;-1:-1:-1;;88254:504:0:o;48672:152::-;48742:4;48766:50;48771:3;-1:-1:-1;;;;;48791:23:0;;48766:4;:50::i;62092:127::-;62157:4;62181:30;:12;62203:7;62181:21;:30::i;31220:106::-;31308:10;31220:106;:::o;68110:192::-;68185:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;68185:29:0;-1:-1:-1;;;;;68185:29:0;;;;;;;;:24;;68239:23;68185:24;68239:14;:23::i;:::-;-1:-1:-1;;;;;68230:46:0;;;;;;;;;;;68110:192;;:::o;82003:332::-;82089:4;82114:16;82122:7;82114;:16::i;:::-;82106:77;;;;-1:-1:-1;;;82106:77:0;;;;;;;:::i;:::-;82194:13;82210:23;82225:7;82210:14;:23::i;:::-;82194:39;;82276:7;-1:-1:-1;;;;;82252:31:0;:20;82264:7;82252:11;:20::i;:::-;-1:-1:-1;;;;;82252:31:0;;:74;;;;82287:39;82311:5;82318:7;82287:23;:39::i;:::-;82244:83;82003:332;-1:-1:-1;;;;82003:332:0:o;9198:123::-;9267:7;9294:19;9302:3;9294:7;:19::i;62386:355::-;62479:4;62504:16;62512:7;62504;:16::i;:::-;62496:73;;;;-1:-1:-1;;;62496:73:0;;;;;;;:::i;:::-;62580:13;62596:23;62611:7;62596:14;:23::i;:::-;62580:39;;62649:5;-1:-1:-1;;;;;62638:16:0;:7;-1:-1:-1;;;;;62638:16:0;;:51;;;;62682:7;-1:-1:-1;;;;;62658:31:0;:20;62670:7;62658:11;:20::i;62638:51::-;:94;;;;62693:39;62717:5;62724:7;62693:23;:39::i;65522:599::-;65647:4;-1:-1:-1;;;;;65620:31:0;:23;65635:7;65620:14;:23::i;:::-;-1:-1:-1;;;;;65620:31:0;;65612:85;;;;-1:-1:-1;;;65612:85:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;65734:16:0;;65726:65;;;;-1:-1:-1;;;65726:65:0;;;;;;;:::i;:::-;65804:39;65825:4;65831:2;65835:7;65804:20;:39::i;:::-;65908:29;65925:1;65929:7;65908:8;:29::i;:::-;-1:-1:-1;;;;;65950:19:0;;;;;;:13;:19;;;;;:35;;65977:7;65950:26;:35::i;:::-;-1:-1:-1;;;;;;65996:17:0;;;;;;:13;:17;;;;;:30;;66018:7;65996:21;:30::i;:::-;-1:-1:-1;66039:29:0;:12;66056:7;66065:2;66039:16;:29::i;:::-;;66105:7;66101:2;-1:-1:-1;;;;;66086:27:0;66095:4;-1:-1:-1;;;;;66086:27:0;;;;;;;;;;;65522:599;;;:::o;30101:114::-;30193:14;;30101:114::o;81583:253::-;81676:4;81760;81743:22;;;;;;;;:::i;:::-;;;;;;;;;;;;;81733:33;;;;;;81724:3;81707:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;81697:32;;;;;;:69;81693:113;;;-1:-1:-1;81790:4:0;81783:11;;77868:188;77942:6;:12;;;;;;;;;;:33;;77967:7;77942:24;:33::i;:::-;77938:111;;;78024:12;:10;:12::i;:::-;-1:-1:-1;;;;;77997:40:0;78015:7;-1:-1:-1;;;;;77997:40:0;78009:4;77997:40;;;;;;;;;;77868:188;;:::o;51586:137::-;51657:7;51692:22;51696:3;51708:5;51692:3;:22::i;78064:192::-;78139:6;:12;;;;;;;;;;:36;;78167:7;78139:27;:36::i;:::-;78135:114;;;78224:12;:10;:12::i;:::-;-1:-1:-1;;;;;78197:40:0;78215:7;-1:-1:-1;;;;;78197:40:0;78209:4;78197:40;;;;;;;;;;78064:192;;:::o;33760:120::-;33304:8;:6;:8::i;:::-;33296:41;;;;-1:-1:-1;;;33296:41:0;;;;;;;:::i;:::-;33819:7:::1;:15:::0;;-1:-1:-1;;33819:15:0::1;::::0;;33850:22:::1;33859:12;:10;:12::i;:::-;33850:22;;;;;;:::i;:::-;;;;;;;;33760:120::o:0;64640:545::-;64700:13;64716:23;64731:7;64716:14;:23::i;:::-;64700:39;;64770:48;64791:5;64806:1;64810:7;64770:20;:48::i;:::-;64859:29;64876:1;64880:7;64859:8;:29::i;:::-;64947:19;;;;:10;:19;;;;;64941:33;;-1:-1:-1;;64941:33:0;;;;;;;;;;;:38;64937:97;;65003:19;;;;:10;:19;;;;;64996:26;;;:::i;:::-;-1:-1:-1;;;;;65046:20:0;;;;;;:13;:20;;;;;:36;;65074:7;65046:27;:36::i;:::-;-1:-1:-1;65095:28:0;:12;65115:7;65095:19;:28::i;:::-;-1:-1:-1;65141:36:0;;65169:7;;65165:1;;-1:-1:-1;;;;;65141:36:0;;;;;65165:1;;65141:36;64640:545;;:::o;9660:236::-;9740:7;;;;9800:22;9804:3;9816:5;9800:3;:22::i;:::-;9769:53;;-1:-1:-1;9769:53:0;-1:-1:-1;;;9660:236:0;;;;;;:::o;10946:213::-;11053:7;11104:44;11109:3;11129;11135:12;11104:4;:44::i;30223:181::-;30377:19;;30395:1;30377:19;;;30223:181::o;64007:404::-;-1:-1:-1;;;;;64087:16:0;;64079:61;;;;-1:-1:-1;;;64079:61:0;;;;;;;:::i;:::-;64160:16;64168:7;64160;:16::i;:::-;64159:17;64151:58;;;;-1:-1:-1;;;64151:58:0;;;;;;;:::i;:::-;64222:45;64251:1;64255:2;64259:7;64222:20;:45::i;:::-;-1:-1:-1;;;;;64280:17:0;;;;;;:13;:17;;;;;:30;;64302:7;64280:21;:30::i;:::-;-1:-1:-1;64323:29:0;:12;64340:7;64349:2;64323:16;:29::i;:::-;-1:-1:-1;64370:33:0;;64395:7;;-1:-1:-1;;;;;64370:33:0;;;64387:1;;64370:33;;64387:1;;64370:33;64007:404;;:::o;66277:215::-;66377:16;66385:7;66377;:16::i;:::-;66369:73;;;;-1:-1:-1;;;66369:73:0;;;;;;;:::i;:::-;66453:19;;;;:10;:19;;;;;;;;:31;;;;;;;;:::i;33501:118::-;33027:8;:6;:8::i;:::-;33026:9;33018:38;;;;-1:-1:-1;;;33018:38:0;;;;;;;:::i;:::-;33561:7:::1;:14:::0;;-1:-1:-1;;33561:14:0::1;33571:4;33561:14;::::0;;33591:20:::1;33598:12;:10;:12::i;49244:167::-:0;49324:4;49348:55;49358:3;-1:-1:-1;;;;;49378:23:0;;49348:9;:55::i;66722:100::-;66795:19;;;;:8;;:19;;;;;:::i;61507:272::-;61621:28;61631:4;61637:2;61641:7;61621:9;:28::i;:::-;61668:48;61691:4;61697:2;61701:7;61710:5;61668:22;:48::i;:::-;61660:111;;;;-1:-1:-1;;;61660:111:0;;;;;;;:::i;333:746::-;389:13;610:10;606:53;;-1:-1:-1;637:10:0;;;;;;;;;;;;-1:-1:-1;;;637:10:0;;;;;;606:53;684:5;669:12;725:78;732:9;;725:78;;758:8;;789:2;781:10;;;;725:78;;;813:19;845:6;835:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;835:17:0;-1:-1:-1;907:5:0;;-1:-1:-1;813:39:0;-1:-1:-1;;;879:10:0;;923:117;930:9;;923:117;;999:2;992:4;:9;987:2;:14;974:29;;956:6;963:7;;;;;;;956:15;;;;;;;;;;;:47;-1:-1:-1;;;;;956:47:0;;;;;;;;-1:-1:-1;1026:2:0;1018:10;;;;923:117;;;-1:-1:-1;1064:6:0;333:746;-1:-1:-1;;;;333:746:0:o;43736:414::-;43799:4;43821:21;43831:3;43836:5;43821:9;:21::i;:::-;43816:327;;-1:-1:-1;43859:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;44042:18;;44020:19;;;:12;;;:19;;;;;;:40;;;;44075:11;;43816:327;-1:-1:-1;44126:5:0;44119:12;;8959:151;9043:4;9067:35;9077:3;9097;9067:9;:35::i;80619:187::-;80753:45;80780:4;80786:2;80790:7;80753:26;:45::i;50673:137::-;50743:4;50767:35;50775:3;50795:5;50767:7;:35::i;50366:131::-;50433:4;50457:32;50462:3;50482:5;50457:4;:32::i;8382:185::-;8471:4;8495:64;8500:3;8520;-1:-1:-1;;;;;8534:23:0;;8495:4;:64::i;46624:204::-;46719:18;;46691:7;;46719:26;-1:-1:-1;46711:73:0;;;;-1:-1:-1;;;46711:73:0;;;;;;;:::i;:::-;46802:3;:11;;46814:5;46802:18;;;;;;;;;;;;;;;;46795:25;;46624:204;;;;:::o;49000:158::-;49073:4;49097:53;49105:3;-1:-1:-1;;;;;49125:23:0;;49097:7;:53::i;8733:142::-;8810:4;8834:33;8842:3;8862;8834:7;:33::i;6242:279::-;6346:19;;6309:7;;;;6346:27;-1:-1:-1;6338:74:0;;;;-1:-1:-1;;;6338:74:0;;;;;;;:::i;:::-;6425:22;6450:3;:12;;6463:5;6450:19;;;;;;;;;;;;;;;;;;6425:44;;6488:5;:10;;;6500:5;:12;;;6480:33;;;;;6242:279;;;;;:::o;7739:319::-;7833:7;7872:17;;;:12;;;:17;;;;;;7923:12;7908:13;7900:36;;;;-1:-1:-1;;;7900:36:0;;;;;;;;:::i;:::-;;7990:3;:12;;8014:1;8003:8;:12;7990:26;;;;;;;;;;;;;;;;;;:33;;;7983:40;;;7739:319;;;;;:::o;45956:129::-;46029:4;46053:19;;;:12;;;;;:19;;;;;;:24;;;45956:129::o;67387:604::-;67508:4;67535:15;:2;-1:-1:-1;;;;;67535:13:0;;:15::i;:::-;67530:60;;-1:-1:-1;67574:4:0;67567:11;;67530:60;67600:23;67626:252;-1:-1:-1;;;67739:12:0;:10;:12::i;:::-;67766:4;67785:7;67807:5;67642:181;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;67642:181:0;;;;;;;-1:-1:-1;;;;;67642:181:0;;;;;;;;;;;67626:252;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;67626:15:0;;;:252;:15;:252::i;:::-;67600:278;;67889:13;67916:10;67905:32;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;67956:26:0;-1:-1:-1;;;67956:26:0;;-1:-1:-1;;;67387:604:0;;;;;;:::o;69658:241::-;69768:45;69795:4;69801:2;69805:7;69768:26;:45::i;:::-;69835:8;:6;:8::i;:::-;69834:9;69826:65;;;;-1:-1:-1;;;69826:65:0;;;;;;;:::i;44326:1544::-;44392:4;44531:19;;;:12;;;:19;;;;;;44567:15;;44563:1300;;45002:18;;-1:-1:-1;;44953:14:0;;;;45002:22;;;;44929:21;;45002:3;;:22;;45289;;;;;;;;;;;;;;45269:42;;45435:9;45406:3;:11;;45418:13;45406:26;;;;;;;;;;;;;;;;;;;:38;;;;45512:23;;;45554:1;45512:12;;;:23;;;;;;45538:17;;;45512:43;;45664:17;;45512:3;;45664:17;;;;;;;;;;;;;;;;;;;;;;45759:3;:12;;:19;45772:5;45759:19;;;;;;;;;;;45752:26;;;45802:4;45795:11;;;;;;;;44563:1300;45846:5;45839:12;;;;;3057:692;3133:4;3268:17;;;:12;;;:17;;;;;;3302:13;3298:444;;-1:-1:-1;;3387:38:0;;;;;;;;;;;;;;;;;;3369:57;;;;;;;;:12;:57;;;;;;;;;;;;;;;;;;;;;;;;3584:19;;3564:17;;;:12;;;:17;;;;;;;:39;3618:11;;3298:444;3698:5;3662:3;:12;;3686:1;3675:8;:12;3662:26;;;;;;;;;;;;;;;;;;:33;;:41;;;;3725:5;3718:12;;;;;3924:1549;3988:4;4123:17;;;:12;;;:17;;;;;;4157:13;;4153:1313;;4589:19;;-1:-1:-1;;4542:12:0;;;;4589:23;;;;4518:21;;4589:3;;:23;;4886;;;;;;;;;;;;;;;;4857:52;;5034:9;5004:3;:12;;5017:13;5004:27;;;;;;;;;;;;;;;;:39;;:27;;;;;:39;;;;;;;;;;;;;;;5124:14;;5111:28;;:12;;;:28;;;;;5142:17;;;5111:48;;5268:18;;5111:3;;5268:18;;;;;;;;;;;;;;-1:-1:-1;;5268:18:0;;;;;;;;;;;;;;;;;;;;;5364:17;;;:12;;;:17;;;;;;5357:24;;;;5268:18;-1:-1:-1;5398:11:0;;-1:-1:-1;;;;5398:11:0;34708:422;35075:20;35114:8;;;34708:422::o;37626:195::-;37729:12;37761:52;37783:6;37791:4;37797:1;37800:12;37729;38930:18;38941:6;38930:10;:18::i;:::-;38922:60;;;;-1:-1:-1;;;38922:60:0;;;;;;;:::i;:::-;39056:12;39070:23;39097:6;-1:-1:-1;;;;;39097:11:0;39117:5;39125:4;39097:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39055:75;;;;39148:52;39166:7;39175:10;39187:12;39148:17;:52::i;:::-;39141:59;38678:530;-1:-1:-1;;;;;;;38678:530:0:o;41218:742::-;41333:12;41362:7;41358:595;;;-1:-1:-1;41393:10:0;41386:17;;41358:595;41507:17;;:21;41503:439;;41770:10;41764:17;41831:15;41818:10;41814:2;41810:19;41803:44;41718:148;41913:12;41906:20;;-1:-1:-1;;;41906:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;5:130;72:20;;-1:-1;;;;;71381:54;;72894:35;;72884:2;;72943:1;;72933:12;685:440;;786:3;779:4;771:6;767:17;763:27;753:2;;-1:-1;;794:12;753:2;841:6;828:20;863:64;878:48;919:6;878:48;:::i;:::-;863:64;:::i;:::-;854:73;;947:6;940:5;933:21;1051:3;983:4;1042:6;975;1033:16;;1030:25;1027:2;;;1068:1;;1058:12;1027:2;72381:6;983:4;975:6;971:17;983:4;1009:5;1005:16;72358:30;72437:1;72419:16;;;983:4;72419:16;72412:27;1009:5;746:379;-1:-1;;746:379::o;1148:337::-;;;1263:3;1256:4;1248:6;1244:17;1240:27;1230:2;;-1:-1;;1271:12;1230:2;-1:-1;1301:20;;1341:18;1330:30;;1327:2;;;-1:-1;;1363:12;1327:2;1407:4;1399:6;1395:17;1383:29;;1458:3;1407:4;1438:17;1399:6;1424:32;;1421:41;1418:2;;;1475:1;;1465:12;2534:241;;2638:2;2626:9;2617:7;2613:23;2609:32;2606:2;;;-1:-1;;2644:12;2606:2;2706:53;2751:7;2727:22;2706:53;:::i;2782:366::-;;;2903:2;2891:9;2882:7;2878:23;2874:32;2871:2;;;-1:-1;;2909:12;2871:2;2971:53;3016:7;2992:22;2971:53;:::i;:::-;2961:63;;3079:53;3124:7;3061:2;3104:9;3100:22;3079:53;:::i;:::-;3069:63;;2865:283;;;;;:::o;3155:491::-;;;;3293:2;3281:9;3272:7;3268:23;3264:32;3261:2;;;-1:-1;;3299:12;3261:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;3351:63;-1:-1;3451:2;3490:22;;72:20;97:33;72:20;97:33;:::i;:::-;3255:391;;3459:63;;-1:-1;;;3559:2;3598:22;;;;2464:20;;3255:391::o;3653:721::-;;;;;3817:3;3805:9;3796:7;3792:23;3788:33;3785:2;;;-1:-1;;3824:12;3785:2;3886:53;3931:7;3907:22;3886:53;:::i;:::-;3876:63;;3994:53;4039:7;3976:2;4019:9;4015:22;3994:53;:::i;:::-;3984:63;;4084:2;4127:9;4123:22;2464:20;4092:63;;4220:2;4209:9;4205:18;4192:32;4244:18;4236:6;4233:30;4230:2;;;-1:-1;;4266:12;4230:2;4296:62;4350:7;4341:6;4330:9;4326:22;4296:62;:::i;:::-;4286:72;;;3779:595;;;;;;;:::o;4381:360::-;;;4499:2;4487:9;4478:7;4474:23;4470:32;4467:2;;;-1:-1;;4505:12;4467:2;4567:53;4612:7;4588:22;4567:53;:::i;:::-;4557:63;;4657:2;4697:9;4693:22;206:20;73040:5;71063:13;71056:21;73018:5;73015:32;73005:2;;-1:-1;;73051:12;73005:2;4665:60;;;;4461:280;;;;;:::o;4748:2095::-;;;;;;;;;;5068:3;5056:9;5047:7;5043:23;5039:33;5036:2;;;-1:-1;;5075:12;5036:2;5137:53;5182:7;5158:22;5137:53;:::i;:::-;5127:63;;5255:2;5244:9;5240:18;5227:32;5279:18;;5271:6;5268:30;5265:2;;;-1:-1;;5301:12;5265:2;5331:63;5386:7;5377:6;5366:9;5362:22;5331:63;:::i;:::-;5321:73;;5459:2;5448:9;5444:18;5431:32;5417:46;;5279:18;5475:6;5472:30;5469:2;;;-1:-1;;5505:12;5469:2;5535:63;5590:7;5581:6;5570:9;5566:22;5535:63;:::i;:::-;5525:73;;5663:2;5652:9;5648:18;5635:32;5621:46;;5279:18;5679:6;5676:30;5673:2;;;-1:-1;;5709:12;5673:2;5739:63;5794:7;5785:6;5774:9;5770:22;5739:63;:::i;:::-;5729:73;;5867:3;5856:9;5852:19;5839:33;5825:47;;5279:18;5884:6;5881:30;5878:2;;;-1:-1;;5914:12;5878:2;5944:63;5999:7;5990:6;5979:9;5975:22;5944:63;:::i;:::-;5934:73;;6072:3;6061:9;6057:19;6044:33;6030:47;;5279:18;6089:6;6086:30;6083:2;;;-1:-1;;6119:12;6083:2;6149:63;6204:7;6195:6;6184:9;6180:22;6149:63;:::i;:::-;6139:73;;6277:3;6266:9;6262:19;6249:33;6235:47;;5279:18;6294:6;6291:30;6288:2;;;-1:-1;;6324:12;6288:2;6354:63;6409:7;6400:6;6389:9;6385:22;6354:63;:::i;:::-;6344:73;;6482:3;6471:9;6467:19;6454:33;6440:47;;5279:18;6499:6;6496:30;6493:2;;;-1:-1;;6529:12;6493:2;6559:63;6614:7;6605:6;6594:9;6590:22;6559:63;:::i;:::-;6549:73;;6687:3;6676:9;6672:19;6659:33;6645:47;;5279:18;6704:6;6701:30;6698:2;;;-1:-1;;6734:12;6698:2;;6764:63;6819:7;6810:6;6799:9;6795:22;6764:63;:::i;:::-;6754:73;;;5030:1813;;;;;;;;;;;:::o;6850:366::-;;;6971:2;6959:9;6950:7;6946:23;6942:32;6939:2;;;-1:-1;;6977:12;6939:2;7039:53;7084:7;7060:22;7039:53;:::i;:::-;7029:63;7129:2;7168:22;;;;2464:20;;-1:-1;;;6933:283::o;7223:241::-;;7327:2;7315:9;7306:7;7302:23;7298:32;7295:2;;;-1:-1;;7333:12;7295:2;-1:-1;340:20;;7289:175;-1:-1;7289:175::o;7471:366::-;;;7592:2;7580:9;7571:7;7567:23;7563:32;7560:2;;;-1:-1;;7598:12;7560:2;353:6;340:20;7650:63;;7750:2;7793:9;7789:22;72:20;97:33;124:5;97:33;:::i;7844:366::-;;;7965:2;7953:9;7944:7;7940:23;7936:32;7933:2;;;-1:-1;;7971:12;7933:2;-1:-1;;340:20;;;8123:2;8162:22;;;2464:20;;-1:-1;7927:283::o;8217:239::-;;8320:2;8308:9;8299:7;8295:23;8291:32;8288:2;;;-1:-1;;8326:12;8288:2;489:6;476:20;501:32;527:5;501:32;:::i;8463:261::-;;8577:2;8565:9;8556:7;8552:23;8548:32;8545:2;;;-1:-1;;8583:12;8545:2;628:6;622:13;640:32;666:5;640:32;:::i;8731:347::-;;8845:2;8833:9;8824:7;8820:23;8816:32;8813:2;;;-1:-1;;8851:12;8813:2;8909:17;8896:31;8947:18;8939:6;8936:30;8933:2;;;-1:-1;;8969:12;8933:2;8999:63;9054:7;9045:6;9034:9;9030:22;8999:63;:::i;9085:362::-;;9210:2;9198:9;9189:7;9185:23;9181:32;9178:2;;;-1:-1;;9216:12;9178:2;9267:17;9261:24;9305:18;9297:6;9294:30;9291:2;;;-1:-1;;9327:12;9291:2;9399:22;;2051:4;2039:17;;2035:27;-1:-1;2025:2;;-1:-1;;2066:12;2025:2;2106:6;2100:13;2128:65;2143:49;2185:6;2143:49;:::i;2128:65::-;2213:6;2206:5;2199:21;2317:3;9210:2;2308:6;2241;2299:16;;2296:25;2293:2;;;-1:-1;;2324:12;2293:2;2344:39;2376:6;9210:2;2275:5;2271:16;9210:2;2241:6;2237:17;2344:39;:::i;:::-;9347:84;9172:275;-1:-1;;;;;9172:275::o;9702:869::-;;;;;;;9897:3;9885:9;9876:7;9872:23;9868:33;9865:2;;;-1:-1;;9904:12;9865:2;2477:6;2464:20;9956:63;;10084:2;10073:9;10069:18;10056:32;10108:18;;10100:6;10097:30;10094:2;;;-1:-1;;10130:12;10094:2;10168:65;10225:7;10216:6;10205:9;10201:22;10168:65;:::i;:::-;10150:83;;-1:-1;10150:83;-1:-1;10270:2;10309:22;;2464:20;;-1:-1;10406:2;10391:18;;10378:32;;-1:-1;10419:30;;;10416:2;;;-1:-1;;10452:12;10416:2;;10490:65;10547:7;10538:6;10527:9;10523:22;10490:65;:::i;:::-;9859:712;;;;-1:-1;9859:712;;-1:-1;9859:712;;10472:83;;9859:712;-1:-1;;;9859:712::o;10578:472::-;;;10709:2;10697:9;10688:7;10684:23;10680:32;10677:2;;;-1:-1;;10715:12;10677:2;2477:6;2464:20;10767:63;;10895:2;10884:9;10880:18;10867:32;10919:18;10911:6;10908:30;10905:2;;;-1:-1;;10941:12;10905:2;10971:63;11026:7;11017:6;11006:9;11002:22;10971:63;:::i;:::-;10961:73;;;10671:379;;;;;:::o;11057:935::-;;;;;11242:3;11230:9;11221:7;11217:23;11213:33;11210:2;;;-1:-1;;11249:12;11210:2;2477:6;2464:20;11301:63;;11429:2;11418:9;11414:18;11401:32;11453:18;;11445:6;11442:30;11439:2;;;-1:-1;;11475:12;11439:2;11505:63;11560:7;11551:6;11540:9;11536:22;11505:63;:::i;:::-;11495:73;;11633:2;11622:9;11618:18;11605:32;11591:46;;11453:18;11649:6;11646:30;11643:2;;;-1:-1;;11679:12;11643:2;11709:63;11764:7;11755:6;11744:9;11740:22;11709:63;:::i;:::-;11699:73;;11837:2;11826:9;11822:18;11809:32;11795:46;;11453:18;11853:6;11850:30;11847:2;;;-1:-1;;11883:12;11847:2;;11913:63;11968:7;11959:6;11948:9;11944:22;11913:63;:::i;13016:343::-;;13158:5;69811:12;70096:6;70091:3;70084:19;13251:52;13296:6;70133:4;70128:3;70124:14;70133:4;13277:5;13273:16;13251:52;:::i;:::-;72814:7;72798:14;-1:-1;;72794:28;13315:39;;;;70133:4;13315:39;;13106:253;-1:-1;;13106:253::o;13729:158::-;-1:-1;;;;;71381:54;13811:71;;13805:82::o;15653:823::-;;15772:5;15766:12;15806:1;;15795:9;15791:17;15819:1;15814:248;;;;16073:1;16068:402;;;;15784:686;;15814:248;15888:1;15873:17;;15892:4;15869:28;70084:19;;-1:-1;;16001:25;;70133:4;70124:14;;15989:38;16041:14;;;;-1:-1;15814:248;;16068:402;16137:1;16126:9;16122:17;70096:6;70091:3;70084:19;16246:38;16278:5;16246:38;:::i;:::-;-1:-1;16308:130;16322:6;16319:1;16316:13;16308:130;;;16387:7;16381:14;70133:4;16377:1;70128:3;16368:11;;16361:35;15806:1;16419:7;16415:15;16404:26;;70133:4;16341:1;16337:12;16332:17;;16308:130;;;16452:11;;70133:4;16452:11;;-1:-1;;;15784:686;;;;15742:734;;;;:::o;40443:271::-;;13526:5;69811:12;13637:52;13682:6;13677:3;13670:4;13663:5;13659:16;13637:52;:::i;:::-;13701:16;;;;;40577:137;-1:-1;;40577:137::o;40721:295::-;;72381:6;72376:3;72371;72358:30;72419:16;;72412:27;;;72419:16;40867:149;-1:-1;40867:149::o;41305:436::-;;13526:5;69811:12;13637:52;13682:6;13677:3;13670:4;13663:5;13659:16;13637:52;:::i;:::-;69811:12;;13701:16;;;;13637:52;69811:12;13701:16;13670:4;13659:16;;13637:52;:::i;:::-;13701:16;;41489:252;-1:-1;;;;41489:252::o;41748:269::-;;-1:-1;16646:5;16640:12;16680:1;;16669:9;16665:17;16693:1;16688:268;;;;16967:1;16962:425;;;;16658:729;;16688:268;-1:-1;;16893:25;;16881:38;;16762:1;16747:17;;16766:4;16743:28;16933:16;;;-1:-1;16688:268;;16962:425;17031:1;17020:9;17016:17;69664:3;-1:-1;69654:14;69696:4;;-1:-1;69683:18;-1:-1;17220:130;17234:6;17231:1;17228:13;17220:130;;;17293:14;;17280:11;;;17273:35;17327:15;;;;17249:12;;17220:130;;;-1:-1;;;17364:16;;;-1:-1;16658:729;-1:-1;42002:10;;41881:136;-1:-1;;;;;41881:136::o;42024:222::-;-1:-1;;;;;71381:54;;;;12608:45;;42151:2;42136:18;;42122:124::o;42498:672::-;-1:-1;;;;;71381:54;;;12608:45;;71381:54;;42924:2;42909:18;;12608:45;43007:2;42992:18;;12967:37;;;42743:3;43044:2;43029:18;;43022:48;;;42498:672;;43084:76;;42728:19;;43146:6;43084:76;:::i;:::-;43076:84;42714:456;-1:-1;;;;;;42714:456::o;43177:210::-;71063:13;;71056:21;12850:34;;43298:2;43283:18;;43269:118::o;43394:222::-;12967:37;;;43521:2;43506:18;;43492:124::o;43623:310::-;;43770:2;43791:17;43784:47;43845:78;43770:2;43759:9;43755:18;43909:6;43845:78;:::i;43940:708::-;;44183:2;44204:17;44197:47;44258:78;44183:2;44172:9;44168:18;44322:6;44258:78;:::i;:::-;44384:9;44378:4;44374:20;44369:2;44358:9;44354:18;44347:48;44409:78;44482:4;44473:6;44409:78;:::i;:::-;44401:86;;44535:9;44529:4;44525:20;44520:2;44509:9;44505:18;44498:48;44560:78;44633:4;44624:6;44560:78;:::i;44655:690::-;;44889:2;44910:17;44903:47;44964:75;44889:2;44878:9;44874:18;45025:6;44964:75;:::i;:::-;45087:9;45081:4;45077:20;45072:2;45061:9;45057:18;45050:48;45112:75;45182:4;45173:6;45112:75;:::i;:::-;45104:83;;45235:9;45229:4;45225:20;45220:2;45209:9;45205:18;45198:48;45260:75;45330:4;45321:6;45260:75;:::i;45352:416::-;45552:2;45566:47;;;17626:2;45537:18;;;70084:19;17662:34;70124:14;;;17642:55;-1:-1;;;17717:12;;;17710:46;17775:12;;;45523:245::o;45775:416::-;45975:2;45989:47;;;18026:2;45960:18;;;70084:19;18062:34;70124:14;;;18042:55;-1:-1;;;18117:12;;;18110:26;18155:12;;;45946:245::o;46198:416::-;46398:2;46412:47;;;18406:2;46383:18;;;70084:19;18442:34;70124:14;;;18422:55;-1:-1;;;18497:12;;;18490:35;18544:12;;;46369:245::o;46621:416::-;46821:2;46835:47;;;18795:2;46806:18;;;70084:19;18831:34;70124:14;;;18811:55;-1:-1;;;18886:12;;;18879:39;18937:12;;;46792:245::o;47044:416::-;47244:2;47258:47;;;19188:2;47229:18;;;70084:19;19224:34;70124:14;;;19204:55;-1:-1;;;19279:12;;;19272:26;19317:12;;;47215:245::o;47467:416::-;47667:2;47681:47;;;19568:2;47652:18;;;70084:19;-1:-1;;;70124:14;;;19584:43;19646:12;;;47638:245::o;47890:416::-;48090:2;48104:47;;;19897:2;48075:18;;;70084:19;;;-1:-1;;;;;;;;;;;70124:14;;;19913:55;20002:34;19988:12;;;19981:56;20056:12;;;48061:245::o;48313:416::-;48513:2;48527:47;;;20307:2;48498:18;;;70084:19;20343:34;70124:14;;;20323:55;-1:-1;;;20398:12;;;20391:42;20452:12;;;48484:245::o;48736:416::-;48936:2;48950:47;;;20703:2;48921:18;;;70084:19;20739:30;70124:14;;;20719:51;20789:12;;;48907:245::o;49159:416::-;49359:2;49373:47;;;21040:2;49344:18;;;70084:19;21076:34;70124:14;;;21056:55;-1:-1;;;21131:12;;;21124:46;21189:12;;;49330:245::o;49582:416::-;49782:2;49796:47;;;21440:2;49767:18;;;70084:19;;;-1:-1;;;;;;;;;;;70124:14;;;21456:55;21545:34;21531:12;;;21524:56;21599:12;;;49753:245::o;50005:416::-;50205:2;50219:47;;;21850:2;50190:18;;;70084:19;21886:34;70124:14;;;21866:55;-1:-1;;;21941:12;;;21934:40;21993:12;;;50176:245::o;50428:416::-;50628:2;50642:47;;;22244:2;50613:18;;;70084:19;22280:34;70124:14;;;22260:55;-1:-1;;;22335:12;;;22328:28;22375:12;;;50599:245::o;50851:416::-;51051:2;51065:47;;;22626:2;51036:18;;;70084:19;22662:27;70124:14;;;22642:48;22709:12;;;51022:245::o;51274:416::-;51474:2;51488:47;;;22960:2;51459:18;;;70084:19;22996:34;70124:14;;;22976:55;-1:-1;;;23051:12;;;23044:36;23099:12;;;51445:245::o;51697:416::-;51897:2;51911:47;;;23350:2;51882:18;;;70084:19;-1:-1;;;;;;;;;;;70124:14;;;23366:55;23455:34;23441:12;;;23434:56;-1:-1;;;23510:12;;;23503:32;23554:12;;;51868:245::o;52120:416::-;52320:2;52334:47;;;23805:2;52305:18;;;70084:19;23841:34;70124:14;;;23821:55;-1:-1;;;23896:12;;;23889:29;23937:12;;;52291:245::o;52543:416::-;52743:2;52757:47;;;24188:2;52728:18;;;70084:19;24224:34;70124:14;;;24204:55;-1:-1;;;24279:12;;;24272:46;24337:12;;;52714:245::o;53389:416::-;53589:2;53603:47;;;24972:2;53574:18;;;70084:19;25008:34;70124:14;;;24988:55;-1:-1;;;25063:12;;;25056:36;25111:12;;;53560:245::o;53812:416::-;54012:2;54026:47;;;25362:2;53997:18;;;70084:19;25398:34;70124:14;;;25378:55;-1:-1;;;25453:12;;;25446:40;25505:12;;;53983:245::o;54235:416::-;54435:2;54449:47;;;25756:2;54420:18;;;70084:19;25792:34;70124:14;;;25772:55;-1:-1;;;25847:12;;;25840:37;25896:12;;;54406:245::o;54658:416::-;54858:2;54872:47;;;26147:2;54843:18;;;70084:19;-1:-1;;;70124:14;;;26163:39;26221:12;;;54829:245::o;55081:416::-;55281:2;55295:47;;;26472:2;55266:18;;;70084:19;26508:34;70124:14;;;26488:55;-1:-1;;;26563:12;;;26556:38;26613:12;;;55252:245::o;55504:416::-;55704:2;55718:47;;;26864:2;55689:18;;;70084:19;26900:34;70124:14;;;26880:55;26969:26;26955:12;;;26948:48;27015:12;;;55675:245::o;55927:416::-;56127:2;56141:47;;;27266:2;56112:18;;;70084:19;27302:34;70124:14;;;27282:55;-1:-1;;;27357:12;;;27350:34;27403:12;;;56098:245::o;56350:416::-;56550:2;56564:47;;;27654:2;56535:18;;;70084:19;27690:34;70124:14;;;27670:55;-1:-1;;;27745:12;;;27738:35;27792:12;;;56521:245::o;56773:416::-;56973:2;56987:47;;;28043:2;56958:18;;;70084:19;-1:-1;;;;;;;;;;;70124:14;;;28059:55;-1:-1;;;28134:12;;;28127:43;28189:12;;;56944:245::o;57196:416::-;57396:2;57410:47;;;28440:2;57381:18;;;70084:19;28476:34;70124:14;;;28456:55;-1:-1;;;28531:12;;;28524:34;28577:12;;;57367:245::o;57619:416::-;57819:2;57833:47;;;28828:2;57804:18;;;70084:19;-1:-1;;;;;;;;;;;70124:14;;;28844:55;28933:34;28919:12;;;28912:56;-1:-1;;;28988:12;;;28981:32;29032:12;;;57790:245::o;58042:416::-;58242:2;58256:47;;;29283:2;58227:18;;;70084:19;29319:34;70124:14;;;29299:55;-1:-1;;;29374:12;;;29367:26;29412:12;;;58213:245::o;58465:416::-;58665:2;58679:47;;;58650:18;;;70084:19;29699:34;70124:14;;;29679:55;29753:12;;;58636:245::o;58888:416::-;59088:2;59102:47;;;30004:2;59073:18;;;70084:19;30040:34;70124:14;;;30020:55;-1:-1;;;30095:12;;;30088:38;30145:12;;;59059:245::o;59311:416::-;59511:2;59525:47;;;30396:2;59496:18;;;70084:19;30432:34;70124:14;;;30412:55;-1:-1;;;30487:12;;;30480:36;30535:12;;;59482:245::o;59734:416::-;59934:2;59948:47;;;30786:2;59919:18;;;70084:19;30822:34;70124:14;;;30802:55;-1:-1;;;30877:12;;;30870:36;30925:12;;;59905:245::o;60157:416::-;60357:2;60371:47;;;31176:2;60342:18;;;70084:19;31212:34;70124:14;;;31192:55;-1:-1;;;31267:12;;;31260:41;31320:12;;;60328:245::o;60580:416::-;60780:2;60794:47;;;31571:2;60765:18;;;70084:19;;;-1:-1;;;;;;;;;;;70124:14;;;31587:55;31676:34;31662:12;;;31655:56;31730:12;;;60751:245::o;61003:416::-;61203:2;61217:47;;;31981:2;61188:18;;;70084:19;32017:34;70124:14;;;31997:55;-1:-1;;;32072:12;;;32065:34;32118:12;;;61174:245::o;61426:416::-;61626:2;61640:47;;;32369:2;61611:18;;;70084:19;32405:34;70124:14;;;32385:55;-1:-1;;;32460:12;;;32453:33;32505:12;;;61597:245::o;61849:416::-;62049:2;62063:47;;;32756:2;62034:18;;;70084:19;32792:34;70124:14;;;32772:55;-1:-1;;;32847:12;;;32840:39;32898:12;;;62020:245::o;62272:416::-;62472:2;62486:47;;;33149:2;62457:18;;;70084:19;33185:34;70124:14;;;33165:55;-1:-1;;;33240:12;;;33233:36;33288:12;;;62443:245::o;62695:416::-;62895:2;62909:47;;;33539:2;62880:18;;;70084:19;33575:34;70124:14;;;33555:55;-1:-1;;;33630:12;;;33623:25;33667:12;;;62866:245::o;63118:416::-;63318:2;63332:47;;;33918:2;63303:18;;;70084:19;33954:34;70124:14;;;33934:55;-1:-1;;;34009:12;;;34002:34;34055:12;;;63289:245::o;63541:416::-;63741:2;63755:47;;;34306:2;63726:18;;;70084:19;34342:34;70124:14;;;34322:55;-1:-1;;;34397:12;;;34390:41;34450:12;;;63712:245::o;63964:416::-;64164:2;64178:47;;;34701:2;64149:18;;;70084:19;34737:31;70124:14;;;34717:52;34788:12;;;64135:245::o;64387:416::-;64587:2;64601:47;;;35039:2;64572:18;;;70084:19;-1:-1;;;;;;;;;;;70124:14;;;35055:55;35144:34;35130:12;;;35123:56;-1:-1;;;35199:12;;;35192:25;35236:12;;;64558:245::o;64810:416::-;65010:2;65024:47;;;35487:2;64995:18;;;70084:19;35523:34;70124:14;;;35503:55;-1:-1;;;35578:12;;;35571:37;35627:12;;;64981:245::o;65233:416::-;65433:2;65447:47;;;35878:2;65418:18;;;70084:19;35914:34;70124:14;;;35894:55;-1:-1;;;35969:12;;;35962:38;36019:12;;;65404:245::o;65656:416::-;65856:2;65870:47;;;36270:2;65841:18;;;70084:19;36306:34;70124:14;;;36286:55;36375:34;36361:12;;;36354:56;-1:-1;;;36430:12;;;36423:28;36470:12;;;65827:245::o;66079:416::-;66279:2;66293:47;;;36721:2;66264:18;;;70084:19;36757:34;70124:14;;;36737:55;-1:-1;;;36812:12;;;36805:36;36860:12;;;66250:245::o;66502:416::-;66702:2;66716:47;;;37111:2;66687:18;;;70084:19;37147:34;70124:14;;;37127:55;-1:-1;;;37202:12;;;37195:46;37260:12;;;66673:245::o;66925:416::-;67125:2;67139:47;;;37511:2;67110:18;;;70084:19;37547:34;70124:14;;;37527:55;-1:-1;;;37602:12;;;37595:39;37653:12;;;67096:245::o;67348:386::-;;67533:2;67554:17;67547:47;37986:16;37980:23;37899:6;;67533:2;67522:9;67518:18;38016:38;38069:73;37890:16;67522:9;37890:16;38123:12;38069:73;:::i;:::-;38061:81;;67533:2;38226:5;38222:16;38216:23;72814:7;;38275:14;67522:9;38279:4;38275:14;;38259;67522:9;38259:14;38252:38;38305:73;38373:4;38359:12;38305:73;:::i;:::-;38297:81;;38259:14;38462:5;38458:16;38452:23;38432:43;;38275:14;67522:9;38515:4;38511:14;;38495;67522:9;38495:14;38488:38;38541:73;38609:4;38595:12;38541:73;:::i;:::-;38533:81;;38495:14;38702:5;38698:16;38692:23;38672:43;;38275:14;67522:9;38755:4;38751:14;;38735;67522:9;38735:14;38728:38;38781:73;38849:4;38835:12;38781:73;:::i;:::-;38773:81;;38735:14;38937:5;38933:16;38927:23;38907:43;;38275:14;67522:9;38990:4;38986:14;;38970;67522:9;38970:14;38963:38;39016:73;39084:4;39070:12;39016:73;:::i;:::-;39008:81;;38970:14;39172:5;39168:16;39162:23;39142:43;;39191:84;39260:14;67522:9;39260:14;39246:12;39191:84;:::i;:::-;39260:14;39352:5;39348:16;39342:23;39322:43;;39371:84;39440:14;67522:9;39440:14;39426:12;39371:84;:::i;:::-;39440:14;39532:5;39528:16;39522:23;39502:43;;39565:14;38275;67522:9;39585:4;39581:14;;39565;67522:9;39565:14;39558:38;39611:73;39679:4;39665:12;39611:73;:::i;:::-;39603:81;;39565:14;39768:5;39764:18;39758:25;39738:45;;;39803:16;38275:14;67522:9;39825:4;39821:14;;39803:16;67522:9;39803:16;39796:40;39851:73;39919:4;39905:12;39851:73;:::i;:::-;40004:18;;;39998:25;40061:14;;;;;;40043:16;;;40036:40;39843:81;-1:-1;39998:25;-1:-1;40091:73;39843:81;39998:25;40091:73;:::i;67970:441::-;;12997:5;12974:3;12967:37;68155:2;68273;68262:9;68258:18;68251:48;70096:6;68155:2;68144:9;68140:18;70084:19;72381:6;72376:3;70124:14;68144:9;70124:14;72358:30;72419:16;;;70124:14;72419:16;;;72412:27;;;;72814:7;72798:14;;;-1:-1;;72794:28;14174:39;;;68126:285;-1:-1;;68126:285::o;68418:214::-;71597:4;71586:16;;;;40396:35;;68541:2;68526:18;;68512:120::o;68639:256::-;68701:2;68695:9;68727:17;;;68802:18;68787:34;;68823:22;;;68784:62;68781:2;;;68859:1;;68849:12;68781:2;68701;68868:22;68679:216;;-1:-1;68679:216::o;68902:321::-;;69045:18;69037:6;69034:30;69031:2;;;-1:-1;;69067:12;69031:2;-1:-1;72814:7;69121:17;-1:-1;;69117:33;69208:4;69198:15;;68968:255::o;69559:158::-;;69654:14;;;69696:4;69683:18;;;69613:104::o;72454:268::-;72519:1;72526:101;72540:6;72537:1;72534:13;72526:101;;;72607:11;;;72601:18;72588:11;;;72581:39;72562:2;72555:10;72526:101;;;72642:6;72639:1;72636:13;72633:2;;;-1:-1;;72519:1;72689:16;;72682:27;72503:219::o;72835:117::-;-1:-1;;;;;71381:54;;72894:35;;72884:2;;72943:1;;72933:12;73201:115;-1:-1;;;;;;71229:78;;73259:34;;73249:2;;73307:1;;73297:12
Swarm Source
ipfs://bb2928fe012e6f6e6a9bdf2e5827c6c96e6ecba38657377283c88a5f58766b03
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.