Transactions
Internal Transactions
Coin Balance History
Logs
Code
Read Proxy
Write Contract
Write Proxy
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- Diamond
- Optimization enabled
- true
- Compiler version
- v0.8.19+commit.7dd6d404
- Optimization runs
- 999999
- EVM Version
- paris
- Verified at
- 2024-06-25T01:18:09.995476Z
Constructor Arguments
0x000000000000000000000000efd739b52045d112c37c5d89a8771b31c165879c
Arg [0] (address) : 0xefd739b52045d112c37c5d89a8771b31c165879c
lib/lg-diamond-template/src/diamond/LGDiamond.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import {IDiamondCut} from '../interfaces/IDiamondCut.sol'; import {LibContractOwner} from '../libraries/LibContractOwner.sol'; import {LibDiamond} from '../libraries/LibDiamond.sol'; /// @title LG Diamond /// @notice Adapted from the Diamond 3 reference implementation by Nick Mudge: /// @notice https://github.com/mudgen/diamond-3-hardhat contract Diamond { error FunctionDoesNotExist(bytes4 methodSelector); error DiamondAlreadyInitialized(); constructor(address diamondCutFacet) payable { initializeDiamond(diamondCutFacet); } // Find facet for function that is called and execute the // function if a facet is found and return any value. fallback() external payable { /* solhint-disable no-inline-assembly */ // get facet from function selector address facet = LibDiamond.diamondStorage().selectorToFacetAndPosition[msg.sig].facetAddress; if (facet == address(0)) revert FunctionDoesNotExist(msg.sig); // Execute external function from facet using delegatecall and return any value. assembly { // copy function selector and any arguments calldatacopy(0, 0, calldatasize()) // execute function call using the facet let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0) // get any return value returndatacopy(0, 0, returndatasize()) // return any return value or error back to the caller switch result case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } /* solhint-enable no-inline-assembly */ } /// @notice Initializes the diamond, by adding the `diamondCut` method and setting the owner. /// @dev This function is automatically called by the constructor. /// @dev The code is separated out to facilitate on-chain copying utilities. function initializeDiamond(address diamondCutFacet) public { LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); if (ds.initialized) revert DiamondAlreadyInitialized(); // Attach the diamondCut function from the diamondCutFacet IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1); cut[0] = IDiamondCut.FacetCut({ facetAddress: diamondCutFacet, action: IDiamondCut.FacetCutAction.Add, functionSelectors: new bytes4[](1) }); cut[0].functionSelectors[0] = IDiamondCut.diamondCut.selector; LibDiamond.diamondCut(cut); // When deployed from an EOA this will be the owner wallet, // when deployed from the clone function, the copier contract will be the owner. LibContractOwner.setContractOwner(msg.sender); ds.initialized = true; } receive() external payable {} }
lib/lg-diamond-template/src/interfaces/IDiamondCut.sol
//SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.19; /******************************************************************************\ * Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen) * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 /******************************************************************************/ interface IDiamondCut { enum FacetCutAction { Add, Replace, Remove } // Add=0, Replace=1, Remove=2 struct FacetCut { address facetAddress; FacetCutAction action; bytes4[] functionSelectors; } /// @notice Add/replace/remove any number of functions and optionally execute /// a function with delegatecall /// @param _diamondCut Contains the facet addresses and function selectors /// @param _init The address of the contract or facet to execute _calldata /// @param _calldata A function call, including function selector and arguments /// _calldata is executed with delegatecall on _init function diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata) external; event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata); }
lib/lg-diamond-template/src/libraries/LibContractOwner.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; /// @title Library for the common LG implementation of ERC-173 Contract Ownership Standard /// @author [email protected] /// @custom:storage-location erc1967:eip1967.proxy.admin library LibContractOwner { error CallerIsNotContractOwner(); /// @notice This emits when ownership of a contract changes. /// @dev ERC-173 event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /// @notice Emitted when the admin account has changed. /// @dev ERC-1967 event AdminChanged(address previousAdmin, address newAdmin); // @dev Standard storage slot for the ERC-1967 admin address // @dev bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1) bytes32 private constant ADMIN_SLOT_POSITION = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; struct LibOwnerStorage { address contractOwner; } /// @notice Storage slot for Contract Owner state data function ownerStorage() internal pure returns (LibOwnerStorage storage storageSlot) { bytes32 position = ADMIN_SLOT_POSITION; // solhint-disable-next-line no-inline-assembly assembly { storageSlot.slot := position } } /// @notice Sets the contract owner /// @param newOwner The new owner /// @custom:emits OwnershipTransferred function setContractOwner(address newOwner) internal { LibOwnerStorage storage ls = ownerStorage(); address previousOwner = ls.contractOwner; ls.contractOwner = newOwner; emit OwnershipTransferred(previousOwner, newOwner); emit AdminChanged(previousOwner, newOwner); } /// @notice Gets the contract owner wallet /// @return owner The contract owner function contractOwner() internal view returns (address owner) { owner = ownerStorage().contractOwner; } /// @notice Ensures that the caller is the contract owner, or throws an error. /// @custom:throws LibAccess: Must be contract owner function enforceIsContractOwner() internal view { if (msg.sender != ownerStorage().contractOwner) revert CallerIsNotContractOwner(); } }
lib/lg-diamond-template/src/libraries/LibDiamond.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import {IDiamondCut} from '../interfaces/IDiamondCut.sol'; import {LibContractOwner} from './LibContractOwner.sol'; /// @title LibDiamond /// @notice Library for the common LG implementation of ERC-2535 Diamond Proxy /// @notice Adapted from the Diamond 3 reference implementation by Nick Mudge: /// @notice https://github.com/mudgen/diamond-3-hardhat /// @custom:storage-location erc2535:diamond.standard.diamond.storage library LibDiamond { error InvalidFacetCutAction(IDiamondCut.FacetCutAction action); /// @notice Emitted when facets are added or removed /// @dev ERC-2535 event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata); // @dev Standard storage slot for the ERC-2535 Diamond storage // @dev keccak256('diamond.standard.diamond.storage') bytes32 internal constant DIAMOND_STORAGE_POSITION = 0xc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c; struct FacetAddressAndPosition { address facetAddress; uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array } struct FacetFunctionSelectors { bytes4[] functionSelectors; uint256 facetAddressPosition; // position of facetAddress in facetAddresses array } struct DiamondStorage { // maps function selector to the facet address and // the position of the selector in the facetFunctionSelectors.selectors array mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition; // maps facet addresses to function selectors mapping(address => FacetFunctionSelectors) facetFunctionSelectors; // facet addresses address[] facetAddresses; // true if the diamond has been initialized bool initialized; // THIS IS ONLY SET BY THE DIAMOND CONSTRUCTOR! } /// @notice Storage slot for Diamond storage function diamondStorage() internal pure returns (DiamondStorage storage ds) { bytes32 position = DIAMOND_STORAGE_POSITION; assembly { ds.slot := position } } /// @notice Ensures that the caller is the contract owner, or throws an error. /// @dev Passthrough to LibContractOwner.enforceIsContractOwner() /// @custom:throws LibAccess: Must be contract owner function enforceIsContractOwner() internal view { LibContractOwner.enforceIsContractOwner(); } // Internal function version of diamondCut function diamondCut(IDiamondCut.FacetCut[] memory _diamondCut) internal { for (uint256 facetIndex; facetIndex < _diamondCut.length; ++facetIndex) { IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action; if (action == IDiamondCut.FacetCutAction.Add) { addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors); } else if (action == IDiamondCut.FacetCutAction.Replace) { replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors); } else if (action == IDiamondCut.FacetCutAction.Remove) { removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors); } else { revert InvalidFacetCutAction(action); } } emit DiamondCut(_diamondCut, address(0), ''); } function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut'); DiamondStorage storage ds = diamondStorage(); require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)"); uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length); // add new facet address if it does not exist if (selectorPosition == 0) { addFacet(ds, _facetAddress); } for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; ++selectorIndex) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress; require(oldFacetAddress == address(0), "LibDiamondCut: Can't add function that already exists"); addFunction(ds, selector, selectorPosition, _facetAddress); ++selectorPosition; } } function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut'); DiamondStorage storage ds = diamondStorage(); require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)"); uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length); // add new facet address if it does not exist if (selectorPosition == 0) { addFacet(ds, _facetAddress); } for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; ++selectorIndex) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress; require(oldFacetAddress != _facetAddress, "LibDiamondCut: Can't replace function with same function"); removeFunction(ds, oldFacetAddress, selector); addFunction(ds, selector, selectorPosition, _facetAddress); ++selectorPosition; } } function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut'); DiamondStorage storage ds = diamondStorage(); // if function does not exist then do nothing and return require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)'); for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; ++selectorIndex) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress; removeFunction(ds, oldFacetAddress, selector); } } function addFacet(DiamondStorage storage ds, address _facetAddress) internal { enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code'); ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length; ds.facetAddresses.push(_facetAddress); } function addFunction( DiamondStorage storage ds, bytes4 _selector, uint96 _selectorPosition, address _facetAddress ) internal { ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition; ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector); ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress; } function removeFunction(DiamondStorage storage ds, address _facetAddress, bytes4 _selector) internal { require(_facetAddress != address(0), "LibDiamondCut: Can't remove function that doesn't exist"); // an immutable function is a function defined directly in a diamond require(_facetAddress != address(this), "LibDiamondCut: Can't remove immutable function"); // replace selector with last selector, then delete last selector uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition; uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1; // if not the same then replace _selector with lastSelector if (selectorPosition != lastSelectorPosition) { bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition]; ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector; ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition); } // delete the last selector ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop(); delete ds.selectorToFacetAndPosition[_selector]; // if no more selectors for facet address then delete the facet address if (lastSelectorPosition == 0) { // replace facet address with last facet address and delete last facet address uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1; uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition; if (facetAddressPosition != lastFacetAddressPosition) { address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition]; ds.facetAddresses[facetAddressPosition] = lastFacetAddress; ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition; } ds.facetAddresses.pop(); delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition; } } function enforceHasContractCode(address _contract, string memory _errorMessage) internal view { uint256 contractSize; assembly { contractSize := extcodesize(_contract) } require(contractSize > 0, _errorMessage); } }
Compiler Settings
{"viaIR":true,"remappings":["ds-test/=lib/forge-std/lib/ds-test/src/","forge-std/=lib/forge-std/src/","@lg-diamond-template/=lib/lg-diamond-template/","@cu-common/=lib/@lagunagames/cu-common/","@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/","@solidstate-contracts/=lib/solidstate-solidity/contracts/"],"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"optimizer":{"runs":999999,"enabled":true,"details":{"yulDetails":{"stackAllocation":true,"optimizerSteps":"dhfoDgvulfnTUtnIf"},"yul":true,"peephole":true,"inliner":true,"deduplicate":true,"cse":true}},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"libraries":{},"evmVersion":"paris"}
Contract ABI
[{"type":"constructor","stateMutability":"payable","inputs":[{"type":"address","name":"diamondCutFacet","internalType":"address"}]},{"type":"error","name":"DiamondAlreadyInitialized","inputs":[]},{"type":"error","name":"FunctionDoesNotExist","inputs":[{"type":"bytes4","name":"methodSelector","internalType":"bytes4"}]},{"type":"error","name":"InvalidFacetCutAction","inputs":[{"type":"uint8","name":"action","internalType":"enum IDiamondCut.FacetCutAction"}]},{"type":"fallback","stateMutability":"payable"},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initializeDiamond","inputs":[{"type":"address","name":"diamondCutFacet","internalType":"address"}]},{"type":"receive","stateMutability":"payable"}]
Contract Creation Code
0x60806040526200001862000012620000cd565b620000f0565b604051611a706200167d8239611a7090f35b634e487b7160e01b600052604160045260246000fd5b90601f01601f191681019081106001600160401b038211176200006257604052565b6200002a565b906200007f6200007760405190565b928362000040565b565b6001600160a01b031690565b90565b6001600160a01b03811603620000a257565b600080fd5b905051906200007f8262000090565b90602082820312620000a2576200008d91620000a7565b6200008d620030ed80380380620000e48162000068565b928339810190620000b6565b6200007f9062000293565b6200008d6200008d6200008d9290565b6001600160401b038111620000625760208091020190565b906200013962000133836200010b565b62000068565b918252565b6200008d606062000068565b620001546200013e565b600080825260208201526060604082015290565b6200008d6200014a565b60005b8281106200018257505050565b6020906200018f62000168565b818401520162000175565b906200007f620001b5620001ae8462000123565b936200010b565b601f19016020840162000172565b369037565b906200007f620001dc620001ae8462000123565b601f190160208401620001c3565b9052565b634e487b7160e01b600052602160045260246000fd5b600311156200020f57565b620001ee565b906200007f8262000204565b90620001ea9062000215565b634e487b7160e01b600052603260045260246000fd5b906200024d825190565b8110156200025f576020809102010190565b6200022d565b9060ff905b9181191691161790565b90620002876200008d6200028f92151590565b825462000265565b9055565b60036200029f62000547565b0190620002ad825460ff1690565b620003ae576200007f916200039d60019262000397620002cd85620000fb565b620002d8816200019a565b926200031f620002ea600093620001c8565b62000309620002f86200013e565b6001600160a01b0390941685850152565b62000318846020850162000221565b6040830152565b620003356200032e83620000fb565b8562000243565b526200034c6200034582620000fb565b8462000243565b506307e4c70760e21b906200038890620003816040620003776200037084620000fb565b8862000243565b51015191620000fb565b9062000243565b906001600160e01b0319169052565b62000739565b620003a83362000436565b62000274565b604051639289b96160e01b8152600490fd5b0390fd5b906001600160a01b03906200026a565b6200008d9062000081906001600160a01b031682565b6200008d90620003d4565b6200008d90620003ea565b90620004146200008d6200028f92620003f5565b8254620003c4565b6001600160a01b0391821681529116602082015260400190565b60006200044262000512565b019062000462816200045b84546001600160a01b031690565b9362000400565b7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e06200048e83620003f5565b6200049983620003f5565b91620004a460405190565b600090a37f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f91620004e2620004d860405190565b928392836200041c565b0390a1565b6200008d7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103620000fb565b6200008d620004e7565b6200008d7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c620000fb565b6200008d6200051c565b634e487b7160e01b600052601160045260246000fd5b6000198114620005775760010190565b62000551565b6200008d905162000215565b6200008d9062000215565b620001ea9062000589565b6020810192916200007f919062000594565b620000816200008d6200008d9290565b6200008d90620005b1565b0190565b90620005f3620005ec620005e2845190565b8084529260200190565b9260200190565b9060005b818110620006055750505090565b9091926200062e6200062760019286516001600160e01b031916815260200190565b9460200190565b929101620005f7565b80516001600160a01b031682526200008d916060810191604090620006656020820151602085019062000594565b0151906040818403910152620005d0565b906200008d9162000637565b906200069a62000690835190565b8083529160200190565b9081620006ad6020830284019460200190565b926000915b838310620006c257505050505090565b90919293946020620006e8620006e18385600195038752895162000676565b9760200190565b9301930191939290620006b2565b60608082526200008d9392620007279162000715919084019062000682565b6001600160a01b039093166020830152565b60408183039101526000815260200190565b9060005b6200074a6200008d845190565b8110156200089f576200076c602062000764838662000243565b51016200057d565b6000906200077a8262000215565b620007858262000215565b03620007d9575090620007cd620007b5620007d393620007a6848862000243565b5101516001600160a01b031690565b6040620007c3848862000243565b5101519062000a82565b62000567565b6200073d565b620007e5600162000215565b620007f08262000215565b0362000829575090620007cd62000811620007d393620007a6848862000243565b60406200081f848862000243565b5101519062000c68565b62000835600262000215565b620008408262000215565b0362000879575090620007cd62000861620007d393620007a6848862000243565b60406200086f848862000243565b5101519062000df7565b620003c0906200088860405190565b6332191c2960e01b8152918291600483016200059f565b5090620008ad6000620005c1565b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67391620004e2620008dd60405190565b92839283620006f6565b15620008ef57565b60405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b6064820152608490fd5b156200095057565b60405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b6064820152608490fd5b90620009b690620003f5565b600052602052604060002090565b620009d46200008d6200008d9290565b6001600160601b031690565b906001600160e01b031916620009b6565b15620009f957565b60405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608490fd5b6001600160601b03166001600160601b038114620005775760010190565b919062000a8d815190565b62000aae60009162000aa762000aa384620000fb565b9190565b11620008e7565b62000ab862000547565b62000ac382620005c1565b62000ae46001600160a01b0382166001600160a01b0388165b141562000948565b62000b0762000b018462000afc8960018701620009aa565b015490565b620009c4565b938462000b2562000b1886620009c4565b916001600160601b031690565b1462000be3575b6000945b62000b3d6200008d835190565b86101562000bd95762000bcb8162000bc58a62000bd2948962000bbe62000b9b8262000b8d8f62000b838f9162000b75908f62000243565b516001600160e01b03191690565b95869101620009e0565b01546001600160a01b031690565b62000bb76001600160a01b038c165b916001600160a01b031690565b14620009f1565b89620010fe565b62000a64565b9562000567565b9462000b30565b5050505050509050565b62000bef878462000fc8565b62000b2c565b1562000bfd57565b60405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608490fd5b815191929162000c8360009162000aa762000aa384620000fb565b62000c8d62000547565b9062000cb162000ca16200008183620005c1565b6001600160a01b03851662000adc565b62000cc962000b018262000afc8660018701620009aa565b948562000cda62000b1884620009c4565b1462000d72575b6000955b62000cf26200008d835190565b87101562000d695762000d5b8162000bc58762000d62948762000bbe8a62000d348f62000b8d62000d2962000b7587938f62000243565b8096819501620009e0565b62000d546001600160a01b0387166001600160a01b038316141562000bf5565b8c620013a2565b9662000567565b9562000ce5565b50505050509050565b62000d7e848462000fc8565b62000ce1565b1562000d8c57565b60405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608490fd5b8151600093929062000e129062000aa762000aa387620000fb565b62000e3b62000e2062000547565b9262000e3462000baa6200008188620005c1565b1462000d84565b60005b62000e4b6200008d835190565b81101562000e8c5780620007cd62000e6c62000b7562000e86948662000243565b62000e7f8862000b8d83828a01620009e0565b86620013a2565b62000e3e565b5050509050565b6001600160401b0381116200006257602090601f01601f19160190565b9062000139620001338362000e93565b62000ecc602462000eb0565b7f4c69624469616d6f6e644375743a204e657720666163657420686173206e6f20602082015263636f646560e01b604082015290565b6200008d62000ec0565b90600019906200026a565b9062000f2b6200008d6200028f92620000fb565b825462000f0c565b80548210156200025f5762000f4f600191600052602060002090565b91020190600090565b916001600160a01b0360089290920291821b911b6200026a565b921b90565b919062000f8c6200008d6200028f93620003f5565b90835462000f58565b908154916801000000000000000083101562000062578262000fc19160016200007f9501815562000f33565b9062000f77565b90620010106200007f9262000fe762000fe062000f02565b846200165e565b6200008d6002820191600162001009868262001001875490565b9401620009aa565b0162000f17565b62000f95565b906001600160a01b03199060a01b6200026a565b6200008d90620009d4906001600160601b031682565b90620010546200008d6200028f926200102a565b825462001016565b80549192918310156200025f5760086200107d600492600052602060002090565b8185040193060290565b919060086200026a91029162000f7263ffffffff841b90565b9190620010c2620010bc6200028f936001600160e01b03191690565b60e01c90565b90835462001087565b9081549168010000000000000000831015620000625782620010f79160016200007f950181556200105c565b90620010a0565b818493620011466000946200114086620005cc6200007f9a60016200114c99620011398582019986620011328a8d620009e0565b0162001040565b01620009aa565b620010cb565b620009e0565b0162000400565b156200115b57565b60405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608490fd5b15620011ce57565b60405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608490fd5b6200008d9060a01c620009d4565b6200008d90546200122a565b6200008d9081906001600160601b031681565b919082039182116200057757565b6200008d916008021c60e01b90565b906200008d915462001265565b634e487b7160e01b600052603160045260246000fd5b6200007f91600091620010a0565b80548015620012cd576000190190620012ca620012c383836200105c565b9062001297565b55565b62001281565b634e487b7160e01b600052600060045260246000fd5b90600003620012f85760009055565b620012d3565b6200008d9081565b6200008d9054620012fe565b6200008d916008021c62000081565b906200008d915462001312565b6200007f9160009162000f77565b80548015620012cd576000190190620012ca6200135a838362000f33565b906200132e565b9160001960089290920291821b911b6200026a565b91906200138b6200008d6200028f93620000fb565b90835462001361565b6200007f9160009162001376565b620014569092919283600093620013d3620013c16200008187620005c1565b6001600160a01b038416141562001153565b620013f8620013e66200008130620003f5565b6001600160a01b0384161415620011c6565b6200148f8562001489818601936200142762001421846200141a8489620009e0565b0162001238565b62001244565b946200143c8462000afc8960018c01620009aa565b87858a60019c8d946200144f86620000fb565b9062001257565b809a620014608290565b81036200155f575b50506200148392506200114693620005cc91019e8f620009aa565b620012a5565b620012e9565b6200149e62000aa386620000fb565b14620014ac575b5050505050565b6200151494620015076200150160026200150d9501620014d9620014ce825490565b6200144f89620000fb565b620014f188620014ea8888620009aa565b0162001306565b888282036200151f575b50505090565b6200133c565b620009aa565b0162001394565b3880808080620014a5565b620010096200153e6200153762001556958762000f33565b9062001321565b6200154f8162000fc1868962000f33565b88620009aa565b388088620014fb565b62000b0185620010f7838762001594620015a26200159b620015ab9984620015b39f6200159490620011329e01998a620009aa565b016200105c565b9062001274565b9a8b95620009aa565b9285620009e0565b8887858a893862001468565b60005b838110620015d35750506000910152565b8181015183820152602001620015c2565b6200160962001613602093620005cc93620015fd815190565b80835293849260200190565b95869101620015bf565b601f01601f191690565b60208082526200008d92910190620015e4565b15620016395750565b620003c0906200164860405190565b62461bcd60e51b8152918291600483016200161d565b6200007f91903b6200167562000aa36000620000fb565b116200163056fe60806040526004361015610015575b366100f557005b60003560e01c630751e5b50361000e5761008c565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b73ffffffffffffffffffffffffffffffffffffffff81160361006457565b600080fd5b9050359061007682610046565b565b906020828203126100645761004391610069565b34610064576100a461009f366004610078565b61047f565b604051005b907fffffffff00000000000000000000000000000000000000000000000000000000165b600052602052604060002090565b61002a6100436100439290565b610043906100db565b9052565b61014c600061013181610106610776565b017fffffffff00000000000000000000000000000000000000000000000000000000833516906100a9565b015473ffffffffffffffffffffffffffffffffffffffff1690565b60009061015b61002a836100e8565b73ffffffffffffffffffffffffffffffffffffffff82161461019457818091368280378136915af43d82803e15610190573d90f35b3d90fd5b61021a7fffffffff000000000000000000000000000000000000000000000000000000008335166101c460405190565b9182917ff8473e6b000000000000000000000000000000000000000000000000000000008352600483017fffffffff00000000000000000000000000000000000000000000000000000000909116815260200190565b0390fd5b6100436100436100439290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810190811067ffffffffffffffff82111761029a57604052565b61022b565b906100766102ac60405190565b928361025a565b67ffffffffffffffff811161029a5760208091020190565b906102dd6102d8836102b3565b61029f565b918252565b610043606061029f565b6102f46102e2565b600080825260208201526060604082015290565b6100436102ec565b60005b82811061031f57505050565b60209061032a610308565b8184015201610313565b9061007661034a610344846102cb565b936102b3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00160208401610310565b369037565b9061007661038a610344846102cb565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00160208401610375565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600311156103ee57565b6103b5565b90610076826103e4565b906100f1906103f3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9061043f825190565b811015610450576020809102010190565b610407565b9060ff905b9181191691161790565b9061047461004361047b92151590565b8254610455565b9055565b6003610489610776565b0190610496825460ff1690565b6105b157610076916105a360019261059e6104b08561021e565b6104b981610334565b926105056104c860009361037a565b6104f16104d36102e2565b73ffffffffffffffffffffffffffffffffffffffff90941685850152565b6104fe84602085016103fd565b6040830152565b6105176105118361021e565b85610436565b5261052a6105248261021e565b84610436565b51506105777f1f931c1c000000000000000000000000000000000000000000000000000000009161057160406105686105628461021e565b88610436565b5101519161021e565b90610436565b907fffffffff00000000000000000000000000000000000000000000000000000000169052565b610991565b6105ac3361066b565b610464565b6040517f9289b961000000000000000000000000000000000000000000000000000000008152600490fd5b9073ffffffffffffffffffffffffffffffffffffffff9061045a565b61002a6100436100439273ffffffffffffffffffffffffffffffffffffffff1690565b610043906105f8565b6100439061061b565b9061063d61004361047b92610624565b82546105dc565b73ffffffffffffffffffffffffffffffffffffffff91821681529116602082015260400190565b6000610675610745565b019061069f81610699845473ffffffffffffffffffffffffffffffffffffffff1690565b9361062d565b7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e06106c983610624565b6106d283610624565b916106dc60405190565b600090a37f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f9161071761070e60405190565b92839283610644565b0390a1565b6100437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610361021e565b61004361071c565b6100437fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c61021e565b61004361074d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146107da5760010190565b61077e565b61004390516103f3565b610043906103f3565b6100f1906107e9565b60208101929161007691906107f2565b0190565b9061082f61082861081e845190565b8084529260200190565b9260200190565b9060005b8181106108405750505090565b90919261087f61087860019286517fffffffff0000000000000000000000000000000000000000000000000000000016815260200190565b9460200190565b929101610833565b805173ffffffffffffffffffffffffffffffffffffffff1682526100439160608101916040906108bf602082015160208501906107f2565b015190604081840391015261080f565b9061004391610887565b906108ef6108e5835190565b8083529160200190565b90816109016020830284019460200190565b926000915b83831061091557505050505090565b90919293946020610938610931838560019503875289516108cf565b9760200190565b9301930191939290610906565b6060808252610043939261097f9161096091908401906108d9565b73ffffffffffffffffffffffffffffffffffffffff9093166020830152565b60408183039101526000815260200190565b9060005b6109a0610043845190565b811015610aea576109bd60206109b68386610436565b51016107df565b6000906109c9826103f3565b6109d2826103f3565b03610a28575090610a1e610a09610a23936109ed8488610436565b51015173ffffffffffffffffffffffffffffffffffffffff1690565b6040610a158488610436565b51015190610d20565b6107ad565b610995565b610a3260016103f3565b610a3b826103f3565b03610a6b575090610a1e610a56610a23936109ed8488610436565b6040610a628488610436565b51015190610f37565b610a7560026103f3565b610a7e826103f3565b03610aae575090610a1e610a99610a23936109ed8488610436565b6040610aa58488610436565b510151906110de565b61021a90610abb60405190565b9182917f32191c29000000000000000000000000000000000000000000000000000000008352600483016107fb565b5090610af660006100e8565b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67391610717610b2460405190565b92839283610945565b15610b3457565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608490fd5b15610bc057565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608490fd5b906100cd90610624565b610c5c6100436100439290565b6bffffffffffffffffffffffff1690565b15610c7457565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608490fd5b6bffffffffffffffffffffffff166bffffffffffffffffffffffff81146107da5760010190565b9190610d2a815190565b610d46600091610d40610d3c8461021e565b9190565b11610b2d565b610d4e610776565b610d57826100e8565b610d9073ffffffffffffffffffffffffffffffffffffffff821673ffffffffffffffffffffffffffffffffffffffff88165b1415610bb9565b610dae610da984610da48960018701610c45565b015490565b610c4f565b9384610dce610dbc86610c4f565b916bffffffffffffffffffffffff1690565b14610e9c575b6000945b610de3610043835190565b861015610e9257610e8681610e818a610e8c9489610e7b610e40826101318f610e378f91610e11908f610436565b517fffffffff000000000000000000000000000000000000000000000000000000001690565b958691016100a9565b610e7573ffffffffffffffffffffffffffffffffffffffff8c165b9173ffffffffffffffffffffffffffffffffffffffff1690565b14610c6d565b8961142b565b610cf9565b956107ad565b94610dd8565b5050505050509050565b610ea687846112df565b610dd4565b15610eb257565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608490fd5b8151919291610f4e600091610d40610d3c8461021e565b610f56610776565b90610f82610f6661002a836100e8565b73ffffffffffffffffffffffffffffffffffffffff8516610d89565b610f96610da982610da48660018701610c45565b9485610fa4610dbc84610c4f565b14611043575b6000955b610fb9610043835190565b87101561103a5761102e81610e81876110349487610e7b8a610ff08f610131610fe6610e1187938f610436565b80968195016100a9565b61102873ffffffffffffffffffffffffffffffffffffffff871673ffffffffffffffffffffffffffffffffffffffff83161415610eab565b8c611770565b966107ad565b95610fae565b50505050509050565b61104d84846112df565b610faa565b1561105957565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608490fd5b815160009392906110f590610d40610d3c8761021e565b611116611100610776565b92611110610e5b61002a886100e8565b14611052565b60005b611124610043835190565b81101561115a5780610a1e61113f610e116111559486610436565b61114f8861013183828a016100a9565b86611770565b611119565b5050509050565b67ffffffffffffffff811161029a57602090601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b906102dd6102d883611161565b6111b3602461119c565b7f4c69624469616d6f6e644375743a204e657720666163657420686173206e6f2060208201527f636f646500000000000000000000000000000000000000000000000000000000604082015290565b6100436111a9565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9061045a565b9061124261004361047b9261021e565b825461120a565b805482101561045057611263600191600052602060002090565b91020190600090565b9190600861045a91029161129373ffffffffffffffffffffffffffffffffffffffff841b90565b921b90565b91906112a961004361047b93610624565b90835461126c565b908154916801000000000000000083101561029a57826112d991600161007695018155611249565b90611298565b9061131c610076926112f86112f2611202565b84611a21565b61004360028201916001611316868261130f875490565b9401610c45565b01611232565b6112b1565b907fffffffffffffffffffffffff00000000000000000000000000000000000000009060a01b61045a565b610c5c610043610043926bffffffffffffffffffffffff1690565b9061137761004361047b9261134c565b8254611321565b805491929183101561045057600861139d600492600052602060002090565b8185040193060290565b9190600861045a91029161129363ffffffff841b90565b91906113f56113ef61047b937fffffffff000000000000000000000000000000000000000000000000000000001690565b60e01c90565b9083546113a7565b908154916801000000000000000083101561029a57826114259160016100769501815561137e565b906113be565b8184936114686000946114638661080b6100769a600161146d9961145d85820199866114578a8d6100a9565b01611367565b01610c45565b6113fd565b6100a9565b0161062d565b1561147a57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608490fd5b1561150657565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608490fd5b6100439060a01c610c5c565b610043905461158b565b610043610043610043926bffffffffffffffffffffffff1690565b919082039182116107da57565b610043916008021c60e01b90565b9061004391546115c9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b610076916000916113be565b8054801561165e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019061165b611655838361137e565b90611611565b55565b6115e2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b906000036116a05760009055565b611663565b6100439081565b61004390546116a5565b610043916008021c61002a565b9061004391546116b6565b61007691600091611298565b8054801561165e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019061165b6117128383611249565b906116ce565b9190600861045a9102916112937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841b90565b919061175c61004361047b9361021e565b908354611718565b6100769160009161174b565b61182590929192836000936117a861178a61002a876100e8565b73ffffffffffffffffffffffffffffffffffffffff84161415611473565b6117d56117b761002a30610624565b73ffffffffffffffffffffffffffffffffffffffff841614156114ff565b61185685611851818601936117fc6117f7846117f184896100a9565b01611597565b6115a1565b9461180e84610da48960018c01610c45565b87858a60019c8d9461181f8661021e565b906115bc565b809a61182e8290565b8103611906575b505061184c92506114689361080b91019e8f610c45565b61161d565b611692565b611862610d3c8661021e565b1461186f575b5050505050565b6118c7946118bc6118b760026118c1950161189461188b825490565b61181f8961021e565b6118a8886118a28888610c45565b016116ac565b888282036118d1575b50505090565b6116da565b610c45565b01611764565b3880808080611868565b6113166118ea6118e46118fe9587611249565b906116c3565b6118f8816112d98689611249565b88610c45565b3880886118b1565b610da985611425838761193161193d611937611945998461194c9f611931906114579e01998a610c45565b0161137e565b906115d7565b9a8b95610c45565b92856100a9565b8887858a8938611835565b60005b83811061196a5750506000910152565b818101518382015260200161195a565b61199b6119a460209361080b9361198f815190565b80835293849260200190565b95869101611957565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690565b60208082526100439291019061197a565b156119e55750565b61021a906119f260405190565b9182917f08c379a0000000000000000000000000000000000000000000000000000000008352600483016119cc565b61007691903b611a34610d3c600061021e565b116119dd56fea26469706673582212203e3403f4d4abb6812d3539c676a4399ede44ef4855711421645e80bd9adf150864736f6c63430008130033000000000000000000000000efd739b52045d112c37c5d89a8771b31c165879c
Deployed ByteCode
0x60806040526004361015610015575b366100f557005b60003560e01c630751e5b50361000e5761008c565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b73ffffffffffffffffffffffffffffffffffffffff81160361006457565b600080fd5b9050359061007682610046565b565b906020828203126100645761004391610069565b34610064576100a461009f366004610078565b61047f565b604051005b907fffffffff00000000000000000000000000000000000000000000000000000000165b600052602052604060002090565b61002a6100436100439290565b610043906100db565b9052565b61014c600061013181610106610776565b017fffffffff00000000000000000000000000000000000000000000000000000000833516906100a9565b015473ffffffffffffffffffffffffffffffffffffffff1690565b60009061015b61002a836100e8565b73ffffffffffffffffffffffffffffffffffffffff82161461019457818091368280378136915af43d82803e15610190573d90f35b3d90fd5b61021a7fffffffff000000000000000000000000000000000000000000000000000000008335166101c460405190565b9182917ff8473e6b000000000000000000000000000000000000000000000000000000008352600483017fffffffff00000000000000000000000000000000000000000000000000000000909116815260200190565b0390fd5b6100436100436100439290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810190811067ffffffffffffffff82111761029a57604052565b61022b565b906100766102ac60405190565b928361025a565b67ffffffffffffffff811161029a5760208091020190565b906102dd6102d8836102b3565b61029f565b918252565b610043606061029f565b6102f46102e2565b600080825260208201526060604082015290565b6100436102ec565b60005b82811061031f57505050565b60209061032a610308565b8184015201610313565b9061007661034a610344846102cb565b936102b3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00160208401610310565b369037565b9061007661038a610344846102cb565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00160208401610375565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600311156103ee57565b6103b5565b90610076826103e4565b906100f1906103f3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9061043f825190565b811015610450576020809102010190565b610407565b9060ff905b9181191691161790565b9061047461004361047b92151590565b8254610455565b9055565b6003610489610776565b0190610496825460ff1690565b6105b157610076916105a360019261059e6104b08561021e565b6104b981610334565b926105056104c860009361037a565b6104f16104d36102e2565b73ffffffffffffffffffffffffffffffffffffffff90941685850152565b6104fe84602085016103fd565b6040830152565b6105176105118361021e565b85610436565b5261052a6105248261021e565b84610436565b51506105777f1f931c1c000000000000000000000000000000000000000000000000000000009161057160406105686105628461021e565b88610436565b5101519161021e565b90610436565b907fffffffff00000000000000000000000000000000000000000000000000000000169052565b610991565b6105ac3361066b565b610464565b6040517f9289b961000000000000000000000000000000000000000000000000000000008152600490fd5b9073ffffffffffffffffffffffffffffffffffffffff9061045a565b61002a6100436100439273ffffffffffffffffffffffffffffffffffffffff1690565b610043906105f8565b6100439061061b565b9061063d61004361047b92610624565b82546105dc565b73ffffffffffffffffffffffffffffffffffffffff91821681529116602082015260400190565b6000610675610745565b019061069f81610699845473ffffffffffffffffffffffffffffffffffffffff1690565b9361062d565b7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e06106c983610624565b6106d283610624565b916106dc60405190565b600090a37f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f9161071761070e60405190565b92839283610644565b0390a1565b6100437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610361021e565b61004361071c565b6100437fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c61021e565b61004361074d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146107da5760010190565b61077e565b61004390516103f3565b610043906103f3565b6100f1906107e9565b60208101929161007691906107f2565b0190565b9061082f61082861081e845190565b8084529260200190565b9260200190565b9060005b8181106108405750505090565b90919261087f61087860019286517fffffffff0000000000000000000000000000000000000000000000000000000016815260200190565b9460200190565b929101610833565b805173ffffffffffffffffffffffffffffffffffffffff1682526100439160608101916040906108bf602082015160208501906107f2565b015190604081840391015261080f565b9061004391610887565b906108ef6108e5835190565b8083529160200190565b90816109016020830284019460200190565b926000915b83831061091557505050505090565b90919293946020610938610931838560019503875289516108cf565b9760200190565b9301930191939290610906565b6060808252610043939261097f9161096091908401906108d9565b73ffffffffffffffffffffffffffffffffffffffff9093166020830152565b60408183039101526000815260200190565b9060005b6109a0610043845190565b811015610aea576109bd60206109b68386610436565b51016107df565b6000906109c9826103f3565b6109d2826103f3565b03610a28575090610a1e610a09610a23936109ed8488610436565b51015173ffffffffffffffffffffffffffffffffffffffff1690565b6040610a158488610436565b51015190610d20565b6107ad565b610995565b610a3260016103f3565b610a3b826103f3565b03610a6b575090610a1e610a56610a23936109ed8488610436565b6040610a628488610436565b51015190610f37565b610a7560026103f3565b610a7e826103f3565b03610aae575090610a1e610a99610a23936109ed8488610436565b6040610aa58488610436565b510151906110de565b61021a90610abb60405190565b9182917f32191c29000000000000000000000000000000000000000000000000000000008352600483016107fb565b5090610af660006100e8565b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67391610717610b2460405190565b92839283610945565b15610b3457565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608490fd5b15610bc057565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608490fd5b906100cd90610624565b610c5c6100436100439290565b6bffffffffffffffffffffffff1690565b15610c7457565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608490fd5b6bffffffffffffffffffffffff166bffffffffffffffffffffffff81146107da5760010190565b9190610d2a815190565b610d46600091610d40610d3c8461021e565b9190565b11610b2d565b610d4e610776565b610d57826100e8565b610d9073ffffffffffffffffffffffffffffffffffffffff821673ffffffffffffffffffffffffffffffffffffffff88165b1415610bb9565b610dae610da984610da48960018701610c45565b015490565b610c4f565b9384610dce610dbc86610c4f565b916bffffffffffffffffffffffff1690565b14610e9c575b6000945b610de3610043835190565b861015610e9257610e8681610e818a610e8c9489610e7b610e40826101318f610e378f91610e11908f610436565b517fffffffff000000000000000000000000000000000000000000000000000000001690565b958691016100a9565b610e7573ffffffffffffffffffffffffffffffffffffffff8c165b9173ffffffffffffffffffffffffffffffffffffffff1690565b14610c6d565b8961142b565b610cf9565b956107ad565b94610dd8565b5050505050509050565b610ea687846112df565b610dd4565b15610eb257565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608490fd5b8151919291610f4e600091610d40610d3c8461021e565b610f56610776565b90610f82610f6661002a836100e8565b73ffffffffffffffffffffffffffffffffffffffff8516610d89565b610f96610da982610da48660018701610c45565b9485610fa4610dbc84610c4f565b14611043575b6000955b610fb9610043835190565b87101561103a5761102e81610e81876110349487610e7b8a610ff08f610131610fe6610e1187938f610436565b80968195016100a9565b61102873ffffffffffffffffffffffffffffffffffffffff871673ffffffffffffffffffffffffffffffffffffffff83161415610eab565b8c611770565b966107ad565b95610fae565b50505050509050565b61104d84846112df565b610faa565b1561105957565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608490fd5b815160009392906110f590610d40610d3c8761021e565b611116611100610776565b92611110610e5b61002a886100e8565b14611052565b60005b611124610043835190565b81101561115a5780610a1e61113f610e116111559486610436565b61114f8861013183828a016100a9565b86611770565b611119565b5050509050565b67ffffffffffffffff811161029a57602090601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b906102dd6102d883611161565b6111b3602461119c565b7f4c69624469616d6f6e644375743a204e657720666163657420686173206e6f2060208201527f636f646500000000000000000000000000000000000000000000000000000000604082015290565b6100436111a9565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9061045a565b9061124261004361047b9261021e565b825461120a565b805482101561045057611263600191600052602060002090565b91020190600090565b9190600861045a91029161129373ffffffffffffffffffffffffffffffffffffffff841b90565b921b90565b91906112a961004361047b93610624565b90835461126c565b908154916801000000000000000083101561029a57826112d991600161007695018155611249565b90611298565b9061131c610076926112f86112f2611202565b84611a21565b61004360028201916001611316868261130f875490565b9401610c45565b01611232565b6112b1565b907fffffffffffffffffffffffff00000000000000000000000000000000000000009060a01b61045a565b610c5c610043610043926bffffffffffffffffffffffff1690565b9061137761004361047b9261134c565b8254611321565b805491929183101561045057600861139d600492600052602060002090565b8185040193060290565b9190600861045a91029161129363ffffffff841b90565b91906113f56113ef61047b937fffffffff000000000000000000000000000000000000000000000000000000001690565b60e01c90565b9083546113a7565b908154916801000000000000000083101561029a57826114259160016100769501815561137e565b906113be565b8184936114686000946114638661080b6100769a600161146d9961145d85820199866114578a8d6100a9565b01611367565b01610c45565b6113fd565b6100a9565b0161062d565b1561147a57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608490fd5b1561150657565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608490fd5b6100439060a01c610c5c565b610043905461158b565b610043610043610043926bffffffffffffffffffffffff1690565b919082039182116107da57565b610043916008021c60e01b90565b9061004391546115c9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b610076916000916113be565b8054801561165e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019061165b611655838361137e565b90611611565b55565b6115e2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b906000036116a05760009055565b611663565b6100439081565b61004390546116a5565b610043916008021c61002a565b9061004391546116b6565b61007691600091611298565b8054801561165e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019061165b6117128383611249565b906116ce565b9190600861045a9102916112937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841b90565b919061175c61004361047b9361021e565b908354611718565b6100769160009161174b565b61182590929192836000936117a861178a61002a876100e8565b73ffffffffffffffffffffffffffffffffffffffff84161415611473565b6117d56117b761002a30610624565b73ffffffffffffffffffffffffffffffffffffffff841614156114ff565b61185685611851818601936117fc6117f7846117f184896100a9565b01611597565b6115a1565b9461180e84610da48960018c01610c45565b87858a60019c8d9461181f8661021e565b906115bc565b809a61182e8290565b8103611906575b505061184c92506114689361080b91019e8f610c45565b61161d565b611692565b611862610d3c8661021e565b1461186f575b5050505050565b6118c7946118bc6118b760026118c1950161189461188b825490565b61181f8961021e565b6118a8886118a28888610c45565b016116ac565b888282036118d1575b50505090565b6116da565b610c45565b01611764565b3880808080611868565b6113166118ea6118e46118fe9587611249565b906116c3565b6118f8816112d98689611249565b88610c45565b3880886118b1565b610da985611425838761193161193d611937611945998461194c9f611931906114579e01998a610c45565b0161137e565b906115d7565b9a8b95610c45565b92856100a9565b8887858a8938611835565b60005b83811061196a5750506000910152565b818101518382015260200161195a565b61199b6119a460209361080b9361198f815190565b80835293849260200190565b95869101611957565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690565b60208082526100439291019061197a565b156119e55750565b61021a906119f260405190565b9182917f08c379a0000000000000000000000000000000000000000000000000000000008352600483016119cc565b61007691903b611a34610d3c600061021e565b116119dd56fea26469706673582212203e3403f4d4abb6812d3539c676a4399ede44ef4855711421645e80bd9adf150864736f6c63430008130033