Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
4946387 | 17 days ago | Contract Creation | 0 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
GameRegistry
Compiler Version
v0.8.26+commit.8a97fa7a
ZkSolc Version
v1.5.10
Optimization Enabled:
Yes with Mode 3
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT LICENSE pragma solidity ^0.8.13; import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol'; import '@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol'; import '@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol'; import '@openzeppelin/contracts/token/ERC20/ERC20.sol'; import '@openzeppelin/contracts/utils/cryptography/ECDSA.sol'; import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; import '@openzeppelin/contracts/utils/Strings.sol'; import '@opengsn/contracts/src/interfaces/IERC2771Recipient.sol'; import {PAUSER_ROLE, VRF_SYSTEM_ROLE, DEPOSITOR_ROLE, MANAGER_ROLE, MINTER_ROLE, GAME_CURRENCY_CONTRACT_ROLE, GAME_NFT_CONTRACT_ROLE, GAME_ITEMS_CONTRACT_ROLE, GAME_LOGIC_CONTRACT_ROLE, TRUSTED_FORWARDER_ROLE, DEPLOYER_ROLE, TRUSTED_MULTICHAIN_ORACLE_ROLE} from './Constants.sol'; import './core/IGameRegistry.sol'; import {EntityLibrary} from './core/EntityLibrary.sol'; import {IComponent} from './core/components/IComponent.sol'; import {GUIDLibrary} from './core/GUIDLibrary.sol'; import {GuidCounterComponent, ID as GUID_COUNTER_COMPONENT_ID} from './generated/components/GuidCounterComponent.sol'; import {IMultichain1155} from './tokens/IMultichain1155.sol'; import {IMultichain721} from './tokens/IMultichain721.sol'; import {ChainIdComponent, ID as CHAIN_ID_COMPONENT_ID} from './generated/components/ChainIdComponent.sol'; import {ArchivedComponent, ID as ARCHIVED_COMPONENT_ID} from './generated/components/ArchivedComponent.sol'; // NOTE: Do NOT change ID if we wish to keep multi-chain GUID's in the same namespace uint256 constant ID = uint256(keccak256('game.piratenation.gameregistry.v1')); uint80 constant GUID_PREFIX = uint80(ID); struct BatchComponentData { uint256[] entities; uint256[] componentIds; bytes[] data; } /** @title Contract to track and limit access by accounts in the same block */ contract GameRegistry is AccessControlUpgradeable, OwnableUpgradeable, PausableUpgradeable, IERC2771Recipient, IGameRegistry { /// @notice Block limit on transmitting a signed operator registration message uint256 public constant OPERATOR_MESSAGE_BLOCK_LIMIT = 30; // 30 blocks /// @notice Operator registration cooldown time in secons uint256 public constant REGISTER_OPERATOR_COOLDOWN_LIMIT = 60 * 2; // 2 minutes /** LIBRARY METHODS **/ using EnumerableSet for EnumerableSet.AddressSet; using EnumerableSet for EnumerableSet.UintSet; /** TYPES **/ /// @notice Player Account structure struct PlayerAccount { address playerAddress; uint256 expiration; } /** MEMBERS **/ /// @notice Last time the player registered an operator wallet mapping(address => uint256) public lastRegisterOperatorTime; /// @notice System registry mapping(uint256 => address) private _systemRegistry; /// @notice Registry of current operator address to the player account mapping(address => PlayerAccount) private _operatorToPlayerAccount; /// @notice Registry of player account mapped to authorized operators mapping(address => EnumerableSet.AddressSet) private _playerToOperatorAddresses; /// @notice Map component id to its contract address mapping(uint256 => address) _componentIdToAddress; /// @notice Map component address to its ID mapping(address => uint256) _componentAddressToId; /// @notice GUID Counter uint96 private _guidCounter; /// @notice Map component ID to a map of the entities it stores mapping(uint256 => EnumerableSet.UintSet) private _entityToComponents; /// @notice Flag to check if the GUID counter has been set bool private _guidCounterSet; // @notice RequestID Mapping for cross-chain transfers mapping(uint256 => bool) public requestIdProcessed; /** EVENTS **/ /// @notice Emitted when an Operator address is registered event OperatorRegistered(address player, address operator, uint256 expiration); /// @notice Emitted when a System address is registered event SystemRegistered(uint256 indexed id, address indexed systemAddress); /// @notice Emitted when an Operator address is removed event OperatorDeregistered(address operator, address player); /// @notice Emitted when a component has been registered event ComponentRegistered(uint256 indexed componentId, address indexed componentAddress); /// @notice Emitted when a component value has been set event ComponentValueSet(uint256 indexed componentId, uint256 indexed entity, bytes data); /// @notice Emitted when a component value has been removed event ComponentValueRemoved(uint256 indexed componentId, uint256 indexed entity); /// @notice Emitted when a batch of component values has been set event BatchComponentValueSet(uint256 indexed componentId, uint256[] entities, bytes[] data); /// @notice Emitted when a batch of component values has been removed event BatchComponentValueRemoved(uint256 indexed componentId, uint256[] entities); /// @notice Emitted when a batch of component values has been set event BatchMultiComponentValueSet(uint256[] componentIds, uint256[] entities, bytes[] data); /// @notice Emitted when a batch of component values has been removed event BatchMultiComponentValueRemoved(uint256[] componentIds, uint256[] entities); /// @notice Emitted when a ComponentValueSet should be mirrored across chains event PublishComponentValueSet( uint256 indexed requestId, uint256 indexed componentId, uint256 indexed entity, uint256 chainId, uint256 requestTime, bytes data ); /// @notice Emitted when a BatchComponentValueSet should be mirrored across chains event PublishBatchComponentValueSet( uint256 indexed requestId, uint256 indexed componentId, uint256 chainId, uint256 requestTime, uint256[] entities, bytes[] data ); /// @notice Emitted when a BatchComponentValueSet should be mirrored across chains event PublishBatchSetComponentValue( uint256 indexed requestId, uint256[] componentIds, uint256[] entities, uint256 fromChainId, uint256 requestTime, bytes[] data ); /// @notice Emitted when a ComponentValueRemoved should be mirrored across chains // TODO: Reenable when we're ready to support cross-chain removal // event PublishComponentValueRemoved( // uint256 indexed requestId, // uint256 indexed componentId, // uint256 indexed entity, // uint256 chainId, // uint256 requestTime // ); /// @notice Emitted when a BatchComponentValueRemoved should be mirrored across chains // TODO: Reenable when we're ready to support cross-chain removal // event PublishBatchComponentValueRemoved( // uint256 indexed requestId, // uint256 indexed componentId, // uint256 chainId, // uint256 requestTime, // uint256[] entities // ); // 1155 Events event Multichain1155TransferSingleSent( uint256 requestId, uint256 indexed systemId, address indexed from, address indexed to, uint256 toChainId, uint256 id, uint256 amount ); event Multichain1155TransferSingleReceived( uint256 requestId, uint256 indexed systemId, address indexed from, address indexed to, uint256 fromChainId, uint256 id, uint256 amount ); event Multichain1155TransferBatchSent( uint256 requestId, uint256 indexed systemId, address indexed from, address indexed to, uint256 toChainId, uint256[] ids, uint256[] amounts ); event Multichain1155TransferBatchReceived( uint256 requestId, uint256 indexed systemId, address indexed from, address indexed to, uint256 fromChainId, uint256[] ids, uint256[] amounts ); // 721 events event Multichain721TransferSent( uint256 requestId, uint256 indexed systemId, address indexed from, address indexed to, uint256 tokenId, uint256 toChainId ); event Multichain721TransferReceived( uint256 requestId, uint256 indexed systemId, address indexed from, address indexed to, uint256 tokenId, uint256 toChainId ); /** ERRORS **/ /// @notice Invalid data count compared to number of entity count error InvalidBatchData(uint256 entityCount, uint256 dataCount); /// @notice Trying to access a component that hasn't been previously registered error ComponentNotRegistered(address component); /// @notice Trying to access a componentId that hasn't been previously registered error ComponentIdNotRegistered(uint256 componentId); /// @notice Operator error InvalidOperatorAddress(); /// @notice Operator address must send transaction error InvalidCaller(); /// @notice Player does not match signature error PlayerSignerMismatch(address expected, address actual); /// @notice Operator is registered to a different address, deregister first error OperatorAlreadyRegistered(); /// @notice Invalid expiration timestamp provided error InvalidExpirationTimestamp(); /// @notice Invalid block number (future block) error InvalidBlockNumber(); /// @notice Invalid block number (expired) error InvalidExpirationBlockNumber(); /// @notice Degregister request must come from player or operator error InvalidDeregisterCaller(); /// @notice Operator has already expired error OperatorExpired(); /// @notice Operator was not registered error OperatorNotRegistered(); /// @notice Register operator in cooldown error RegisterOperatorInCooldown(); /// @notice Not authorized to perform action error MissingRole(address account, bytes32 expectedRole); /// @notice Guid counter already set error GuidCounterSet(); /// @notice Invalid System ID - The system ID must be registered. error InvalidSystem(uint256 systemId); /// @notice Invalid Chain ID - Must be processed on the correct Chain error InvalidChain(uint256 chainId); /// @notice Already Processed this request error AlreadyProcessed(uint256 requestId); /** SETUP **/ /** * Initializer for this upgradeable contract */ function initialize(address admin) public initializer { __AccessControl_init(); __Ownable_init(); __Pausable_init(); // Move ownership to deployer _transferOwnership(admin); // Give admin access role to owner _setupRole(DEFAULT_ADMIN_ROLE, admin); _setRoleAdmin(PAUSER_ROLE, DEFAULT_ADMIN_ROLE); _setRoleAdmin(VRF_SYSTEM_ROLE, DEFAULT_ADMIN_ROLE); _setRoleAdmin(DEPOSITOR_ROLE, DEFAULT_ADMIN_ROLE); _setRoleAdmin(MINTER_ROLE, DEFAULT_ADMIN_ROLE); _setRoleAdmin(MANAGER_ROLE, DEFAULT_ADMIN_ROLE); _setRoleAdmin(DEPLOYER_ROLE, DEFAULT_ADMIN_ROLE); _setRoleAdmin(GAME_NFT_CONTRACT_ROLE, DEFAULT_ADMIN_ROLE); _setRoleAdmin(GAME_CURRENCY_CONTRACT_ROLE, DEFAULT_ADMIN_ROLE); _setRoleAdmin(GAME_ITEMS_CONTRACT_ROLE, DEFAULT_ADMIN_ROLE); _setRoleAdmin(GAME_LOGIC_CONTRACT_ROLE, DEFAULT_ADMIN_ROLE); _pause(); } /** EXTERNAL **/ /** * @dev Set the GUID counter, should only be called once */ function setGuidCounter(uint96 guidValue) external onlyRole(MANAGER_ROLE) { if (_guidCounterSet) { revert GuidCounterSet(); } _guidCounterSet = true; _guidCounter = guidValue; } /** * @dev Get the GUID counter value */ function getGuidCounter() external view returns (uint96) { return _guidCounter; } /** * Pause/Unpause the game and ALL the systems that utilize this game * * @param _paused Whether or pause or unpause */ function setPaused(bool _paused) external { if (_msgSender() == owner() || hasRole(PAUSER_ROLE, _msgSender())) { if (_paused) { _pause(); } else { _unpause(); } } else { revert MissingRole(_msgSender(), PAUSER_ROLE); } } /** * @inheritdoc IGameRegistry */ function paused() public view override(IGameRegistry, PausableUpgradeable) returns (bool) { return PausableUpgradeable.paused(); } /** * @inheritdoc IGameRegistry */ function registerSystem(uint256 systemId, address systemAddress) external onlyRole(DEPLOYER_ROLE) { _systemRegistry[systemId] = systemAddress; emit SystemRegistered(systemId, systemAddress); } /** * @inheritdoc IGameRegistry */ function getSystem(uint256 systemId) external view returns (address) { return _systemRegistry[systemId]; } /** * @inheritdoc IGameRegistry */ function registerComponent(uint256 componentId, address componentAddress) public { if ( hasAccessRole(GAME_LOGIC_CONTRACT_ROLE, _msgSender()) == false && hasAccessRole(MANAGER_ROLE, _msgSender()) == false && hasAccessRole(DEFAULT_ADMIN_ROLE, _msgSender()) == false ) { revert MissingRole(_msgSender(), GAME_LOGIC_CONTRACT_ROLE); } _componentIdToAddress[componentId] = componentAddress; _componentAddressToId[componentAddress] = componentId; emit ComponentRegistered(componentId, componentAddress); } /** * Gets a raw entity component value * @param entity Entity to get value for * @param componentId Component to get value from * * @return Bytes value of the entity component */ function getComponentValue(uint256 entity, uint256 componentId) external view returns (bytes memory) { address componentAddress = _componentIdToAddress[componentId]; if (componentAddress == address(0)) { revert ComponentNotRegistered(componentAddress); } return IComponent(componentAddress).getBytes(entity); } /** * @inheritdoc IGameRegistry * @dev Only registered components can call this function, otherwise it will revert */ function batchGetComponentValues( uint256[] calldata entities, uint256[] calldata componentIds ) external view returns (bytes[] memory values) { values = new bytes[](entities.length); for (uint256 i = 0; i < entities.length; i++) { address componentAddress = _componentIdToAddress[componentIds[i]]; if (componentAddress == address(0)) { revert ComponentNotRegistered(componentAddress); } values[i] = IComponent(componentAddress).getBytes(entities[i]); } } /** * @inheritdoc IGameRegistry */ function batchSetComponentValue( uint256[] calldata entities, uint256[] calldata componentIds, bytes[] calldata values ) external override { if ( hasAccessRole(GAME_LOGIC_CONTRACT_ROLE, _msgSender()) == false && hasAccessRole(MANAGER_ROLE, _msgSender()) == false && owner() != _msgSender() ) { revert MissingRole(_msgSender(), GAME_LOGIC_CONTRACT_ROLE); } _batchSetComponentValue(entities, componentIds, values); } /** * @inheritdoc IGameRegistry */ function batchPublishSetComponentValue( uint256[] calldata entities, uint256[] calldata componentIds, bytes[] calldata values ) external override returns (uint256 requestId) { if ( hasAccessRole(GAME_LOGIC_CONTRACT_ROLE, _msgSender()) == false && hasAccessRole(MANAGER_ROLE, _msgSender()) == false && owner() != _msgSender() ) { revert MissingRole(_msgSender(), GAME_LOGIC_CONTRACT_ROLE); } _batchSetComponentValue(entities, componentIds, values); requestId = _generateGUID(); emit PublishBatchSetComponentValue(requestId, componentIds, entities, block.chainid, block.timestamp, values); return requestId; } /** * @inheritdoc IGameRegistry * @dev Only registered components can call this function, otherwise it will revert */ function registerComponentValueSet(uint256 entity, bytes calldata data) external virtual { // Only registered components can call this function, if the component isn't register the event won't be emitted uint256 componentId = _componentAddressToId[msg.sender]; if (componentId == 0) { revert ComponentNotRegistered(msg.sender); } // Store reference of entity to component _entityToComponents[entity].add(componentId); emit ComponentValueSet(componentId, entity, data); } /** * @inheritdoc IGameRegistry * @dev Only registered components can call this function, otherwise it will revert */ function publishComponentValueSet( uint256 componentId, uint256 entity, bytes calldata data ) external virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) returns (uint256 requestId) { if (_componentIdToAddress[componentId] == address(0)) { revert ComponentIdNotRegistered(componentId); } requestId = _generateGUID(); emit PublishComponentValueSet(requestId, componentId, entity, block.chainid, block.timestamp, data); } /** * @inheritdoc IGameRegistry * @dev Only registered components can call this function, otherwise it will revert */ function batchRegisterComponentValueSet(uint256[] calldata entities, bytes[] calldata data) external virtual { // Check to make sure the component is registered uint256 componentId = _componentAddressToId[msg.sender]; if (componentId == 0) { revert ComponentNotRegistered(msg.sender); } if (entities.length != data.length) { revert InvalidBatchData(entities.length, data.length); } // Store references of entities to component for (uint256 i = 0; i < entities.length; i++) { _entityToComponents[entities[i]].add(componentId); } emit BatchComponentValueSet(componentId, entities, data); } /** * @inheritdoc IGameRegistry * @dev Only registered components can call this function, otherwise it will revert */ function batchPublishComponentValueSet( uint256 componentId, uint256[] calldata entities, bytes[] calldata data ) external virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) returns (uint256 requestId) { if (_componentIdToAddress[componentId] == address(0)) { revert ComponentIdNotRegistered(componentId); } // Check to make sure the component is registered if (entities.length != data.length) { revert InvalidBatchData(entities.length, data.length); } requestId = _generateGUID(); emit PublishBatchComponentValueSet(requestId, componentId, block.chainid, block.timestamp, entities, data); } /** * @inheritdoc IGameRegistry * @dev Only registered components can call this function, otherwise it will revert */ function registerComponentValueRemoved(uint256 entity) external virtual { // Only registered components can call this function, if the component isn't register the event won't be emitted uint256 componentId = _componentAddressToId[msg.sender]; if (componentId == 0) { revert ComponentNotRegistered(msg.sender); } // Remove reference of entity to component _entityToComponents[entity].remove(componentId); emit ComponentValueRemoved(componentId, entity); } /** * @inheritdoc IGameRegistry * @dev Only registered components can call this function, otherwise it will revert */ function batchRegisterComponentValueRemoved(uint256[] calldata entities) external virtual { uint256 componentId = _componentAddressToId[msg.sender]; if (componentId == 0) { revert ComponentNotRegistered(msg.sender); } // Store references of entities to component for (uint256 i = 0; i < entities.length; i++) { _entityToComponents[entities[i]].remove(componentId); } emit BatchComponentValueRemoved(componentId, entities); } /** * @notice Emits an event which oracles pick up to mint the item on another chian. * @dev Only registered components can call this function, otherwise it will revert */ function sendMultichain1155TransferSingle( uint256 systemId, address from, address to, uint256 toChainId, uint256 id, uint256 amount ) external onlyRole(GAME_LOGIC_CONTRACT_ROLE) { if (to == address(0)) { return; } uint256 requestId = _generateGUID(); if (address(_systemRegistry[systemId]) != msg.sender) { revert InvalidSystem(systemId); } emit Multichain1155TransferSingleSent(requestId, systemId, from, to, toChainId, id, amount); } /** * @notice Emits an event which oracles pick up to mint the item on another chian. * @dev Only registered components can call this function, otherwise it will revert */ function sendMultichain1155TransferBatch( uint256 systemId, address from, address to, uint256 toChainId, uint256[] calldata ids, uint256[] calldata amounts ) external onlyRole(GAME_LOGIC_CONTRACT_ROLE) { if (to == address(0)) { return; } uint256 requestId = _generateGUID(); if (address(_systemRegistry[systemId]) != msg.sender) { revert InvalidSystem(systemId); } emit Multichain1155TransferBatchSent(requestId, systemId, from, to, toChainId, ids, amounts); } /** * @notice Emits an event which oracles pick up to mint the item on another chian. * @dev Only registered components can call this function, otherwise it will revert */ function sendMultichain721Transfer( uint256 systemId, address from, address to, uint256 tokenId, uint256 toChainId ) external onlyRole(GAME_LOGIC_CONTRACT_ROLE) { if (to == address(0)) { return; } uint256 requestId = _generateGUID(); if (address(_systemRegistry[systemId]) != msg.sender) { revert InvalidSystem(systemId); } emit Multichain721TransferSent(requestId, systemId, from, to, tokenId, toChainId); } /** * @notice Delivers an item that has been transferred from another chain in the Multichain * @dev Must be called by a trusted multichain */ function deliverMultichain1155TransferSingle( uint256 requestId, uint256 systemId, address from, address to, uint256 fromChainId, uint256 id, uint256 amount ) external onlyRole(TRUSTED_MULTICHAIN_ORACLE_ROLE) { _enforceChain(to); //replay protection _validateRequestId(requestId); // mint items if (_systemRegistry[systemId] == address(0)) { revert InvalidSystem(systemId); } IMultichain1155 system = IMultichain1155(_systemRegistry[systemId]); system.receivedMultichain1155TransferSingle(to, id, amount); emit Multichain1155TransferSingleReceived(requestId, systemId, from, to, fromChainId, id, amount); } /** * @notice Delivers an item that has been transferred from another chain in the Multichain * @dev Must be called by a trusted multichain */ function deliverMultichain1155TransferBatch( uint256 requestId, uint256 systemId, address from, address to, uint256 fromChainId, uint256[] calldata ids, uint256[] calldata amounts ) external onlyRole(TRUSTED_MULTICHAIN_ORACLE_ROLE) { _enforceChain(to); //replay protection _validateRequestId(requestId); // mint items if (_systemRegistry[systemId] == address(0)) { revert InvalidSystem(systemId); } IMultichain1155 system = IMultichain1155(_systemRegistry[systemId]); system.receivedMultichain1155TransferBatch(to, ids, amounts); emit Multichain1155TransferBatchReceived(requestId, systemId, from, to, fromChainId, ids, amounts); } /** * @notice Delivers an item that has been transferred from another chain in the Multichain * @dev Must be called by a trusted multichain */ function deliverMultichain721Transfer( uint256 requestId, uint256 systemId, address from, address to, uint256 tokenId, uint256 fromChainId, BatchComponentData calldata componentData ) external onlyRole(TRUSTED_MULTICHAIN_ORACLE_ROLE) { _enforceChain(to); _validateRequestId(requestId); if (_systemRegistry[systemId] == address(0)) { revert InvalidSystem(systemId); } // mint items IMultichain721 system = IMultichain721(_systemRegistry[systemId]); system.receivedMultichain721Transfer(to, tokenId); _batchSetComponentData(componentData); emit Multichain721TransferReceived(requestId, systemId, from, to, tokenId, fromChainId); } /** * @inheritdoc IGameRegistry */ function getComponent(uint256 componentId) external view returns (address) { return _componentIdToAddress[componentId]; } /** * @inheritdoc IGameRegistry */ function getComponentIdFromAddress(address componentAddr) external view returns (uint256) { return _componentAddressToId[componentAddr]; } /** * @inheritdoc IGameRegistry */ function getEntityHasComponent(uint256 entity, uint256 componentId) external view returns (bool) { return _entityToComponents[entity].contains(componentId); } /** * @inheritdoc IGameRegistry */ function batchGetEntitiesHasComponents( uint256[] calldata entities, uint256[] calldata componentIds ) external view returns (bool[] memory) { bool[] memory results = new bool[](entities.length); for (uint256 i = 0; i < entities.length; i++) { results[i] = _entityToComponents[entities[i]].contains(componentIds[i]); } return results; } /** * @inheritdoc IGameRegistry */ function getEntityComponents(uint256 entity) external view returns (uint256[] memory) { return _entityToComponents[entity].values(); } /** * @dev Will filter out archived components and return only unarchived components */ function getUnarchivedEntityComponents(uint256 entity) external view returns (uint256[] memory) { uint256[] memory componentIds = _entityToComponents[entity].values(); ArchivedComponent archivedComponent = ArchivedComponent(_componentIdToAddress[ARCHIVED_COMPONENT_ID]); uint256[] memory unarchivedComponentIds = new uint256[](componentIds.length); uint256 counter = 0; for (uint256 i = 0; i < componentIds.length; i++) { if (archivedComponent.getValue(componentIds[i])) { continue; } unarchivedComponentIds[counter] = componentIds[i]; counter++; } assembly { mstore(unarchivedComponentIds, counter) } return unarchivedComponentIds; } /** * @inheritdoc IGameRegistry */ function getEntityComponentCount(uint256 entity) external view returns (uint256) { return _entityToComponents[entity].length(); } /** * @inheritdoc IGameRegistry */ function generateGUIDDeprecated() external onlyRole(GAME_LOGIC_CONTRACT_ROLE) returns (uint256) { _guidCounter++; uint256 guidEntity = EntityLibrary.tokenToEntity(address(this), _guidCounter); return guidEntity; } /** * @inheritdoc IERC165 */ function supportsInterface( bytes4 interfaceId ) public view virtual override(IERC165, AccessControlUpgradeable) returns (bool) { return interfaceId == type(IGameRegistry).interfaceId || interfaceId == type(IERC165).interfaceId || AccessControlUpgradeable.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasAccessRole(bytes32 role, address account) public view override returns (bool) { return AccessControlUpgradeable.hasRole(role, account); } /** * Returns the address of the account the operatorAddress is authorized to * * @param operatorAddress Address the sending controller */ function getPlayerAccount(address operatorAddress) external view returns (address) { if (operatorAddress == address(0)) { revert InvalidOperatorAddress(); } PlayerAccount memory account = _operatorToPlayerAccount[operatorAddress]; address playerAddress = account.playerAddress; if (playerAddress != address(0)) { if (account.expiration < block.timestamp && account.expiration != 0) { revert OperatorExpired(); } } else { return operatorAddress; } return playerAddress; } /** * Called in order to retrieve message to sign to register an oeperator * * @param player address operator is being registered for * @param operator address of operator being registered * @param expiration block time for registration (or 0 for infinite) * @param blockNumber the message was signed at */ function getOperatorAccountRegistrationMessageToSign( address player, address operator, uint256 expiration, uint256 blockNumber ) public pure returns (bytes memory) { return abi.encodePacked( 'Authorize operator account ', Strings.toHexString(uint256(uint160(operator)), 20), ' to perform gameplay actions on behalf of player account ', Strings.toHexString(uint256(uint160(player)), 20), ' with expiration ', Strings.toString(expiration), ' signed at block ', Strings.toString(blockNumber) ); } /** * Called by an Operator Address with a signature from a Player Address authorizing it until a given expiration time * * @param signature from signer/player address authorizing operator until expiration time * @param player address of player being registered * @param operator address of operator being registered * @param expiration block time for registration (or 0 for infinite) * @param blockNumber the message was signed at */ function registerOperator( bytes calldata signature, address player, address operator, uint256 expiration, uint256 blockNumber ) external whenNotPaused { if (_msgSender() != operator) { revert InvalidCaller(); } if ((block.timestamp - lastRegisterOperatorTime[player]) < REGISTER_OPERATOR_COOLDOWN_LIMIT) { revert RegisterOperatorInCooldown(); } if (operator == player || operator == address(0)) { revert InvalidOperatorAddress(); } if (expiration < block.timestamp && expiration != 0) { revert InvalidExpirationTimestamp(); } // if (blockNumber > block.number) { // revert InvalidBlockNumber(); // } // if (block.number > blockNumber + OPERATOR_MESSAGE_BLOCK_LIMIT) { // revert InvalidExpirationBlockNumber(); // } PlayerAccount memory currentAccount = _operatorToPlayerAccount[operator]; if (currentAccount.playerAddress != address(0) && currentAccount.playerAddress != player) { revert OperatorAlreadyRegistered(); } bytes memory message = getOperatorAccountRegistrationMessageToSign(player, operator, expiration, blockNumber); bytes32 digest = ECDSA.toEthSignedMessageHash(message); address recoveredSigner = ECDSA.recover(digest, signature); if (player != recoveredSigner) { revert PlayerSignerMismatch(player, recoveredSigner); } _operatorToPlayerAccount[operator] = PlayerAccount({playerAddress: player, expiration: expiration}); _playerToOperatorAddresses[player].add(operator); // Track cooldown timer lastRegisterOperatorTime[player] = block.timestamp; emit OperatorRegistered(player, operator, expiration); } /** * Batch set operator accounts for players * @param players addresses of players being registered * @param operators addresses of operators being registered * @param expirations block times for registration (or 0 for infinite) */ function registerOperatorBatch( address[] calldata players, address[] calldata operators, uint256[] calldata expirations ) external whenNotPaused onlyRole(MANAGER_ROLE) { if (players.length != operators.length || players.length != expirations.length) { revert InvalidOperatorAddress(); } for (uint256 i = 0; i < players.length; i++) { if (operators[i] == players[i] || operators[i] == address(0)) { revert InvalidOperatorAddress(); } _operatorToPlayerAccount[operators[i]] = PlayerAccount({playerAddress: players[i], expiration: expirations[i]}); _playerToOperatorAddresses[players[i]].add(operators[i]); // Track cooldown timer lastRegisterOperatorTime[players[i]] = block.timestamp; emit OperatorRegistered(players[i], operators[i], expirations[i]); } } function deregisterOperatorBatch(address[] calldata operators) public whenNotPaused onlyRole(MANAGER_ROLE) { for (uint256 i = 0; i < operators.length; i++) { address playerAddress = _operatorToPlayerAccount[operators[i]].playerAddress; // if (playerAddress == address(0)) { // revert OperatorNotRegistered(); // } delete _operatorToPlayerAccount[operators[i]]; _playerToOperatorAddresses[playerAddress].remove(operators[i]); // if (operatorRemovedFromPlayer != true) { // revert OperatorNotRegistered(); // } emit OperatorDeregistered(operators[i], playerAddress); } } /** * Called by an Operator or Player to deregister an Operator account * * @param operatorToDeregister address of operator to deregister */ function deregisterOperator(address operatorToDeregister) external { address playerAddress = _operatorToPlayerAccount[operatorToDeregister].playerAddress; if (playerAddress == address(0)) { revert OperatorNotRegistered(); } if (operatorToDeregister != _msgSender() && playerAddress != _msgSender()) { revert InvalidDeregisterCaller(); } delete _operatorToPlayerAccount[operatorToDeregister]; bool operatorRemovedFromPlayer = _playerToOperatorAddresses[playerAddress].remove(operatorToDeregister); if (operatorRemovedFromPlayer != true) { revert OperatorNotRegistered(); } emit OperatorDeregistered(operatorToDeregister, playerAddress); } /** * Returns an array of registered Operators for a Player address * * @param player address to retrieve operators for */ function getRegisteredOperators(address player) external view returns (address[] memory) { return _playerToOperatorAddresses[player].values(); } /// @inheritdoc IERC2771Recipient function isTrustedForwarder(address forwarder) public view virtual override returns (bool) { return hasAccessRole(TRUSTED_FORWARDER_ROLE, forwarder); } /// @inheritdoc IERC2771Recipient function _msgSender() internal view virtual override(ContextUpgradeable, IERC2771Recipient) returns (address ret) { if (msg.data.length >= 20 && isTrustedForwarder(msg.sender)) { assembly { ret := shr(96, calldataload(sub(calldatasize(), 20))) } } else { ret = msg.sender; } } /// @inheritdoc IERC2771Recipient function _msgData() internal view virtual override(ContextUpgradeable, IERC2771Recipient) returns (bytes calldata ret) { if (msg.data.length >= 20 && isTrustedForwarder(msg.sender)) { return msg.data[0:msg.data.length - 20]; } else { return msg.data; } } function _generateGUID() internal returns (uint256) { GuidCounterComponent counter = GuidCounterComponent(_componentIdToAddress[GUID_COUNTER_COMPONENT_ID]); // Increment guid counter uint256 count = counter.getValue(GUID_PREFIX) + 1; counter.setValue(GUID_PREFIX, count); return GUIDLibrary.packGuid(GUID_PREFIX, count); } function _enforceChain(address to) internal view { uint256 userToChainId = ChainIdComponent(_componentIdToAddress[CHAIN_ID_COMPONENT_ID]).getValue( EntityLibrary.addressToEntity(to) ); if (userToChainId != block.chainid) { revert InvalidChain(userToChainId); } } function _validateRequestId(uint256 requestId) internal { if (requestIdProcessed[requestId]) { revert AlreadyProcessed(requestId); } requestIdProcessed[requestId] = true; } function _batchSetComponentData(BatchComponentData calldata componentData) internal { _batchSetComponentValue(componentData.entities, componentData.componentIds, componentData.data); } function _batchSetComponentValue( uint256[] calldata entities, uint256[] calldata componentIds, bytes[] calldata values ) internal { if (entities.length != values.length || entities.length != componentIds.length) { revert InvalidBatchData(entities.length, values.length); } for (uint256 i = 0; i < entities.length; i++) { address componentAddress = _componentIdToAddress[componentIds[i]]; if (componentAddress == address(0)) { revert ComponentNotRegistered(componentAddress); } IComponent(componentAddress).setBytes(entities[i], values[i]); } } }
// SPDX-License-Identifier: MIT LICENSE pragma solidity ^0.8.9; // Used for calculating decimal-point percentages (10000 = 100%) uint256 constant PERCENTAGE_RANGE = 10000; // Pauser Role - Can pause the game bytes32 constant PAUSER_ROLE = keccak256('PAUSER_ROLE'); // Minter Role - Can mint items, NFTs, and ERC20 currency bytes32 constant MINTER_ROLE = keccak256('MINTER_ROLE'); // Manager Role - Can manage the shop, loot tables, and other game data bytes32 constant MANAGER_ROLE = keccak256('MANAGER_ROLE'); // Depoloyer Role - Can Deploy new Systems bytes32 constant DEPLOYER_ROLE = keccak256('DEPLOYER_ROLE'); // Game Logic Contract - Contract that executes game logic and accesses other systems bytes32 constant GAME_LOGIC_CONTRACT_ROLE = keccak256('GAME_LOGIC_CONTRACT_ROLE'); // Game Currency Contract - Allowlisted currency ERC20 contract bytes32 constant GAME_CURRENCY_CONTRACT_ROLE = keccak256('GAME_CURRENCY_CONTRACT_ROLE'); // Game NFT Contract - Allowlisted game NFT ERC721 contract bytes32 constant GAME_NFT_CONTRACT_ROLE = keccak256('GAME_NFT_CONTRACT_ROLE'); // Game Items Contract - Allowlist game items ERC1155 contract bytes32 constant GAME_ITEMS_CONTRACT_ROLE = keccak256('GAME_ITEMS_CONTRACT_ROLE'); // Depositor role - used by Polygon bridge to mint on child chain bytes32 constant DEPOSITOR_ROLE = keccak256('DEPOSITOR_ROLE'); // Randomizer role - Used by the randomizer contract to callback bytes32 constant VRF_SYSTEM_ROLE = keccak256('VRF_SYSTEM_ROLE'); // VRF Consumer Contract - Contract that uses VRF to demonstrate randomness bytes32 constant VRF_CONSUMER_ROLE = keccak256('VRF_CONSUMER_ROLE'); // Trusted forwarder role - Used by meta transactions to verify trusted forwader(s) bytes32 constant TRUSTED_FORWARDER_ROLE = keccak256('TRUSTED_FORWARDER_ROLE'); // Trusted mirror role - Used by pirate mirroring bytes32 constant TRUSTED_MIRROR_ROLE = keccak256('TRUSTED_MIRROR_ROLE'); // Trusted multichain oracle role - Used by multichain contracts bytes32 constant TRUSTED_MULTICHAIN_ORACLE_ROLE = keccak256('TRUSTED_MULTICHAIN_ORACLE_ROLE'); // ===== // All of the possible traits in the system // ===== /// @dev Trait that points to another token/template id uint256 constant TEMPLATE_ID_TRAIT_ID = uint256(keccak256('template_id')); // Generation of a token uint256 constant GENERATION_TRAIT_ID = uint256(keccak256('generation')); // XP for a token uint256 constant XP_TRAIT_ID = uint256(keccak256('xp')); // Current level of a token uint256 constant LEVEL_TRAIT_ID = uint256(keccak256('level')); // Whether or not a token is a pirate uint256 constant IS_PIRATE_TRAIT_ID = uint256(keccak256('is_pirate')); // Whether or not a token is a ship uint256 constant IS_SHIP_TRAIT_ID = uint256(keccak256('is_ship')); // Whether or not an item is equippable on ships uint256 constant EQUIPMENT_TYPE_TRAIT_ID = uint256(keccak256('equipment_type')); // Combat modifiers for items and tokens uint256 constant COMBAT_MODIFIERS_TRAIT_ID = uint256(keccak256('combat_modifiers')); // Animation URL for the token uint256 constant ANIMATION_URL_TRAIT_ID = uint256(keccak256('animation_url')); // Item slots uint256 constant ITEM_SLOTS_TRAIT_ID = uint256(keccak256('item_slots')); // Rank of the ship uint256 constant SHIP_RANK_TRAIT_ID = uint256(keccak256('ship_rank')); // Current Health trait uint256 constant CURRENT_HEALTH_TRAIT_ID = uint256(keccak256('current_health')); // Health trait uint256 constant HEALTH_TRAIT_ID = uint256(keccak256('health')); // Damage trait uint256 constant DAMAGE_TRAIT_ID = uint256(keccak256('damage')); // Speed trait uint256 constant SPEED_TRAIT_ID = uint256(keccak256('speed')); // Accuracy trait uint256 constant ACCURACY_TRAIT_ID = uint256(keccak256('accuracy')); // Evasion trait uint256 constant EVASION_TRAIT_ID = uint256(keccak256('evasion')); // Image hash of token's image, used for verifiable / fair drops uint256 constant IMAGE_HASH_TRAIT_ID = uint256(keccak256('image_hash')); // Name of a token uint256 constant NAME_TRAIT_ID = uint256(keccak256('name_trait')); // Description of a token uint256 constant DESCRIPTION_TRAIT_ID = uint256(keccak256('description_trait')); // General rarity for a token (corresponds to IGameRarity) uint256 constant RARITY_TRAIT_ID = uint256(keccak256('rarity')); // The character's affinity for a specific element uint256 constant ELEMENTAL_AFFINITY_TRAIT_ID = uint256(keccak256('affinity_id')); // The character's expertise value uint256 constant EXPERTISE_TRAIT_ID = uint256(keccak256('expertise_id')); // Expertise damage mod ID from SoT uint256 constant EXPERTISE_DAMAGE_ID = uint256(keccak256('expertise.levelmultiplier.damage')); // Expertise evasion mod ID from SoT uint256 constant EXPERTISE_EVASION_ID = uint256(keccak256('expertise.levelmultiplier.evasion')); // Expertise speed mod ID from SoT uint256 constant EXPERTISE_SPEED_ID = uint256(keccak256('expertise.levelmultiplier.speed')); // Expertise accuracy mod ID from SoT uint256 constant EXPERTISE_ACCURACY_ID = uint256(keccak256('expertise.levelmultiplier.accuracy')); // Expertise health mod ID from SoT uint256 constant EXPERTISE_HEALTH_ID = uint256(keccak256('expertise.levelmultiplier.health')); // Boss start time trait uint256 constant BOSS_START_TIME_TRAIT_ID = uint256(keccak256('boss_start_time')); // Boss end time trait uint256 constant BOSS_END_TIME_TRAIT_ID = uint256(keccak256('boss_end_time')); // Boss type trait uint256 constant BOSS_TYPE_TRAIT_ID = uint256(keccak256('boss_type')); // The character's dice rolls uint256 constant DICE_ROLL_1_TRAIT_ID = uint256(keccak256('dice_roll_1')); uint256 constant DICE_ROLL_2_TRAIT_ID = uint256(keccak256('dice_roll_2')); // The character's star sign (astrology) uint256 constant STAR_SIGN_TRAIT_ID = uint256(keccak256('star_sign')); // Image for the token uint256 constant IMAGE_TRAIT_ID = uint256(keccak256('image_trait')); // How much energy the token provides if used uint256 constant ENERGY_PROVIDED_TRAIT_ID = uint256(keccak256('energy_provided')); // Whether a given token is soulbound, meaning it is unable to be transferred uint256 constant SOULBOUND_TRAIT_ID = uint256(keccak256('soulbound')); // ------ // Avatar Profile Picture related traits // If an avatar is a 1 of 1, this is their only trait uint256 constant PROFILE_IS_LEGENDARY_TRAIT_ID = uint256(keccak256('profile_is_legendary')); // Avatar's archetype -- possible values: Human (including Druid, Mage, Berserker, Crusty), Robot, Animal, Zombie, Vampire, Ghost uint256 constant PROFILE_CHARACTER_TYPE = uint256(keccak256('profile_character_type')); // Avatar's profile picture's background image uint256 constant PROFILE_BACKGROUND_TRAIT_ID = uint256(keccak256('profile_background')); // Avatar's eye style uint256 constant PROFILE_EYES_TRAIT_ID = uint256(keccak256('profile_eyes')); // Avatar's facial hair type uint256 constant PROFILE_FACIAL_HAIR_TRAIT_ID = uint256(keccak256('profile_facial_hair')); // Avatar's hair style uint256 constant PROFILE_HAIR_TRAIT_ID = uint256(keccak256('profile_hair')); // Avatar's skin color uint256 constant PROFILE_SKIN_TRAIT_ID = uint256(keccak256('profile_skin')); // Avatar's coat color uint256 constant PROFILE_COAT_TRAIT_ID = uint256(keccak256('profile_coat')); // Avatar's earring(s) type uint256 constant PROFILE_EARRING_TRAIT_ID = uint256(keccak256('profile_facial_hair')); // Avatar's eye covering uint256 constant PROFILE_EYE_COVERING_TRAIT_ID = uint256(keccak256('profile_eye_covering')); // Avatar's headwear uint256 constant PROFILE_HEADWEAR_TRAIT_ID = uint256(keccak256('profile_headwear')); // Avatar's (Mages only) gem color uint256 constant PROFILE_MAGE_GEM_TRAIT_ID = uint256(keccak256('profile_mage_gem')); // ------ // Dungeon traits // Whether this token template is a dungeon trigger uint256 constant IS_DUNGEON_TRIGGER_TRAIT_ID = uint256(keccak256('is_dungeon_trigger')); // Dungeon start time trait uint256 constant DUNGEON_START_TIME_TRAIT_ID = uint256(keccak256('dungeon.start_time')); // Dungeon end time trait uint256 constant DUNGEON_END_TIME_TRAIT_ID = uint256(keccak256('dungeon.end_time')); // Dungeon SoT map id trait uint256 constant DUNGEON_MAP_TRAIT_ID = uint256(keccak256('dungeon.map_id')); // Whether this token template is a mob uint256 constant IS_MOB_TRAIT_ID = uint256(keccak256('is_mob')); // ------ // Island traits // Whether a game item is placeable on an island uint256 constant IS_PLACEABLE_TRAIT_ID = uint256(keccak256('is_placeable')); // ------ // Extra traits for component migration // NOTE: CURRENTLY NOT USED IN CONTRACTS CODE uint256 constant MODEL_GLTF_URL_TRAIT_ID = uint256(keccak256('model_gltf_url')); uint256 constant PLACEABLE_CATEGORY_TRAIT_ID = uint256(keccak256('placeable_category')); uint256 constant PLACEABLE_IS_BOTTOM_STACKABLE_TRAIT_ID = uint256(keccak256('placeable.is_bottom_stackable')); uint256 constant PLACEABLE_IS_TOP_STACKABLE_TRAIT_ID = uint256(keccak256('placeable.is_top_stackable')); uint256 constant PLACEABLE_TERRAIN_TRAIT_ID = uint256(keccak256('placeable.terrain')); uint256 constant GLTF_SCALING_FACTOR_TRAIT_ID = uint256(keccak256('gltf_scaling_factor')); uint256 constant SIZE_TRAIT_ID = uint256(keccak256('size'));
// SPDX-License-Identifier: MIT LICENSE pragma solidity ^0.8.13; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; // @title Interface the game's ACL / Management Layer interface IGameRegistry is IERC165 { /** * @dev Returns `true` if `account` has been granted `role`. * @param role The role to query * @param account The address to query */ function hasAccessRole( bytes32 role, address account ) external view returns (bool); /** * @return Whether or not the registry is paused */ function paused() external view returns (bool); /** * Registers a system by id * * @param systemId Id of the system * @param systemAddress Address of the system contract */ function registerSystem(uint256 systemId, address systemAddress) external; /** * @param systemId Id of the system * @return System based on an id */ function getSystem(uint256 systemId) external view returns (address); /** * Registers a component using an id and contract address * @param componentId Id of the component to register * @param componentAddress Address of the component contract */ function registerComponent( uint256 componentId, address componentAddress ) external; /** * @param componentId Id of the component * @return A component's contract address given its ID */ function getComponent(uint256 componentId) external view returns (address); /** * @param componentAddr Address of the component contract * @return A component's id given its contract address */ function getComponentIdFromAddress( address componentAddr ) external view returns (uint256); /** * @param entity Entity to check * @param componentId Component to check * @return Boolean indicating if entity belongs to component */ function getEntityHasComponent( uint256 entity, uint256 componentId ) external view returns (bool); /** * @return Boolean array indicating if entity belongs to component * @param entities Entities to check * @param componentIds Components to check */ function batchGetEntitiesHasComponents( uint256[] calldata entities, uint256[] calldata componentIds ) external view returns (bool[] memory); /** * Sets multiple component values at once * @param entities Entities to set values for * @param componentIds Component to set value on * @param values Values to set */ function batchSetComponentValue( uint256[] calldata entities, uint256[] calldata componentIds, bytes[] calldata values ) external; /** * Sets multiple component values at once and emits a publish event (for cross-chain) * @param entities Entities to set values for * @param componentIds Component to set value on * @param values Values to set */ function batchPublishSetComponentValue( uint256[] calldata entities, uint256[] calldata componentIds, bytes[] calldata values ) external returns (uint256 requestId); /** * @param componentId Id of the component * @return Entire array of components belonging an entity * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function getEntityComponents( uint256 componentId ) external view returns (uint256[] memory); /** * @param componentId Id of the component * @return Number of components belonging to an entity */ function getEntityComponentCount( uint256 componentId ) external view returns (uint256); /** * Gets multiple component values at once * @param entities Entities to get values for * @param componentIds Component to get value from */ function batchGetComponentValues( uint256[] calldata entities, uint256[] calldata componentIds ) external view returns (bytes[] memory values); /** * Register a component value update. * Emits the `ComponentValueSet` event for clients to reconstruct the state. * @param entity Entity to update * @param data Data to update */ function registerComponentValueSet( uint256 entity, bytes calldata data ) external; /** * Emit a component value update across chains. * Emits the `PublishComponentValueSet` event for cross-chain clients to reconstruct the state. * @param entity Entity to update * @param data Data to update */ function publishComponentValueSet( uint256 componentId, uint256 entity, bytes calldata data ) external returns (uint256); /** * Register a component batch value update. * Emits the `ComponentBatchValueSet` event for clients to reconstruct the state. * @param entities Entities to update * @param data Data to update */ function batchRegisterComponentValueSet( uint256[] calldata entities, bytes[] calldata data ) external; /** * Emit a component batch value update across chains. * Emits the `PublishComponentBatchValueSet` event for cross-chain clients to reconstruct the state. * @param entities Entities to update * @param data Data to update */ function batchPublishComponentValueSet( uint256 componentId, uint256[] calldata entities, bytes[] calldata data ) external returns (uint256); /** * Register a component value removal. * Emits the `ComponentValueRemoved` event for clients to reconstruct the state. */ function registerComponentValueRemoved(uint256 entity) external; /** * Emit a component value removal across chains. * Emits the `PublishComponentValueRemoved` event for cross-chain clients to reconstruct the state. */ // TODO: Reenable when we're ready to support cross-chain removal // function publishComponentValueRemoved( // uint256 componentId, // uint256 entity // ) external returns (uint256); /** * Register a component batch value removal. * Emits the `ComponentBatchValueRemoved` event for clients to reconstruct the state. * @param entities Entities to update */ function batchRegisterComponentValueRemoved( uint256[] calldata entities ) external; /** * Emit a component batch value removal across chains. * Emits the `PublishComponentBatchValueRemoved` event for cross-chain clients to reconstruct the state. * @param entities Entities to update */ // TODO: Reenable when we're ready to support cross-chain removal // function batchPublishComponentValueRemoved( // uint256 componentId, // uint256[] calldata entities // ) external returns (uint256); /** * DEPRECATED: Generate a new general-purpose entity GUID */ function generateGUIDDeprecated() external returns (uint256); /** * * @param operatorAddress Address of the Operator account * @return Authorized Player account for an address */ function getPlayerAccount( address operatorAddress ) external view returns (address); /** * @notice Sends a transfer to another chain in the multichain * @param systemId Id of the 1155 System (Must implement IMultichain1155) * @param from From address of the user sending the token * @param to To address of the user receiving the token * @param toChainId Chain ID of the receiving chain * @param id Array of token IDs to send * @param amount Array of token amounts to send */ function sendMultichain1155TransferSingle( uint256 systemId, address from, address to, uint256 toChainId, uint256 id, uint256 amount ) external; /** * @notice Sends a transfer to another chain in the multichain * @param systemId Id of the 1155 System (Must implement IMultichain1155) * @param from From address of the user sending the token * @param to To address of the user receiving the token * @param toChainId Chain ID of the receiving chain * @param ids Array of token IDs to send * @param amounts Array of token amounts to send */ function sendMultichain1155TransferBatch( uint256 systemId, address from, address to, uint256 toChainId, uint256[] calldata ids, uint256[] calldata amounts ) external; /** * @notice Sends a transfer to another chain in the multichain * @param systemId Id of the 1155 System (Must implement Multichain721) * @param from From address of the user sending the token * @param to To address of the user receiving the token * @param tokenId the tokenId being transferred * @param toChainId Chain ID of the receiving chain */ function sendMultichain721Transfer( uint256 systemId, address from, address to, uint256 tokenId, uint256 toChainId ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; uint256 constant MAX_UINT96 = 2 ** 96 - 1; /** @title Entity related helpers **/ library EntityLibrary { /** ERRORS **/ error TokenIdExceedsMaxValue(uint256 tokenId); /** INTERNAL **/ /** * @dev Note this function will require the tokenId is < uint96.MAX * Unpacks a token address from a single uint256 which is the entity ID * * @return tokenAddress Address of the unpacked token */ function entityToAddress( uint256 value ) internal pure returns (address tokenAddress) { tokenAddress = address(uint160(value)); uint256 tokenId = uint256(value >> 160); uint256 verify = (tokenId << 160) | uint160(tokenAddress); require(verify == value); } /** * Packs an address into a single uint256 entity * * @param addr Address to convert to entity * @return Converted address to entity */ function addressToEntity(address addr) internal pure returns (uint256) { return uint160(addr); } /** * @dev Note this function will require the tokenId is < uint96.MAX * Unpacks a token address and token id from a single uint256 * * @return tokenAddress Address of the unpacked token * @return tokenId Id of the unpacked token */ function entityToToken( uint256 value ) internal pure returns (address tokenAddress, uint256 tokenId) { tokenAddress = address(uint160(value)); tokenId = uint256(value >> 160); uint256 verify = (tokenId << 160) | uint160(tokenAddress); require(verify == value); } /** * @dev Note this function will require the tokenId is < uint96.MAX * Packs a token address and token id into a single uint256 * * @param tokenAddress Address of the unpacked token * @param tokenId Id of the unpacked token * @return Token address and token id packed into single uint256 */ function tokenToEntity( address tokenAddress, uint256 tokenId ) internal pure returns (uint256) { if (tokenId > MAX_UINT96) { revert TokenIdExceedsMaxValue(tokenId); } return (tokenId << 160) | uint160(tokenAddress); } /** * @dev Pack an account and entity ID together and keccak256 hash them, then return the uint value of the hash * @param account Account address * @param entity Entity ID * @return Uint256 value of the keccak256 hash */ function accountSubEntity( address account, uint256 entity ) internal pure returns (uint256) { return uint256((keccak256(abi.encodePacked(account, entity)))); } }
// SPDX-License-Identifier: MIT LICENSE pragma solidity ^0.8.9; import "@openzeppelin/contracts/utils/Strings.sol"; import {IGameRegistry} from "./IGameRegistry.sol"; import {CounterComponent, Layout as CounterLayout, ID as COUNTER_COMPONENT_ID} from "../generated/components/CounterComponent.sol"; import {GuidCounterComponent, ID as GUID_COUNTER_COMPONENT_ID} from "../generated/components/GuidCounterComponent.sol"; string constant GUID_PREFIX = "game.piratenation.guid."; /// @notice Error thrown when the counter is too large to fit in 144 bits error CounterOverflow(uint256 counter); /// @notice Error thrown when the chain ID is too large to fit in 32 bits error ChainIdOverflow(uint256 chainId); /// @notice Error thrown when the prefix is too large to fit in 80 bits error PrefixOverflow(uint256 prefix); /** * Common helper functions for dealing with GUIDS */ library GUIDLibrary { /** * @dev DEPRECATED: Increments the counter for a given key and returns a new GUID * @dev WARNING: Does NOT generated cross-chain safe guids * @param gameRegistry Address of the Counter component * @param key A prefix to namespace the GUID and prevent collisions */ function guidV1( IGameRegistry gameRegistry, string memory key ) internal returns (uint256) { string memory prefix = string.concat(GUID_PREFIX, key); uint256 entity = uint256(keccak256(abi.encodePacked(prefix))); CounterComponent counterComponent = CounterComponent( gameRegistry.getComponent(COUNTER_COMPONENT_ID) ); // Increment counter uint256 ct = counterComponent.getValue(entity) + 1; counterComponent.setValue(entity, ct); // Return new guid return uint256( keccak256( abi.encodePacked( string.concat(prefix, ".", Strings.toString(ct)) ) ) ); } /** * Increments the counter for a given prefix and returns a new multi-chain safe GUID * @param gameRegistry Address of the GuidCounter component * @param prefix A prefix to namespace the GUID and prevent collisions */ function guid( IGameRegistry gameRegistry, uint80 prefix ) internal returns (uint256) { GuidCounterComponent counter = GuidCounterComponent( gameRegistry.getComponent(GUID_COUNTER_COMPONENT_ID) ); // Increment guid counter uint256 count = counter.getValue(prefix) + 1; counter.setValue(prefix, count); return packGuid(prefix, count); } /** * Packs prefix and counter into a multi-chain safe GUID * @param prefix A prefix to namespace the GUID and prevent collisions * @param counter A counter to increment the GUID */ function packGuid( uint80 prefix, uint256 counter ) internal view returns (uint256) { if (block.chainid > type(uint32).max) { revert ChainIdOverflow(block.chainid); } if (prefix > type(uint80).max) { revert PrefixOverflow(prefix); } if (counter > type(uint144).max) { revert CounterOverflow(counter); } // Pack into a uint256: // - Chain ID in the highest 32 bits // - Prefix in the next 80 bits (10 characters) // - Counter in the lowest 144 bits return (uint256(block.chainid) << 224) | (uint256(prefix) << 144) | counter; } }
// SPDX-License-Identifier: MIT LICENSE pragma solidity ^0.8.13; interface IMultichain721 { /** * A contract that implements this interface is capable of receiving Multichain721 transfers * This functiog the item * @param tokenId id of the items to mintn should mint the item appropriately * This will be called AFTER generic checks have been made such as * - Validating to address is on this chain * - Ensuring replay attacks are prevented * @param to address of user recievin */ function receivedMultichain721Transfer( address to, uint256 tokenId ) external; }
// SPDX-License-Identifier: MIT LICENSE pragma solidity ^0.8.13; interface IMultichain1155 { /** * A contract that implements this interface is capable of receiving Multichain1155 transfers * This function should mint the item appropriately * This will be called AFTER generic checks have been made such as * - Validating to address is on this chain * - Ensuring replay attacks are prevented * @param to address of user recieving the item * @param id ids of the items to mint * @param amount amount of the items to mint */ function receivedMultichain1155TransferSingle( address to, uint256 id, uint256 amount ) external; /** * A contract that implements this interface is capable of receiving Multichain1155 transfers * This function should mint the item appropriately * This will be called AFTER generic checks have been made such as * - Validating to address is on this chain * - Ensuring replay attacks are prevented * @param to address of user recieving the item * @param ids ids of the items to mint * @param amounts amount of the items to mint */ function receivedMultichain1155TransferBatch( address to, uint256[] calldata ids, uint256[] calldata amounts ) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import {TypesLibrary} from "../TypesLibrary.sol"; interface IComponent { /** * Sets the raw bytes value for this component * * @param entity Entity to set value for * @param value Bytes encoded value for this component */ function setBytes(uint256 entity, bytes memory value) external; /** * Removes an entity from this component * @param entity Entity to remove */ function remove(uint256 entity) external; /** * Whether or not the entity exists in this component * @param entity Entity to check for * @return true if the entity exists */ function has(uint256 entity) external view returns (bool); /** * @param entity Entity to retrieve value for * @return The raw bytes value for the given entity in this component */ function getBytes(uint256 entity) external view returns (bytes memory); /** Return the keys and value types of the schema of this component. */ function getSchema() external pure returns ( string[] memory keys, TypesLibrary.SchemaValue[] memory values ); /** * Sets the raw bytes value for this component in batches * * @param entities Entities to set values for * @param values Bytes encoded values for this component */ function batchSetBytes( uint256[] calldata entities, bytes[] calldata values ) external; }
// SPDX-License-Identifier: MIT // Auto-generated using Mage CLI codegen (v1) - DO NOT EDIT pragma solidity ^0.8.13; import {TypesLibrary} from "../../core/TypesLibrary.sol"; import {BaseStorageComponentV2, IBaseStorageComponentV2} from "../../core/components/BaseStorageComponentV2.sol"; import {GAME_LOGIC_CONTRACT_ROLE} from "../../Constants.sol"; uint256 constant ID = uint256(keccak256("core.mage.archivedcomponent.v1")); struct Layout { bool value; } library ArchivedComponentStorage { bytes32 internal constant STORAGE_SLOT = bytes32(ID); // Declare struct for mapping entity to struct struct InternalLayout { mapping(uint256 => Layout) entityIdToStruct; } function layout() internal pure returns (InternalLayout storage dataStruct) { bytes32 position = STORAGE_SLOT; // solhint-disable-next-line no-inline-assembly assembly { dataStruct.slot := position } } } /** * @title ArchivedComponent * @dev maps entity id → boolean if an entity is archived or not */ contract ArchivedComponent is BaseStorageComponentV2 { /** SETUP **/ /** Sets the GameRegistry contract address for this contract */ constructor( address gameRegistryAddress ) BaseStorageComponentV2(gameRegistryAddress, ID) { // Do nothing } /** * @inheritdoc IBaseStorageComponentV2 */ function getSchema() public pure override returns (string[] memory keys, TypesLibrary.SchemaValue[] memory values) { keys = new string[](1); values = new TypesLibrary.SchemaValue[](1); // Whether the entity is archived or not keys[0] = "value"; values[0] = TypesLibrary.SchemaValue.BOOL; } /** * Sets the typed value for this component * * @param entity Entity to get value for * @param value Layout to set for the given entity */ function setLayoutValue( uint256 entity, Layout calldata value ) external virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { _setValue(entity, value); } /** * Sets the native value for this component * * @param entity Entity to get value for * @param value Whether the entity is archived or not */ function setValue( uint256 entity, bool value ) external virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { _setValue(entity, Layout(value)); } /** * Batch sets the typed value for this component * * @param entities Entity to batch set values for * @param values Layout to set for the given entities */ function batchSetValue( uint256[] calldata entities, Layout[] calldata values ) external virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { if (entities.length != values.length) { revert InvalidBatchData(entities.length, values.length); } // Set the values in storage bytes[] memory encodedValues = new bytes[](entities.length); for (uint256 i = 0; i < entities.length; i++) { _setValueToStorage(entities[i], values[i]); encodedValues[i] = _getEncodedValues(values[i]); } // ABI Encode all native types of the struct _emitBatchSetBytes(entities, encodedValues); } /** * Returns the typed value for this component * * @param entity Entity to get value for * @return value Layout value for the given entity */ function getLayoutValue( uint256 entity ) external view virtual returns (Layout memory value) { // Get the struct from storage value = ArchivedComponentStorage.layout().entityIdToStruct[entity]; } /** * Returns the native values for this component * * @param entity Entity to get value for * @return value Whether the entity is archived or not */ function getValue( uint256 entity ) external view virtual returns ( bool value ) { if (has(entity)) { Layout memory s = ArchivedComponentStorage.layout().entityIdToStruct[entity]; (value) = abi.decode( _getEncodedValues(s), (bool) ); } } /** * Returns an array of byte values for each field of this component. * * @param entity Entity to build array of byte values for. */ function getByteValues( uint256 entity ) external view virtual returns (bytes[] memory values) { // Get the struct from storage Layout storage s = ArchivedComponentStorage .layout() .entityIdToStruct[entity]; // ABI Encode all fields of the struct and add to values array values = new bytes[](1); values[0] = abi.encode(s.value); } /** * Returns the bytes value for this component * * @param entity Entity to get value for */ function getBytes( uint256 entity ) external view returns (bytes memory value) { Layout memory s = ArchivedComponentStorage.layout().entityIdToStruct[entity]; value = _getEncodedValues(s); } /** * Sets the value of this component using a byte array * * @param entity Entity to set value for */ function setBytes( uint256 entity, bytes calldata value ) external onlyRole(GAME_LOGIC_CONTRACT_ROLE) { Layout memory s = ArchivedComponentStorage.layout().entityIdToStruct[entity]; (s.value) = abi.decode(value, (bool)); _setValueToStorage(entity, s); // ABI Encode all native types of the struct _emitSetBytes( entity, value ); } /** * Sets bytes data in batch format * * @param entities Entities to set value for * @param values Bytes values to set for the given entities */ function batchSetBytes( uint256[] calldata entities, bytes[] calldata values ) external onlyRole(GAME_LOGIC_CONTRACT_ROLE) { if (entities.length != values.length) { revert InvalidBatchData(entities.length, values.length); } for (uint256 i = 0; i < entities.length; i++) { Layout memory s = ArchivedComponentStorage.layout().entityIdToStruct[entities[i]]; (s.value) = abi.decode(values[i], (bool)); _setValueToStorage(entities[i], s); } // ABI Encode all native types of the struct _emitBatchSetBytes( entities, values ); } /** * Remove the given entity from this component. * * @param entity Entity to remove from this component. */ function remove(uint256 entity) public virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { // Remove the entity from the component delete ArchivedComponentStorage.layout().entityIdToStruct[entity]; _emitRemoveBytes(entity); } /** * Batch remove the given entities from this component. * * @param entities Entities to remove from this component. */ function batchRemove(uint256[] calldata entities) public virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { // Remove the entities from the component for (uint256 i = 0; i < entities.length; i++) { delete ArchivedComponentStorage.layout().entityIdToStruct[ entities[i] ]; } _emitBatchRemoveBytes(entities); } /** * Check whether the given entity has a value in this component. * * @param entity Entity to check whether it has a value in this component for. */ function has(uint256 entity) public view virtual returns (bool) { return gameRegistry.getEntityHasComponent(entity, ID); } /** INTERNAL **/ function _setValueToStorage( uint256 entity, Layout memory value ) internal { Layout storage s = ArchivedComponentStorage .layout() .entityIdToStruct[entity]; s.value = value.value; } function _setValue( uint256 entity, Layout memory value ) internal { _setValueToStorage(entity, value); // ABI Encode all native types of the struct _emitSetBytes( entity, abi.encode(value.value) ); } function _getEncodedValues( Layout memory value ) internal pure returns (bytes memory) { return abi.encode( value.value ); } }
// SPDX-License-Identifier: MIT // Auto-generated using Mage CLI codegen (v1) - DO NOT EDIT pragma solidity ^0.8.13; import {TypesLibrary} from "../../core/TypesLibrary.sol"; import {BaseStorageComponentV2, IBaseStorageComponentV2} from "../../core/components/BaseStorageComponentV2.sol"; import {GAME_LOGIC_CONTRACT_ROLE} from "../../Constants.sol"; uint256 constant ID = uint256(keccak256("core.mage.guidcountercomponent.v1")); struct Layout { uint256 value; } library GuidCounterComponentStorage { bytes32 internal constant STORAGE_SLOT = bytes32(ID); // Declare struct for mapping entity to struct struct InternalLayout { mapping(uint256 => Layout) entityIdToStruct; } function layout() internal pure returns (InternalLayout storage dataStruct) { bytes32 position = STORAGE_SLOT; // solhint-disable-next-line no-inline-assembly assembly { dataStruct.slot := position } } } /** * @title GuidCounterComponent * @dev An uneditable counter specifically for universal guids */ contract GuidCounterComponent is BaseStorageComponentV2 { /** SETUP **/ /** Sets the GameRegistry contract address for this contract */ constructor( address gameRegistryAddress ) BaseStorageComponentV2(gameRegistryAddress, ID) { // Do nothing } /** * @inheritdoc IBaseStorageComponentV2 */ function getSchema() public pure override returns (string[] memory keys, TypesLibrary.SchemaValue[] memory values) { keys = new string[](1); values = new TypesLibrary.SchemaValue[](1); // Counter tracking total counts keys[0] = "value"; values[0] = TypesLibrary.SchemaValue.UINT256; } /** * Sets the typed value for this component * * @param entity Entity to get value for * @param value Layout to set for the given entity */ function setLayoutValue( uint256 entity, Layout calldata value ) external virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { _setValue(entity, value); } /** * Sets the native value for this component * * @param entity Entity to get value for * @param value Counter tracking total counts */ function setValue( uint256 entity, uint256 value ) external virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { _setValue(entity, Layout(value)); } /** * Batch sets the typed value for this component * * @param entities Entity to batch set values for * @param values Layout to set for the given entities */ function batchSetValue( uint256[] calldata entities, Layout[] calldata values ) external virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { if (entities.length != values.length) { revert InvalidBatchData(entities.length, values.length); } // Set the values in storage bytes[] memory encodedValues = new bytes[](entities.length); for (uint256 i = 0; i < entities.length; i++) { _setValueToStorage(entities[i], values[i]); encodedValues[i] = _getEncodedValues(values[i]); } // ABI Encode all native types of the struct _emitBatchSetBytes(entities, encodedValues); } /** * Returns the typed value for this component * * @param entity Entity to get value for * @return value Layout value for the given entity */ function getLayoutValue( uint256 entity ) external view virtual returns (Layout memory value) { // Get the struct from storage value = GuidCounterComponentStorage.layout().entityIdToStruct[entity]; } /** * Returns the native values for this component * * @param entity Entity to get value for * @return value Counter tracking total counts */ function getValue( uint256 entity ) external view virtual returns ( uint256 value ) { if (has(entity)) { Layout memory s = GuidCounterComponentStorage.layout().entityIdToStruct[entity]; (value) = abi.decode( _getEncodedValues(s), (uint256) ); } } /** * Returns an array of byte values for each field of this component. * * @param entity Entity to build array of byte values for. */ function getByteValues( uint256 entity ) external view virtual returns (bytes[] memory values) { // Get the struct from storage Layout storage s = GuidCounterComponentStorage .layout() .entityIdToStruct[entity]; // ABI Encode all fields of the struct and add to values array values = new bytes[](1); values[0] = abi.encode(s.value); } /** * Returns the bytes value for this component * * @param entity Entity to get value for */ function getBytes( uint256 entity ) external view returns (bytes memory value) { Layout memory s = GuidCounterComponentStorage.layout().entityIdToStruct[entity]; value = _getEncodedValues(s); } /** * Sets the value of this component using a byte array * * @param entity Entity to set value for */ function setBytes( uint256 entity, bytes calldata value ) external onlyRole(GAME_LOGIC_CONTRACT_ROLE) { Layout memory s = GuidCounterComponentStorage.layout().entityIdToStruct[entity]; (s.value) = abi.decode(value, (uint256)); _setValueToStorage(entity, s); // ABI Encode all native types of the struct _emitSetBytes( entity, value ); } /** * Sets bytes data in batch format * * @param entities Entities to set value for * @param values Bytes values to set for the given entities */ function batchSetBytes( uint256[] calldata entities, bytes[] calldata values ) external onlyRole(GAME_LOGIC_CONTRACT_ROLE) { if (entities.length != values.length) { revert InvalidBatchData(entities.length, values.length); } for (uint256 i = 0; i < entities.length; i++) { Layout memory s = GuidCounterComponentStorage.layout().entityIdToStruct[entities[i]]; (s.value) = abi.decode(values[i], (uint256)); _setValueToStorage(entities[i], s); } // ABI Encode all native types of the struct _emitBatchSetBytes( entities, values ); } /** * Remove the given entity from this component. * * @param entity Entity to remove from this component. */ function remove(uint256 entity) public virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { // Remove the entity from the component delete GuidCounterComponentStorage.layout().entityIdToStruct[entity]; _emitRemoveBytes(entity); } /** * Batch remove the given entities from this component. * * @param entities Entities to remove from this component. */ function batchRemove(uint256[] calldata entities) public virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { // Remove the entities from the component for (uint256 i = 0; i < entities.length; i++) { delete GuidCounterComponentStorage.layout().entityIdToStruct[ entities[i] ]; } _emitBatchRemoveBytes(entities); } /** * Check whether the given entity has a value in this component. * * @param entity Entity to check whether it has a value in this component for. */ function has(uint256 entity) public view virtual returns (bool) { return gameRegistry.getEntityHasComponent(entity, ID); } /** INTERNAL **/ function _setValueToStorage( uint256 entity, Layout memory value ) internal { Layout storage s = GuidCounterComponentStorage .layout() .entityIdToStruct[entity]; s.value = value.value; } function _setValue( uint256 entity, Layout memory value ) internal { _setValueToStorage(entity, value); // ABI Encode all native types of the struct _emitSetBytes( entity, abi.encode(value.value) ); } function _getEncodedValues( Layout memory value ) internal pure returns (bytes memory) { return abi.encode( value.value ); } }
// SPDX-License-Identifier: MIT // Auto-generated using Mage CLI codegen (v1) - DO NOT EDIT pragma solidity ^0.8.13; import {TypesLibrary} from "../../core/TypesLibrary.sol"; import {BaseStorageComponentV2, IBaseStorageComponentV2} from "../../core/components/BaseStorageComponentV2.sol"; import {GAME_LOGIC_CONTRACT_ROLE} from "../../Constants.sol"; uint256 constant ID = uint256(keccak256("core.mage.chainidcomponent.v1")); struct Layout { uint256 value; } library ChainIdComponentStorage { bytes32 internal constant STORAGE_SLOT = bytes32(ID); // Declare struct for mapping entity to struct struct InternalLayout { mapping(uint256 => Layout) entityIdToStruct; } function layout() internal pure returns (InternalLayout storage dataStruct) { bytes32 position = STORAGE_SLOT; // solhint-disable-next-line no-inline-assembly assembly { dataStruct.slot := position } } } /** * @title ChainIdComponent * @dev This component stores the chain ID for an entity */ contract ChainIdComponent is BaseStorageComponentV2 { /** SETUP **/ /** Sets the GameRegistry contract address for this contract */ constructor( address gameRegistryAddress ) BaseStorageComponentV2(gameRegistryAddress, ID) { // Do nothing } /** * @inheritdoc IBaseStorageComponentV2 */ function getSchema() public pure override returns (string[] memory keys, TypesLibrary.SchemaValue[] memory values) { keys = new string[](1); values = new TypesLibrary.SchemaValue[](1); // The home chain ID for entity keys[0] = "value"; values[0] = TypesLibrary.SchemaValue.UINT256; } /** * Sets the typed value for this component * * @param entity Entity to get value for * @param value Layout to set for the given entity */ function setLayoutValue( uint256 entity, Layout calldata value ) external virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { _setValue(entity, value); } /** * Sets the native value for this component * * @param entity Entity to get value for * @param value The home chain ID for entity */ function setValue( uint256 entity, uint256 value ) external virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { _setValue(entity, Layout(value)); } /** * Batch sets the typed value for this component * * @param entities Entity to batch set values for * @param values Layout to set for the given entities */ function batchSetValue( uint256[] calldata entities, Layout[] calldata values ) external virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { if (entities.length != values.length) { revert InvalidBatchData(entities.length, values.length); } // Set the values in storage bytes[] memory encodedValues = new bytes[](entities.length); for (uint256 i = 0; i < entities.length; i++) { _setValueToStorage(entities[i], values[i]); encodedValues[i] = _getEncodedValues(values[i]); } // ABI Encode all native types of the struct _emitBatchSetBytes(entities, encodedValues); } /** * Returns the typed value for this component * * @param entity Entity to get value for * @return value Layout value for the given entity */ function getLayoutValue( uint256 entity ) external view virtual returns (Layout memory value) { // Get the struct from storage value = ChainIdComponentStorage.layout().entityIdToStruct[entity]; } /** * Returns the native values for this component * * @param entity Entity to get value for * @return value The home chain ID for entity */ function getValue( uint256 entity ) external view virtual returns ( uint256 value ) { if (has(entity)) { Layout memory s = ChainIdComponentStorage.layout().entityIdToStruct[entity]; (value) = abi.decode( _getEncodedValues(s), (uint256) ); } } /** * Returns an array of byte values for each field of this component. * * @param entity Entity to build array of byte values for. */ function getByteValues( uint256 entity ) external view virtual returns (bytes[] memory values) { // Get the struct from storage Layout storage s = ChainIdComponentStorage .layout() .entityIdToStruct[entity]; // ABI Encode all fields of the struct and add to values array values = new bytes[](1); values[0] = abi.encode(s.value); } /** * Returns the bytes value for this component * * @param entity Entity to get value for */ function getBytes( uint256 entity ) external view returns (bytes memory value) { Layout memory s = ChainIdComponentStorage.layout().entityIdToStruct[entity]; value = _getEncodedValues(s); } /** * Sets the value of this component using a byte array * * @param entity Entity to set value for */ function setBytes( uint256 entity, bytes calldata value ) external onlyRole(GAME_LOGIC_CONTRACT_ROLE) { Layout memory s = ChainIdComponentStorage.layout().entityIdToStruct[entity]; (s.value) = abi.decode(value, (uint256)); _setValueToStorage(entity, s); // ABI Encode all native types of the struct _emitSetBytes( entity, value ); } /** * Sets bytes data in batch format * * @param entities Entities to set value for * @param values Bytes values to set for the given entities */ function batchSetBytes( uint256[] calldata entities, bytes[] calldata values ) external onlyRole(GAME_LOGIC_CONTRACT_ROLE) { if (entities.length != values.length) { revert InvalidBatchData(entities.length, values.length); } for (uint256 i = 0; i < entities.length; i++) { Layout memory s = ChainIdComponentStorage.layout().entityIdToStruct[entities[i]]; (s.value) = abi.decode(values[i], (uint256)); _setValueToStorage(entities[i], s); } // ABI Encode all native types of the struct _emitBatchSetBytes( entities, values ); } /** * Remove the given entity from this component. * * @param entity Entity to remove from this component. */ function remove(uint256 entity) public virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { // Remove the entity from the component delete ChainIdComponentStorage.layout().entityIdToStruct[entity]; _emitRemoveBytes(entity); } /** * Batch remove the given entities from this component. * * @param entities Entities to remove from this component. */ function batchRemove(uint256[] calldata entities) public virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { // Remove the entities from the component for (uint256 i = 0; i < entities.length; i++) { delete ChainIdComponentStorage.layout().entityIdToStruct[ entities[i] ]; } _emitBatchRemoveBytes(entities); } /** * Check whether the given entity has a value in this component. * * @param entity Entity to check whether it has a value in this component for. */ function has(uint256 entity) public view virtual returns (bool) { return gameRegistry.getEntityHasComponent(entity, ID); } /** INTERNAL **/ function _setValueToStorage( uint256 entity, Layout memory value ) internal { Layout storage s = ChainIdComponentStorage .layout() .entityIdToStruct[entity]; s.value = value.value; } function _setValue( uint256 entity, Layout memory value ) internal { _setValueToStorage(entity, value); // ABI Encode all native types of the struct _emitSetBytes( entity, abi.encode(value.value) ); } function _getEncodedValues( Layout memory value ) internal pure returns (bytes memory) { return abi.encode( value.value ); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControlUpgradeable.sol"; import "../utils/ContextUpgradeable.sol"; import "../utils/StringsUpgradeable.sol"; import "../utils/introspection/ERC165Upgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable { function __AccessControl_init() internal onlyInitializing { } function __AccessControl_init_unchained() internal onlyInitializing { } struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", StringsUpgradeable.toHexString(account), " is missing role ", StringsUpgradeable.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @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 PausableUpgradeable is Initializable, ContextUpgradeable { /** * @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. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20.sol"; import "./extensions/IERC20Metadata.sol"; import "../../utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer( address from, address to, uint256 amount ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _balances[to] += amount; } emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 amount ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.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. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ 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; if (lastIndex != toDeleteIndex) { 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] = valueIndex; // Replace lastValue's index to valueIndex } // 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) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // 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); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // 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)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // 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 in 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)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; /** * @title The ERC-2771 Recipient Base Abstract Class - Declarations * * @notice A contract must implement this interface in order to support relayed transaction. * * @notice It is recommended that your contract inherits from the ERC2771Recipient contract. */ abstract contract IERC2771Recipient { /** * :warning: **Warning** :warning: The Forwarder can have a full control over your Recipient. Only trust verified Forwarder. * @param forwarder The address of the Forwarder contract that is being used. * @return isTrustedForwarder `true` if the Forwarder is trusted to forward relayed transactions by this Recipient. */ function isTrustedForwarder(address forwarder) public virtual view returns(bool); /** * @notice Use this method the contract anywhere instead of msg.sender to support relayed transactions. * @return sender The real sender of this call. * For a call that came through the Forwarder the real sender is extracted from the last 20 bytes of the `msg.data`. * Otherwise simply returns `msg.sender`. */ function _msgSender() internal virtual view returns (address); /** * @notice Use this method in the contract instead of `msg.data` when difference matters (hashing, signature, etc.) * @return data The real `msg.data` of this call. * For a call that came through the Forwarder, the real sender address was appended as the last 20 bytes * of the `msg.data` - so this method will strip those 20 bytes off. * Otherwise (if the call was made directly and not through the forwarder) simply returns `msg.data`. */ function _msgData() internal virtual view returns (bytes calldata); }
// SPDX-License-Identifier: MIT // Auto-generated using Mage CLI codegen (v1) - DO NOT EDIT pragma solidity ^0.8.13; import {TypesLibrary} from "../../core/TypesLibrary.sol"; import {BaseStorageComponentV2, IBaseStorageComponentV2} from "../../core/components/BaseStorageComponentV2.sol"; import {GAME_LOGIC_CONTRACT_ROLE} from "../../Constants.sol"; uint256 constant ID = uint256(keccak256("core.mage.countercomponent.v1")); struct Layout { uint256 counts; } library CounterComponentStorage { bytes32 internal constant STORAGE_SLOT = bytes32(ID); // Declare struct for mapping entity to struct struct InternalLayout { mapping(uint256 => Layout) entityIdToStruct; } function layout() internal pure returns (InternalLayout storage dataStruct) { bytes32 position = STORAGE_SLOT; // solhint-disable-next-line no-inline-assembly assembly { dataStruct.slot := position } } } /** * @title CounterComponent * @dev A generic uneditable counter */ contract CounterComponent is BaseStorageComponentV2 { /** SETUP **/ /** Sets the GameRegistry contract address for this contract */ constructor( address gameRegistryAddress ) BaseStorageComponentV2(gameRegistryAddress, ID) { // Do nothing } /** * @inheritdoc IBaseStorageComponentV2 */ function getSchema() public pure override returns (string[] memory keys, TypesLibrary.SchemaValue[] memory values) { keys = new string[](1); values = new TypesLibrary.SchemaValue[](1); // Counter tracking total counts keys[0] = "counts"; values[0] = TypesLibrary.SchemaValue.UINT256; } /** * Sets the typed value for this component * * @param entity Entity to get value for * @param value Layout to set for the given entity */ function setLayoutValue( uint256 entity, Layout calldata value ) external virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { _setValue(entity, value); } /** * Sets the native value for this component * * @param entity Entity to get value for * @param counts Counter tracking total counts */ function setValue( uint256 entity, uint256 counts ) external virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { _setValue(entity, Layout(counts)); } /** * Batch sets the typed value for this component * * @param entities Entity to batch set values for * @param values Layout to set for the given entities */ function batchSetValue( uint256[] calldata entities, Layout[] calldata values ) external virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { if (entities.length != values.length) { revert InvalidBatchData(entities.length, values.length); } // Set the values in storage bytes[] memory encodedValues = new bytes[](entities.length); for (uint256 i = 0; i < entities.length; i++) { _setValueToStorage(entities[i], values[i]); encodedValues[i] = _getEncodedValues(values[i]); } // ABI Encode all native types of the struct _emitBatchSetBytes(entities, encodedValues); } /** * Returns the typed value for this component * * @param entity Entity to get value for * @return value Layout value for the given entity */ function getLayoutValue( uint256 entity ) external view virtual returns (Layout memory value) { // Get the struct from storage value = CounterComponentStorage.layout().entityIdToStruct[entity]; } /** * Returns the native values for this component * * @param entity Entity to get value for * @return counts Counter tracking total counts */ function getValue( uint256 entity ) external view virtual returns ( uint256 counts ) { if (has(entity)) { Layout memory s = CounterComponentStorage.layout().entityIdToStruct[entity]; (counts) = abi.decode( _getEncodedValues(s), (uint256) ); } } /** * Returns an array of byte values for each field of this component. * * @param entity Entity to build array of byte values for. */ function getByteValues( uint256 entity ) external view virtual returns (bytes[] memory values) { // Get the struct from storage Layout storage s = CounterComponentStorage .layout() .entityIdToStruct[entity]; // ABI Encode all fields of the struct and add to values array values = new bytes[](1); values[0] = abi.encode(s.counts); } /** * Returns the bytes value for this component * * @param entity Entity to get value for */ function getBytes( uint256 entity ) external view returns (bytes memory value) { Layout memory s = CounterComponentStorage.layout().entityIdToStruct[entity]; value = _getEncodedValues(s); } /** * Sets the value of this component using a byte array * * @param entity Entity to set value for */ function setBytes( uint256 entity, bytes calldata value ) external onlyRole(GAME_LOGIC_CONTRACT_ROLE) { Layout memory s = CounterComponentStorage.layout().entityIdToStruct[entity]; (s.counts) = abi.decode(value, (uint256)); _setValueToStorage(entity, s); // ABI Encode all native types of the struct _emitSetBytes( entity, value ); } /** * Sets bytes data in batch format * * @param entities Entities to set value for * @param values Bytes values to set for the given entities */ function batchSetBytes( uint256[] calldata entities, bytes[] calldata values ) external onlyRole(GAME_LOGIC_CONTRACT_ROLE) { if (entities.length != values.length) { revert InvalidBatchData(entities.length, values.length); } for (uint256 i = 0; i < entities.length; i++) { Layout memory s = CounterComponentStorage.layout().entityIdToStruct[entities[i]]; (s.counts) = abi.decode(values[i], (uint256)); _setValueToStorage(entities[i], s); } // ABI Encode all native types of the struct _emitBatchSetBytes( entities, values ); } /** * Remove the given entity from this component. * * @param entity Entity to remove from this component. */ function remove(uint256 entity) public virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { // Remove the entity from the component delete CounterComponentStorage.layout().entityIdToStruct[entity]; _emitRemoveBytes(entity); } /** * Batch remove the given entities from this component. * * @param entities Entities to remove from this component. */ function batchRemove(uint256[] calldata entities) public virtual onlyRole(GAME_LOGIC_CONTRACT_ROLE) { // Remove the entities from the component for (uint256 i = 0; i < entities.length; i++) { delete CounterComponentStorage.layout().entityIdToStruct[ entities[i] ]; } _emitBatchRemoveBytes(entities); } /** * Check whether the given entity has a value in this component. * * @param entity Entity to check whether it has a value in this component for. */ function has(uint256 entity) public view virtual returns (bool) { return gameRegistry.getEntityHasComponent(entity, ID); } /** INTERNAL **/ function _setValueToStorage( uint256 entity, Layout memory value ) internal { Layout storage s = CounterComponentStorage .layout() .entityIdToStruct[entity]; s.counts = value.counts; } function _setValue( uint256 entity, Layout memory value ) internal { _setValueToStorage(entity, value); // ABI Encode all native types of the struct _emitSetBytes( entity, abi.encode(value.counts) ); } function _getEncodedValues( Layout memory value ) internal pure returns (bytes memory) { return abi.encode( value.counts ); } }
// SPDX-License-Identifier: MIT LICENSE pragma solidity ^0.8.9; /** * Enum of supported schema types * Note: This is pulled directly from MUD (mud.dev) to maintain compatibility */ library TypesLibrary { enum SchemaValue { BOOL, INT8, INT16, INT32, INT64, INT128, INT256, INT, UINT8, UINT16, UINT32, UINT64, UINT128, UINT256, BYTES, STRING, ADDRESS, BYTES4, BOOL_ARRAY, INT8_ARRAY, INT16_ARRAY, INT32_ARRAY, INT64_ARRAY, INT128_ARRAY, INT256_ARRAY, INT_ARRAY, UINT8_ARRAY, UINT16_ARRAY, UINT32_ARRAY, UINT64_ARRAY, UINT128_ARRAY, UINT256_ARRAY, BYTES_ARRAY, STRING_ARRAY, ADDRESS_ARRAY } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; import {IBaseStorageComponentV2} from "./IBaseStorageComponentV2.sol"; import "../GameRegistryConsumerV2.sol"; /** * @title BaseStorageComponentV2 * @notice Base storage component class, version 2 */ abstract contract BaseStorageComponentV2 is IBaseStorageComponentV2, GameRegistryConsumerV2 { /// @notice Invalid data count compared to number of entity count error InvalidBatchData(uint256 entityCount, uint256 valueCount); /** SETUP **/ /** * @param _gameRegistryAddress Address of the GameRegistry contract * @param id ID of the component being created */ constructor( address _gameRegistryAddress, uint256 id ) GameRegistryConsumerV2(_gameRegistryAddress, id) { // Do nothing } /** INTERNAL */ /** * Use GameRegistry to trigger emit when setting * @param entity Entity to set the value for. * @param value Value to set for the given entity. */ function _emitSetBytes( uint256 entity, bytes memory value ) internal virtual { // Emit global event gameRegistry.registerComponentValueSet(entity, value); } /** * Use GameRegistry to trigger emit when setting * @param entities Array of entities to set values for. * @param values Array of values to set for a given entity. */ function _emitBatchSetBytes( uint256[] calldata entities, bytes[] memory values ) internal virtual { // Emit global event gameRegistry.batchRegisterComponentValueSet(entities, values); } /** * Use GameRegistry to trigger emit when removing * @param entity Entity to remove from this component. */ function _emitRemoveBytes(uint256 entity) internal virtual { // Emit global event gameRegistry.registerComponentValueRemoved(entity); } /** * Use GameRegistry to trigger emit when removing * @param entities Array of entities to remove from this component. */ function _emitBatchRemoveBytes( uint256[] calldata entities ) internal virtual { // Emit global event gameRegistry.batchRegisterComponentValueRemoved(entities); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControlUpgradeable { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/MathUpgradeable.sol"; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = MathUpgradeable.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, MathUpgradeable.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Internal function that returns the initialized version. Returns `_initialized` */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Internal function that returns the initialized version. Returns `_initializing` */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT LICENSE pragma solidity ^0.8.9; import "@openzeppelin/contracts/access/Ownable.sol"; import "@opengsn/contracts/src/interfaces/IERC2771Recipient.sol"; import {IGameRegistry} from "./IGameRegistry.sol"; import {ISystem} from "./ISystem.sol"; import {TRUSTED_FORWARDER_ROLE, MANAGER_ROLE} from "../Constants.sol"; /** @title Contract that lets a child contract access the GameRegistry contract */ contract GameRegistryConsumerV2 is ISystem, Ownable, IERC2771Recipient { /// @notice Id for the system/component uint256 private _id; /// @notice Read access contract IGameRegistry public gameRegistry; /** ERRORS **/ /// @notice Not authorized to perform action error MissingRole(address account, bytes32 expectedRole); /** MODIFIERS **/ // Modifier to verify a user has the appropriate role to call a given function modifier onlyRole(bytes32 role) { _checkRole(role, _msgSender()); _; } /** ERRORS **/ /// @notice gameRegistryAddress does not implement IGameRegistry error InvalidGameRegistry(); /** SETUP **/ /** Sets the GameRegistry contract address for this contract */ constructor(address gameRegistryAddress, uint256 id) { gameRegistry = IGameRegistry(gameRegistryAddress); _id = id; if (gameRegistryAddress == address(0)) { revert InvalidGameRegistry(); } } /** EXTERNAL **/ /** @return ID for this system */ function getId() public view override returns (uint256) { return _id; } /** * Sets the GameRegistry contract address for this contract * * @param gameRegistryAddress Address for the GameRegistry contract */ function setGameRegistry( address gameRegistryAddress ) external onlyRole(MANAGER_ROLE) { gameRegistry = IGameRegistry(gameRegistryAddress); if (gameRegistryAddress == address(0)) { revert InvalidGameRegistry(); } } /** @return GameRegistry contract for this contract */ function getGameRegistry() external view returns (IGameRegistry) { return gameRegistry; } /** * @dev Returns `true` if `account` has been granted `role`. */ function _hasAccessRole( bytes32 role, address account ) internal view returns (bool) { return gameRegistry.hasAccessRole(role, account); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!gameRegistry.hasAccessRole(role, account)) { revert MissingRole(account, role); } } /** * Returns the Player address for the Operator account * @param operatorAccount address of the Operator account to retrieve the player for */ function _getPlayerAccount( address operatorAccount ) internal view returns (address playerAccount) { return gameRegistry.getPlayerAccount(operatorAccount); } /// @inheritdoc IERC2771Recipient function isTrustedForwarder( address forwarder ) public view virtual override returns (bool) { return address(gameRegistry) != address(0) && _hasAccessRole(TRUSTED_FORWARDER_ROLE, forwarder); } /** INTERNAL **/ /// @inheritdoc IERC2771Recipient function _msgSender() internal view virtual override(Context, IERC2771Recipient) returns (address ret) { if (msg.data.length >= 20 && isTrustedForwarder(msg.sender)) { assembly { ret := shr(96, calldataload(sub(calldatasize(), 20))) } } else { ret = msg.sender; } } /// @inheritdoc IERC2771Recipient function _msgData() internal view virtual override(Context, IERC2771Recipient) returns (bytes calldata ret) { if (msg.data.length >= 20 && isTrustedForwarder(msg.sender)) { return msg.data[0:msg.data.length - 20]; } else { return msg.data; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import {TypesLibrary} from "../TypesLibrary.sol"; interface IBaseStorageComponentV2 { /** Return the keys and value types of the schema of this component. */ function getSchema() external pure returns ( string[] memory keys, TypesLibrary.SchemaValue[] memory values ); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT LICENSE pragma solidity ^0.8.13; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; /** * Defines a system the game engine */ interface ISystem { /** @return The ID for the system. Ex: a uint256 casted keccak256 hash */ function getId() external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 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"); (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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @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); }
{ "optimizer": { "enabled": true, "mode": "3" }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "abi" ] } }, "detectMissingLibraries": false, "forceEVMLA": false, "enableEraVMExtensions": false, "libraries": {} }
[{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"AlreadyProcessed","type":"error"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"}],"name":"ChainIdOverflow","type":"error"},{"inputs":[{"internalType":"uint256","name":"componentId","type":"uint256"}],"name":"ComponentIdNotRegistered","type":"error"},{"inputs":[{"internalType":"address","name":"component","type":"address"}],"name":"ComponentNotRegistered","type":"error"},{"inputs":[{"internalType":"uint256","name":"counter","type":"uint256"}],"name":"CounterOverflow","type":"error"},{"inputs":[],"name":"GuidCounterSet","type":"error"},{"inputs":[{"internalType":"uint256","name":"entityCount","type":"uint256"},{"internalType":"uint256","name":"dataCount","type":"uint256"}],"name":"InvalidBatchData","type":"error"},{"inputs":[],"name":"InvalidBlockNumber","type":"error"},{"inputs":[],"name":"InvalidCaller","type":"error"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"}],"name":"InvalidChain","type":"error"},{"inputs":[],"name":"InvalidDeregisterCaller","type":"error"},{"inputs":[],"name":"InvalidExpirationBlockNumber","type":"error"},{"inputs":[],"name":"InvalidExpirationTimestamp","type":"error"},{"inputs":[],"name":"InvalidOperatorAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"systemId","type":"uint256"}],"name":"InvalidSystem","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"expectedRole","type":"bytes32"}],"name":"MissingRole","type":"error"},{"inputs":[],"name":"OperatorAlreadyRegistered","type":"error"},{"inputs":[],"name":"OperatorExpired","type":"error"},{"inputs":[],"name":"OperatorNotRegistered","type":"error"},{"inputs":[{"internalType":"address","name":"expected","type":"address"},{"internalType":"address","name":"actual","type":"address"}],"name":"PlayerSignerMismatch","type":"error"},{"inputs":[{"internalType":"uint256","name":"prefix","type":"uint256"}],"name":"PrefixOverflow","type":"error"},{"inputs":[],"name":"RegisterOperatorInCooldown","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"TokenIdExceedsMaxValue","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"componentId","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"entities","type":"uint256[]"}],"name":"BatchComponentValueRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"componentId","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"entities","type":"uint256[]"},{"indexed":false,"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"BatchComponentValueSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"componentIds","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"entities","type":"uint256[]"}],"name":"BatchMultiComponentValueRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"componentIds","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"entities","type":"uint256[]"},{"indexed":false,"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"BatchMultiComponentValueSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"componentId","type":"uint256"},{"indexed":true,"internalType":"address","name":"componentAddress","type":"address"}],"name":"ComponentRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"componentId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"entity","type":"uint256"}],"name":"ComponentValueRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"componentId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"entity","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"ComponentValueSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"systemId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"fromChainId","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"Multichain1155TransferBatchReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"systemId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"toChainId","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"Multichain1155TransferBatchSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"systemId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"fromChainId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Multichain1155TransferSingleReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"systemId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"toChainId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Multichain1155TransferSingleSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"systemId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toChainId","type":"uint256"}],"name":"Multichain721TransferReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"systemId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toChainId","type":"uint256"}],"name":"Multichain721TransferSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"address","name":"player","type":"address"}],"name":"OperatorDeregistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"uint256","name":"expiration","type":"uint256"}],"name":"OperatorRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"componentId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestTime","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"entities","type":"uint256[]"},{"indexed":false,"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"PublishBatchComponentValueSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"componentIds","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"entities","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"fromChainId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestTime","type":"uint256"},{"indexed":false,"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"PublishBatchSetComponentValue","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"componentId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"entity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestTime","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"PublishComponentValueSet","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":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"systemAddress","type":"address"}],"name":"SystemRegistered","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":"OPERATOR_MESSAGE_BLOCK_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REGISTER_OPERATOR_COOLDOWN_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"entities","type":"uint256[]"},{"internalType":"uint256[]","name":"componentIds","type":"uint256[]"}],"name":"batchGetComponentValues","outputs":[{"internalType":"bytes[]","name":"values","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"entities","type":"uint256[]"},{"internalType":"uint256[]","name":"componentIds","type":"uint256[]"}],"name":"batchGetEntitiesHasComponents","outputs":[{"internalType":"bool[]","name":"","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"componentId","type":"uint256"},{"internalType":"uint256[]","name":"entities","type":"uint256[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"batchPublishComponentValueSet","outputs":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"entities","type":"uint256[]"},{"internalType":"uint256[]","name":"componentIds","type":"uint256[]"},{"internalType":"bytes[]","name":"values","type":"bytes[]"}],"name":"batchPublishSetComponentValue","outputs":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"entities","type":"uint256[]"}],"name":"batchRegisterComponentValueRemoved","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"entities","type":"uint256[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"batchRegisterComponentValueSet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"entities","type":"uint256[]"},{"internalType":"uint256[]","name":"componentIds","type":"uint256[]"},{"internalType":"bytes[]","name":"values","type":"bytes[]"}],"name":"batchSetComponentValue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"uint256","name":"systemId","type":"uint256"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"fromChainId","type":"uint256"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"deliverMultichain1155TransferBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"uint256","name":"systemId","type":"uint256"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"fromChainId","type":"uint256"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deliverMultichain1155TransferSingle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"uint256","name":"systemId","type":"uint256"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"fromChainId","type":"uint256"},{"components":[{"internalType":"uint256[]","name":"entities","type":"uint256[]"},{"internalType":"uint256[]","name":"componentIds","type":"uint256[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"internalType":"struct BatchComponentData","name":"componentData","type":"tuple"}],"name":"deliverMultichain721Transfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operatorToDeregister","type":"address"}],"name":"deregisterOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"operators","type":"address[]"}],"name":"deregisterOperatorBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"generateGUIDDeprecated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"componentId","type":"uint256"}],"name":"getComponent","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"componentAddr","type":"address"}],"name":"getComponentIdFromAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"entity","type":"uint256"},{"internalType":"uint256","name":"componentId","type":"uint256"}],"name":"getComponentValue","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"entity","type":"uint256"}],"name":"getEntityComponentCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"entity","type":"uint256"}],"name":"getEntityComponents","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"entity","type":"uint256"},{"internalType":"uint256","name":"componentId","type":"uint256"}],"name":"getEntityHasComponent","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGuidCounter","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"player","type":"address"},{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getOperatorAccountRegistrationMessageToSign","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"operatorAddress","type":"address"}],"name":"getPlayerAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"player","type":"address"}],"name":"getRegisteredOperators","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"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":"uint256","name":"systemId","type":"uint256"}],"name":"getSystem","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"entity","type":"uint256"}],"name":"getUnarchivedEntityComponents","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":"hasAccessRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"admin","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"isTrustedForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastRegisterOperatorTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"componentId","type":"uint256"},{"internalType":"uint256","name":"entity","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"publishComponentValueSet","outputs":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"componentId","type":"uint256"},{"internalType":"address","name":"componentAddress","type":"address"}],"name":"registerComponent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"entity","type":"uint256"}],"name":"registerComponentValueRemoved","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"entity","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"registerComponentValueSet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"address","name":"player","type":"address"},{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"registerOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"players","type":"address[]"},{"internalType":"address[]","name":"operators","type":"address[]"},{"internalType":"uint256[]","name":"expirations","type":"uint256[]"}],"name":"registerOperatorBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"systemId","type":"uint256"},{"internalType":"address","name":"systemAddress","type":"address"}],"name":"registerSystem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"requestIdProcessed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"systemId","type":"uint256"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"toChainId","type":"uint256"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"sendMultichain1155TransferBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"systemId","type":"uint256"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"toChainId","type":"uint256"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sendMultichain1155TransferSingle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"systemId","type":"uint256"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"toChainId","type":"uint256"}],"name":"sendMultichain721Transfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"guidValue","type":"uint96"}],"name":"setGuidCounter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","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":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
9c4d535b000000000000000000000000000000000000000000000000000000000000000001000b839e2ade3372da115691404d219fc83f3854c6e49dff01aab9c5cc489000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x000200000000000200140000000000020001000000010355000000600310027000000a830030019d0000008004000039000000400040043f0000000100200190000000530000c13d00000a8302300197000000040020008c000024960000413d000000000301043b000000e00330027000000a850030009c0000005b0000a13d00000a860030009c000000940000213d00000a9a0030009c000002120000213d00000aa40030009c000003d00000a13d00000aa50030009c000004bb0000213d00000aa80030009c0000067b0000613d00000aa90030009c000024960000c13d0000000001000416000000000001004b000024960000c13d00000000010004110000009703000039000000000403041a000000140020008c0000003e0000413d001200000004001d00000ad201100197000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff001001900000009703000039000000120400002900000000010004110000003e0000613d000000140100008a00000000011000310000000101100367000000000101043b0000006001100270000000000141013f00000ad20010019800000de30000c13d000000000103041a00000b1102100197000000000023041b000000000200041400000ad20510019700000a830020009c00000a8302008041000000c00120021000000ae1011001c70000800d02000039000000030300003900000b120400004100000000060000192a0929ff0000040f0000000100200190000024960000613d000000000100001900002a0a0001042e0000000001000416000000000001004b000024960000c13d00000020010000390000010000100443000001200000044300000a840100004100002a0a0001042e00000aad0030009c000001ed0000a13d00000aae0030009c000002000000213d00000ab80030009c0000032d0000a13d00000ab90030009c000004780000213d00000abc0030009c000005f20000613d00000abd0030009c000024960000c13d000000440020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000402100370000000000202043b001100000002001d0000002401100370000000000101043b001200000001001d00000ad20010009c000024960000213d000000000100041100000ad201100197000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff0010019000000000010004110000008c0000613d000000140100008a00000000011000310000000101100367000000000101043b00000060011002700000001202000029000000000121013f00000ad20010019800000f060000c13d00000011010000292a0928780000040f000000000100001900002a0a0001042e00000a870030009c000002260000213d00000a910030009c000004070000a13d00000a920030009c0000052a0000213d00000a950030009c000006c70000613d00000a960030009c000024960000c13d000000640020008c000024960000413d0000000003000416000000000003004b000024960000c13d0000000403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d0000000404300039000000000441034f000000000404043b001200000004001d00000ad90040009c000024960000213d000000240330003900000012040000290000000504400210000b00000003001d000600000004001d0000000003340019000000000023004b000024960000213d0000002403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d0000000404300039000000000441034f000000000404043b000a00000004001d00000ad90040009c000024960000213d00000024043000390000000a030000290000000503300210000800000004001d000500000003001d0000000003430019000000000023004b000024960000213d0000004403100370000000000303043b000900000003001d00000ad90030009c000024960000213d00000009030000290000002303300039000000000023004b000024960000813d00000009030000290000000403300039000000000131034f000000000101043b001100000001001d00000ad90010009c000024960000213d0000000901000029000000240110003900000011030000290000000503300210001000000001001d000400000003001d0000000001130019000000000021004b000024960000213d0000000001000411000e00000001001d00000ad201100197000f00000001001d000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff001001900000000f01000029000001000000613d000000140100008a00000000011000310000000101100367000000000101043b0000006001100270000000000010043f00000ada01000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff001001900000015b0000c13d0000000001000031000000140010008c0000000f010000290000012b0000413d0000000f01000029000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff001001900000000f010000290000012b0000613d000000140100008a00000000011000310000000101100367000000000101043b0000006001100270000000000010043f00000aee01000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff001001900000015b0000c13d0000009701000039000000000101041a000d00000001001d0000000001000031000000140010008c000001570000413d0000000f01000029000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000001570000613d000000140100008a00000000011000310000000101100367000000000101043b000e0060001002780000000d020000290000000e0120014f00000ad20010019800000cd10000c13d00000012020000290000000a0020006c00001cc80000c13d0000001102000029000000120020006b00001cc80000c13d0000000a0000006b00001ddd0000c13d000000400100043d000700040010003d00000a830010009c000f00000001001d00000a8301008041001100400010021800000af701000041000000000010043f000000ff01000039000000200010043f00000af801000041000000000201041a00000af9010000410000000f03000029000f00000003001d000000000013043500000afa0100004100000007030000290000000000130435000000000100041400000a830010009c00000a8301008041000000c00110021000000011011001af00000ae5011001c700000ad202200197001200000002001d2a092a040000040f000000600310027000000a8303300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000f057000290000018e0000613d000000000801034f0000000f09000029000000008a08043c0000000009a90436000000000059004b0000018a0000c13d000000000006004b0000019b0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000000010020019000001e8f0000613d0000001f01400039000000600210018f0000000f01200029000000000021004b0000000002000039000000010200403900000ad90010009c00001e890000213d000000010020019000001e890000c13d000000400010043f000000200030008c000024960000413d0000000f010000290000000001010433001100000001001d000f00010010003e00000ee80000613d00000afb01000041000000000010044300000012010000290000000400100443000000000100041400000a830010009c00000a8301008041000000c00110021000000afc011001c700008002020000392a092a040000040f0000000100200190000024980000613d000000000101043b000000000001004b000024960000613d000000400300043d00000024013000390000000f02000029000000000021043500000afd010000410000000000130435000000040130003900000afa02000041000000000021043500000a830030009c000e00000003001d00000a830100004100000000010340190000004001100210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000adc011001c700000012020000292a0929ff0000040f0000000100200190000021bf0000613d0000000e0100002900000ad90010009c00001e890000213d0000000e01000029000000400010043f00000adf010000410000000000100443000000000100041400000a830010009c00000a8301008041000000c00110021000000ade011001c70000800b020000392a092a040000040f0000000100200190000024980000613d000000000101043b000e00000001001d00000afe0010009c0000223a0000413d00000b050100004100001a3d0000013d00000ac10030009c0000023a0000a13d00000ac20030009c000002610000a13d00000ac30030009c000004660000213d00000ac60030009c0000059b0000613d00000ac70030009c000024960000c13d000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000101043b2a0926670000040f0000055b0000013d00000aaf0030009c0000039e0000a13d00000ab00030009c000004a50000213d00000ab30030009c000005fb0000613d00000ab40030009c000024960000c13d000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000101043b000000000010043f000000fc01000039000006040000013d00000a9b0030009c0000040e0000a13d00000a9c0030009c000005420000213d00000a9f0030009c000006e00000613d00000aa00030009c000024960000c13d000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000101043b00000ad20010009c000024960000213d000000000010043f0000010001000039000008f90000013d00000a880030009c000004280000a13d00000a890030009c000005620000213d00000a8c0030009c000006f10000613d00000a8d0030009c000024960000c13d000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000101043b00000ad20010009c000024960000213d000000000010043f000000fb01000039000008f90000013d00000acb0030009c000002bd0000213d00000acf0030009c00000b9e0000613d00000ad00030009c000009010000613d00000ad10030009c000024960000c13d000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000101043b001200000001001d0000000001000411000000000010043f0000010001000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000000001004b00000eb60000c13d00000b0901000041000000000010043f0000000001000411000000040010043f00000ae50100004100002a0b0001043000000ac80030009c000009860000613d00000ac90030009c000008f00000613d00000aca0030009c000024960000c13d000000240020008c000024960000413d0000000003000416000000000003004b000024960000c13d0000000403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d000900040030003d0000000901100360000000000101043b000d00000001001d00000ad90010009c000024960000213d00000024033000390000000d010000290000000501100210000800000001001d000c00000003001d0000000001310019000000000021004b000024960000213d0000000001000411000000000010043f0000010001000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000e00000001001d000000000001004b0000025b0000613d0000000d0000006b0000155d0000c13d000000400100043d000000200200003900000000022104360000000d03000029000000000032043500000b0d0030009c000024960000213d00000008030000290000001f0230018f000000000003004b000002a90000613d00000040031000390000000804300029000000090500002900000020055000390000000105500367000000005605043c0000000003630436000000000043004b000002a50000c13d000000000002004b00000a830010009c00000a83010080410000004001100210000000080200002900000b060020009c00000b06020080410000006002200210000000000112019f000000000200041400000a830020009c00000a8302008041000000c002200210000000000121019f00000b070110009a0000800d02000039000000020300003900000b62040000410000000e05000029000012c70000013d00000acc0030009c00000bb10000613d00000acd0030009c0000094d0000613d00000ace0030009c000024960000c13d000000c40020008c000024960000413d0000000003000416000000000003004b000024960000c13d0000000403100370000000000303043b001200000003001d0000002403100370000000000303043b001100000003001d00000ad20030009c000024960000213d0000004403100370000000000303043b001000000003001d00000ad20030009c000024960000213d0000006403100370000000000303043b000f00000003001d0000008403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d0000000404300039000000000441034f000000000404043b000e00000004001d00000ad90040009c000024960000213d00000024033000390000000e040000290000000504400210000c00000003001d000d00000004001d0000000003340019000000000023004b000024960000213d000000a403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d0000000404300039000000000141034f000000000101043b000b00000001001d00000ad90010009c000024960000213d00000024033000390000000b010000290000000501100210000a00000001001d000900000003001d0000000001310019000000000021004b000024960000213d000000000100041100000ad201100197000800000001001d000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff001001900000031a0000613d000000140100008a00000000011000310000000101100367000000000101043b00080060001002780000000801000029000000000010043f00000ada01000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff0010019000001bbd0000c13d000000080100002900000d730000013d00000abe0030009c00000bcb0000613d00000abf0030009c000009f30000613d00000ac00030009c000024960000c13d000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000101043b000000000010043f0000010201000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000301041a000000400200043d000f00000002001d001200000003001d0000000002320436000d00000002001d000000000010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c700008010020000392a092a040000040f0000000100200190000024960000613d0000001205000029000000000005004b0000000d02000029000003640000613d000000000101043b0000000d020000290000000003000019000000000401041a000000000242043600000001011000390000000103300039000000000053004b0000035e0000413d0000000f0120006a0000001f0110003900000b72011001970000000f02100029000000000012004b00000000010000390000000101004039000b00000002001d00000ad90020009c00001e890000213d000000010010019000001e890000c13d0000000b01000029000000400010043f00000b5b01000041000000000010043f000000ff01000039000000200010043f0000000f01000029000000000201043300000ad90020009c00001e890000213d00000005032002100000003f0130003900000b2c011001970000000b0410002900000ad90040009c00001e890000213d00000b5c01000041000000000101041a000000400040043f0000000b040000290000000002240436000a00000002001d0000001f0230018f000000000003004b000003910000613d0000000a05000029000000000335001900000000040000310000000104400367000000004604043c0000000005650436000000000035004b0000038d0000c13d000000000002004b0000000f020000290000000002020433000000000002004b001200000000001d000015eb0000c13d0000000b0200002900000012010000290000000000120435000000400100043d001200000001001d2a0924da0000040f00000bc90000013d00000ab50030009c00000c060000613d00000ab60030009c00000a680000613d00000ab70030009c000024960000c13d000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000101043b00000ad20010009c000024960000213d000000000010043f000000fe01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000301041a000000400200043d001200000002001d001000000003001d0000000002320436001100000002001d000000000010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c700008010020000392a092a040000040f0000000100200190000024960000613d0000001005000029000000000005004b000012380000c13d00000012060000290000001104000029000012420000013d00000aaa0030009c00000c460000613d00000aab0030009c00000aaf0000613d00000aac0030009c000024960000c13d0000000001000416000000000001004b000024960000c13d0000000001000411000000140020008c000003f30000413d00000ad201100197000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff001001900000000001000411000003f30000613d000000140100008a00000000011000310000000101100367000000000101043b000000600110027000000ad201100197001200000001001d000000000010043f00000ada01000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff0010019000000ee30000c13d000000120100002900000d730000013d00000a970030009c00000cda0000613d00000a980030009c00000aba0000613d00000a990030009c000004140000613d000024960000013d00000aa10030009c00000d2e0000613d00000aa20030009c00000b760000613d00000aa30030009c000024960000c13d000000440020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000002402100370000000000202043b001200000002001d00000ad20020009c000024960000213d0000000401100370000000000101043b000000000010043f0000006501000039000000200010043f000000400200003900000000010000192a0929ea0000040f0000001202000029000004b70000013d00000a8e0030009c00000d9c0000613d00000a8f0030009c00000b7f0000613d00000a900030009c000024960000c13d000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000101043b001200000001001d00000aed0010009c000024960000213d000000000100041100000ad201100197001100000001001d000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000004500000613d000000140100008a00000000011000310000000101100367000000000101043b00110060001002780000001101000029000000000010043f00000aee01000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000012660000c13d00000011010000292a0926e80000040f001100000001001d00000af20100004100000d760000013d00000ac40030009c000005a20000613d00000ac50030009c000024960000c13d000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000101043b000000000010043f0000010401000039000000200010043f000000400200003900000000010000192a0929ea0000040f00000ab30000013d00000aba0030009c000006090000613d00000abb0030009c000024960000c13d000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000101043b000000000010043f0000010201000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000301041a000000400200043d001200000002001d001000000003001d0000000002320436001100000002001d000000000010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c700008010020000392a092a040000040f0000000100200190000024960000613d0000001005000029000000000005004b00000f100000c13d000000110400002900000f190000013d00000ab10030009c000006740000613d00000ab20030009c000024960000c13d000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000201043b00000ad20020009c000024960000213d00000b5001000041000000000010043f0000006501000039000000200010043f00000ad3010000412a0924e90000040f000000000101041a000000ff00100190000005590000013d00000aa60030009c000007100000613d00000aa70030009c000024960000c13d000000a40020008c000024960000413d0000000003000416000000000003004b000024960000c13d0000000403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d0000000404300039000000000441034f000000000404043b001200000004001d00000ad90040009c000024960000213d0000002404300039001000000004001d001100120040002d000000110020006b000024960000213d0000002402100370000000000202043b000f00000002001d00000ad20020009c000024960000213d0000004402100370000000000202043b000e00000002001d00000ad20020009c000024960000213d0000008402100370000000000202043b000c00000002001d0000006401100370000000000101043b000d00000001001d000000c901000039000000000101041a000000ff00100190000011d10000c13d000000000100041100000ad201100197000b00000001001d000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000005020000613d000000140100008a00000000011000310000000101100367000000000101043b000b0060001002780000000b020000290000000e0020006c000017e10000c13d0000000f01000029000000000010043f000000fb01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000b00000001001d00000add010000410000000000100443000000000100041400000a830010009c00000a8301008041000000c00110021000000ade011001c70000800b020000392a092a040000040f0000000100200190000024980000613d000000000101043b000a00000001001d0000000b0110006c00000ee80000413d000000770010008c00001ca60000213d00000b4a01000041000000000010043f00000af00100004100002a0b0001043000000a930030009c000007df0000613d00000a940030009c000024960000c13d000000440020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000002402100370000000000202043b001200000002001d00000ad20020009c000024960000213d0000000401100370000000000101043b001100000001001d2a0926670000040f2a0926790000040f000000110100002900000012020000292a0928780000040f000000000100001900002a0a0001042e00000a9d0030009c0000088b0000613d00000a9e0030009c000024960000c13d000000440020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000002402100370000000000202043b001200000002001d0000000401100370000000000101043b000000000010043f0000010201000039000000200010043f000000400200003900000000010000192a0929ea0000040f00000012020000292a0929d50000040f000000000001004b0000000001000039000000010100c039000000400200043d000000000012043500000a830020009c00000a8302008041000000400120021000000ae3011001c700002a0a0001042e00000a8a0030009c000008910000613d00000a8b0030009c000024960000c13d000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000101043b001200000001001d00000ad20010009c000024960000213d0000009701000039000000000101041a001100000001001d000000000100041100000ad201100197000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff0010019000000000020004110000058b0000613d000000140100008a00000000011000310000000101100367000000000101043b0000006002100270000000110120014f00000ad20010019800000de30000c13d0000001201000029000000000001004b000012350000c13d000000400100043d000000640210003900000ad5030000410000000000320435000000440210003900000ad603000041000000000032043500000024021000390000002603000039000010180000013d0000000001000416000000000001004b000024960000c13d0000007801000039000000800010043f00000ae90100004100002a0a0001042e000000e40020008c000024960000413d0000000003000416000000000003004b000024960000c13d0000002403100370000000000303043b001100000003001d0000000403100370000000000303043b001200000003001d0000004403100370000000000303043b001000000003001d00000ad20030009c000024960000213d0000006403100370000000000303043b000f00000003001d00000ad20030009c000024960000213d000000a403100370000000000303043b000c00000003001d0000008403100370000000000303043b000d00000003001d000000c401100370000000000101043b000e00000001001d00000ad90010009c000024960000213d0000000e0120006a00000b5f0010009c000024960000213d000000640010008c000024960000413d000000000100041100000ad201100197000b00000001001d000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000005df0000613d000000140100008a00000000011000310000000101100367000000000101043b000b0060001002780000000b01000029000000000010043f00000b5101000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000014d10000c13d0000000b01000029000009490000013d0000000001000416000000000001004b000024960000c13d0000010101000039000000000101041a00000aed01100197000000800010043f00000ae90100004100002a0a0001042e000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000101043b000000000010043f000000ff01000039000000200010043f000000400200003900000000010000192a0929ea0000040f00000b7a0000013d000000e40020008c000024960000413d0000000003000416000000000003004b000024960000c13d0000002403100370000000000303043b001100000003001d0000000403100370000000000303043b001200000003001d0000004403100370000000000303043b001000000003001d00000ad20030009c000024960000213d0000006403100370000000000303043b000f00000003001d00000ad20030009c000024960000213d0000008403100370000000000303043b000e00000003001d000000a403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d000c00040030003d0000000c04100360000000000404043b000d00000004001d00000ad90040009c000024960000213d0000000d04000029000b0005004002180000000b033000290000002403300039000000000023004b000024960000213d000000c403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d0000000404300039000000000141034f000000000101043b000a00000001001d00000ad90010009c000024960000213d00000024033000390000000a010000290000000501100210000900000001001d000800000003001d0000000001310019000000000021004b000024960000213d000000000100041100000ad201100197000700000001001d000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000006610000613d000000140100008a00000000011000310000000101100367000000000101043b00070060001002780000000701000029000000000010043f00000b5101000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff0010019000001a420000c13d0000000701000029000009490000013d0000000001000416000000000001004b000024960000c13d0000001e01000039000000800010043f00000ae90100004100002a0a0001042e000000440020008c000024960000413d0000000003000416000000000003004b000024960000c13d0000000403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d000a00040030003d0000000a04100360000000000404043b001200000004001d00000ad90040009c000024960000213d000000240430003900000012030000290000000503300210000800000003001d000d00000004001d0000000003430019000000000023004b000024960000213d0000002403100370000000000303043b000900000003001d00000ad90030009c000024960000213d00000009030000290000002303300039000000000023004b000024960000813d00000009030000290000000403300039000000000131034f000000000101043b001000000001001d00000ad90010009c000024960000213d0000000901000029000000240310003900000010010000290000000501100210000b00000003001d000700000001001d0000000001310019000000000021004b000024960000213d0000000001000411000000000010043f0000010001000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000f00000001001d000000000001004b000017a50000c13d00000b0901000041000000000010043f000000000100041100000ad201100197000000040010043f00000ae50100004100002a0b00010430000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000101043b001200000001001d00000ad20010009c000024960000213d000000000200041a0010ff000020019400000df30000c13d0000000001000415000000130110008a0000000501100210000000ff00200190001300000000003d001300010000603d00000df70000c13d00000b730120019700000001011001bf00000b740110019700000100011001bf00000e180000013d000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000101043b001200000001001d00000ad20010009c000024960000213d0000001201000029000000000001004b00000e250000c13d00000b6501000041000000000010043f00000af00100004100002a0b00010430000000440020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000402100370000000000202043b001200000002001d0000002401100370000000000101043b000000000010043f000000ff01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a00000ad20210019800000e480000c13d00000b0901000041000000000010043f000000040000043f00000ae50100004100002a0b00010430000000a40020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000402100370000000000202043b001200000002001d0000002402100370000000000202043b001100000002001d00000ad20020009c000024960000213d0000004402100370000000000202043b001000000002001d00000ad20020009c000024960000213d0000008402100370000000000202043b000d00000002001d0000006401100370000000000101043b000e00000001001d000000000100041100000ad201100197000f00000001001d000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000007400000613d000000140100008a00000000011000310000000101100367000000000101043b000f0060001002780000000f01000029000000000010043f00000ada01000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff0010019000000d720000613d000000100000006b000000510000613d00000af701000041000000000010043f000000ff01000039000000200010043f00000af801000041000000000201041a000000400400043d000f00000004001d00000af9010000410000000000140435000000040140003900000afa03000041000000000031043500000a830040009c00000a830100004100000000010440190000004001100210000000000300041400000a830030009c00000a8303008041000000c003300210000000000113019f00000ae5011001c700000ad202200197000c00000002001d2a092a040000040f000000600310027000000a8303300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000f0b0000290000000f057000290000077d0000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000007790000c13d000000000006004b0000078a0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000016760000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900000ad90010009c00001e890000213d000000010020019000001e890000c13d000000400010043f000000200030008c000024960000413d00000000010b0433000b00000001001d000f00010010003e00000ee80000613d00000afb0100004100000000001004430000000c010000290000000400100443000000000100041400000a830010009c00000a8301008041000000c00110021000000afc011001c700008002020000392a092a040000040f0000000100200190000024980000613d000000000101043b000000000001004b000024960000613d000000400300043d00000024013000390000000f02000029000000000021043500000afd010000410000000000130435000000040130003900000afa02000041000000000021043500000a830030009c000a00000003001d00000a830100004100000000010340190000004001100210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000adc011001c70000000c020000292a0929ff0000040f000000010020019000001cd00000613d0000000a0100002900000ad90010009c00001e890000213d0000000a01000029000000400010043f00000adf010000410000000000100443000000000100041400000a830010009c00000a8301008041000000c00110021000000ade011001c70000800b020000392a092a040000040f0000000100200190000024980000613d000000000101043b000c00000001001d00000afe0010009c00001fcc0000413d00000b0501000041000000000010043f0000000c01000029000000040010043f00000ae50100004100002a0b00010430000000440020008c000024960000413d0000000003000416000000000003004b000024960000c13d0000000403100370000000000303043b001200000003001d0000002403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d001000040030003d0000001001100360000000000101043b001100000001001d00000ad90010009c000024960000213d00000011013000290000002401100039000000000021004b000024960000213d0000000001000411000000000010043f0000010001000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000f00000001001d000000000001004b0000025b0000613d0000001201000029000000000010043f0000010201000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000201043b0000000f01000029000000000010043f000e00000002001d0000000101200039000d00000001001d000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000000001004b000008540000c13d0000000e01000029000000000101041a000c00000001001d00000ad90010009c00001e890000213d0000000c0100002900000001011000390000000e02000029000000000012041b000000000020043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b0000000c011000290000000f02000029000000000021041b0000000e01000029000000000101041a000e00000001001d000000000020043f0000000d01000029000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b0000000e02000029000000000021041b000000400100043d000000200200003900000000022104360000001103000029000000000032043500000b72053001980000001f0630018f00000040031000390000000004530019000000100700002900000020077000390000000107700367000008670000613d000000000807034f0000000009030019000000008a08043c0000000009a90436000000000049004b000008630000c13d000000000006004b000008740000613d000000000557034f0000000306600210000000000704043300000000076701cf000000000767022f000000000505043b0000010006600089000000000565022f00000000056501cf000000000575019f00000000005404350000001104000029000000000343001900000000000304350000001f0340003900000b720230019700000b060020009c00000b0602008041000000600220021000000a830010009c00000a83010080410000004001100210000000000112019f000000000200041400000a830020009c00000a8302008041000000c002200210000000000121019f00000b070110009a0000800d02000039000000030300003900000b08040000410000000f0500002900000ee10000013d0000000001000416000000000001004b000024960000c13d000000800000043f00000ae90100004100002a0a0001042e000000640020008c000024960000413d0000000003000416000000000003004b000024960000c13d0000000403100370000000000303043b000e00000003001d0000002403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d001000040030003d0000001004100360000000000404043b001200000004001d00000ad90040009c000024960000213d0000001204000029000f0005004002180000000f033000290000002403300039000000000023004b000024960000213d0000004403100370000000000303043b000d00000003001d00000ad90030009c000024960000213d0000000d030000290000002303300039000000000023004b000024960000813d0000000d030000290000000403300039000000000131034f000000000101043b000c00000001001d00000ad90010009c000024960000213d0000000d0100002900000024011000390000000c030000290000000503300210001100000001001d000b00000003001d0000000001130019000000000021004b000024960000213d000000000100041100000ad201100197000a00000001001d000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000008dd0000613d000000140100008a00000000011000310000000101100367000000000101043b000a0060001002780000000a01000029000000000010043f00000ada01000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff001001900000196d0000c13d0000000a0100002900000d730000013d000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000101043b000000000010043f0000010201000039000000200010043f000000400200003900000000010000192a0929ea0000040f000000000101041a000000800010043f00000ae90100004100002a0a0001042e000000e40020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000002402100370000000000202043b001100000002001d0000000402100370000000000202043b001200000002001d0000004402100370000000000202043b001000000002001d00000ad20020009c000024960000213d0000006402100370000000000202043b000f00000002001d00000ad20020009c000024960000213d000000c402100370000000000202043b000c00000002001d000000a402100370000000000202043b000d00000002001d0000008401100370000000000101043b000b00000001001d000000000100041100000ad201100197000e00000001001d000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000009370000613d000000140100008a00000000011000310000000101100367000000000101043b000e0060001002780000000e01000029000000000010043f00000b5101000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000012dd0000c13d0000000e010000292a0926e80000040f001100000001001d00000b580100004100000d760000013d000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000201043b000000000002004b0000000001000039000000010100c039001200000002001d000000000012004b000024960000c13d000000000100041100000ad201100197001100000001001d000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff001001900000000002000411000009730000613d000000140100008a00000000011000310000000101100367000000000101043b00000060021002700000009701000039000000000101041a000000000121013f00000ad20010019800000f2a0000c13d000000c901000039000000000201041a000000ff0320018f000000120000006b000012070000c13d000000000003004b0000129d0000c13d000000400100043d000000440210003900000b6903000041000000000032043500000024021000390000001403000039000012970000013d000000640020008c000024960000413d0000000003000416000000000003004b000024960000c13d0000000403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d0000000404300039000000000441034f000000000404043b001200000004001d00000ad90040009c000024960000213d000b00240030003d000000120300002900000005033002100000000b03300029000000000023004b000024960000213d0000002403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d0000000404300039000000000441034f000000000404043b000a00000004001d00000ad90040009c000024960000213d000900240030003d0000000a0300002900000005033002100000000903300029000000000023004b000024960000213d0000004403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d0000000404300039000000000141034f000000000101043b001100000001001d00000ad90010009c000024960000213d000800240030003d000000110100002900000005011002100000000801100029000000000021004b000024960000213d000000c901000039000000000101041a000000ff00100190000011d10000c13d000000000100041100000ad201100197001000000001001d000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000009e00000613d000000140100008a00000000011000310000000101100367000000000101043b00100060001002780000001001000029000000000010043f00000aee01000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff0010019000001cdd0000c13d0000001001000029000004620000013d000000440020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000402100370000000000202043b001200000002001d0000002401100370000000000101043b001100000001001d00000ad20010009c000024960000213d0000001201000029000000000010043f0000006501000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d0000000002000411000000000101043b0000000101100039000000000301041a0000000001000031000000140010008c0000000001020019001000000003001d00000a2f0000413d00000ad201200197000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff0010019000000000020004110000000001020019000000100300002900000a2f0000613d000000140100008a00000000011000310000000101100367000000000101043b0000006001100270000f00000001001d000e00000002001d000000000030043f0000006501000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b0000000f0200002900000ad202200197000f00000002001d000000000020043f000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000014690000c13d0000000f010000292a0926e80000040f000f00000001001d00000010010000292a0927310000040f000000400400043d001200000004001d000000200240003900000ae7030000410000000000320435001100000001001d0000000f010000290000000013010434000f00000003001d0000003702400039001000000002001d2a0924a60000040f0000000f02000029000000100120002900000ae80200004100000000002104350000001102100039000000110100002900000d840000013d000000240020008c000024960000413d0000000003000416000000000003004b000024960000c13d0000000403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d0000000404300039000000000141034f000000000101043b000b00000001001d00000ad90010009c000024960000213d000a00240030003d0000000b0100002900000005011002100000000a01100029000000000021004b000024960000213d000000c901000039000000000101041a000000ff00100190000011d10000c13d000000000100041100000ad201100197001200000001001d000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff0010019000000a9c0000613d000000140100008a00000000011000310000000101100367000000000101043b00120060001002780000001201000029000000000010043f00000aee01000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000016820000c13d0000001201000029000004620000013d0000000001000416000000000001004b000024960000c13d000000c901000039000000000101041a000000ff001001900000000001000039000000010100c039000000800010043f00000ae90100004100002a0a0001042e000000640020008c000024960000413d0000000003000416000000000003004b000024960000c13d0000000403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d0000000404300039000000000441034f000000000404043b001200000004001d00000ad90040009c000024960000213d001100240030003d000000120300002900000005033002100000001103300029000000000023004b000024960000213d0000002403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d0000000404300039000000000441034f000000000404043b001000000004001d00000ad90040009c000024960000213d000f00240030003d000000100300002900000005033002100000000f03300029000000000023004b000024960000213d0000004403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d0000000404300039000000000141034f000000000101043b000e00000001001d00000ad90010009c000024960000213d000d00240030003d0000000e0100002900000005011002100000000d01100029000000000021004b000024960000213d0000000001000411000b00000001001d00000ad201100197000c00000001001d000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff001001900000000c0100002900000b120000613d000000140100008a00000000011000310000000101100367000000000101043b0000006001100270000000000010043f00000ada01000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff0010019000000b6d0000c13d0000000001000031000000140010008c0000000c0100002900000b3d0000413d0000000c01000029000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff001001900000000c0100002900000b3d0000613d000000140100008a00000000011000310000000101100367000000000101043b0000006001100270000000000010043f00000aee01000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff0010019000000b6d0000c13d0000009701000039000000000101041a000a00000001001d0000000001000031000000140010008c00000b690000413d0000000c01000029000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff0010019000000b690000613d000000140100008a00000000011000310000000101100367000000000101043b000b0060001002780000000a020000290000000b0120014f00000ad20010019800000cd10000c13d000000110100002900000012020000290000000f0300002900000010040000290000000d050000290000000e060000292a0928f90000040f000000000100001900002a0a0001042e0000000001000416000000000001004b000024960000c13d0000009701000039000000000101041a00000ad201100197000000800010043f00000ae90100004100002a0a0001042e000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000101043b001200000001001d00000ad20010009c000024960000213d0000001201000029000000000010043f000000fd01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a00000ad20110019800000f5e0000c13d00000af601000041000000000010043f00000af00100004100002a0b00010430000000240020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000401100370000000000201043b00000b6e00200198000024960000c13d000000010100003900000b6f0020009c00000b7c0000613d00000b700020009c00000b7c0000613d00000b710020009c000000000100c019000000800010043f00000ae90100004100002a0a0001042e000000840020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000402100370000000000502043b00000ad20050009c000024960000213d0000002402100370000000000202043b00000ad20020009c000024960000213d0000006403100370000000000403043b0000004401100370000000000301043b00000000010500192a0925190000040f0000002002000039000000400300043d001200000003001d00000000022304362a0924b30000040f000000120200002900000f210000013d000000440020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000402100370000000000202043b001200000002001d0000002401100370000000000101043b001100000001001d00000ad20010009c000024960000213d000000000100041100000ad201100197001000000001001d000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff0010019000000bf00000613d000000140100008a00000000011000310000000101100367000000000101043b00100060001002780000001001000029000000000010043f00000b5d01000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000012740000c13d00000010010000292a0926e80000040f001100000001001d00000b200100004100000d760000013d000000440020008c000024960000413d0000000003000416000000000003004b000024960000c13d0000000403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d0000000404300039000000000441034f000000000404043b000f00000004001d00000ad90040009c000024960000213d000e00240030003d0000000f0300002900000005033002100000000e04300029000000000024004b000024960000213d0000002404100370000000000404043b00000ad90040009c000024960000213d0000002305400039000000000025004b000024960000813d0000000405400039000000000151034f000000000101043b000d00000001001d00000ad90010009c000024960000213d000c00240040003d0000000d0100002900000005011002100000000c01100029000000000021004b000024960000213d0000003f0130003900000b2c0110019700000b2d0010009c00001e890000213d0000008001100039000000400010043f0000000f02000029000000800020043f000000000002004b000018710000c13d00000020020000390000000003210436000000800200043d0000000000230435000000400310003900000005042002100000000007340019000000000002004b000019500000c13d00000000021700490000125e0000013d000000440020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000402100370000000000202043b001200000002001d0000002401100370000000000101043b001100000001001d00000ad20010009c000024960000213d000000000100041100000ad201100197001000000001001d000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000000100100002900000c6c0000613d000000140100008a00000000011000310000000101100367000000000101043b0000006001100270000000000010043f00000ada01000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000011db0000c13d0000000001000031000000140010008c000000100100002900000c970000413d0000001001000029000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000000100100002900000c970000613d000000140100008a00000000011000310000000101100367000000000101043b0000006001100270000000000010043f00000aee01000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000011db0000c13d0000000001000031000000140010008c00000cc00000413d0000001001000029000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff0010019000000cc00000613d000000140100008a00000000011000310000000101100367000000000101043b00100060001002780000001001000029000000000010043f00000b1301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000011db0000c13d2a09277a0000040f00000b4f02000041000000000020043f00000ad201100197000000040010043f00000ae601000041000000240010043f00000adc0100004100002a0b00010430000000440020008c000024960000413d0000000003000416000000000003004b000024960000c13d0000000403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d0000000404300039000000000441034f000000000404043b001000000004001d00000ad90040009c000024960000213d000f00240030003d000000100300002900000005033002100000000f04300029000000000024004b000024960000213d0000002404100370000000000404043b00000ad90040009c000024960000213d0000002305400039000000000025004b000024960000813d0000000405400039000000000551034f000000000505043b000e00000005001d00000ad90050009c000024960000213d000d00240040003d0000000e0400002900000005044002100000000d04400029000000000024004b000024960000213d0000003f0430003900000b2c0440019700000b2d0040009c00001e890000213d0000008004400039000000400040043f0000001004000029000000800040043f0000001f0430018f000000000003004b00000d170000613d000000000121034f000000a002300039000000a003000039000000001501043c0000000003530436000000000023004b00000d130000c13d000000000004004b000000100000006b0000190d0000c13d000000400100043d00000020020000390000000002210436000000800300043d00000000003204350000004002100039000000000003004b0000125d0000613d0000000004000019000000800600003900000020066000390000000005060433000000000005004b0000000005000039000000010500c03900000000025204360000000104400039000000000034004b00000d240000413d0000125d0000013d000000c40020008c000024960000413d0000000002000416000000000002004b000024960000c13d0000000402100370000000000202043b001200000002001d0000002402100370000000000202043b001100000002001d00000ad20020009c000024960000213d0000004402100370000000000202043b001000000002001d00000ad20020009c000024960000213d000000a402100370000000000202043b000c00000002001d0000008402100370000000000202043b000d00000002001d0000006401100370000000000101043b000e00000001001d000000000100041100000ad201100197000f00000001001d000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff0010019000000d610000613d000000140100008a00000000011000310000000101100367000000000101043b000f0060001002780000000f01000029000000000010043f00000ada01000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000013df0000c13d0000000f010000292a0926e80000040f001100000001001d00000ae6010000412a0927310000040f000000400400043d001200000004001d000000200240003900000ae7030000410000000000320435001000000001001d000000370240003900000011010000292a09250b0000040f00000ae8020000410000000000210435000000110210003900000010010000292a09250b0000040f00000012030000290000000002310049000000200120008a000000000013043500000000010300192a0924f90000040f00000ad701000041000000400200043d001100000002001d0000000000120435000000040120003900000012020000292a0924c50000040f0000001102000029000000000121004900000a830010009c00000a8301008041000000600110021000000a830020009c00000a83020080410000004002200210000000000121019f00002a0b00010430000000640020008c000024960000413d0000000003000416000000000003004b000024960000c13d0000002403100370000000000303043b001100000003001d0000000403100370000000000303043b001200000003001d0000004403100370000000000303043b00000ad90030009c000024960000213d0000002304300039000000000024004b000024960000813d000f00040030003d0000000f01100360000000000101043b001000000001001d00000ad90010009c000024960000213d00000010013000290000002401100039000000000021004b000024960000213d000000000100041100000ad201100197000e00000001001d000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff0010019000000dd00000613d000000140100008a00000000011000310000000101100367000000000101043b000e0060001002780000000e01000029000000000010043f00000ada01000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000016530000c13d0000000e0100002900000d730000013d000000400100043d000000440210003900000b4c03000041000000000032043500000ad70200004100000000002104350000002402100039000000200300003900000000003204350000000402100039000000000032043500000a830010009c00000a8301008041000000400110021000000b41011001c700002a0b000104300000000001000415000000140110008a0000000501100210001400000000003d001100000001001d000f00000002001d00000afb01000041000000000010044300000000010004100000000400100443000000000100041400000a830010009c00000a8301008041000000c00110021000000afc011001c700008002020000392a092a040000040f0000000100200190000024980000613d000000000101043b000000000001004b0000100c0000c13d0000000f01000029000000ff0110018f000000010010008c00000011010000290000000501100270000000000100003f000000010100603f0000100f0000c13d000000000200041a00000b730120019700000001011001bf000000100000006b0000ff010200608a000000000121616f00000100011061bf000000000010041b0000ff00001001900000102b0000c13d000000400100043d000000640210003900000b2a030000410000000000320435000000440210003900000b2b03000041000000000032043500000024021000390000002b03000039000010180000013d000000000010043f000000fd01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000400200043d00000b2e0020009c00001e890000213d000000000101043b0000004003200039000000400030043f000000000301041a00000ad203300198001000000003001d00000000023204360000000101100039000000000101041a001100000001001d0000000000120435000012c80000c13d000000400100043d0000001202000029000000000021043500000a830010009c00000a8301008041000000400110021000000ae3011001c700002a0a0001042e000000400400043d00000aea01000041000000000014043500000004014000390000001203000029000000000031043500000a830040009c001200000004001d00000a830100004100000000010440190000004001100210000000000300041400000a830030009c00000a8303008041000000c003300210000000000113019f00000ae5011001c72a092a040000040f00000060031002700000001f0430018f00000aeb0530019700000a8303300197000000010020019000000eee0000613d00000012090000290000000002590019000000000005004b00000e6a0000613d000000000601034f0000000007090019000000006806043c0000000007870436000000000027004b00000e660000c13d000000000004004b00000e770000613d000000000151034f0000000304400210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001204350000001f0130003900000aec011001970000000002910019000000000012004b0000000001000039000000010100403900000ad90020009c00001e890000213d000000010010019000001e890000c13d000000400020043f000000200030008c000024960000413d000000000109043300000ad90010009c000024960000213d000000000493001900000000019100190000001f03100039000000000043004b000000000500001900000ae00500804100000ae00330019700000ae006400197000000000763013f000000000063004b000000000300001900000ae00300404100000ae00070009c000000000305c019000000000003004b000024960000c13d000000003101043400000ad90010009c00001e890000213d0000001f0510003900000b72055001970000003f0550003900000b7205500197000000000525001900000ad90050009c00001e890000213d000000400050043f00000000051204360000000006310019000000000046004b000024960000213d000000000001004b00000eb00000613d000000000400001900000000065400190000000007340019000000000707043300000000007604350000002004400039000000000014004b00000ea90000413d00000000015100190000000000010435000000400100043d001200000001001d2a0924c50000040f00000bc90000013d001100000001001d0000001201000029000000000010043f0000010201000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000201043b0000001101000029000000000010043f001000000002001d0000000101200039000f00000001001d000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000000001004b000013b00000c13d000000000100041400000a830010009c00000a8301008041000000c00110021000000ae1011001c70000800d02000039000000030300003900000b6b04000041000000110500002900000012060000290000004e0000013d0000010101000039000000000201041a00000aed0320019700000aed0030009c000010230000c13d00000b6a01000041000000000010043f0000001101000039000000040010043f00000ae50100004100002a0b00010430000000400200043d0000000006520019000000000005004b00000ef80000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000068004b00000ef40000c13d000000000004004b000019a00000613d000000000151034f0000000304400210000000000506043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000160435000019a00000013d000000400100043d000000640210003900000b59030000410000000000320435000000440210003900000b5a03000041000000000032043500000024021000390000002f03000039000010180000013d000000000101043b00000000020000190000001104000029000000000301041a000000000434043600000001011000390000000102200039000000000052004b00000f130000413d000000120100002900000000021400492a0924f90000040f000000400100043d001100000001001d00000012020000292a0924da0000040f0000001102000029000000000121004900000a830010009c00000a8301008041000000600110021000000a830020009c00000a83020080410000004002200210000000000121019f00002a0a0001042e0000000001000031000000140010008c000000110100002900000f450000413d0000001101000029000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000000110100002900000f450000613d000000140100008a00000000011000310000000101100367000000000101043b0000006001100270000000000010043f00000b6701000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000009780000c13d2a09277a0000040f00000b4f02000041000000000020043f00000ad201100197000000040010043f00000b1601000041000000240010043f00000adc0100004100002a0b00010430001100000001001d00000000030004110000000001000031000000140010008c000000000103001900000f7c0000413d00000ad201300197000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff001001900000000003000411000000000103001900000f7c0000613d000000140100008a00000000011000310000000101100367000000000101043b000000600110027000000ad201100197000000120010006b00000f9d0000613d0000000001000031000000140010008c001000000003001d00000f990000413d00000ad201300197000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff0010019000000f990000613d000000140100008a00000000011000310000000101100367000000000101043b0010006000100278000000100100002900000ad201100197000000110010006b000014cd0000c13d0000001201000029000000000010043f000000fd01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000001041b0000000101100039000000000001041b0000001101000029000000000010043f000000fe01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000201043b0000001201000029000000000010043f001000000002001d0000000101200039000f00000001001d000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000e00000001001d000000000001004b00000b9a0000613d0000001001000029000000000101041a000d00000001001d000000000001004b00000ee80000613d0000000d020000290000000e0020006c000019a60000c13d0000001001000029000000000010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c700008010020000392a092a040000040f0000000100200190000024960000613d0000000e02000029000000010220008a000000000101043b0000000001210019000000000001041b0000001001000029000000000021041b0000001201000029000000000010043f0000000f01000029000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000001041b000000400100043d0000002002100039000000110300002900000000003204350000001202000029000000000021043500000a830010009c00000a83010080410000004001100210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000ad4011001c70000800d02000039000000010300003900000af504000041000012c70000013d00000011010000290000000501100270000000000100003f000000400100043d000000640210003900000b0f030000410000000000320435000000440210003900000b1003000041000000000032043500000024021000390000002e03000039000000000032043500000ad702000041000000000021043500000004021000390000002003000039000000000032043500000a830010009c00000a8301008041000000400110021000000ad8011001c700002a0b0001043000000af1022001970000000103300039000000000223019f000000000021041b000000a0013002100000000002000410000000000112019f0000055b0000013d00000000020004110000000001000031000000140010008c0000000001020019000010480000413d00000ad201200197000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff0010019000000000020004110000000001020019000010480000613d000000140100008a00000000011000310000000101100367000000000101043b0000006001100270001100000002001d00000ad2061001970000009703000039000000000103041a00000b1102100197000000000262019f000000000023041b000000000200041400000ad20510019700000a830020009c00000a8302008041000000c00120021000000ae1011001c70000800d02000039000000030300003900000b12040000412a0929ff0000040f0000000100200190000024960000613d000000000100041a0000ff000010019000000e1b0000613d000000c902000039000000000102041a00000b7301100197000000000012041b0000009703000039000000000103041a00000b11021001970000001206000029000000000262019f000000000023041b000000000200041400000ad20510019700000a830020009c00000a8302008041000000c00120021000000ae1011001c70000800d02000039000000030300003900000b12040000412a0929ff0000040f0000000100200190000024960000613d0000001201000029000000000010043f00000b1301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000010c00000c13d0000001201000029000000000010043f00000b1301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000201041a00000b730220019700000001022001bf000000000021041b0000000001000031000000140010008c0000000001000411000010b20000413d00000ad201100197000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff001001900000000001000411000010b20000613d000000140100008a00000000011000310000000101100367000000000101043b0000006001100270000000000200041400000a830020009c00000a830200804100000ad207100197000000c00120021000000ae1011001c70000800d02000039000000040300003900000b1404000041000000000500001900000012060000292a0929ff0000040f0000000100200190000024960000613d00000b1501000041000000000601041a00000b1602000041000000000020043f0000006502000039000000200020043f000000000001041b000000000100041400000a830010009c00000a8301008041000000c00110021000000ae1011001c70000800d02000039000000040300003900000b170400004100000b160500004100000000070000192a0929ff0000040f0000000100200190000024960000613d00000b1801000041000000000601041a00000b1902000041000000000020043f0000006502000039000000200020043f000000000001041b000000000100041400000a830010009c00000a8301008041000000c00110021000000ae1011001c70000800d02000039000000040300003900000b170400004100000b190500004100000000070000192a0929ff0000040f0000000100200190000024960000613d00000b1a01000041000000000601041a00000b1b02000041000000000020043f0000006502000039000000200020043f000000000001041b000000000100041400000a830010009c00000a8301008041000000c00110021000000ae1011001c70000800d02000039000000040300003900000b170400004100000b1b0500004100000000070000192a0929ff0000040f0000000100200190000024960000613d00000b1c01000041000000000601041a00000b1d02000041000000000020043f0000006502000039000000200020043f000000000001041b000000000100041400000a830010009c00000a8301008041000000c00110021000000ae1011001c70000800d02000039000000040300003900000b170400004100000b1d0500004100000000070000192a0929ff0000040f0000000100200190000024960000613d00000b1e01000041000000000601041a00000af202000041000000000020043f0000006502000039000000200020043f000000000001041b000000000100041400000a830010009c00000a8301008041000000c00110021000000ae1011001c70000800d02000039000000040300003900000b170400004100000af20500004100000000070000192a0929ff0000040f0000000100200190000024960000613d00000b1f01000041000000000601041a00000b2002000041000000000020043f0000006502000039000000200020043f000000000001041b000000000100041400000a830010009c00000a8301008041000000c00110021000000ae1011001c70000800d02000039000000040300003900000b170400004100000b200500004100000000070000192a0929ff0000040f0000000100200190000024960000613d00000b2101000041000000000601041a00000b2202000041000000000020043f0000006502000039000000200020043f000000000001041b000000000100041400000a830010009c00000a8301008041000000c00110021000000ae1011001c70000800d02000039000000040300003900000b170400004100000b220500004100000000070000192a0929ff0000040f0000000100200190000024960000613d00000b2301000041000000000601041a00000b2402000041000000000020043f0000006502000039000000200020043f000000000001041b000000000100041400000a830010009c00000a8301008041000000c00110021000000ae1011001c70000800d02000039000000040300003900000b170400004100000b240500004100000000070000192a0929ff0000040f0000000100200190000024960000613d00000b2501000041000000000601041a00000b2602000041000000000020043f0000006502000039000000200020043f000000000001041b000000000100041400000a830010009c00000a8301008041000000c00110021000000ae1011001c70000800d02000039000000040300003900000b170400004100000b260500004100000000070000192a0929ff0000040f0000000100200190000024960000613d00000b2701000041000000000601041a00000ae602000041000000000020043f0000006502000039000000200020043f000000000001041b000000000100041400000a830010009c00000a8301008041000000c00110021000000ae1011001c70000800d02000039000000040300003900000b170400004100000ae60500004100000000070000192a0929ff0000040f0000000100200190000024960000613d000000c901000039000000000101041a000000ff00100190000012910000c13d00000b730110019700000001011001bf000000c902000039000000000012041b0000000001000031000000140010008c000011aa0000413d000000000100041100000ad201100197000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000011aa0000613d000000140100008a00000000011000310000000101100367000000000101043b0011006000100278000000110100002900000ad201100197000000400200043d000000000012043500000a830020009c00000a83020080410000004001200210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000af4011001c70000800d02000039000000010300003900000b28040000412a0929ff0000040f0000000100200190000024960000613d000000100000006b000000510000c13d000000000200041a00000b7401200197000000000010041b000000400100043d0000000103000039000000000031043500000a830010009c00000a83010080410000004001100210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000af4011001c70000800d0200003900000b2904000041000012c70000013d00000ad701000041000000800010043f0000002001000039000000840010043f0000001001000039000000a40010043f00000b6301000041000000c40010043f00000b640100004100002a0b000104300000001201000029000000000010043f000000ff01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000201041a00000b11022001970000001103000029000000000232019f000000000021041b000000000030043f0000010001000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b0000001205000029000000000051041b000000000100041400000a830010009c00000a8301008041000000c00110021000000ae1011001c70000800d02000039000000030300003900000b4e0400004100000011060000290000004e0000013d000000000003004b000012910000c13d00000b730220019700000001022001bf000000000021041b0000000001000031000000140010008c000012250000413d0000001101000029000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000012250000613d000000140100008a00000000011000310000000101100367000000000101043b0011006000100278000000400100043d0000001102000029000000000021043500000a830010009c00000a83010080410000004001100210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000af4011001c70000800d02000039000000010300003900000b2804000041000012c70000013d2a0928e40000040f000000000100001900002a0a0001042e000000000101043b000000000200001900000012060000290000001104000029000000000301041a000000000434043600000001011000390000000102200039000000000052004b0000123c0000413d00000000016400490000001f0110003900000b72021001970000000001620019000000000021004b0000000002000039000000010200403900000ad90010009c00001e890000213d000000010020019000001e890000c13d000000400010043f00000020020000390000000002210436000000000306043300000000003204350000004002100039000000000003004b0000125d0000613d00000000040000190000002006600039000000000506043300000ad20550019700000000025204360000000104400039000000000034004b000012560000413d000000000212004900000a830020009c00000a8302008041000000600220021000000a830010009c00000a83010080410000004001100210000000000112019f00002a0a0001042e0000010301000039000000000201041a000000ff00200190000013db0000c13d00000b730220019700000001022001bf000000000021041b0000010101000039000000000201041a00000af10220019700000012022001af000000000021041b000000000100001900002a0a0001042e0000001201000029000000000010043f000000fc01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000201041a00000b11022001970000001106000029000000000262019f000000000021041b000000000100041400000a830010009c00000a8301008041000000c00110021000000ae1011001c70000800d02000039000000030300003900000b5e0400004100000012050000290000004e0000013d000000400100043d000000440210003900000b6303000041000000000032043500000024021000390000001003000039000000000032043500000ad70200004100000000002104350000000402100039000000200300003900000ded0000013d00000b7302200197000000000021041b0000000001000031000000140010008c000012b80000413d0000001101000029000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000012b80000613d000000140100008a00000000011000310000000101100367000000000101043b0011006000100278000000400100043d0000001102000029000000000021043500000a830010009c00000a83010080410000004001100210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000af4011001c70000800d02000039000000010300003900000b68040000410000004e0000013d00000add010000410000000000100443000000000100041400000a830010009c00000a8301008041000000c00110021000000ade011001c70000800b020000392a092a040000040f0000000100200190000024980000613d000000000101043b000000110000006b000017df0000613d000000110010006b001200100000002d00000e400000813d00000b2f01000041000000000010043f00000af00100004100002a0b0001043000000b5201000041000000000010043f000000ff01000039000000200010043f00000b5301000041000000000201041a000000400400043d000e00000004001d00000af901000041000000000014043500000004014000390000000f03000029000000000031043500000a830040009c00000a830100004100000000010440190000004001100210000000000300041400000a830030009c00000a8303008041000000c003300210000000000113019f00000ae5011001c700000ad2022001972a092a040000040f000000600310027000000a8303300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000e0b0000290000000e05700029000013060000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000013020000c13d000000000006004b000013130000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000015510000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900000ad90010009c00001e890000213d000000010020019000001e890000c13d000000400010043f000000200030008c000024960000413d00000000010b0433000e00000001001d00000adf010000410000000000100443000000000100041400000a830010009c00000a8301008041000000c00110021000000ade011001c70000800b020000392a092a040000040f0000000100200190000024980000613d000000000101043b0000000e0010006b00001a3c0000c13d0000001201000029000000000010043f0000010401000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000201041a000000ff0020019000001c470000c13d00000b730220019700000001022001bf000000000021041b0000001101000029000000000010043f000000fc01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a00000ad2001001980000154b0000613d0000001101000029000000000010043f000000fc01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a00000afb02000041000000000020044300000ad201100197000e00000001001d0000000400100443000000000100041400000a830010009c00000a8301008041000000c00110021000000afc011001c700008002020000392a092a040000040f0000000100200190000024980000613d000000000101043b000000000001004b000024960000613d000000400300043d00000044013000390000000c02000029000000000021043500000024013000390000000d02000029000000000021043500000b6c010000410000000001130436000800000001001d00000004013000390000000f02000029000000000021043500000a830030009c000a00000003001d00000a830100004100000000010340190009004000100218000000000100041400000a830010009c00000a8301008041000000c00110021000000009011001af00000b41011001c70000000e020000292a0929ff0000040f0000000100200190000020640000613d0000000a0100002900000ad90010009c00001e890000213d0000000a03000029000000400030043f00000060013000390000000c02000029000000000021043500000040013000390000000d0200002900000000002104350000000b010000290000000802000029000000000012043500000012010000290000000000130435000000000100041400000a830010009c00000a8301008041000000c00110021000000009011001af00000b31011001c70000800d02000039000000040300003900000b6d04000041000000110500002900000010060000290000000f070000290000004e0000013d000e00000001001d0000001001000029000000000101041a000d00000001001d000000000001004b00000ee80000613d0000000d020000290000000e0020006c000017590000c13d0000001001000029000000000010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c700008010020000392a092a040000040f0000000100200190000024960000613d0000000e02000029000000010220008a000000000101043b0000000001210019000000000001041b0000001001000029000000000021041b0000001101000029000000000010043f0000000f01000029000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000001041b00000ed80000013d00000aef01000041000000000010043f00000af00100004100002a0b00010430000000100000006b000000510000613d00000af701000041000000000010043f000000ff01000039000000200010043f00000af801000041000000000201041a000000400400043d000f00000004001d00000af9010000410000000000140435000000040140003900000afa03000041000000000031043500000a830040009c00000a830100004100000000010440190000004001100210000000000300041400000a830030009c00000a8303008041000000c003300210000000000113019f00000ae5011001c700000ad202200197000b00000002001d2a092a040000040f000000600310027000000a8303300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000f0b0000290000000f057000290000140b0000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000014070000c13d000000000006004b000014180000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000017990000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900000ad90010009c00001e890000213d000000010020019000001e890000c13d000000400010043f000000200030008c000024960000413d00000000010b0433000a00000001001d000f00010010003e00000ee80000613d00000afb0100004100000000001004430000000b010000290000000400100443000000000100041400000a830010009c00000a8301008041000000c00110021000000afc011001c700008002020000392a092a040000040f0000000100200190000024980000613d000000000101043b000000000001004b000024960000613d000000400300043d00000024013000390000000f02000029000000000021043500000afd010000410000000000130435000000040130003900000afa02000041000000000021043500000a830030009c000900000003001d00000a830100004100000000010340190000004001100210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000adc011001c70000000b020000292a0929ff0000040f000000010020019000001db50000613d000000090100002900000ad90010009c00001e890000213d0000000901000029000000400010043f00000adf010000410000000000100443000000000100041400000a830010009c00000a8301008041000000c00110021000000ade011001c70000800b020000392a092a040000040f0000000100200190000024980000613d000000000101043b000b00000001001d00000afe0010009c00001ffb0000413d00000b050100004100001b5a0000013d0000001201000029000000000010043f0000006501000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b0000001102000029000000000020043f000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000000510000c13d0000001201000029000000000010043f0000006501000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b0000001102000029000000000020043f000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000201041a00000b730220019700000001022001bf000000000021041b0000000001000031000000140010008c000014c00000413d000000000100041100000ad201100197000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000ff00100190000014c00000613d000000140100008a00000000011000310000000101100367000000000101043b000e006000100278000000000100041400000a830010009c00000a8301008041000000c0011002100000000e0200002900000ad20720019700000ae1011001c70000800d02000039000000040300003900000b1404000041000000120500002900000011060000290000004e0000013d00000af301000041000000000010043f00000af00100004100002a0b0001043000000b5201000041000000000010043f000000ff01000039000000200010043f00000b5301000041000000000201041a000000400400043d000b00000004001d00000af901000041000000000014043500000004014000390000000f03000029000000000031043500000a830040009c00000a830100004100000000010440190000004001100210000000000300041400000a830030009c00000a8303008041000000c003300210000000000113019f00000ae5011001c700000ad2022001972a092a040000040f000000600310027000000a8303300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000b0b0000290000000b05700029000014fa0000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000014f60000c13d000000000006004b000015070000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f000000000065043500000001002001900000166a0000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900000ad90010009c00001e890000213d000000010020019000001e890000c13d000000400010043f000000200030008c000024960000413d00000000010b0433000b00000001001d00000adf010000410000000000100443000000000100041400000a830010009c00000a8301008041000000c00110021000000ade011001c70000800b020000392a092a040000040f0000000100200190000024980000613d000000000101043b0000000b0010006b00001b590000c13d0000001201000029000000000010043f0000010401000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000201041a000000ff0020019000001c470000c13d00000b730220019700000001022001bf000000000021041b0000001101000029000000000010043f000000fc01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a00000ad20010019800001e9b0000c13d00000b3001000041000000000010043f0000001101000029000000040010043f00000ae50100004100002a0b000104300000001f0530018f00000aeb06300198000000400200043d0000000004620019000019930000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000015580000c13d000019930000013d00008010030000390000000002000019000015650000013d000000100200002900000001022000390000000d0020006c0000801003000039000002950000813d001000000002001d00000005012002100000000c011000290000000101100367000000000101043b000000000010043f0000010201000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700000000020300192a092a040000040f0000000100200190000024960000613d000000000201043b0000000e01000029000000000010043f001200000002001d0000000101200039000f00000001001d000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d0000001203000029000000000101043b000000000101041a000000000001004b000015600000613d000000000403041a000000000004004b000080100200003900000ee80000613d000000000014004b001100000001001d000015cb0000613d000b00000004001d000000000030043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c72a092a040000040f0000000100200190000024960000613d0000001102000029000a000100200092000000000101043b0000001204000029000000000204041a0000000a0020006c000019e10000a13d0000000b02000029000000010220008a0000000001120019000000000101041a000b00000001001d000000000040043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b0000000a011000290000000b02000029000000000021041b000000000020043f0000000f01000029000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b0000001102000029000000000021041b0000001203000029000000000103041a001100000001001d000000000001004b0000801002000039000017930000613d000000000030043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c72a092a040000040f0000000100200190000024960000613d0000001102000029000000010220008a000000000101043b0000000001210019000000000001041b0000001201000029000000000021041b0000000e01000029000000000010043f0000000f01000029000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000001041b000015600000013d000c0ad20010019b000000400500043d0000000004000019001200000000001d000015f80000013d00000000050100190000001203000029001200000003001d00000001044000390000000f010000290000000001010433000000000014004b000003970000813d001100000005001d001000000004001d00000005014002100000000d01100029000e00000001001d000000000101043300000af90200004100000000002504350000000402500039000000000012043500000a830050009c00000a830100004100000000010540190000004001100210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000ae5011001c70000000c020000292a092a040000040f000000110a000029000000600310027000000a8303300197000000200030008c00000020040000390000000004034019000000200640019000000000056a00190000161d0000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000058004b000016190000c13d0000001f074001900000162a0000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f00000000006504350000000100200190000019440000613d0000001f01400039000000600210018f0000000001a20019000000000021004b0000000002000039000000010200403900000ad90010009c00001e890000213d000000010020019000001e890000c13d000000400010043f000000200030008c0000001004000029000024960000413d00000000020a0433000000000002004b0000000003000039000000010300c039000000000032004b000024960000c13d000000000002004b000015f00000c13d0000000f010000290000000001010433000000000041004b0000001203000029000019e10000a13d0000000b010000290000000001010433000000000031004b000019e10000a13d00000005013002100000000a011000290000000e02000029000000000202043300000000002104350000000103300039000000400500043d000015f20000013d0000001201000029000000000010043f000000ff01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a00000ad200100198000017e50000c13d00000ae401000041000000000010043f0000001201000029000000040010043f00000ae50100004100002a0b000104300000001f0530018f00000aeb06300198000000400200043d0000000004620019000019930000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000016710000c13d000019930000013d0000001f0530018f00000aeb06300198000000400200043d0000000004620019000019930000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000167d0000c13d000019930000013d0000000b0000006b000000510000613d001000000000001d000000100100002900000005011002100000000a01100029001200000001001d0000000101100367000000000101043b00000ad20010009c000024960000213d000000000010043f000000fd01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a001100000001001d00000012010000290000000101100367000000000101043b00000ad20010009c000024960000213d000000000010043f000000fd01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000110200002900000ad202200197000000000101043b000000000001041b0000000101100039000000000001041b000d00000002001d000000000020043f000000fe01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000301043b00000012010000290000000101100367000000000101043b000f00000001001d00000ad20010009c000024960000213d0000000f01000029000000000010043f0000000101300039000c00000001001d000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c70000801002000039001100000003001d2a092a040000040f00000011030000290000000100200190000024960000613d000000000101043b000000000101041a000000000001004b0000173a0000613d000000000203041a000000000002004b00000ee80000613d000000000012004b000e00000001001d0000171a0000613d000900000002001d000000000030043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c700008010020000392a092a040000040f00000011030000290000000100200190000024960000613d0000000e020000290008000100200092000000000101043b000000000203041a000000080020006c000019e10000a13d0000000902000029000000010220008a0000000001120019000000000101041a000900000001001d000000000030043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b00000008011000290000000902000029000000000021041b000000000020043f0000000c01000029000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f00000011030000290000000100200190000024960000613d000000000101043b0000000e02000029000000000021041b000000000103041a000e00000001001d000000000001004b000017930000613d000000000030043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c700008010020000392a092a040000040f00000011030000290000000100200190000024960000613d0000000e02000029000000010220008a000000000101043b0000000001210019000000000001041b000000000023041b0000000f01000029000000000010043f0000000c01000029000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000001041b00000012010000290000000101100367000000000101043b00000ad20010009c000024960000213d000000400200043d00000020032000390000000d040000290000000000430435000000000012043500000a830020009c00000a83020080410000004001200210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000ad4011001c70000800d02000039000000010300003900000af5040000412a0929ff0000040f0000000100200190000024960000613d00000010020000290000000102200039001000000002001d0000000b0020006c000016850000413d000000510000013d0000001001000029000000000010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c700008010020000392a092a040000040f0000000100200190000024960000613d0000000e02000029000c000100200092000000000101043b0000001002000029000000000202041a0000000c0020006c000019e10000a13d0000000d02000029000000010220008a0000000001120019000000000101041a000d00000001001d0000001001000029000000000010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b0000000c011000290000000d02000029000000000021041b000000000020043f0000000f01000029000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b0000000e02000029000000000021041b0000001001000029000000000101041a000e00000001001d000000000001004b000013b90000c13d00000b6a01000041000000000010043f0000003101000039000000040010043f00000ae50100004100002a0b000104300000001f0530018f00000aeb06300198000000400200043d0000000004620019000019930000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000017a00000c13d000019930000013d0000001202000029000000100020006c000019800000c13d000000100000006b000019e70000c13d000000400200043d00000040010000390000000004120436000e00000002001d00000040012000390000001002000029000000000021043500000b0d0020009c000024960000213d000000010200036700000008010000290000001f0510018f0000000e0300002900000060063000390000000003160019000000000001004b000017c20000613d0000000a010000290000002001100039000000000712034f000000007107043c0000000006160436000000000036004b000017be0000c13d000000000005004b0000000e0130006a0000000000140435000000100400002900000000004304350000000701300029000000200b100039000000000004004b00001c490000c13d0000000e0200002900000000012b004900000a830010009c00000a8301008041000000600110021000000a830020009c00000a83020080410000004002200210000000000121019f000000000200041400000a830020009c00000a8302008041000000c002200210000000000121019f00000ae1011001c70000800d02000039000000020300003900000b4d040000410000000f05000029000012c70000013d001200100000002d00000e400000013d00000b3301000041000000000010043f00000af00100004100002a0b0001043000000af701000041000000000010043f000000ff01000039000000200010043f00000af801000041000000000201041a000000400400043d000e00000004001d00000af9010000410000000000140435000000040140003900000afa03000041000000000031043500000a830040009c00000a830100004100000000010440190000004001100210000000000300041400000a830030009c00000a8303008041000000c003300210000000000113019f00000ae5011001c700000ad202200197000d00000002001d2a092a040000040f000000600310027000000a8303300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000e0b0000290000000e057000290000180f0000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b0000180b0000c13d000000000006004b0000181c0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000019880000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900000ad90010009c00001e890000213d000000010020019000001e890000c13d000000400010043f000000200030008c000024960000413d00000000010b0433000c00000001001d000e00010010003e00000ee80000613d00000afb0100004100000000001004430000000d010000290000000400100443000000000100041400000a830010009c00000a8301008041000000c00110021000000afc011001c700008002020000392a092a040000040f0000000100200190000024980000613d000000000101043b000000000001004b000024960000613d000000400300043d00000024013000390000000e02000029000000000021043500000afd010000410000000000130435000000040130003900000afa02000041000000000021043500000a830030009c000b00000003001d00000a830100004100000000010340190000004001100210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000adc011001c70000000d020000292a0929ff0000040f000000010020019000001f6d0000613d0000000b0100002900000ad90010009c00001e890000213d0000000b01000029000000400010043f00000adf010000410000000000100443000000000100041400000a830010009c00000a8301008041000000c00110021000000ade011001c70000800b020000392a092a040000040f0000000100200190000024980000613d000000000101043b000d00000001001d00000afe0010009c000020710000413d00000b0501000041000000000010043f0000000d01000029000000040010043f00000ae50100004100002a0b0001043000000060010000390000000002000019000000a00420003900000000001404350000002002200039000000000032004b000018730000413d00000000030000190000000d0030006c000019e10000813d001000000003001d0000000502300210001200000002001d0000000c012000290000000101100367000000000101043b000000000010043f000000ff01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a00000ad2021001980000070b0000613d00000012030000290000000e013000290000000101100367000000000101043b000000400400043d00000aea0300004100000000003404350000000403400039000000000013043500000a830040009c001100000004001d00000a830100004100000000010440190000004001100210000000000300041400000a830030009c00000a8303008041000000c003300210000000000113019f00000ae5011001c72a092a040000040f00000060031002700000001f0430018f00000aeb0530019700000a8303300197000000010020019000001c9b0000613d00000011090000290000000002590019000000000005004b000018b60000613d000000000601034f0000000007090019000000006806043c0000000007870436000000000027004b000018b20000c13d000000000004004b000018c30000613d000000000151034f0000000304400210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001204350000001f0130003900000aec021001970000000001920019000000000021004b0000000002000039000000010200403900000ad90010009c00001e890000213d000000010020019000001e890000c13d000000400010043f000000200030008c000024960000413d000000000209043300000ad90020009c000024960000213d000000000493001900000000029200190000001f03200039000000000043004b000000000500001900000ae00500804100000ae00330019700000ae006400197000000000763013f000000000063004b000000000300001900000ae00300404100000ae00070009c000000000305c019000000000003004b000024960000c13d000000003202043400000ad90020009c00001e890000213d0000001f0520003900000b72055001970000003f0550003900000b7205500197000000000515001900000ad90050009c00001e890000213d000000400050043f00000000052104360000000006320019000000000046004b000024960000213d000000000002004b000018fc0000613d000000000400001900000000065400190000000007340019000000000707043300000000007604350000002004400039000000000024004b000018f50000413d00000000025200190000000000020435000000800200043d0000001003000029000000000032004b000019e10000a13d0000001202000029000000a0022000390000000000120435000000800100043d000000000031004b000019e10000a13d00000001033000390000000f0030006c000018790000413d000000400100043d00000c3b0000013d0000000003000019001200000003001d0000000502300210001100000002001d0000000f012000290000000101100367000000000101043b000000000010043f0000010201000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d00000012030000290000000e0030006c000019e10000813d00000011040000290000000d024000290000000102200367000000000202043b000000000101043b000000000020043f0000000101100039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000800200043d0000001203000029000000000032004b000019e10000a13d0000001102000029000000a002200039000000000101043b000000000101041a000000000001004b0000000001000039000000010100c03900000000001204350000000103300039000000100030006c0000190e0000413d00000d1a0000013d0000001f0530018f00000aeb06300198000000400200043d0000000004620019000019930000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000194b0000c13d000019930000013d000000800400003900000000060000190000195b0000013d0000001f0980003900000b72099001970000000008780019000000000008043500000000077900190000000106600039000000000026004b00000c440000813d0000000008170049000000400880008a00000000038304360000002004400039000000000804043300000000980804340000000007870436000000000008004b000019530000613d000000000a000019000000000b7a0019000000000ca90019000000000c0c04330000000000cb0435000000200aa0003900000000008a004b000019650000413d000019530000013d0000000e01000029000000000010043f000000ff01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a00000ad20010019800001b5f0000c13d00000ae40100004100001a3d0000013d00000adb01000041000000000010043f0000001201000029000000040010043f0000001001000029000000240010043f00000adc0100004100002a0b000104300000001f0530018f00000aeb06300198000000400200043d0000000004620019000019930000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000198f0000c13d000000000005004b000019a00000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000000600130021000000a830020009c00000a83020080410000004002200210000000000112019f00002a0b000104300000001001000029000000000010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c700008010020000392a092a040000040f0000000100200190000024960000613d0000000e02000029000c000100200092000000000101043b0000001002000029000000000202041a0000000c0020006c000019e10000a13d0000000d02000029000000010220008a0000000001120019000000000101041a000d00000001001d0000001001000029000000000010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b0000000c011000290000000d02000029000000000021041b000000000020043f0000000f01000029000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b0000000e02000029000000000021041b0000001001000029000000000101041a000e00000001001d000000000001004b00000fd80000c13d000017930000013d00000b6a01000041000000000010043f0000003201000039000000040010043f00000ae50100004100002a0b0001043000008010030000390000000002000019000019f20000013d000000000101043b0000001102000029000000000021041b00000012020000290000000102200039000000100020006c0000801003000039000017aa0000813d001200000002001d00000005012002100000000d011000290000000101100367000000000101043b000000000010043f0000010201000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700000000020300192a092a040000040f0000000100200190000024960000613d000000000201043b0000000f01000029000000000010043f001100000002001d0000000101200039000e00000001001d000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000000001004b000019ed0000c13d0000001103000029000000000103041a00000ad90010009c000080100200003900001e890000213d000c00000001001d0000000101100039000000000013041b000000000030043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c72a092a040000040f0000000100200190000024960000613d000000000101043b0000000c011000290000000f02000029000000000021041b0000001101000029000000000101041a001100000001001d000000000020043f0000000e01000029000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000019ea0000c13d000024960000013d00000b5401000041000000000010043f0000000e01000029000000040010043f00000ae50100004100002a0b0001043000000b5201000041000000000010043f000000ff01000039000000200010043f00000b5301000041000000000201041a000000400400043d000700000004001d00000af901000041000000000014043500000004014000390000000f03000029000000000031043500000a830040009c00000a830100004100000000010440190000004001100210000000000300041400000a830030009c00000a8303008041000000c003300210000000000113019f00000ae5011001c700000ad2022001972a092a040000040f000000600310027000000a8303300197000000200030008c000000200400003900000000040340190000001f0640018f0000002007400190000000070b000029000000070570002900001a6b0000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b00001a670000c13d000000000006004b00001a780000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000000010020019000001cb40000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900000ad90010009c00001e890000213d000000010020019000001e890000c13d000000400010043f000000200030008c000024960000413d00000000010b0433000700000001001d00000adf010000410000000000100443000000000100041400000a830010009c00000a8301008041000000c00110021000000ade011001c70000800b020000392a092a040000040f0000000100200190000024980000613d000000000101043b000000070010006b000020040000c13d0000001201000029000000000010043f0000010401000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000201041a000000ff0020019000001c470000c13d00000b730220019700000001022001bf000000000021041b0000001101000029000000000010043f000000fc01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a00000ad2001001980000154b0000613d0000001101000029000000000010043f000000fc01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a00000afb02000041000000000020044300000ad201100197000700000001001d0000000400100443000000000100041400000a830010009c00000a8301008041000000c00110021000000afc011001c700008002020000392a092a040000040f0000000100200190000024980000613d000000000101043b000000000001004b000024960000613d000000400300043d00000064013000390000000d02000029000000000021043500000024013000390000006002000039000000000021043500000b56010000410000000001130436000300000001001d00000004023000390000000f0100002900000000001204350000000b050000290005001f00500193000600000003001d000000840430003900000000035400190000000c01000029000400200010003d0000000101000367000000000005004b00001af80000613d0000000405100360000000005605043c0000000004640436000000000034004b00001af40000c13d000000050000006b00000000022300490000000604000029000000440440003900000000002404350000000a0200002900000000022304360000000903000029000c001f00300193000000000003004b00001b0a0000613d000000080110036000000009032000290000000004020019000000001501043c0000000004540436000000000034004b00001b060000c13d0000000c0000006b00000006030000290002000900300071000000020120002900000a830010009c00000a83010080410000006001100210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000a830030009c00000a83020000410000000002034019000100400020021800000001011001af00000007020000292a0929ff0000040f0000000100200190000022a70000613d000000060100002900000ad90010009c00001e890000213d0000000603000029000000400030043f00000080013000390000000d0200002900000000002104350000004001300039000000800200003900000000002104350000000e010000290000000302000029000000000012043500000012010000290000000000130435000000a0033000390000000b0230002900000001010003670000000b0000006b00001b390000613d0000000404100360000000004504043c0000000003530436000000000023004b00001b350000c13d000000050000006b00000006040000290000000003420049000000600440003900000000003404350000000a030000290000000002320436000000090000006b00001b490000613d000000080110036000000009032000290000000004020019000000001501043c0000000004540436000000000034004b00001b450000c13d0000000c0000006b000000020120002900000a830010009c00000a83010080410000006001100210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000001011001af00000ae1011001c70000800d02000039000000040300003900000b5704000041000013ac0000013d00000b5401000041000000000010043f0000000b01000029000000040010043f00000ae50100004100002a0b000104300000000c02000029000000120020006b00001cc00000c13d2a0927980000040f000000400200043d000c00000002001d00000add020000410000000000200443000a00000001001d000000000100041400000a830010009c00000a8301008041000000c00110021000000ade011001c70000800b020000392a092a040000040f0000000100200190000024980000613d000000000101043b000900000001001d00000adf010000410000000000100443000000000100041400000a830010009c00000a8301008041000000c00110021000000ade011001c70000800b020000392a092a040000040f0000000100200190000024980000613d000000000101043b0000000c0400002900000080024000390000001203000029000000000032043500000040024000390000008003000039000000000032043500000020024000390000000903000029000000000032043500000000001404350000000f050000290000001f0350018f000000a00440003900000000015400190000000102000367000000000005004b00001b980000613d00000010050000290000002005500039000000000552034f000000005605043c0000000004640436000000000014004b00001b940000c13d000000000003004b0000000c04000029000000000341004900000060044000390000000000340435000000120400002900000000004104350000000b03100029000000200a300039000000000004004b00001f7a0000c13d0000000c0200002900000000012a004900000a830010009c00000a8301008041000000600110021000000a830020009c00000a83020080410000004002200210000000000121019f000000000200041400000a830020009c00000a8302008041000000c002200210000000000121019f00000ae1011001c70000800d02000039000000030300003900000ae2040000410000000a050000290000000e060000292a0929ff0000040f0000000100200190000024960000613d000000400100043d0000000a0200002900000e420000013d000000100000006b000000510000613d00000af701000041000000000010043f000000ff01000039000000200010043f00000af801000041000000000201041a000000400400043d000800000004001d00000af9010000410000000000140435000000040140003900000afa03000041000000000031043500000a830040009c00000a830100004100000000010440190000004001100210000000000300041400000a830030009c00000a8303008041000000c003300210000000000113019f00000ae5011001c700000ad202200197000700000002001d2a092a040000040f000000600310027000000a8303300197000000200030008c000000200400003900000000040340190000001f0640018f0000002007400190000000080b000029000000080570002900001be90000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b00001be50000c13d000000000006004b00001bf60000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000000010020019000001dd10000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900000ad90010009c00001e890000213d000000010020019000001e890000c13d000000400010043f000000200030008c000024960000413d00000000010b0433000600000001001d000800010010003e00000ee80000613d00000afb01000041000000000010044300000007010000290000000400100443000000000100041400000a830010009c00000a8301008041000000c00110021000000afc011001c700008002020000392a092a040000040f0000000100200190000024980000613d000000000101043b000000000001004b000024960000613d000000400300043d00000024013000390000000802000029000000000021043500000afd010000410000000000130435000000040130003900000afa02000041000000000021043500000a830030009c000500000003001d00000a830100004100000000010340190000004001100210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000adc011001c700000007020000292a0929ff0000040f0000000100200190000021410000613d000000050100002900000ad90010009c00001e890000213d0000000501000029000000400010043f00000adf010000410000000000100443000000000100041400000a830010009c00000a8301008041000000c00110021000000ade011001c70000800b020000392a092a040000040f0000000100200190000024980000613d000000000101043b000700000001001d00000afe0010009c000021cc0000413d00000b0501000041000020050000013d00000b5501000041000016650000013d000000090100002900110000000000350000000001100079000000430110008a001200000001001d00000ae006100197000000000803001900000000090000190000000b0a00002900001c5c0000013d0000001f01c0003900000b720110019700000000054c00190000000000050435000000000b410019000000200aa000390000000109900039000000100090006c000017cb0000813d00000000013b0049000000200110008a000000200880003900000000001804350000000001a2034f000000000c01043b00000ae001c00197000000000461013f000000000061004b000000000100001900000ae0010040410000001200c0006c000000000d00001900000ae00d00804100000ae00040009c00000000010dc019000000000001004b000024960000c13d0000000b01c00029000000000412034f000000000c04043b00000ad900c0009c000024960000213d000000200d1000390000001101c0006900000000001d004b000000000400001900000ae00400204100000ae00110019700000ae00ed00197000000000f1e013f00000000001e004b000000000100001900000ae00100404100000ae000f0009c000000000104c019000000000001004b000024960000c13d0000000001d2034f0000000004cb043600000b720fc00198000000000df4001900001c8d0000613d000000000e01034f000000000b04001900000000e50e043c000000000b5b04360000000000db004b00001c890000c13d0000001f0bc0019000001c530000613d0000000001f1034f0000000305b00210000000000b0d0433000000000b5b01cf000000000b5b022f000000000101043b0000010005500089000000000151022f00000000015101cf0000000001b1019f00000000001d043500001c530000013d000000400200043d0000000006520019000000000005004b00000ef80000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000068004b00001ca10000c13d00000ef80000013d0000000e020000290000000f0020006c000006ed0000613d0000000e0000006b000006ed0000613d0000000d0000006b00001e790000613d0000000a020000290000000d0020006b00001e790000813d00000b3401000041000000000010043f00000af00100004100002a0b000104300000001f0530018f00000aeb06300198000000400200043d0000000004620019000019930000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00001cbb0000c13d000019930000013d00000adb01000041000000000010043f0000001201000029000000040010043f0000000c01000029000000240010043f00000adc0100004100002a0b0001043000000adb01000041000000000010043f0000001201000029000000040010043f0000001101000029000000240010043f00000adc0100004100002a0b0001043000000060061002700000001f0460018f00000aeb05600198000000400200043d000000000352001900001dc10000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b00001cd80000c13d00001dc10000013d00000012020000290000000a0020006c000006ed0000c13d0000001102000029000000120020006b000006ed0000c13d0000000a0000006b000000510000613d001100000000001d00000011010000290000000502100210001000090020002d00000001030003670000001001300360000000000101043b00000ad20010009c000024960000213d0012000b0020002d0000001204300360000000000404043b00000ad20040009c000024960000213d000000000001004b000006ed0000613d000000000041004b000006ed0000613d000000400600043d00000b2e0060009c00001e890000213d000d00080020002d0000000d02300360000000000202043b0000004003600039000000400030043f000f00000006001d0000000003460436000e00000003001d0000000000230435000000000010043f000000fd01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d0000000f02000029000000000202043300000ad202200197000000000101043b000000000301041a00000b1103300197000000000223019f000000000021041b00000001011000390000000e020000290000000002020433000000000021041b00000012010000290000000101100367000000000101043b00000ad20010009c000024960000213d000000000010043f000000fe01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000f00000001001d00000010010000290000000101100367000000000101043b000e00000001001d00000ad20010009c000024960000213d0000000e01000029000000000010043f0000000f010000290000000101100039000c00000001001d000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000000001004b00001d6e0000c13d0000000f02000029000000000102041a00000ad90010009c00001e890000213d000700000001001d0000000101100039000000000012041b000000000020043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b00000007011000290000000e02000029000000000021041b0000000f01000029000000000101041a000f00000001001d000000000020043f0000000c01000029000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b0000000f02000029000000000021041b00000add010000410000000000100443000000000100041400000a830010009c00000a8301008041000000c00110021000000ade011001c70000800b020000392a092a040000040f0000000100200190000024980000613d000000000101043b000f00000001001d00000012010000290000000101100367000000000101043b00000ad20010009c000024960000213d000000000010043f000000fb01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b0000000f02000029000000000021041b00000001020003670000001201200360000000000101043b00000ad20010009c000024960000213d0000001003200360000000000303043b00000ad20030009c000024960000213d0000000d02200360000000000202043b000000400400043d0000004005400039000000000025043500000020024000390000000000320435000000000014043500000a830040009c00000a83040080410000004001400210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000b45011001c70000800d02000039000000010300003900000b46040000412a0929ff0000040f0000000100200190000024960000613d00000011020000290000000102200039001100000002001d0000000a0020006c00001ce60000413d000000510000013d00000060061002700000001f0460018f00000aeb05600198000000400200043d000000000352001900001dc10000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b00001dbd0000c13d00000a8306600197000000000004004b00001dcf0000613d000000000151034f0000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001304350000006001600210000019a10000013d0000001f0530018f00000aeb06300198000000400200043d0000000004620019000019930000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00001dd80000c13d000019930000013d0000000003000019000e00000003001d0000000502300210001100000002001d00000008012000290000000101100367000000000101043b000000000010043f000000ff01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a00120ad20010019c0000070b0000613d000000110800002900000010018000290000000102000367000000000112034f000000000301043b0000000001000031000000090410006a000000430440008a00000ae00540019700000ae006300197000000000756013f000000000056004b000000000500001900000ae005004041000000000043004b000000000400001900000ae00400804100000ae00070009c000000000504c0190000000b04800029000000000442034f000000000404043b000d00000004001d000000000005004b000024960000c13d0000001003300029000000000232034f000000000202043b001100000002001d00000ad90020009c000024960000213d000000110110006a000000200530003900000ae00210019700000ae003500197000000000423013f000000000023004b000000000200001900000ae002004041000c00000005001d000000000015004b000000000100001900000ae00100204100000ae00040009c000000000201c019000000000002004b000024960000c13d00000afb01000041000000000010044300000012010000290000000400100443000000000100041400000a830010009c00000a8301008041000000c00110021000000afc011001c700008002020000392a092a040000040f0000000100200190000024980000613d000000000101043b000000000001004b000024960000613d000000400800043d00000024018000390000004002000039000000000021043500000b0a0100004100000000001804350000004401800039000000110900002900000000009104350000000401800039000700000001001d0000000d02000029000000000021043500000b7203900198000000640180003900000000023100190000000c04000029000000010440036700001e4c0000613d000000000504034f0000000006010019000000005705043c0000000006760436000000000026004b00001e480000c13d0000001f0590019000001e590000613d000000000334034f0000000304500210000000000502043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000320435000000000191001900000000000104350000001f0190003900000b720110019700000b0b0010009c00000b0b010080410000006001100210000000000200041400000a830020009c00000a8302008041000000c002200210000000000121019f00000a830080009c00000a83020000410000000002084019001100400020021800000011011001af00000b0c0110009a0000001202000029000f00000008001d2a0929ff0000040f00000001002001900000201a0000613d0000000f0200002900000ad90020009c0000000e0300002900001e890000213d000000400020043f00000001033000390000000a0030006c00001dde0000413d000001690000013d0000000e01000029000000000010043f000000fd01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000400200043d00000b2e0020009c0000200a0000a13d00000b6a01000041000000000010043f0000004101000039000000040010043f00000ae50100004100002a0b000104300000001f0530018f00000aeb06300198000000400200043d0000000004620019000019930000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00001e960000c13d000019930000013d0000001101000029000000000010043f000000fc01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a00000afb02000041000000000020044300000ad201100197000a00000001001d0000000400100443000000000100041400000a830010009c00000a8301008041000000c00110021000000afc011001c700008002020000392a092a040000040f0000000100200190000024980000613d000000000101043b000000000001004b000024960000613d000000400300043d00000024013000390000000d02000029000000000021043500000b6001000041000000000013043500000004013000390000000f02000029000000000021043500000a830030009c000b00000003001d00000a830100004100000000010340190007004000100218000000000100041400000a830010009c00000a8301008041000000c00110021000000007011001af00000adc011001c70000000a020000292a0929ff0000040f00000001002001900000214e0000613d0000000b0100002900000ad90010009c00001e890000213d0000000e0100002900000004021000390000000b01000029000000400010043f0000000103000367000000000123034f000000000601043b000000000100003100000000042100490000001f0440008a00000ae00540019700000ae007600197000000000857013f000000000057004b000000000700001900000ae007004041000000000046004b000000000900001900000ae00900804100000ae00080009c000000000709c019000000000007004b000024960000c13d0000000006260019000000000763034f000000000707043b000600000007001d00000ad90070009c000024960000213d000000060700002900000005077002100000000007710049000000200a60003900000ae00670019700000ae008a00197000000000968013f000000000068004b000000000600001900000ae00600404100050000000a001d00000000007a004b000000000700001900000ae00700204100000ae00090009c000000000607c019000000000006004b000024960000c13d0000002007200039000000000673034f000000000606043b00000ae008600197000000000958013f000000000058004b000000000800001900000ae008004041000000000046004b000000000a00001900000ae00a00804100000ae00090009c00000000080ac019000000000008004b000024960000c13d0000000008260019000000000683034f000000000606043b00000ad90060009c000024960000213d00000005096002100000000009910049000000200c80003900000ae00890019700000ae00ac00197000000000b8a013f00000000008a004b000000000800001900000ae00800404100040000000c001d00000000009c004b000000000900001900000ae00900204100000ae000b0009c000000000809c019000000000008004b000024960000c13d0000002007700039000000000773034f000000000707043b00000ae008700197000000000958013f000000000058004b000000000500001900000ae005004041000000000047004b000000000400001900000ae00400804100000ae00090009c000000000504c019000000000005004b000024960000c13d000300000027001d0000000302300360000000000202043b00000ad90020009c000024960000213d000000050320021000000000013100490000000303000029000000200730003900000ae00310019700000ae004700197000000000534013f000000000034004b000000000300001900000ae003004041000800000007001d000000000017004b000000000100001900000ae00100204100000ae00050009c000000000301c019000000000003004b000024960000c13d000000060060006b000023f00000c13d000000060020006b000023f00000c13d000000060000006b000023f70000c13d00000012010000290000000b03000029000000000013043500000040013000390000000c02000029000000000021043500000020013000390000000d020000290000000000210435000000000100041400000a830010009c00000a8301008041000000c00110021000000007011001af00000b45011001c7000000100200002900000ad2062001970000800d02000039000000040300003900000b610400004100000011050000290000000f070000290000004e0000013d00000060061002700000001f0460018f00000aeb05600198000000400200043d000000000352001900001dc10000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b00001f750000c13d00001dc10000013d0000000d03000029000f0000000000350000000003300079000000430330008a001000000003001d00000ae00530019700000000070100190000000008000019000000110900002900001f8d0000013d0000001f04b0003900000b7204400197000000000a3b001900000000000a0435000000000a34001900000020099000390000000108800039000000120080006c00001ba30000813d00000000031a0049000000200330008a00000020077000390000000000370435000000000392034f000000000b03043b00000ae003b00197000000000c53013f000000000053004b000000000300001900000ae0030040410000001000b0006c000000000d00001900000ae00d00804100000ae000c0009c00000000030dc019000000000003004b000024960000c13d0000001103b00029000000000b32034f000000000b0b043b00000ad900b0009c000024960000213d000000200c3000390000000f03b0006900000000003c004b000000000d00001900000ae00d00204100000ae00330019700000ae00ec00197000000000f3e013f00000000003e004b000000000300001900000ae00300404100000ae000f0009c00000000030dc019000000000003004b000024960000c13d000000000dc2034f0000000003ba043600000b720eb00198000000000ce3001900001fbe0000613d000000000f0d034f000000000a03001900000000f40f043c000000000a4a04360000000000ca004b00001fba0000c13d0000001f0ab0019000001f840000613d0000000004ed034f000000030aa00210000000000d0c0433000000000dad01cf000000000dad022f000000000404043b000001000aa000890000000004a4022f0000000004a401cf0000000004d4019f00000000004c043500001f840000013d0000000b0100002900000aff0010009c00001ffe0000813d0000001201000029000000000010043f000000fc01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a00000ad2011001970000000002000411000000000021004b000022380000c13d0000000c01000029000000e0011002100000000f011001af00000b00011001c7000000400200043d00000040032000390000000d04000029000000000043043500000020032000390000000e040000290000000000430435000000000012043500000a830020009c00000a83020080410000004001200210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000b45011001c70000800d02000039000000040300003900000b4b04000041000020550000013d0000000a0100002900000aff0010009c000020270000413d00000b0401000041000000000010043f0000000f01000029000000040010043f00000ae50100004100002a0b0001043000000b5401000041000000000010043f0000000701000029000000040010043f00000ae50100004100002a0b00010430000000000301043b0000004001200039000000400010043f000000000103041a00000ad20110019800000000021204360000000103300039000000000303041a0000000000320435000020590000613d0000000f0010006c000020590000613d00000b3501000041000000000010043f00000af00100004100002a0b0001043000000060061002700000001f0460018f00000aeb05600198000000400200043d000000000352001900001dc10000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b000020220000c13d00001dc10000013d0000001201000029000000000010043f000000fc01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a00000ad2011001970000000002000411000000000021004b000022380000c13d0000000b01000029000000e0011002100000000f011001af00000b00011001c7000000400200043d00000060032000390000000c04000029000000000043043500000040032000390000000d04000029000000000043043500000020032000390000000e040000290000000000430435000000000012043500000a830020009c00000a83020080410000004001200210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000b31011001c70000800d02000039000000040300003900000b32040000410000001205000029000000110600002900000010070000290000004e0000013d0000000f010000290000000e020000290000000d030000290000000c040000292a0925190000040f000000002301043400000b360030009c000020760000413d000000400400003900000b360530012a0000207f0000013d00000060061002700000001f0460018f00000aeb05600198000000400200043d000000000352001900001dc10000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b0000206c0000c13d00001dc10000013d0000000c0100002900000aff0010009c0000215b0000413d00000b040100004100001a3d0000013d00000b380030009c000000000503001900000b370550212a0000000004000039000000200400203900000b390050009c00000010044081bf00000b3a0550819700000b390550812a00000b3b0050009c000000080440803900000ad90550819700000b3b0550812a000027100050008c000000040440803900000a8305508197000027100550811a000000640050008c00000002044080390000ffff0550818f000000640550811a000000090050008c000000010440203900000b72074001970000005f0570003900000b7208500197000000400600043d0000000005680019000000000085004b0000000008000039000000010800403900000ad90050009c00001e890000213d000000010080019000001e890000c13d000000400050043f00000001054000390000000005560436000000200770003900000b72087001980000001f0770018f000020a80000613d000000000885001900000000090000310000000109900367000000000a050019000000009b09043c000000000aba043600000000008a004b000020a40000c13d000000000007004b00000000044600190000002104400039000000090030008c0000000a7330011a0000000307700210000000010440008a000000000804043300000b3c0880019700000b3d0770021f00000b3e07700197000000000787019f0000000000740435000020ab0000213d000000400300043d000000200430003900000b3f0700004100000000007404350000003a073000390000000006060433000000000006004b000020c60000613d00000000080000190000000009780019000000000a580019000000000a0a04330000000000a904350000002008800039000000000068004b000020bf0000413d000000000576001900000000000504350000000001010433000000000001004b000020d30000613d000000000700001900000000085700190000000009720019000000000909043300000000009804350000002007700039000000000017004b000020cc0000413d0000000002510019000000000002043500000000011600190000001a021000390000000000230435000000590110003900000b72021001970000000001320019000000000021004b0000000002000039000000010200403900000ad90010009c00001e890000213d000000010020019000001e890000c13d000000400010043f00000a830040009c00000a83040080410000004001400210000000000203043300000a830020009c00000a83020080410000006002200210000000000112019f000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000ae1011001c700008010020000392a092a040000040f0000000100200190000024960000613d00000012020000290000001f0220003900000b72022001970000003f0220003900000b7203200197000000000101043b000000400200043d0000000003320019000000000023004b0000000004000039000000010400403900000ad90030009c00001e890000213d000000010040019000001e890000c13d000000400030043f000000120300002900000000043204360000001103000029000000000030007c000024960000213d000000120300002900000b72053001980000001f0630018f000000100300002900000001073003670000000003540019000021170000613d000000000807034f0000000009040019000000008a08043c0000000009a90436000000000039004b000021130000c13d000000000006004b000021240000613d000000000557034f0000000306600210000000000703043300000000076701cf000000000767022f000000000505043b0000010006600089000000000565022f00000000056501cf000000000575019f000000000053043500000012034000290000000000030435000000400300043d0000000005020433000000410050008c000021d50000c13d0000004005200039000000000505043300000b420050009c000022b40000a13d000000640130003900000b48020000410000000000210435000000440130003900000b4902000041000000000021043500000024013000390000002202000039000000000021043500000ad701000041000000000013043500000004013000390000002002000039000000000021043500000a830030009c00000a8303008041000000400130021000000ad8011001c700002a0b0001043000000060061002700000001f0460018f00000aeb05600198000000400200043d000000000352001900001dc10000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b000021490000c13d00001dc10000013d00000060061002700000001f0460018f00000aeb05600198000000400200043d000000000352001900001dc10000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b000021560000c13d00001dc10000013d000000400100043d000c00000001001d00000adf010000410000000000100443000000000100041400000a830010009c00000a8301008041000000c00110021000000ade011001c70000800b020000392a092a040000040f0000000100200190000024980000613d000000000101043b0000000c020000290000000001120436000b00000001001d00000add010000410000000000100443000000000100041400000a830010009c00000a8301008041000000c00110021000000ade011001c70000800b020000392a092a040000040f0000000100200190000024980000613d0000000d02000029000000e0022002100000000e042001af000000000101043b0000000c070000290000004002700039000000600300003900000000003204350000000b02000029000000000012043500000060017000390000001002000029000000000021043500000b72052001980000001f0620018f000000800270003900000000035200190000000f0700002900000020077000390000000107700367000021920000613d000000000807034f0000000009020019000000008a08043c0000000009a90436000000000039004b0000218e0000c13d000f0b00004001cb000000000006004b000021a00000613d000000000457034f0000000305600210000000000603043300000000065601cf000000000656022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000464019f00000000004304350000001003000029000000000232001900000000000204350000001f0230003900000b720120019700000b010010009c00000b010100804100000060011002100000000c0200002900000a830020009c00000a83020080410000004002200210000000000121019f000000000200041400000a830020009c00000a8302008041000000c002200210000000000121019f00000b020110009a0000800d02000039000000040300003900000b03040000410000000f05000029000000120600002900000011070000292a0929ff0000040f0000000100200190000024960000613d000000400100043d0000000f0200002900000e420000013d00000060061002700000001f0460018f00000aeb05600198000000400200043d000000000352001900001dc10000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b000021c70000c13d00001dc10000013d000000060100002900000aff0010009c000021e50000413d00000b0401000041000000000010043f0000000801000029000000040010043f00000ae50100004100002a0b00010430000000440130003900000b4002000041000000000021043500000024013000390000001f02000039000000000021043500000ad701000041000000000013043500000004013000390000002002000039000000000021043500000a830030009c00000a8303008041000000400130021000000b41011001c700002a0b000104300000001201000029000000000010043f000000fc01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a00000ad2011001970000000002000411000000000021004b000022380000c13d0000000701000029000000e00110021000000008011001af00000b00021001c7000000400100043d00000080031000390000000e04000029000000000043043500000040031000390000008004000039000000000043043500000020031000390000000f04000029000000000043043500000000002104350000000d060000290000001f0460018f000000a00510003900000000036500190000000102000367000000000006004b000022130000613d0000000c06200360000000006706043c0000000005750436000000000035004b0000220f0000c13d000000000004004b0000000004130049000000600510003900000000004504350000000b0400002900000000034304360000000a050000290000001f0450018f000000000005004b000022240000613d00000009022003600000000a053000290000000006030019000000002702043c0000000006760436000000000056004b000022200000c13d000000000004004b0000000a02100069000000000232001900000a830020009c00000a8302008041000000600220021000000a830010009c00000a83010080410000004001100210000000000112019f000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000ae1011001c70000800d02000039000000040300003900000b6604000041000020550000013d00000b3001000041000016650000013d000000110100002900000aff0010009c00001ffe0000813d000000400100043d000d00000001001d00000add010000410000000000100443000000000100041400000a830010009c00000a8301008041000000c00110021000000ade011001c70000800b020000392a092a040000040f0000000100200190000024980000613d000000000101043b001200000001001d00000adf010000410000000000100443000000000100041400000a830010009c00000a8301008041000000c00110021000000ade011001c70000800b020000392a092a040000040f0000000100200190000024980000613d000000000301043b000000a0010000390000000d040000290000000002140436000000a0014000390000000a04000029000000000041043500000b0d0040009c000024960000213d000000010100036700000005070000290000001f0570018f0000000d04000029000000c0064000390000000004760019000000000007004b0000226d0000613d0000000807100360000000007807043c0000000006860436000000000046004b000022690000c13d000000000005004b0000000d0540006a00000000005204350000000a02000029000000000524043600000006060000290000001f0460018f0000000002650019000000000006004b0000227c0000613d0000000b06100360000000006706043c0000000005750436000000000025004b000022780000c13d000000000004004b0000000d05000029000000600450003900000012060000290000000000640435000000400450003900000000003404350000000003520049000000800450003900000000003404350000000a0400002900000000004204350000000403200029000000200a300039000000000004004b0000239e0000c13d0000000e01000029000000e0011002100000000f011001af00000b00051001c70000000d0200002900000000012a004900000a830010009c00000a8301008041000000600110021000000a830020009c00000a83020080410000004002200210000000000121019f000000000200041400000a830020009c00000a8302008041000000c002200210000000000121019f00000ae1011001c70000800d02000039000000020300003900000b0e04000041001200000005001d2a0929ff0000040f000000010020019000000e400000c13d000024960000013d00000060061002700000001f0460018f00000aeb05600198000000400200043d000000000352001900001dc10000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b000022af0000c13d00001dc10000013d0000006002200039000000000202043300000000040404330000006006300039000000000056043500000040053000390000000000450435000000f802200270000000200430003900000000002404350000000000130435000000000000043f00000a830030009c00000a83030080410000004001300210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000b43011001c700000001020000392a092a040000040f000000600310027000000a8303300197000000200030008c000000200400003900000000040340190000001f0540018f0000002004400190000022d90000613d000000000601034f0000000007000019000000006806043c0000000007870436000000000047004b000022d50000c13d000000000005004b000022e60000613d000000000641034f0000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f00000000005404350000000100200190000022f20000613d000000000100043d00000ad201100198000022fe0000c13d000000400100043d000000440210003900000b4703000041000000000032043500000024021000390000001803000039000012970000013d0000001f0530018f00000aeb06300198000000400200043d0000000004620019000019930000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000022f90000c13d000019930000013d0000000f0010006b000023970000c13d000000400100043d001200000001001d00000b2e0010009c00001e890000213d00000012020000290000004001200039000000400010043f0000000f0100002900000000021204360000000d01000029001100000002001d00000000001204350000000e01000029000000000010043f000000fd01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d0000001202000029000000000202043300000ad202200197000000000101043b000000000301041a00000b1103300197000000000223019f000000000021041b000000010110003900000011020000290000000002020433000000000021041b0000000f01000029000000000010043f000000fe01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000201043b0000000e01000029000000000010043f001200000002001d0000000101200039001100000001001d000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a000000000001004b0000236f0000c13d0000001201000029000000000101041a001000000001001d00000ad90010009c00001e890000213d000000100100002900000001011000390000001202000029000000000012041b000000000020043f000000000100041400000a830010009c00000a8301008041000000c00110021000000af4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b00000010011000290000000e02000029000000000021041b0000001201000029000000000101041a001200000001001d000000000020043f0000001101000029000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b0000001202000029000000000021041b0000000f01000029000000000010043f000000fb01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b0000000a02000029000000000021041b000000400100043d00000040021000390000000d0300002900000000003204350000000e0200002900000ad202200197000000200310003900000000002304350000000f0200002900000ad202200197000000000021043500000a830010009c00000a83010080410000004001100210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000b45011001c70000800d02000039000000010300003900000b4604000041000012c70000013d00000b4402000041000000000020043f0000000f02000029000000040020043f000000240010043f00000adc0100004100002a0b00010430000000090300002900110000000000350000000003300079000000430330008a001200000003001d00000ae005300197000000000702001900000000080000190000001009000029000023b10000013d0000001f04b0003900000b7204400197000000000a3b001900000000000a0435000000000a340019000000200990003900000001088000390000000a0080006c0000228c0000813d00000000032a0049000000200330008a00000020077000390000000000370435000000000391034f000000000b03043b00000ae003b00197000000000c53013f000000000053004b000000000300001900000ae0030040410000001200b0006c000000000d00001900000ae00d00804100000ae000c0009c00000000030dc019000000000003004b000024960000c13d0000001003b00029000000000b31034f000000000b0b043b00000ad900b0009c000024960000213d000000200c3000390000001103b0006900000000003c004b000000000d00001900000ae00d00204100000ae00330019700000ae00ec00197000000000f3e013f00000000003e004b000000000300001900000ae00300404100000ae000f0009c00000000030dc019000000000003004b000024960000c13d000000000dc1034f0000000003ba043600000b720eb00198000000000ce30019000023e20000613d000000000f0d034f000000000a03001900000000f40f043c000000000a4a04360000000000ca004b000023de0000c13d0000001f0ab00190000023a80000613d0000000004ed034f000000030aa00210000000000d0c0433000000000dad01cf000000000dad022f000000000404043b000001000aa000890000000004a4022f0000000004a401cf0000000004d4019f00000000004c0435000023a80000013d00000adb01000041000000000010043f0000000601000029000000040010043f000000240020043f00000adc0100004100002a0b00010430000a00000000001d0000000a010000290000000502100210000e00000002001d00000004012000290000000101100367000000000101043b000000000010043f000000ff01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024960000613d000000000101043b000000000101041a00090ad20010019c0000070b0000613d0000000e0800002900000008018000290000000102000367000000000112034f000000000301043b0000000001000031000000030410006a0000003f0440008a00000ae00540019700000ae006300197000000000756013f000000000056004b000000000500001900000ae005004041000000000043004b000000000400001900000ae00400804100000ae00070009c000000000504c0190000000504800029000000000442034f000000000404043b000b00000004001d000000000005004b000024960000c13d0000000803300029000000000232034f000000000202043b000e00000002001d00000ad90020009c000024960000213d0000000e0110006a000000200530003900000ae00210019700000ae003500197000000000423013f000000000023004b000000000200001900000ae002004041000700000005001d000000000015004b000000000100001900000ae00100204100000ae00040009c000000000201c019000000000002004b000024960000c13d00000afb01000041000000000010044300000009010000290000000400100443000000000100041400000a830010009c00000a8301008041000000c00110021000000afc011001c700008002020000392a092a040000040f0000000100200190000024980000613d000000000101043b000000000001004b000024960000613d000000400200043d00000024012000390000004003000039000000000031043500000b0a01000041000000000012043500000004012000390000000b03000029000000000031043500000044012000390000000e03000029000000000031043500000b7203300198000b00000002001d0000006401200039000000000231001900000007040000290000000104400367000024660000613d000000000504034f0000000006010019000000005705043c0000000006760436000000000026004b000024620000c13d0000000e050000290000001f05500190000024740000613d000000000334034f0000000304500210000000000502043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f00000000003204350000000e02000029000000000121001900000000000104350000001f0120003900000b720110019700000b0b0010009c00000b0b010080410000006001100210000000000200041400000a830020009c00000a8302008041000000c002200210000000000121019f0000000b0200002900000a830020009c00000a8302008041000700400020021800000007011001af00000b0c0110009a00000009020000292a0929ff0000040f0000000100200190000024990000613d0000000b0100002900000ad90010009c00001e890000213d0000000b01000029000000400010043f0000000a020000290000000102200039000a00000002001d000000060020006c000023f80000413d00001f560000013d000000000100001900002a0b00010430000000000001042f00000060061002700000001f0460018f00000aeb05600198000000400200043d000000000352001900001dc10000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b000024a10000c13d00001dc10000013d000000000003004b000024b00000613d000000000400001900000000052400190000000006140019000000000606043300000000006504350000002004400039000000000034004b000024a90000413d00000000012300190000000000010435000000000001042d00000000430104340000000001320436000000000003004b000024bf0000613d000000000200001900000000051200190000000006240019000000000606043300000000006504350000002002200039000000000032004b000024b80000413d000000000213001900000000000204350000001f0230003900000b72022001970000000001210019000000000001042d00000020030000390000000004310436000000003202043400000000002404350000004001100039000000000002004b000024d40000613d000000000400001900000000051400190000000006430019000000000606043300000000006504350000002004400039000000000024004b000024cd0000413d000000000312001900000000000304350000001f0220003900000b72022001970000000001120019000000000001042d00000020030000390000000004310436000000000302043300000000003404350000004001100039000000000003004b000024e80000613d00000000040000190000002002200039000000000502043300000000015104360000000104400039000000000034004b000024e20000413d000000000001042d00000ad202200197000000000020043f000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000024f70000613d000000000101043b000000000001042d000000000100001900002a0b000104300000001f0220003900000b72022001970000000001120019000000000021004b0000000002000039000000010200403900000ad90010009c000025050000213d0000000100200190000025050000c13d000000400010043f000000000001042d00000b6a01000041000000000010043f0000004101000039000000040010043f00000ae50100004100002a0b000104300000000031010434000000000001004b000025160000613d000000000400001900000000052400190000000006430019000000000606043300000000006504350000002004400039000000000014004b0000250f0000413d00000000012100190000000000010435000000000001042d000000400600043d00000b750060009c000026510000813d0000006007600039000000400070043f0000002a09000039000000000596043600000ad20220019700000000080000310000000108800367000000000a08034f000000000b05001900000000ac0a043c000000000bcb043600000000007b004b000025250000c13d000000000705043300000b3c0770019700000b76077001c700000000007504350000002107600039000000000a07043300000b3c0aa0019700000b770aa001c70000000000a704350000002907000039000000000a0200190000000002060433000000000072004b0000264b0000a13d0000000002570019000000000b02043300000b3c0bb00197000000030ca00210000000780cc0018f00000b3d0cc0021f00000b3e0cc00197000000000bcb019f0000000000b204350000000402a00270000000010770008a000000010070008c000025330000213d0000001000a0008c000026570000813d000000400700043d00000b780070009c000026510000213d000000600a7000390000004000a0043f000000000297043600000ad201100197000000000908034f000000000b020019000000009c09043c000000000bcb04360000000000ab004b0000254f0000c13d000000000902043300000b3c0990019700000b76099001c700000000009204350000002109700039000000000a09043300000b3c0aa0019700000b770aa001c70000000000a904350000002909000039000000000a0100190000000001070433000000000091004b0000264b0000a13d0000000001290019000000000b01043300000b3c0bb00197000000030ca00210000000780cc0018f00000b3d0cc0021f00000b3e0cc00197000000000bcb019f0000000000b104350000000401a00270000000010990008a000000010090008c0000255d0000213d0000000f00a0008c000026570000213d00000b360030009c000025750000413d000000400100003900000b360930012a0000257e0000013d00000b380030009c000000000903001900000b370990212a0000000001000039000000200100203900000b390090009c00000010011081bf00000b3a0990819700000b390990812a00000b3b0090009c000000080110803900000ad90990819700000b3b0990812a000027100090008c000000040110803900000a8309908197000027100990811a000000640090008c00000002011080390000ffff0990818f000000640990811a000000090090008c000000010110203900000b720c1001970000005f0ac0003900000b720da00197000000400b00043d000000000abd00190000000000da004b000000000d000039000000010d00403900000ad900a0009c000026510000213d0000000100d00190000026510000c13d0000004000a0043f000000010a100039000000000aab0436000000200cc0003900000b720dc001980000001f0cc0018f000025a60000613d000000000dda0019000000000e08034f000000000f0a001900000000e90e043c000000000f9f04360000000000df004b000025a20000c13d00000000000c004b00000000011b00190000002101100039000000090030008c0000000a9330011a0000000309900210000000010110008a000000000c01043300000b3c0cc0019700000b3d0990021f00000b3e099001970000000009c9019f0000000000910435000025a90000213d00000b360040009c000025b90000413d000000400100003900000b360340012a000025c20000013d00000b380040009c000000000304001900000b370330212a0000000001000039000000200100203900000b390030009c00000010011081bf00000b3a0330819700000b390330812a00000b3b0030009c000000080110803900000ad90330819700000b3b0330812a000027100030008c000000040110803900000a8303308197000027100330811a000000640030008c00000002011080390000ffff0330818f000000640330811a000000090030008c000000010110203900000b720d1001970000005f03d0003900000b7209300197000000400c00043d0000000003c90019000000000093004b000000000e000039000000010e00403900000ad90030009c000026510000213d0000000100e00190000026510000c13d000000400030043f000000010310003900000000033c04360000002009d0003900000b720e9001980000001f0d90018f000025e90000613d000000000ee30019000000000f030019000000008908043c000000000f9f04360000000000ef004b000025e50000c13d00000000000d004b00000000011c00190000002101100039000000090040008c0000000a8440011a0000000308800210000000010110008a000000000901043300000b3c0990019700000b3d0880021f00000b3e08800197000000000898019f0000000000810435000025ec0000213d000000400100043d000000200410003900000b7a0800004100000000008404350000003b081000390000000004060433000000000004004b000026070000613d00000000060000190000000009860019000000000d560019000000000d0d04330000000000d904350000002006600039000000000046004b000026000000413d0000000005840019000000000005043500000000041400190000005b0540003900000b7b0600004100000000006504350000003b0540003900000b7c06000041000000000065043500000074044000390000000005070433000000000005004b0000261c0000613d000000000600001900000000074600190000000008260019000000000808043300000000008704350000002006600039000000000056004b000026150000413d000000000245001900000b7d040000410000000000420435000000110220003900000000040b0433000000000004004b0000262b0000613d000000000500001900000000062500190000000007a50019000000000707043300000000007604350000002005500039000000000045004b000026240000413d000000000224001900000b7e040000410000000000420435000000110220003900000000040c0433000000000004004b0000263a0000613d000000000500001900000000062500190000000007350019000000000707043300000000007604350000002005500039000000000045004b000026330000413d000000000224001900000000000204350000000002120049000000200320008a00000000003104350000001f0220003900000b72032001970000000002130019000000000032004b0000000003000039000000010300403900000ad90020009c000026510000213d0000000100300190000026510000c13d000000400020043f000000000001042d00000b6a01000041000000000010043f0000003201000039000000040010043f00000ae50100004100002a0b0001043000000b6a01000041000000000010043f0000004101000039000000040010043f00000ae50100004100002a0b00010430000000400100043d000000440210003900000b7903000041000000000032043500000ad70200004100000000002104350000002402100039000000200300003900000000003204350000000402100039000000000032043500000a830010009c00000a8301008041000000400110021000000b41011001c700002a0b00010430000000000010043f0000006501000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000026770000613d000000000101043b0000000101100039000000000101041a000000000001042d000000000100001900002a0b00010430000400000000000200000000030004110000000002000031000000140020008c000300000001001d000400000003001d000026970000413d00000ad201300197000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000026b70000613d000000000101043b000000000101041a000000ff001001900000000301000029000026970000613d000000140200008a00000000022000310000000102200367000000000202043b0004006000200278000000000010043f0000006501000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000026b70000613d000000000101043b000000040200002900000ad202200197000400000002001d000000000020043f000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000026b70000613d000000000101043b000000000101041a000000ff00100190000026b90000613d000000000001042d000000000100001900002a0b0001043000000004010000292a0926e80000040f000200000001001d00000003010000292a0927310000040f000000400400043d000400000004001d000000200240003900000ae7030000410000000000320435000300000001001d00000002010000290000000013010434000100000003001d0000003702400039000200000002001d2a0924a60000040f0000000102000029000000020120002900000ae8020000410000000000210435000000110210003900000003010000292a09250b0000040f00000004030000290000000002310049000000200120008a000000000013043500000000010300192a0924f90000040f00000ad701000041000000400200043d000300000002001d0000000000120435000000040120003900000004020000292a0924c50000040f0000000302000029000000000121004900000a830010009c00000a8301008041000000600110021000000a830020009c00000a83020080410000004002200210000000000121019f00002a0b000104300000000002010019000000400100043d00000b750010009c0000271b0000813d0000006004100039000000400040043f0000002a030000390000000003310436000000000500003100000001055003670000000006030019000000005705043c0000000006760436000000000046004b000026f30000c13d000000000403043300000b3c0440019700000b76044001c700000000004304350000002104100039000000000504043300000b3c0550019700000b77055001c70000000000540435000000290400003900000000050200190000000002010433000000000042004b000027150000a13d0000000002340019000000000602043300000b3c066001970000000307500210000000780770018f00000b3d0770021f00000b3e07700197000000000676019f00000000006204350000000402500270000000010440008a000000010040008c000027010000213d000000100050008c000027210000813d000000000001042d00000b6a01000041000000000010043f0000003201000039000000040010043f00000ae50100004100002a0b0001043000000b6a01000041000000000010043f0000004101000039000000040010043f00000ae50100004100002a0b00010430000000400100043d000000440210003900000b7903000041000000000032043500000ad70200004100000000002104350000002402100039000000200300003900000000003204350000000402100039000000000032043500000a830010009c00000a8301008041000000400110021000000b41011001c700002a0b000104300000000002010019000000400100043d00000b7f0010009c000027640000813d0000008004100039000000400040043f00000042030000390000000003310436000000000500003100000001055003670000000006030019000000005705043c0000000006760436000000000046004b0000273c0000c13d000000000403043300000b3c0440019700000b76044001c700000000004304350000002104100039000000000504043300000b3c0550019700000b77055001c70000000000540435000000410400003900000000050200190000000002010433000000000042004b0000275e0000a13d0000000002340019000000000602043300000b3c066001970000000307500210000000780770018f00000b3d0770021f00000b3e07700197000000000676019f00000000006204350000000402500270000000010440008a000000010040008c0000274a0000213d000000100050008c0000276a0000813d000000000001042d00000b6a01000041000000000010043f0000003201000039000000040010043f00000ae50100004100002a0b0001043000000b6a01000041000000000010043f0000004101000039000000040010043f00000ae50100004100002a0b00010430000000400100043d000000440210003900000b7903000041000000000032043500000ad70200004100000000002104350000002402100039000000200300003900000000003204350000000402100039000000000032043500000a830010009c00000a8301008041000000400110021000000b41011001c700002a0b0001043000000000010004110000000002000031000000140020008c000027950000413d00000ad201100197000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000027960000613d000000000101043b000000000101041a000000ff001001900000000001000411000027950000613d000000140100008a00000000011000310000000101100367000000000101043b0000006001100270000000000001042d000000000100001900002a0b00010430000400000000000200000af701000041000000000010043f000000ff01000039000000200010043f00000af801000041000000000201041a000000400400043d000300000004001d00000af9010000410000000000140435000000040140003900000afa03000041000000000031043500000a830040009c00000a830100004100000000010440190000004001100210000000000300041400000a830030009c00000a8303008041000000c003300210000000000113019f00000ae5011001c700000ad202200197000400000002001d2a092a040000040f000000030b000029000000600310027000000a8303300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b0019000027c30000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000027bf0000c13d000000000006004b000027d00000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f000000000065043500000001002001900000282d0000613d0000001f01400039000000600210018f0000000001b20019000000000021004b0000000002000039000000010200403900000ad90010009c000028260000213d0000000100200190000028260000c13d000000400010043f0000001f0030008c000028240000a13d00000000010b0433000200000001001d000300010010003e000028470000613d00000afb01000041000000000010044300000004010000290000000400100443000000000100041400000a830010009c00000a8301008041000000c00110021000000afc011001c700008002020000392a092a040000040f00000001002001900000282c0000613d000000000101043b000000000001004b000028240000613d000000400300043d00000024013000390000000302000029000000000021043500000afd010000410000000000130435000000040130003900000afa02000041000000000021043500000a830030009c000100000003001d00000a830100004100000000010340190000004001100210000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000adc011001c700000004020000292a0929ff0000040f00000001002001900000284d0000613d000000010100002900000ad90010009c000028260000213d000000400010043f00000adf010000410000000000100443000000000100041400000a830010009c00000a8301008041000000c00110021000000ade011001c70000800b020000392a092a040000040f00000001002001900000282c0000613d000000000101043b00000afe0010009c0000286d0000813d000000020200002900000aff0020009c000028720000813d000000e00110021000000003011001af00000b00011001c7000000000001042d000000000100001900002a0b0001043000000b6a01000041000000000010043f0000004101000039000000040010043f00000ae50100004100002a0b00010430000000000001042f0000001f0530018f00000aeb06300198000000400200043d0000000004620019000028380000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000028340000c13d000000000005004b000028450000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f00000000001404350000006001300210000028680000013d00000b6a01000041000000000010043f0000001101000039000000040010043f00000ae50100004100002a0b0001043000000060061002700000001f0460018f00000aeb05600198000000400200043d0000000003520019000028590000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b000028550000c13d00000a8306600197000000000004004b000028670000613d000000000151034f0000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000130435000000600160021000000a830020009c00000a83020080410000004002200210000000000112019f00002a0b0001043000000b0502000041000000000020043f000000040010043f00000ae50100004100002a0b0001043000000b0401000041000000000010043f0000000301000029000000040010043f00000ae50100004100002a0b000104300002000000000002000100000002001d000200000001001d000000000010043f0000006501000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000028e20000613d000000000101043b000000010200002900000ad202200197000100000002001d000000000020043f000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000028e20000613d000000000101043b000000000101041a000000ff00100190000028e10000613d0000000201000029000000000010043f0000006501000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000028e20000613d000000000101043b0000000102000029000000000020043f000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000028e20000613d000000000101043b000000000201041a00000b7302200197000000000021041b00000000020004110000000001000031000000140010008c000028d30000413d00000ad201200197000000000010043f00000ad301000041000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000028e20000613d000000000101043b000000000101041a000000ff001001900000000002000411000028d30000613d000000140100008a00000000011000310000000101100367000000000101043b0000006002100270000000000100041400000a830010009c00000a8301008041000000c00110021000000ad20720019700000ae1011001c70000800d02000039000000040300003900000b8004000041000000020500002900000001060000292a0929ff0000040f0000000100200190000028e20000613d000000000001042d000000000100001900002a0b0001043000000ad2061001970000009701000039000000000201041a00000b1103200197000000000363019f000000000031041b000000000100041400000ad20520019700000a830010009c00000a8301008041000000c00110021000000ae1011001c70000800d02000039000000030300003900000b12040000412a0929ff0000040f0000000100200190000028f70000613d000000000001042d000000000100001900002a0b000104300009000000000002000900000005001d000300000003001d000200000001001d000000000062004b000029cf0000c13d000000000042004b000029cf0000c13d000000000002004b000029a00000613d0000000001000019000100000002001d000700000001001d0000000502100210000800000002001d00000003012000290000000101100367000000000101043b000000000010043f000000ff01000039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000029a10000613d000000000101043b000000000101041a00000ad208100198000029a30000613d000000080900002900000009019000290000000102000367000000000112034f000000000301043b0000000001000031000000090410006a0000001f0440008a00000ae00540019700000ae006300197000000000756013f000000000056004b000000000500001900000ae005004041000000000043004b000000000400001900000ae00400804100000ae00070009c000000000504c0190000000204900029000000000442034f000000000604043b000000000005004b000029a10000c13d0000000903300029000000000232034f000000000502043b00000ad90050009c000029a10000213d0000000001510049000000200730003900000ae00210019700000ae003700197000000000423013f000000000023004b000000000200001900000ae002004041000400000007001d000000000017004b000000000100001900000ae00100204100000ae00040009c000000000201c019000000000002004b000029a10000c13d000500000006001d000600000005001d00000afb010000410000000000100443000800000008001d0000000400800443000000000100041400000a830010009c00000a8301008041000000c00110021000000afc011001c700008002020000392a092a040000040f0000000100200190000029a80000613d000000000101043b000000000001004b000000080800002900000006090000290000000503000029000029a10000613d000000400a00043d0000002401a000390000004002000039000000000021043500000b0a0100004100000000001a04350000000401a0003900000000003104350000004401a00039000000000091043500000b72039001980000006401a00039000000000231001900000004040000290000000104400367000029730000613d000000000504034f0000000006010019000000005705043c0000000006760436000000000026004b0000296f0000c13d0000001f05900190000029800000613d000000000334034f0000000304500210000000000502043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000320435000000000191001900000000000104350000001f0190003900000b720110019700000b0b0010009c00000b0b01008041000000600110021000000a8300a0009c00000a830200004100000000020a40190000004002200210000000000121019f000000000200041400000a830020009c00000a8302008041000000c002200210000000000121019f00000b0c0110009a000000000208001900080000000a001d2a0929ff0000040f0000000100200190000029a90000613d000000080100002900000b810010009c0000000102000029000029c90000813d000000400010043f00000007010000290000000101100039000000000021004b000029050000413d000000000001042d000000000100001900002a0b0001043000000b0901000041000000000010043f000000040000043f00000ae50100004100002a0b00010430000000000001042f00000060061002700000001f0460018f00000aeb05600198000000400200043d0000000003520019000029b50000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b000029b10000c13d00000a8306600197000000000004004b000029c30000613d000000000151034f0000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000130435000000600160021000000a830020009c00000a83020080410000004002200210000000000112019f00002a0b0001043000000b6a01000041000000000010043f0000004101000039000000040010043f00000ae50100004100002a0b0001043000000adb01000041000000000010043f000000040020043f000000240060043f00000adc0100004100002a0b00010430000000000020043f0000000101100039000000200010043f000000000100041400000a830010009c00000a8301008041000000c00110021000000ad4011001c700008010020000392a092a040000040f0000000100200190000029e70000613d000000000101043b000000000101041a000000000001004b0000000001000039000000010100c039000000000001042d000000000100001900002a0b00010430000000000001042f00000a830010009c00000a8301008041000000400110021000000a830020009c00000a83020080410000006002200210000000000112019f000000000200041400000a830020009c00000a8302008041000000c002200210000000000112019f00000ae1011001c700008010020000392a092a040000040f0000000100200190000029fd0000613d000000000101043b000000000001042d000000000100001900002a0b0001043000002a02002104210000000102000039000000000001042d0000000002000019000000000001042d00002a07002104230000000102000039000000000001042d0000000002000019000000000001042d00002a090000043200002a0a0001042e00002a0b0001043000000000000000000000000000000000000000000000000000000000ffffffff0000000200000000000000000000000000000040000001000000000000000000000000000000000000000000000000000000000000000000000000005c8cd1d900000000000000000000000000000000000000000000000000000000b69ec14e00000000000000000000000000000000000000000000000000000000d671c72000000000000000000000000000000000000000000000000000000000e21592dd00000000000000000000000000000000000000000000000000000000ee86384f00000000000000000000000000000000000000000000000000000000ee86385000000000000000000000000000000000000000000000000000000000f2fde38b00000000000000000000000000000000000000000000000000000000e21592de00000000000000000000000000000000000000000000000000000000e6ce49b000000000000000000000000000000000000000000000000000000000d671c72100000000000000000000000000000000000000000000000000000000d8cf98ca00000000000000000000000000000000000000000000000000000000e13e02ae00000000000000000000000000000000000000000000000000000000c4d66de700000000000000000000000000000000000000000000000000000000cfd3c57e00000000000000000000000000000000000000000000000000000000cfd3c57f00000000000000000000000000000000000000000000000000000000d547741f00000000000000000000000000000000000000000000000000000000c4d66de800000000000000000000000000000000000000000000000000000000cf38bcec00000000000000000000000000000000000000000000000000000000b69ec14f00000000000000000000000000000000000000000000000000000000ba64197800000000000000000000000000000000000000000000000000000000c36dd7ea000000000000000000000000000000000000000000000000000000008b3d318f0000000000000000000000000000000000000000000000000000000093f7cc9800000000000000000000000000000000000000000000000000000000a217fdde00000000000000000000000000000000000000000000000000000000a217fddf00000000000000000000000000000000000000000000000000000000a55cce990000000000000000000000000000000000000000000000000000000093f7cc99000000000000000000000000000000000000000000000000000000009f54f545000000000000000000000000000000000000000000000000000000008b3d3190000000000000000000000000000000000000000000000000000000008da5cb5b0000000000000000000000000000000000000000000000000000000091d14854000000000000000000000000000000000000000000000000000000006e0e51d50000000000000000000000000000000000000000000000000000000084db94640000000000000000000000000000000000000000000000000000000084db946500000000000000000000000000000000000000000000000000000000868b4ea3000000000000000000000000000000000000000000000000000000006e0e51d600000000000000000000000000000000000000000000000000000000715018a6000000000000000000000000000000000000000000000000000000005c8cd1da000000000000000000000000000000000000000000000000000000005c975abb000000000000000000000000000000000000000000000000000000005eb328e8000000000000000000000000000000000000000000000000000000002e9e37d90000000000000000000000000000000000000000000000000000000047c32fc8000000000000000000000000000000000000000000000000000000004f27da1700000000000000000000000000000000000000000000000000000000552b6cbc00000000000000000000000000000000000000000000000000000000552b6cbd00000000000000000000000000000000000000000000000000000000572b6c05000000000000000000000000000000000000000000000000000000004f27da180000000000000000000000000000000000000000000000000000000053e41c1e0000000000000000000000000000000000000000000000000000000047c32fc9000000000000000000000000000000000000000000000000000000004b84859e000000000000000000000000000000000000000000000000000000004b9b233d000000000000000000000000000000000000000000000000000000003632e55c0000000000000000000000000000000000000000000000000000000038b34ce10000000000000000000000000000000000000000000000000000000038b34ce2000000000000000000000000000000000000000000000000000000003e2b4731000000000000000000000000000000000000000000000000000000003632e55d0000000000000000000000000000000000000000000000000000000036568abe000000000000000000000000000000000000000000000000000000002e9e37da000000000000000000000000000000000000000000000000000000002f2ff15d00000000000000000000000000000000000000000000000000000000306b8fdb000000000000000000000000000000000000000000000000000000002078e59e0000000000000000000000000000000000000000000000000000000023b7307f0000000000000000000000000000000000000000000000000000000028895a640000000000000000000000000000000000000000000000000000000028895a65000000000000000000000000000000000000000000000000000000002a07379f0000000000000000000000000000000000000000000000000000000023b7308000000000000000000000000000000000000000000000000000000000248a9ca3000000000000000000000000000000000000000000000000000000002078e59f00000000000000000000000000000000000000000000000000000000209e1d1f0000000000000000000000000000000000000000000000000000000023685630000000000000000000000000000000000000000000000000000000001548a8dd000000000000000000000000000000000000000000000000000000001548a8de0000000000000000000000000000000000000000000000000000000016c38b3c000000000000000000000000000000000000000000000000000000001aa49f0a0000000000000000000000000000000000000000000000000000000001ffc9a70000000000000000000000000000000000000000000000000000000007000fa3000000000000000000000000000000000000000000000000000000000de3b7b5000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7eadaa3f9670d14565ac2870e1aeb25dbbb517904328cdf89e01a9f9a24cb413020000000000000000000000000000000000004000000000000000000000000064647265737300000000000000000000000000000000000000000000000000004f776e61626c653a206e6577206f776e657220697320746865207a65726f206108c379a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff5b1199226da0590ea946c8bc878a515f748d1b38090957904ded76250443b018a12b573a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044000000000000000000000000796b89b91644bc98cd93958e4c9038275d622183e25ac5af08cc6b5d9553913202000002000000000000000000000000000000040000000000000000000000009a8a0592ac89c5ad3bc6df8224c17b485976f597df104ee20d0df415241f670b800000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000005dd9f2865acd7453c002f561361db29d62d00f13b37f508d085a51d10248ec0b0000000000000000000000000000000000000020000000000000000000000000ac7776ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000d3dc2a3a14cbd0cdbf3069fc3927e48506f271b9dda2c21625b93e6a99d3eb53416363657373436f6e74726f6c3a206163636f756e7420000000000000000000206973206d697373696e6720726f6c6520000000000000000000000000000000000000000000000000000000000000000000002000000080000000000000000057bc2ef30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffe000000000000000000000000000000000000000000000000000000001ffffffe00000000000000000000000000000000000000000ffffffffffffffffffffffffcee91eb23e767f0f440dd9fce5554f355614443931e9ac5ce78c67b9e06e6f7036d3814c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08d84503c400000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000002000000000000000000000000031e0adfec71bccee37b6e83a90c2fedb17d8f1693fee863c4771e7bfe2aed58025ec6c1f00000000000000000000000000000000000000000000000000000000e3bfd6d54b84ccae00cc6cad7783a88be07b38aacd8ade36a87a216bbfed603930104a02363e5c98ba717549f6c9fbda80dd783fbe95f052dd2bbb597ed89d910ff4c916000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000094e155dc6bbc332671c31806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b8302000002000000000000000000000000000000240000000000000000000000007b8d56e30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffff0000000094e155dc6bbc332671c300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffff7ffdffffffffffffffffffffffffffffffffffff8000000000000000000000000058eb7fdba04a3157c5464689ccf75a24765262e09ce90b3c6c5c03f2299aa31831e597c700000000000000000000000000000000000000000000000000000000e44bb4250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffbffdffffffffffffffffffffffffffffffffffffc00000000000000000000000006837901feacdbb2b5f689b180c02268b287523b334088077ba4c35daf4fe34a82939675d00000000000000000000000000000000000000000000000000000000011827fd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffff9bffffffffffffffffffffffffffffffffffffff9c00000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84cb1eedfefdbdc180ee81820e256e281ad4aeef64fc39f0b359f385534a3c4f647920696e697469616c697a6564000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e747261637420697320616c726561ffffffffffffffffffffffff00000000000000000000000000000000000000008be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0ffdfc1249c027f9191656349feb0761381bb32c9f557e01f419fd08754bf5a1b2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0dbfe93621c6aa2dbf737e9056c9b79e4d30ee4f6b28b18be2cb71aac8a7bf258f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862abd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff1205d77ca9d53a707971ee4987c58d8c7aa5cb89fa7fd09eda17968771861e53ea835c7d72284b79a066e6c72c2ec0626564e721352a92b0f8d5f16cb009fdd685c17057e64b90c0253930284e1a55b6799192f06efd0cf6b55dde7bdc2502b58f4f2da22e8ac8f11e15f9fc141cddbb5deea8800186560abb6e68c5496619a9a0f6cebec7fb889cc5ac88647269c4c0108fb926abd2111b551f234b348876e09f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6cee91eb23e767f0f440dd9fce5554f355614443931e9ac5ce78c67b9e06e6f7169301b51f018d97141301c1c6a53ae25a6fd16bc84b1ecc98625000043f0fb6cfc425f2263d0df187444b70e47283d622c70181c5baebb1306a01edba1ce184c72b1eaf56aee67bc26a907f00ed5803068b07bae780909283c035775bf79db5c5a0afddc7ecb0deaa549d40e18566f1c87c8ed09187b6915eaf44079f37e2aca9b9dd2dfc7af3e1dd36e94ea8ab7db77e1e62d8947a584bc19d3415afa077185def43b3901ce74522c0564b6b61fb50e09ecc39765fd64702dad6f2446fc4b637ca263f9d2081764a69ef996d223c3377f8b4bee83584423029ae3cf48728b3ff7b302cb700b7a54f3e005e07d62e8f53814068ec358c9a9e3f0423fa744c6a75b1199226da0590ea946c8bc878a515f748d1b38090957904ded76250443b01962e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2587f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986e697469616c697a696e67000000000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420697fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000000000000000000000000000000000000000000ffffffffffffff7f000000000000000000000000000000000000000000000000ffffffffffffffbfb2861d8f00000000000000000000000000000000000000000000000000000000393f13e7000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000080000000000000000000000000e0226f66a5bd2706623f73806e7eb62f852960f4713e38d6084b01290d66781648f5c3ed000000000000000000000000000000000000000000000000000000003686fe220000000000000000000000000000000000000000000000000000000042ee68b5000000000000000000000000000000000000000000000000000000000000000000184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000000000000000000000000000000000000000004ee2d6d415b85acef810000000000000000000000000000000000000000000004ee2d6d415b85acef80ffffffff000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000ffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000005f5e10000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff30313233343536373839616263646566000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000019457468657265756d205369676e6564204d6573736167653a0a00000000000045434453413a20696e76616c6964207369676e6174757265206c656e6774680000000000000000000000000000000000000000640000000000000000000000007fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a000000000000000000000000000000000000000800000000000000000000000009be21ff1000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000060000000000000000000000000dcb4af7d57cc106724f816a55242fbe9d45d800af6a574cb2814d7adf23e494045434453413a20696e76616c6964207369676e61747572650000000000000000756500000000000000000000000000000000000000000000000000000000000045434453413a20696e76616c6964207369676e6174757265202773272076616c604dacb2000000000000000000000000000000000000000000000000000000001d9aaee2c014ed511e93b0e1289132b78abaf5ff3b3915f9a7aec2876531a00c4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657282efdbd4005a1d1eb82fddd472f42232c242d2ad44b9a242ba765e816f23cbcee065b93b78fd9ec871610269cc875e4f300f3cf0ed219355a75c09ffdc72c1850161a64a00000000000000000000000000000000000000000000000000000000d3df22cd6a774f62b0ae21ffd602cc92e7f3390518eee8b33307fc70380da7d227b23f6e54cb694c9edaa3491242047bdb1767b0525e5e79763e05e44e1b0d15690f6f6afcfb5c8f87210087be9555decb669a5a5a6d12111f620ca044144c3e82d63b350eafefeb8f4c7183a150a8f3b98db6d3d9cb91528652ef104b3c2d3317555622000000000000000000000000000000000000000000000000000000005ad313b900000000000000000000000000000000000000000000000000000000b27b85dc00000000000000000000000000000000000000000000000000000000187fe03859dbfadac49b3639bdca667cd35ee572856cdc74f634ea56843e607e455d2a126e5e85ea9f46f822a38d5695336cd3a8180a3a74ea4601221f9ed98720726f6c657320666f722073656c660000000000000000000000000000000000416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e63656f6904abf86d9d6d5114fd2ba5c3020cff3fb91d7ec4594f71ef6b5ff6bb3e495f23ddf214f07432adde492f045b7ea97a86cf90f50f14f22ae77d3bf437c9ee69301b51f018d97141301c1c6a53ae25a6fd16bc84b1ecc98625000043f0fb6b4ad49251ddae0b218995a7fd001ab79155bdbb25933c94a417e2d67103cfe3497fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff63fe8d7a00000000000000000000000000000000000000000000000000000000b316fa5abbed8c6419c8559a4ee6369b7ec8fff26ea1d1c3d54ec5efedd1225ae25d213f62bc7c4e937e89492babb3d2720fa992806de157203dfbf8e631a0425061757361626c653a20706175736564000000000000000000000000000000000000000000000000000000000000000000000064000000800000000000000000eb32d3bf00000000000000000000000000000000000000000000000000000000a2d715629f9034d65861900d057bee4ffbe715c0b061eca73a32225091eba73abfe93621c6aa2dbf737e9056c9b79e4d30ee4f6b28b18be2cb71aac8a7bf258e5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa5061757361626c653a206e6f74207061757365640000000000000000000000004e487b71000000000000000000000000000000000000000000000000000000008989859870cc0d47cc5f8909459290e411f855f5535f7dbfaf1038cf40fccc0ea514d6ff00000000000000000000000000000000000000000000000000000000bbc2c05b9ccfe02f6e3b80f1a5a22a06ad7f0f20c4ea818e9dae43b9240f064400000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff01ffc9a7000000000000000000000000000000000000000000000000000000003e30d364000000000000000000000000000000000000000000000000000000007965db0b00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff000000000000000000000000000000000000000000000000ffffffffffffffa030000000000000000000000000000000000000000000000000000000000000007800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff9f537472696e67733a20686578206c656e67746820696e73756666696369656e74417574686f72697a65206f70657261746f72206163636f756e74200000000000626568616c66206f6620706c61796572206163636f756e74200000000000000020746f20706572666f726d2067616d65706c617920616374696f6e73206f6e2020776974682065787069726174696f6e20000000000000000000000000000000207369676e656420617420626c6f636b20000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff80f6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b000000000000000000000000000000000000000000000001000000000000000007dc6755b40ac6e48e60555a4c7fdb9b8110caa1b4769b9a4137bf051489147f
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.