Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- DiamondCutFacet
- Optimization enabled
- true
- Compiler version
- v0.8.19+commit.7dd6d404
- Optimization runs
- 999999
- EVM Version
- paris
- Verified at
- 2024-05-20T18:03:41.067239Z
lib/@lagunagames/lg-diamond-template/src/diamond/DiamondCutFacet.sol
//SPDX-License-Identifier: UNLICENSED 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 extended DiamondCut Facet /// @notice Adapted from the Diamond 3 reference implementation by Nick Mudge: /// @notice https://github.com/mudgen/diamond-3-hardhat contract DiamondCutFacet is IDiamondCut { /// @notice Add/replace/remove any number of functions and optionally execute /// a function with delegatecall /// @dev The LG implementation DOES NOT SUPPORT initializers! /// @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 /// @custom:selector 0x1f931c1c == bytes4(keccak256("diamondCut((address,uint8,bytes4[])[],address,bytes)")) function diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata) external override { (_init); // noop (_calldata); // noop LibDiamond.enforceIsContractOwner(); LibDiamond.diamondCut(_diamondCut); } /// @notice Add/replace/remove any number of functions and optionally execute /// a function with delegatecall /// @dev This is a convenience implementation of the above /// @param _diamondCut Contains the facet addresses and function selectors /// @custom:selector 0xe57e69c6 == bytes4(keccak256("diamondCut((address,uint8,bytes4[])[])")) function diamondCut(FacetCut[] calldata _diamondCut) external { LibDiamond.enforceIsContractOwner(); LibDiamond.diamondCut(_diamondCut); } /// @notice Removes one selector from the Diamond, using DiamondCut /// @param selector - The byte4 signature for a method selector to remove /// @custom:emits FacetCutAction function cutSelector(bytes4 selector) external { LibContractOwner.enforceIsContractOwner(); IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1); bytes4[] memory functionSelectors = new bytes4[](1); functionSelectors[0] = selector; cut[0] = IDiamondCut.FacetCut({ facetAddress: address(0), action: IDiamondCut.FacetCutAction.Remove, functionSelectors: functionSelectors }); LibDiamond.diamondCut(cut); } /// @notice Removes one selector from the Diamond, using removeFunction() /// @param selector - The byte4 signature for a method selector to remove function deleteSelector(bytes4 selector) external { LibContractOwner.enforceIsContractOwner(); LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); LibDiamond.removeFunction(ds, ds.selectorToFacetAndPosition[selector].facetAddress, selector); } /// @notice Removes many selectors from the Diamond, using DiamondCut /// @param selectors - Array of byte4 signatures for method selectors to remove /// @custom:emits FacetCutAction function cutSelectors(bytes4[] memory selectors) external { LibContractOwner.enforceIsContractOwner(); IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1); cut[0] = IDiamondCut.FacetCut({ facetAddress: address(0), action: IDiamondCut.FacetCutAction.Remove, functionSelectors: selectors }); LibDiamond.diamondCut(cut); } /// @notice Removes many selectors from the Diamond, using removeFunctions() /// @param selectors - Array of byte4 signatures for method selectors to remove function deleteSelectors(bytes4[] memory selectors) external { LibContractOwner.enforceIsContractOwner(); LibDiamond.removeFunctions(address(0), selectors); } /// @notice Removes any selectors from the Diamond that come from a target /// @notice contract address, using DiamondCut. /// @param facet - The address of the Facet smart contract to remove /// @custom:emits FacetCutAction function cutFacet(address facet) external { LibContractOwner.enforceIsContractOwner(); LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1); cut[0] = IDiamondCut.FacetCut({ facetAddress: address(0), action: IDiamondCut.FacetCutAction.Remove, functionSelectors: ds.facetFunctionSelectors[facet].functionSelectors }); LibDiamond.diamondCut(cut); } }
lib/@lagunagames/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/@lagunagames/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/@lagunagames/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/"],"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":"error","name":"CallerIsNotContractOwner","inputs":[]},{"type":"error","name":"InvalidFacetCutAction","inputs":[{"type":"uint8","name":"action","internalType":"enum IDiamondCut.FacetCutAction"}]},{"type":"event","name":"DiamondCut","inputs":[{"type":"tuple[]","name":"_diamondCut","internalType":"struct IDiamondCut.FacetCut[]","indexed":false,"components":[{"type":"address","name":"facetAddress","internalType":"address"},{"type":"uint8","name":"action","internalType":"enum IDiamondCut.FacetCutAction"},{"type":"bytes4[]","name":"functionSelectors","internalType":"bytes4[]"}]},{"type":"address","name":"_init","internalType":"address","indexed":false},{"type":"bytes","name":"_calldata","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cutFacet","inputs":[{"type":"address","name":"facet","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cutSelector","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cutSelectors","inputs":[{"type":"bytes4[]","name":"selectors","internalType":"bytes4[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"deleteSelector","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"deleteSelectors","inputs":[{"type":"bytes4[]","name":"selectors","internalType":"bytes4[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"diamondCut","inputs":[{"type":"tuple[]","name":"_diamondCut","internalType":"struct IDiamondCut.FacetCut[]","components":[{"type":"address","name":"facetAddress","internalType":"address"},{"type":"uint8","name":"action","internalType":"enum IDiamondCut.FacetCutAction"},{"type":"bytes4[]","name":"functionSelectors","internalType":"bytes4[]"}]},{"type":"address","name":"_init","internalType":"address"},{"type":"bytes","name":"_calldata","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"diamondCut","inputs":[{"type":"tuple[]","name":"_diamondCut","internalType":"struct IDiamondCut.FacetCut[]","components":[{"type":"address","name":"facetAddress","internalType":"address"},{"type":"uint8","name":"action","internalType":"enum IDiamondCut.FacetCutAction"},{"type":"bytes4[]","name":"functionSelectors","internalType":"bytes4[]"}]}]}]
Contract Creation Code
0x60806040523461001a57604051611fc36100208239611fc390f35b600080fdfe6080604052600436101561001257600080fd5b60003560e01c80631f931c1c146100825780636463e3a01461007d578063a6638c0e14610078578063debb385614610073578063e0435c0b1461006e578063e57e69c6146100695763ff6f3e0b03610087576103e2565b6103c9565b61038b565b610373565b610347565b61031b565b610192565b600080fd5b909182601f830112156100875781359167ffffffffffffffff831161008757602001926020830284011161008757565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b73ffffffffffffffffffffffffffffffffffffffff81165b0361008757565b90503590610104826100d8565b565b909182601f830112156100875781359167ffffffffffffffff831161008757602001926001830284011161008757565b919060608382031261008757823567ffffffffffffffff8111610087578161015f91850161008c565b92909361016f83602083016100f7565b92604082013567ffffffffffffffff81116100875761018e9201610106565b9091565b34610087576101ae6101a5366004610136565b939290926104dc565b604051005b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810190811067ffffffffffffffff82111761022257604052565b6101b3565b9061010461023460405190565b92836101e2565b67ffffffffffffffff81116102225760208091020190565b7fffffffff0000000000000000000000000000000000000000000000000000000081166100f0565b9050359061010482610253565b9092919261029d6102988261023b565b610227565b938185526020808601920283019281841161008757915b8383106102c15750505050565b602080916102cf848661027b565b8152019201916102b4565b9080601f83011215610087578160206100d593359101610288565b9060208282031261008757813567ffffffffffffffff8111610087576100d592016102da565b34610087576101ae61032e3660046102f5565b610801565b90602082820312610087576100d5916100f7565b34610087576101ae61035a366004610333565b610b64565b90602082820312610087576100d59161027b565b34610087576101ae61038636600461035f565b6106b7565b34610087576101ae61039e36600461035f565b6107d2565b9060208282031261008757813567ffffffffffffffff81116100875761018e920161008c565b34610087576101ae6103dc3660046103a3565b906104fb565b34610087576101ae6103f53660046102f5565b610835565b6003111561008757565b90503590610104826103fa565b919091606081840312610087576104286060610227565b92600061043582846100f7565b90850152602061044782828501610404565b90850152604082013567ffffffffffffffff81116100875761046992016102da565b6040830152565b92919061047f6102988261023b565b93818552602080860192028101918383116100875781905b8382106104a5575050505050565b813567ffffffffffffffff8111610087576020916104c68784938701610411565b815201910190610497565b6100d5913691610470565b90915061010493506104f692506104f1610cb1565b6104d1565b610ec2565b610104916104f6916104f1610cb1565b6100d56100d56100d59290565b906105256102988361023b565b918252565b6100d56060610227565b61053c61052a565b600080825260208201526060604082015290565b6100d5610534565b60005b82811061056757505050565b602090610572610550565b818401520161055b565b9061010461059261058c84610518565b9361023b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00160208401610558565b369037565b906101046105d261058c84610518565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001602084016105bd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90610635825190565b811015610646576020809102010190565b6105fd565b9052565b6100bc6100d56100d59290565b6100d59061064f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6003111561069e57565b610665565b9061010482610694565b9061064b906106a3565b610104906106c3610beb565b6107876107816106d3600161050b565b926106e66106e08561057c565b946105c2565b6107256000926106fe6106f88561050b565b8461062c565b907fffffffff00000000000000000000000000000000000000000000000000000000169052565b6107696107318361065c565b91610469600261076061074261052a565b73ffffffffffffffffffffffffffffffffffffffff90961687870152565b602085016106ad565b61077b6107758361050b565b8661062c565b5261050b565b8261062c565b50610ec2565b907fffffffff00000000000000000000000000000000000000000000000000000000165b600052602052604060002090565b6100d5906100bc565b6100d590546107bf565b610104906107de610beb565b6107e6610ca9565b6107fb60006107f5848461078d565b016107c8565b90611cc3565b6101049061080d610beb565b610787610781610825610820600161050b565b61057c565b926000906107696107318361065c565b61010490610841610beb565b61084b600061065c565b6115f4565b6100bc6100d56100d59273ffffffffffffffffffffffffffffffffffffffff1690565b6100d590610850565b6100d590610873565b906107b19061087c565b6100d59060201c60e01b90565b6100d59060401c60e01b90565b6100d59060601c60e01b90565b6100d59060801c60e01b90565b6100d59060a01c60e01b90565b6100d59060c01c60e01b90565b906109026108f66108ec845490565b8084529260200190565b92600052602060002090565b906000915b600783018211610a82575490808310610a64575b808310610a47575b808310610a2a575b808310610a0d575b8083106109f0575b8083106109d3575b8083106109b6575b821061095657505090565b826109af600193946109896020947fffffffff000000000000000000000000000000000000000000000000000000001690565b7fffffffff00000000000000000000000000000000000000000000000000000000169052565b0191505090565b91926020816109ca600193610989866108d0565b0193019161094b565b91926020816109e7600193610989866108c3565b01930191610943565b9192602081610a04600193610989866108b6565b0193019161093b565b9192602081610a21600193610989866108a9565b01930191610933565b9192602081610a3e6001936109898661089c565b0193019161092b565b9192602081610a5b6001936109898661088f565b01930191610923565b9192602081610a796001936109898660e01b90565b0193019161091b565b9260016020610989610b25600894838080808080808f5497610aa8816109898b60e01b90565b01610ab6816109898a61088f565b01610ac4816109898961089c565b01610ad281610989886108a9565b01610ae081610989876108b6565b01610aee81610989866108c3565b01610afc81610989856108d0565b019283917fffffffff000000000000000000000000000000000000000000000000000000001690565b019401920191610907565b906100d5916108dd565b90610104610b5492610b4b60405190565b93848092610b30565b03836101e2565b6100d590610b3a565b61010490610b70610beb565b610787610781610bb2610b81610ca9565b610769610469600192610be6610b996108208661050b565b986000968791610ba88361065c565b9760029501610885565b0191610bdd610bbf61052a565b73ffffffffffffffffffffffffffffffffffffffff90971688880152565b602086016106ad565b610b5b565b33610c19610bff6100bc60006107f5610c78565b9173ffffffffffffffffffffffffffffffffffffffff1690565b03610c2057565b6040517ff5d3c8cc000000000000000000000000000000000000000000000000000000008152600490fd5b0390fd5b6100d57fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610361050b565b6100d5610c4f565b6100d57fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c61050b565b6100d5610c80565b610104610beb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610d155760010190565b610cb9565b6100d590516106a3565b6100d5906106a3565b61064b90610d24565b6020810192916101049190610d2d565b0190565b90610d60610d596108ec845190565b9260200190565b9060005b818110610d715750505090565b909192610db0610da960019286517fffffffff0000000000000000000000000000000000000000000000000000000016815260200190565b9460200190565b929101610d64565b805173ffffffffffffffffffffffffffffffffffffffff1682526100d5916060810191604090610df060208201516020850190610d2d565b0151906040818403910152610d4a565b906100d591610db8565b90610e20610e16835190565b8083529160200190565b9081610e326020830284019460200190565b926000915b838310610e4657505050505090565b90919293946020610e69610e6283856001950387528951610e00565b9760200190565b9301930191939290610e37565b60608082526100d59392610eb091610e919190840190610e0a565b73ffffffffffffffffffffffffffffffffffffffff9093166020830152565b60408183039101526000815260200190565b9060005b610ed16100d5845190565b81101561101b57610eee6020610ee7838661062c565b5101610d1a565b600090610efa826106a3565b610f03826106a3565b03610f59575090610f4f610f3a610f5493610f1e848861062c565b51015173ffffffffffffffffffffffffffffffffffffffff1690565b6040610f46848861062c565b5101519061124c565b610ce8565b610ec6565b610f6360016106a3565b610f6c826106a3565b03610f9c575090610f4f610f87610f5493610f1e848861062c565b6040610f93848861062c565b5101519061144d565b610fa660026106a3565b610faf826106a3565b03610fdf575090610f4f610fca610f5493610f1e848861062c565b6040610fd6848861062c565b510151906115f4565b610c4b90610fec60405190565b9182917f32191c2900000000000000000000000000000000000000000000000000000000835260048301610d36565b5090611027600061065c565b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6739161105e61105560405190565b92839283610e76565b0390a1565b1561106a57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608490fd5b156110f657565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608490fd5b6111886100d56100d59290565b6bffffffffffffffffffffffff1690565b156111a057565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608490fd5b6bffffffffffffffffffffffff166bffffffffffffffffffffffff8114610d155760010190565b9190611256815190565b61127260009161126c6112688461050b565b9190565b11611063565b61127a610ca9565b6112838261065c565b6112bc73ffffffffffffffffffffffffffffffffffffffff821673ffffffffffffffffffffffffffffffffffffffff88165b14156110ef565b6112da6112d5846112d08960018701610885565b015490565b61117b565b93846112fa6112e88661117b565b916bffffffffffffffffffffffff1690565b146113b2575b6000945b61130f6100d5835190565b8610156113a85761139c816113978a6113a2948961139161136c826107f58f6113638f9161133d908f61062c565b517fffffffff000000000000000000000000000000000000000000000000000000001690565b9586910161078d565b61138b73ffffffffffffffffffffffffffffffffffffffff8c16610bff565b14611199565b8961197e565b611225565b95610ce8565b94611304565b5050505050509050565b6113bc87846117ff565b611300565b156113c857565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608490fd5b815191929161146460009161126c6112688461050b565b61146c610ca9565b9061149861147c6100bc8361065c565b73ffffffffffffffffffffffffffffffffffffffff85166112b5565b6114ac6112d5826112d08660018701610885565b94856114ba6112e88461117b565b14611559575b6000955b6114cf6100d5835190565b87101561155057611544816113978761154a94876113918a6115068f6107f56114fc61133d87938f61062c565b809681950161078d565b61153e73ffffffffffffffffffffffffffffffffffffffff871673ffffffffffffffffffffffffffffffffffffffff831614156113c1565b8c611cc3565b96610ce8565b956114c4565b50505050509050565b61156384846117ff565b6114c0565b1561156f57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608490fd5b8151600093929061160b9061126c6112688761050b565b61162c611616610ca9565b92611626610bff6100bc8861065c565b14611568565b60005b61163a6100d5835190565b8110156116705780610f4f61165561133d61166b948661062c565b611665886107f583828a0161078d565b86611cc3565b61162f565b5050509050565b67ffffffffffffffff811161022257602090601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b9061052561029883611677565b6116c960246116b2565b7f4c69624469616d6f6e644375743a204e657720666163657420686173206e6f2060208201527f636f646500000000000000000000000000000000000000000000000000000000604082015290565b6100d56116bf565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905b9181191691161790565b9061175e6100d56117659261050b565b8254611720565b9055565b805482101561064657611783600191600052602060002090565b91020190600090565b919060086117449102916117b373ffffffffffffffffffffffffffffffffffffffff841b90565b921b90565b91906117c96100d56117659361087c565b90835461178c565b908154916801000000000000000083101561022257826117f991600161010495018155611769565b906117b8565b9061183c61010492611818611812611718565b84611f74565b6100d560028201916001611836868261182f875490565b9401610885565b0161174e565b6117d1565b907fffffffffffffffffffffffff00000000000000000000000000000000000000009060a01b611744565b6111886100d56100d5926bffffffffffffffffffffffff1690565b906118976100d56117659261186c565b8254611841565b80549192918310156106465760086118bd600492600052602060002090565b8185040193060290565b919060086117449102916117b363ffffffff841b90565b919061191561190f611765937fffffffff000000000000000000000000000000000000000000000000000000001690565b60e01c90565b9083546118c7565b908154916801000000000000000083101561022257826119459160016101049501815561189e565b906118de565b9073ffffffffffffffffffffffffffffffffffffffff90611744565b906119776100d56117659261087c565b825461194b565b8184936119bb6000946119b686610d466101049a60016119c0996119b085820199866119aa8a8d61078d565b01611887565b01610885565b61191d565b61078d565b01611967565b156119cd57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608490fd5b15611a5957565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608490fd5b6100d59060a01c611188565b6100d59054611ade565b6100d56100d56100d5926bffffffffffffffffffffffff1690565b91908203918211610d1557565b6100d5916008021c60e01b90565b906100d59154611b1c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b610104916000916118de565b80548015611bb1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190611bae611ba8838361189e565b90611b64565b55565b611b35565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b90600003611bf35760009055565b611bb6565b6100d59081565b6100d59054611bf8565b6100d5916008021c6100bc565b906100d59154611c09565b610104916000916117b8565b80548015611bb1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190611bae611c658383611769565b90611c21565b919060086117449102916117b37fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841b90565b9190611caf6100d56117659361050b565b908354611c6b565b61010491600091611c9e565b611d789092919283600093611cfb611cdd6100bc8761065c565b73ffffffffffffffffffffffffffffffffffffffff841614156119c6565b611d28611d0a6100bc3061087c565b73ffffffffffffffffffffffffffffffffffffffff84161415611a52565b611da985611da481860193611d4f611d4a84611d44848961078d565b01611aea565b611af4565b94611d61846112d08960018c01610885565b87858a60019c8d94611d728661050b565b90611b0f565b809a611d818290565b8103611e59575b5050611d9f92506119bb93610d4691019e8f610885565b611b70565b611be5565b611db56112688661050b565b14611dc2575b5050505050565b611e1a94611e0f611e0a6002611e149501611de7611dde825490565b611d728961050b565b611dfb88611df58888610885565b01611bff565b88828203611e24575b50505090565b611c2d565b610885565b01611cb7565b3880808080611dbb565b611836611e3d611e37611e519587611769565b90611c16565b611e4b816117f98689611769565b88610885565b388088611e04565b6112d5856119458387611e84611e90611e8a611e989984611e9f9f611e84906119aa9e01998a610885565b0161189e565b90611b2a565b9a8b95610885565b928561078d565b8887858a8938611d88565b60005b838110611ebd5750506000910152565b8181015183820152602001611ead565b611eee611ef7602093610d4693611ee2815190565b80835293849260200190565b95869101611eaa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690565b60208082526100d592910190611ecd565b15611f385750565b610c4b90611f4560405190565b9182917f08c379a000000000000000000000000000000000000000000000000000000000835260048301611f1f565b61010491903b611f87611268600061050b565b11611f3056fea26469706673582212204c8f26abad050a4c2e8b888a50adb23cd6b84b5d667e0b200800a5ca6553d39064736f6c63430008130033
Deployed ByteCode
0x6080604052600436101561001257600080fd5b60003560e01c80631f931c1c146100825780636463e3a01461007d578063a6638c0e14610078578063debb385614610073578063e0435c0b1461006e578063e57e69c6146100695763ff6f3e0b03610087576103e2565b6103c9565b61038b565b610373565b610347565b61031b565b610192565b600080fd5b909182601f830112156100875781359167ffffffffffffffff831161008757602001926020830284011161008757565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b73ffffffffffffffffffffffffffffffffffffffff81165b0361008757565b90503590610104826100d8565b565b909182601f830112156100875781359167ffffffffffffffff831161008757602001926001830284011161008757565b919060608382031261008757823567ffffffffffffffff8111610087578161015f91850161008c565b92909361016f83602083016100f7565b92604082013567ffffffffffffffff81116100875761018e9201610106565b9091565b34610087576101ae6101a5366004610136565b939290926104dc565b604051005b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810190811067ffffffffffffffff82111761022257604052565b6101b3565b9061010461023460405190565b92836101e2565b67ffffffffffffffff81116102225760208091020190565b7fffffffff0000000000000000000000000000000000000000000000000000000081166100f0565b9050359061010482610253565b9092919261029d6102988261023b565b610227565b938185526020808601920283019281841161008757915b8383106102c15750505050565b602080916102cf848661027b565b8152019201916102b4565b9080601f83011215610087578160206100d593359101610288565b9060208282031261008757813567ffffffffffffffff8111610087576100d592016102da565b34610087576101ae61032e3660046102f5565b610801565b90602082820312610087576100d5916100f7565b34610087576101ae61035a366004610333565b610b64565b90602082820312610087576100d59161027b565b34610087576101ae61038636600461035f565b6106b7565b34610087576101ae61039e36600461035f565b6107d2565b9060208282031261008757813567ffffffffffffffff81116100875761018e920161008c565b34610087576101ae6103dc3660046103a3565b906104fb565b34610087576101ae6103f53660046102f5565b610835565b6003111561008757565b90503590610104826103fa565b919091606081840312610087576104286060610227565b92600061043582846100f7565b90850152602061044782828501610404565b90850152604082013567ffffffffffffffff81116100875761046992016102da565b6040830152565b92919061047f6102988261023b565b93818552602080860192028101918383116100875781905b8382106104a5575050505050565b813567ffffffffffffffff8111610087576020916104c68784938701610411565b815201910190610497565b6100d5913691610470565b90915061010493506104f692506104f1610cb1565b6104d1565b610ec2565b610104916104f6916104f1610cb1565b6100d56100d56100d59290565b906105256102988361023b565b918252565b6100d56060610227565b61053c61052a565b600080825260208201526060604082015290565b6100d5610534565b60005b82811061056757505050565b602090610572610550565b818401520161055b565b9061010461059261058c84610518565b9361023b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00160208401610558565b369037565b906101046105d261058c84610518565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001602084016105bd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90610635825190565b811015610646576020809102010190565b6105fd565b9052565b6100bc6100d56100d59290565b6100d59061064f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6003111561069e57565b610665565b9061010482610694565b9061064b906106a3565b610104906106c3610beb565b6107876107816106d3600161050b565b926106e66106e08561057c565b946105c2565b6107256000926106fe6106f88561050b565b8461062c565b907fffffffff00000000000000000000000000000000000000000000000000000000169052565b6107696107318361065c565b91610469600261076061074261052a565b73ffffffffffffffffffffffffffffffffffffffff90961687870152565b602085016106ad565b61077b6107758361050b565b8661062c565b5261050b565b8261062c565b50610ec2565b907fffffffff00000000000000000000000000000000000000000000000000000000165b600052602052604060002090565b6100d5906100bc565b6100d590546107bf565b610104906107de610beb565b6107e6610ca9565b6107fb60006107f5848461078d565b016107c8565b90611cc3565b6101049061080d610beb565b610787610781610825610820600161050b565b61057c565b926000906107696107318361065c565b61010490610841610beb565b61084b600061065c565b6115f4565b6100bc6100d56100d59273ffffffffffffffffffffffffffffffffffffffff1690565b6100d590610850565b6100d590610873565b906107b19061087c565b6100d59060201c60e01b90565b6100d59060401c60e01b90565b6100d59060601c60e01b90565b6100d59060801c60e01b90565b6100d59060a01c60e01b90565b6100d59060c01c60e01b90565b906109026108f66108ec845490565b8084529260200190565b92600052602060002090565b906000915b600783018211610a82575490808310610a64575b808310610a47575b808310610a2a575b808310610a0d575b8083106109f0575b8083106109d3575b8083106109b6575b821061095657505090565b826109af600193946109896020947fffffffff000000000000000000000000000000000000000000000000000000001690565b7fffffffff00000000000000000000000000000000000000000000000000000000169052565b0191505090565b91926020816109ca600193610989866108d0565b0193019161094b565b91926020816109e7600193610989866108c3565b01930191610943565b9192602081610a04600193610989866108b6565b0193019161093b565b9192602081610a21600193610989866108a9565b01930191610933565b9192602081610a3e6001936109898661089c565b0193019161092b565b9192602081610a5b6001936109898661088f565b01930191610923565b9192602081610a796001936109898660e01b90565b0193019161091b565b9260016020610989610b25600894838080808080808f5497610aa8816109898b60e01b90565b01610ab6816109898a61088f565b01610ac4816109898961089c565b01610ad281610989886108a9565b01610ae081610989876108b6565b01610aee81610989866108c3565b01610afc81610989856108d0565b019283917fffffffff000000000000000000000000000000000000000000000000000000001690565b019401920191610907565b906100d5916108dd565b90610104610b5492610b4b60405190565b93848092610b30565b03836101e2565b6100d590610b3a565b61010490610b70610beb565b610787610781610bb2610b81610ca9565b610769610469600192610be6610b996108208661050b565b986000968791610ba88361065c565b9760029501610885565b0191610bdd610bbf61052a565b73ffffffffffffffffffffffffffffffffffffffff90971688880152565b602086016106ad565b610b5b565b33610c19610bff6100bc60006107f5610c78565b9173ffffffffffffffffffffffffffffffffffffffff1690565b03610c2057565b6040517ff5d3c8cc000000000000000000000000000000000000000000000000000000008152600490fd5b0390fd5b6100d57fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610361050b565b6100d5610c4f565b6100d57fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c61050b565b6100d5610c80565b610104610beb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610d155760010190565b610cb9565b6100d590516106a3565b6100d5906106a3565b61064b90610d24565b6020810192916101049190610d2d565b0190565b90610d60610d596108ec845190565b9260200190565b9060005b818110610d715750505090565b909192610db0610da960019286517fffffffff0000000000000000000000000000000000000000000000000000000016815260200190565b9460200190565b929101610d64565b805173ffffffffffffffffffffffffffffffffffffffff1682526100d5916060810191604090610df060208201516020850190610d2d565b0151906040818403910152610d4a565b906100d591610db8565b90610e20610e16835190565b8083529160200190565b9081610e326020830284019460200190565b926000915b838310610e4657505050505090565b90919293946020610e69610e6283856001950387528951610e00565b9760200190565b9301930191939290610e37565b60608082526100d59392610eb091610e919190840190610e0a565b73ffffffffffffffffffffffffffffffffffffffff9093166020830152565b60408183039101526000815260200190565b9060005b610ed16100d5845190565b81101561101b57610eee6020610ee7838661062c565b5101610d1a565b600090610efa826106a3565b610f03826106a3565b03610f59575090610f4f610f3a610f5493610f1e848861062c565b51015173ffffffffffffffffffffffffffffffffffffffff1690565b6040610f46848861062c565b5101519061124c565b610ce8565b610ec6565b610f6360016106a3565b610f6c826106a3565b03610f9c575090610f4f610f87610f5493610f1e848861062c565b6040610f93848861062c565b5101519061144d565b610fa660026106a3565b610faf826106a3565b03610fdf575090610f4f610fca610f5493610f1e848861062c565b6040610fd6848861062c565b510151906115f4565b610c4b90610fec60405190565b9182917f32191c2900000000000000000000000000000000000000000000000000000000835260048301610d36565b5090611027600061065c565b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6739161105e61105560405190565b92839283610e76565b0390a1565b1561106a57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608490fd5b156110f657565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608490fd5b6111886100d56100d59290565b6bffffffffffffffffffffffff1690565b156111a057565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608490fd5b6bffffffffffffffffffffffff166bffffffffffffffffffffffff8114610d155760010190565b9190611256815190565b61127260009161126c6112688461050b565b9190565b11611063565b61127a610ca9565b6112838261065c565b6112bc73ffffffffffffffffffffffffffffffffffffffff821673ffffffffffffffffffffffffffffffffffffffff88165b14156110ef565b6112da6112d5846112d08960018701610885565b015490565b61117b565b93846112fa6112e88661117b565b916bffffffffffffffffffffffff1690565b146113b2575b6000945b61130f6100d5835190565b8610156113a85761139c816113978a6113a2948961139161136c826107f58f6113638f9161133d908f61062c565b517fffffffff000000000000000000000000000000000000000000000000000000001690565b9586910161078d565b61138b73ffffffffffffffffffffffffffffffffffffffff8c16610bff565b14611199565b8961197e565b611225565b95610ce8565b94611304565b5050505050509050565b6113bc87846117ff565b611300565b156113c857565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608490fd5b815191929161146460009161126c6112688461050b565b61146c610ca9565b9061149861147c6100bc8361065c565b73ffffffffffffffffffffffffffffffffffffffff85166112b5565b6114ac6112d5826112d08660018701610885565b94856114ba6112e88461117b565b14611559575b6000955b6114cf6100d5835190565b87101561155057611544816113978761154a94876113918a6115068f6107f56114fc61133d87938f61062c565b809681950161078d565b61153e73ffffffffffffffffffffffffffffffffffffffff871673ffffffffffffffffffffffffffffffffffffffff831614156113c1565b8c611cc3565b96610ce8565b956114c4565b50505050509050565b61156384846117ff565b6114c0565b1561156f57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608490fd5b8151600093929061160b9061126c6112688761050b565b61162c611616610ca9565b92611626610bff6100bc8861065c565b14611568565b60005b61163a6100d5835190565b8110156116705780610f4f61165561133d61166b948661062c565b611665886107f583828a0161078d565b86611cc3565b61162f565b5050509050565b67ffffffffffffffff811161022257602090601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b9061052561029883611677565b6116c960246116b2565b7f4c69624469616d6f6e644375743a204e657720666163657420686173206e6f2060208201527f636f646500000000000000000000000000000000000000000000000000000000604082015290565b6100d56116bf565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905b9181191691161790565b9061175e6100d56117659261050b565b8254611720565b9055565b805482101561064657611783600191600052602060002090565b91020190600090565b919060086117449102916117b373ffffffffffffffffffffffffffffffffffffffff841b90565b921b90565b91906117c96100d56117659361087c565b90835461178c565b908154916801000000000000000083101561022257826117f991600161010495018155611769565b906117b8565b9061183c61010492611818611812611718565b84611f74565b6100d560028201916001611836868261182f875490565b9401610885565b0161174e565b6117d1565b907fffffffffffffffffffffffff00000000000000000000000000000000000000009060a01b611744565b6111886100d56100d5926bffffffffffffffffffffffff1690565b906118976100d56117659261186c565b8254611841565b80549192918310156106465760086118bd600492600052602060002090565b8185040193060290565b919060086117449102916117b363ffffffff841b90565b919061191561190f611765937fffffffff000000000000000000000000000000000000000000000000000000001690565b60e01c90565b9083546118c7565b908154916801000000000000000083101561022257826119459160016101049501815561189e565b906118de565b9073ffffffffffffffffffffffffffffffffffffffff90611744565b906119776100d56117659261087c565b825461194b565b8184936119bb6000946119b686610d466101049a60016119c0996119b085820199866119aa8a8d61078d565b01611887565b01610885565b61191d565b61078d565b01611967565b156119cd57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608490fd5b15611a5957565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608490fd5b6100d59060a01c611188565b6100d59054611ade565b6100d56100d56100d5926bffffffffffffffffffffffff1690565b91908203918211610d1557565b6100d5916008021c60e01b90565b906100d59154611b1c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b610104916000916118de565b80548015611bb1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190611bae611ba8838361189e565b90611b64565b55565b611b35565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b90600003611bf35760009055565b611bb6565b6100d59081565b6100d59054611bf8565b6100d5916008021c6100bc565b906100d59154611c09565b610104916000916117b8565b80548015611bb1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190611bae611c658383611769565b90611c21565b919060086117449102916117b37fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841b90565b9190611caf6100d56117659361050b565b908354611c6b565b61010491600091611c9e565b611d789092919283600093611cfb611cdd6100bc8761065c565b73ffffffffffffffffffffffffffffffffffffffff841614156119c6565b611d28611d0a6100bc3061087c565b73ffffffffffffffffffffffffffffffffffffffff84161415611a52565b611da985611da481860193611d4f611d4a84611d44848961078d565b01611aea565b611af4565b94611d61846112d08960018c01610885565b87858a60019c8d94611d728661050b565b90611b0f565b809a611d818290565b8103611e59575b5050611d9f92506119bb93610d4691019e8f610885565b611b70565b611be5565b611db56112688661050b565b14611dc2575b5050505050565b611e1a94611e0f611e0a6002611e149501611de7611dde825490565b611d728961050b565b611dfb88611df58888610885565b01611bff565b88828203611e24575b50505090565b611c2d565b610885565b01611cb7565b3880808080611dbb565b611836611e3d611e37611e519587611769565b90611c16565b611e4b816117f98689611769565b88610885565b388088611e04565b6112d5856119458387611e84611e90611e8a611e989984611e9f9f611e84906119aa9e01998a610885565b0161189e565b90611b2a565b9a8b95610885565b928561078d565b8887858a8938611d88565b60005b838110611ebd5750506000910152565b8181015183820152602001611ead565b611eee611ef7602093610d4693611ee2815190565b80835293849260200190565b95869101611eaa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690565b60208082526100d592910190611ecd565b15611f385750565b610c4b90611f4560405190565b9182917f08c379a000000000000000000000000000000000000000000000000000000000835260048301611f1f565b61010491903b611f87611268600061050b565b11611f3056fea26469706673582212204c8f26abad050a4c2e8b888a50adb23cd6b84b5d667e0b200800a5ca6553d39064736f6c63430008130033