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-03-26T01:14:18.983062Z
lib/@cu-tokens/lib/@lagunagames/lg-diamond-template/src/diamond/DiamondCutFacet.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;
import '../interfaces/IDiamondCut.sol';
import '../libraries/LibContractOwner.sol';
import '../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/@cu-tokens/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/@cu-tokens/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/@cu-tokens/lib/@lagunagames/lg-diamond-template/src/libraries/LibDiamond.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import '../interfaces/IDiamondCut.sol';
import './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":["@cu-common/=lib/@cu-tokens/lib/@lagunagames/cu-common/","@cu-tokens/=lib/@cu-tokens/","@lagunagames/=lib/@lagunagames/","@lagunagames/lg-diamond-template/=lib/@cu-tokens/lib/@lagunagames/lg-diamond-template/","@layerzerolabs/=lib/@layerzerolabs/","@lg-arb-bridge/=lib/@lg-arb-bridge/src/","@lg-diamond-template/=lib/@cu-tokens/lib/@lagunagames/lg-diamond-template/","@lg-layerzero/=lib/@lg-layerzero/src/","@openzeppelin-contracts/=lib/@cu-tokens/lib/openzeppelin-contracts/","@openzeppelin/=lib/@openzeppelin/","ds-test/=lib/@cu-tokens/lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/@openzeppelin/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","openzeppelin-contracts/=lib/@cu-tokens/lib/openzeppelin-contracts/","openzeppelin/=lib/@openzeppelin/contracts/","solidity-stringutils/=lib/@lagunagames/lg-diamond-template/lib/solidity-stringutils/"],"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
0x60806040523461001a57604051611fc36100208239611fc390f35b600080fdfe6080604052600436101561001257600080fd5b60003560e01c80631f931c1c146100825780636463e3a01461007d578063a6638c0e14610078578063debb385614610073578063e0435c0b1461006e578063e57e69c6146100695763ff6f3e0b03610087576103e2565b6103c9565b61038b565b610373565b610347565b61031b565b610192565b600080fd5b909182601f830112156100875781359167ffffffffffffffff831161008757602001926020830284011161008757565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b73ffffffffffffffffffffffffffffffffffffffff81165b0361008757565b90503590610104826100d8565b565b909182601f830112156100875781359167ffffffffffffffff831161008757602001926001830284011161008757565b919060608382031261008757823567ffffffffffffffff8111610087578161015f91850161008c565b92909361016f83602083016100f7565b92604082013567ffffffffffffffff81116100875761018e9201610106565b9091565b34610087576101ae6101a5366004610136565b939290926104dc565b604051005b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810190811067ffffffffffffffff82111761022257604052565b6101b3565b9061010461023460405190565b92836101e2565b67ffffffffffffffff81116102225760208091020190565b7fffffffff0000000000000000000000000000000000000000000000000000000081166100f0565b9050359061010482610253565b9092919261029d6102988261023b565b610227565b938185526020808601920283019281841161008757915b8383106102c15750505050565b602080916102cf848661027b565b8152019201916102b4565b9080601f83011215610087578160206100d593359101610288565b9060208282031261008757813567ffffffffffffffff8111610087576100d592016102da565b34610087576101ae61032e3660046102f5565b610801565b90602082820312610087576100d5916100f7565b34610087576101ae61035a366004610333565b610b64565b90602082820312610087576100d59161027b565b34610087576101ae61038636600461035f565b6106b7565b34610087576101ae61039e36600461035f565b6107d2565b9060208282031261008757813567ffffffffffffffff81116100875761018e920161008c565b34610087576101ae6103dc3660046103a3565b906104fb565b34610087576101ae6103f53660046102f5565b610835565b6003111561008757565b90503590610104826103fa565b919091606081840312610087576104286060610227565b92600061043582846100f7565b90850152602061044782828501610404565b90850152604082013567ffffffffffffffff81116100875761046992016102da565b6040830152565b92919061047f6102988261023b565b93818552602080860192028101918383116100875781905b8382106104a5575050505050565b813567ffffffffffffffff8111610087576020916104c68784938701610411565b815201910190610497565b6100d5913691610470565b90915061010493506104f692506104f1610cb1565b6104d1565b610ec2565b610104916104f6916104f1610cb1565b6100d56100d56100d59290565b906105256102988361023b565b918252565b6100d56060610227565b61053c61052a565b600080825260208201526060604082015290565b6100d5610534565b60005b82811061056757505050565b602090610572610550565b818401520161055b565b9061010461059261058c84610518565b9361023b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00160208401610558565b369037565b906101046105d261058c84610518565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001602084016105bd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90610635825190565b811015610646576020809102010190565b6105fd565b9052565b6100bc6100d56100d59290565b6100d59061064f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6003111561069e57565b610665565b9061010482610694565b9061064b906106a3565b610104906106c3610beb565b6107876107816106d3600161050b565b926106e66106e08561057c565b946105c2565b6107256000926106fe6106f88561050b565b8461062c565b907fffffffff00000000000000000000000000000000000000000000000000000000169052565b6107696107318361065c565b91610469600261076061074261052a565b73ffffffffffffffffffffffffffffffffffffffff90961687870152565b602085016106ad565b61077b6107758361050b565b8661062c565b5261050b565b8261062c565b50610ec2565b907fffffffff00000000000000000000000000000000000000000000000000000000165b600052602052604060002090565b6100d5906100bc565b6100d590546107bf565b610104906107de610beb565b6107e6610ca9565b6107fb60006107f5848461078d565b016107c8565b90611cc3565b6101049061080d610beb565b610787610781610825610820600161050b565b61057c565b926000906107696107318361065c565b61010490610841610beb565b61084b600061065c565b6115f4565b6100bc6100d56100d59273ffffffffffffffffffffffffffffffffffffffff1690565b6100d590610850565b6100d590610873565b906107b19061087c565b6100d59060201c60e01b90565b6100d59060401c60e01b90565b6100d59060601c60e01b90565b6100d59060801c60e01b90565b6100d59060a01c60e01b90565b6100d59060c01c60e01b90565b906109026108f66108ec845490565b8084529260200190565b92600052602060002090565b906000915b600783018211610a82575490808310610a64575b808310610a47575b808310610a2a575b808310610a0d575b8083106109f0575b8083106109d3575b8083106109b6575b821061095657505090565b826109af600193946109896020947fffffffff000000000000000000000000000000000000000000000000000000001690565b7fffffffff00000000000000000000000000000000000000000000000000000000169052565b0191505090565b91926020816109ca600193610989866108d0565b0193019161094b565b91926020816109e7600193610989866108c3565b01930191610943565b9192602081610a04600193610989866108b6565b0193019161093b565b9192602081610a21600193610989866108a9565b01930191610933565b9192602081610a3e6001936109898661089c565b0193019161092b565b9192602081610a5b6001936109898661088f565b01930191610923565b9192602081610a796001936109898660e01b90565b0193019161091b565b9260016020610989610b25600894838080808080808f5497610aa8816109898b60e01b90565b01610ab6816109898a61088f565b01610ac4816109898961089c565b01610ad281610989886108a9565b01610ae081610989876108b6565b01610aee81610989866108c3565b01610afc81610989856108d0565b019283917fffffffff000000000000000000000000000000000000000000000000000000001690565b019401920191610907565b906100d5916108dd565b90610104610b5492610b4b60405190565b93848092610b30565b03836101e2565b6100d590610b3a565b61010490610b70610beb565b610787610781610bb2610b81610ca9565b610769610469600192610be6610b996108208661050b565b986000968791610ba88361065c565b9760029501610885565b0191610bdd610bbf61052a565b73ffffffffffffffffffffffffffffffffffffffff90971688880152565b602086016106ad565b610b5b565b33610c19610bff6100bc60006107f5610c78565b9173ffffffffffffffffffffffffffffffffffffffff1690565b03610c2057565b6040517ff5d3c8cc000000000000000000000000000000000000000000000000000000008152600490fd5b0390fd5b6100d57fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610361050b565b6100d5610c4f565b6100d57fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c61050b565b6100d5610c80565b610104610beb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610d155760010190565b610cb9565b6100d590516106a3565b6100d5906106a3565b61064b90610d24565b6020810192916101049190610d2d565b0190565b90610d60610d596108ec845190565b9260200190565b9060005b818110610d715750505090565b909192610db0610da960019286517fffffffff0000000000000000000000000000000000000000000000000000000016815260200190565b9460200190565b929101610d64565b805173ffffffffffffffffffffffffffffffffffffffff1682526100d5916060810191604090610df060208201516020850190610d2d565b0151906040818403910152610d4a565b906100d591610db8565b90610e20610e16835190565b8083529160200190565b9081610e326020830284019460200190565b926000915b838310610e4657505050505090565b90919293946020610e69610e6283856001950387528951610e00565b9760200190565b9301930191939290610e37565b60608082526100d59392610eb091610e919190840190610e0a565b73ffffffffffffffffffffffffffffffffffffffff9093166020830152565b60408183039101526000815260200190565b9060005b610ed16100d5845190565b81101561101b57610eee6020610ee7838661062c565b5101610d1a565b600090610efa826106a3565b610f03826106a3565b03610f59575090610f4f610f3a610f5493610f1e848861062c565b51015173ffffffffffffffffffffffffffffffffffffffff1690565b6040610f46848861062c565b5101519061124c565b610ce8565b610ec6565b610f6360016106a3565b610f6c826106a3565b03610f9c575090610f4f610f87610f5493610f1e848861062c565b6040610f93848861062c565b5101519061144d565b610fa660026106a3565b610faf826106a3565b03610fdf575090610f4f610fca610f5493610f1e848861062c565b6040610fd6848861062c565b510151906115f4565b610c4b90610fec60405190565b9182917f32191c2900000000000000000000000000000000000000000000000000000000835260048301610d36565b5090611027600061065c565b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6739161105e61105560405190565b92839283610e76565b0390a1565b1561106a57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608490fd5b156110f657565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608490fd5b6111886100d56100d59290565b6bffffffffffffffffffffffff1690565b156111a057565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608490fd5b6bffffffffffffffffffffffff166bffffffffffffffffffffffff8114610d155760010190565b9190611256815190565b61127260009161126c6112688461050b565b9190565b11611063565b61127a610ca9565b6112838261065c565b6112bc73ffffffffffffffffffffffffffffffffffffffff821673ffffffffffffffffffffffffffffffffffffffff88165b14156110ef565b6112da6112d5846112d08960018701610885565b015490565b61117b565b93846112fa6112e88661117b565b916bffffffffffffffffffffffff1690565b146113b2575b6000945b61130f6100d5835190565b8610156113a85761139c816113978a6113a2948961139161136c826107f58f6113638f9161133d908f61062c565b517fffffffff000000000000000000000000000000000000000000000000000000001690565b9586910161078d565b61138b73ffffffffffffffffffffffffffffffffffffffff8c16610bff565b14611199565b8961197e565b611225565b95610ce8565b94611304565b5050505050509050565b6113bc87846117ff565b611300565b156113c857565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608490fd5b815191929161146460009161126c6112688461050b565b61146c610ca9565b9061149861147c6100bc8361065c565b73ffffffffffffffffffffffffffffffffffffffff85166112b5565b6114ac6112d5826112d08660018701610885565b94856114ba6112e88461117b565b14611559575b6000955b6114cf6100d5835190565b87101561155057611544816113978761154a94876113918a6115068f6107f56114fc61133d87938f61062c565b809681950161078d565b61153e73ffffffffffffffffffffffffffffffffffffffff871673ffffffffffffffffffffffffffffffffffffffff831614156113c1565b8c611cc3565b96610ce8565b956114c4565b50505050509050565b61156384846117ff565b6114c0565b1561156f57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608490fd5b8151600093929061160b9061126c6112688761050b565b61162c611616610ca9565b92611626610bff6100bc8861065c565b14611568565b60005b61163a6100d5835190565b8110156116705780610f4f61165561133d61166b948661062c565b611665886107f583828a0161078d565b86611cc3565b61162f565b5050509050565b67ffffffffffffffff811161022257602090601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b9061052561029883611677565b6116c960246116b2565b7f4c69624469616d6f6e644375743a204e657720666163657420686173206e6f2060208201527f636f646500000000000000000000000000000000000000000000000000000000604082015290565b6100d56116bf565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905b9181191691161790565b9061175e6100d56117659261050b565b8254611720565b9055565b805482101561064657611783600191600052602060002090565b91020190600090565b919060086117449102916117b373ffffffffffffffffffffffffffffffffffffffff841b90565b921b90565b91906117c96100d56117659361087c565b90835461178c565b908154916801000000000000000083101561022257826117f991600161010495018155611769565b906117b8565b9061183c61010492611818611812611718565b84611f74565b6100d560028201916001611836868261182f875490565b9401610885565b0161174e565b6117d1565b907fffffffffffffffffffffffff00000000000000000000000000000000000000009060a01b611744565b6111886100d56100d5926bffffffffffffffffffffffff1690565b906118976100d56117659261186c565b8254611841565b80549192918310156106465760086118bd600492600052602060002090565b8185040193060290565b919060086117449102916117b363ffffffff841b90565b919061191561190f611765937fffffffff000000000000000000000000000000000000000000000000000000001690565b60e01c90565b9083546118c7565b908154916801000000000000000083101561022257826119459160016101049501815561189e565b906118de565b9073ffffffffffffffffffffffffffffffffffffffff90611744565b906119776100d56117659261087c565b825461194b565b8184936119bb6000946119b686610d466101049a60016119c0996119b085820199866119aa8a8d61078d565b01611887565b01610885565b61191d565b61078d565b01611967565b156119cd57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608490fd5b15611a5957565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608490fd5b6100d59060a01c611188565b6100d59054611ade565b6100d56100d56100d5926bffffffffffffffffffffffff1690565b91908203918211610d1557565b6100d5916008021c60e01b90565b906100d59154611b1c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b610104916000916118de565b80548015611bb1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190611bae611ba8838361189e565b90611b64565b55565b611b35565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b90600003611bf35760009055565b611bb6565b6100d59081565b6100d59054611bf8565b6100d5916008021c6100bc565b906100d59154611c09565b610104916000916117b8565b80548015611bb1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190611bae611c658383611769565b90611c21565b919060086117449102916117b37fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841b90565b9190611caf6100d56117659361050b565b908354611c6b565b61010491600091611c9e565b611d789092919283600093611cfb611cdd6100bc8761065c565b73ffffffffffffffffffffffffffffffffffffffff841614156119c6565b611d28611d0a6100bc3061087c565b73ffffffffffffffffffffffffffffffffffffffff84161415611a52565b611da985611da481860193611d4f611d4a84611d44848961078d565b01611aea565b611af4565b94611d61846112d08960018c01610885565b87858a60019c8d94611d728661050b565b90611b0f565b809a611d818290565b8103611e59575b5050611d9f92506119bb93610d4691019e8f610885565b611b70565b611be5565b611db56112688661050b565b14611dc2575b5050505050565b611e1a94611e0f611e0a6002611e149501611de7611dde825490565b611d728961050b565b611dfb88611df58888610885565b01611bff565b88828203611e24575b50505090565b611c2d565b610885565b01611cb7565b3880808080611dbb565b611836611e3d611e37611e519587611769565b90611c16565b611e4b816117f98689611769565b88610885565b388088611e04565b6112d5856119458387611e84611e90611e8a611e989984611e9f9f611e84906119aa9e01998a610885565b0161189e565b90611b2a565b9a8b95610885565b928561078d565b8887858a8938611d88565b60005b838110611ebd5750506000910152565b8181015183820152602001611ead565b611eee611ef7602093610d4693611ee2815190565b80835293849260200190565b95869101611eaa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690565b60208082526100d592910190611ecd565b15611f385750565b610c4b90611f4560405190565b9182917f08c379a000000000000000000000000000000000000000000000000000000000835260048301611f1f565b61010491903b611f87611268600061050b565b11611f3056fea2646970667358221220fc4877dcf7349a5bce46f2e81f0b616e98af3b94b1be3971110ea007861c841b64736f6c63430008130033
Deployed ByteCode
0x6080604052600436101561001257600080fd5b60003560e01c80631f931c1c146100825780636463e3a01461007d578063a6638c0e14610078578063debb385614610073578063e0435c0b1461006e578063e57e69c6146100695763ff6f3e0b03610087576103e2565b6103c9565b61038b565b610373565b610347565b61031b565b610192565b600080fd5b909182601f830112156100875781359167ffffffffffffffff831161008757602001926020830284011161008757565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b73ffffffffffffffffffffffffffffffffffffffff81165b0361008757565b90503590610104826100d8565b565b909182601f830112156100875781359167ffffffffffffffff831161008757602001926001830284011161008757565b919060608382031261008757823567ffffffffffffffff8111610087578161015f91850161008c565b92909361016f83602083016100f7565b92604082013567ffffffffffffffff81116100875761018e9201610106565b9091565b34610087576101ae6101a5366004610136565b939290926104dc565b604051005b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810190811067ffffffffffffffff82111761022257604052565b6101b3565b9061010461023460405190565b92836101e2565b67ffffffffffffffff81116102225760208091020190565b7fffffffff0000000000000000000000000000000000000000000000000000000081166100f0565b9050359061010482610253565b9092919261029d6102988261023b565b610227565b938185526020808601920283019281841161008757915b8383106102c15750505050565b602080916102cf848661027b565b8152019201916102b4565b9080601f83011215610087578160206100d593359101610288565b9060208282031261008757813567ffffffffffffffff8111610087576100d592016102da565b34610087576101ae61032e3660046102f5565b610801565b90602082820312610087576100d5916100f7565b34610087576101ae61035a366004610333565b610b64565b90602082820312610087576100d59161027b565b34610087576101ae61038636600461035f565b6106b7565b34610087576101ae61039e36600461035f565b6107d2565b9060208282031261008757813567ffffffffffffffff81116100875761018e920161008c565b34610087576101ae6103dc3660046103a3565b906104fb565b34610087576101ae6103f53660046102f5565b610835565b6003111561008757565b90503590610104826103fa565b919091606081840312610087576104286060610227565b92600061043582846100f7565b90850152602061044782828501610404565b90850152604082013567ffffffffffffffff81116100875761046992016102da565b6040830152565b92919061047f6102988261023b565b93818552602080860192028101918383116100875781905b8382106104a5575050505050565b813567ffffffffffffffff8111610087576020916104c68784938701610411565b815201910190610497565b6100d5913691610470565b90915061010493506104f692506104f1610cb1565b6104d1565b610ec2565b610104916104f6916104f1610cb1565b6100d56100d56100d59290565b906105256102988361023b565b918252565b6100d56060610227565b61053c61052a565b600080825260208201526060604082015290565b6100d5610534565b60005b82811061056757505050565b602090610572610550565b818401520161055b565b9061010461059261058c84610518565b9361023b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00160208401610558565b369037565b906101046105d261058c84610518565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001602084016105bd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90610635825190565b811015610646576020809102010190565b6105fd565b9052565b6100bc6100d56100d59290565b6100d59061064f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6003111561069e57565b610665565b9061010482610694565b9061064b906106a3565b610104906106c3610beb565b6107876107816106d3600161050b565b926106e66106e08561057c565b946105c2565b6107256000926106fe6106f88561050b565b8461062c565b907fffffffff00000000000000000000000000000000000000000000000000000000169052565b6107696107318361065c565b91610469600261076061074261052a565b73ffffffffffffffffffffffffffffffffffffffff90961687870152565b602085016106ad565b61077b6107758361050b565b8661062c565b5261050b565b8261062c565b50610ec2565b907fffffffff00000000000000000000000000000000000000000000000000000000165b600052602052604060002090565b6100d5906100bc565b6100d590546107bf565b610104906107de610beb565b6107e6610ca9565b6107fb60006107f5848461078d565b016107c8565b90611cc3565b6101049061080d610beb565b610787610781610825610820600161050b565b61057c565b926000906107696107318361065c565b61010490610841610beb565b61084b600061065c565b6115f4565b6100bc6100d56100d59273ffffffffffffffffffffffffffffffffffffffff1690565b6100d590610850565b6100d590610873565b906107b19061087c565b6100d59060201c60e01b90565b6100d59060401c60e01b90565b6100d59060601c60e01b90565b6100d59060801c60e01b90565b6100d59060a01c60e01b90565b6100d59060c01c60e01b90565b906109026108f66108ec845490565b8084529260200190565b92600052602060002090565b906000915b600783018211610a82575490808310610a64575b808310610a47575b808310610a2a575b808310610a0d575b8083106109f0575b8083106109d3575b8083106109b6575b821061095657505090565b826109af600193946109896020947fffffffff000000000000000000000000000000000000000000000000000000001690565b7fffffffff00000000000000000000000000000000000000000000000000000000169052565b0191505090565b91926020816109ca600193610989866108d0565b0193019161094b565b91926020816109e7600193610989866108c3565b01930191610943565b9192602081610a04600193610989866108b6565b0193019161093b565b9192602081610a21600193610989866108a9565b01930191610933565b9192602081610a3e6001936109898661089c565b0193019161092b565b9192602081610a5b6001936109898661088f565b01930191610923565b9192602081610a796001936109898660e01b90565b0193019161091b565b9260016020610989610b25600894838080808080808f5497610aa8816109898b60e01b90565b01610ab6816109898a61088f565b01610ac4816109898961089c565b01610ad281610989886108a9565b01610ae081610989876108b6565b01610aee81610989866108c3565b01610afc81610989856108d0565b019283917fffffffff000000000000000000000000000000000000000000000000000000001690565b019401920191610907565b906100d5916108dd565b90610104610b5492610b4b60405190565b93848092610b30565b03836101e2565b6100d590610b3a565b61010490610b70610beb565b610787610781610bb2610b81610ca9565b610769610469600192610be6610b996108208661050b565b986000968791610ba88361065c565b9760029501610885565b0191610bdd610bbf61052a565b73ffffffffffffffffffffffffffffffffffffffff90971688880152565b602086016106ad565b610b5b565b33610c19610bff6100bc60006107f5610c78565b9173ffffffffffffffffffffffffffffffffffffffff1690565b03610c2057565b6040517ff5d3c8cc000000000000000000000000000000000000000000000000000000008152600490fd5b0390fd5b6100d57fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610361050b565b6100d5610c4f565b6100d57fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c61050b565b6100d5610c80565b610104610beb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610d155760010190565b610cb9565b6100d590516106a3565b6100d5906106a3565b61064b90610d24565b6020810192916101049190610d2d565b0190565b90610d60610d596108ec845190565b9260200190565b9060005b818110610d715750505090565b909192610db0610da960019286517fffffffff0000000000000000000000000000000000000000000000000000000016815260200190565b9460200190565b929101610d64565b805173ffffffffffffffffffffffffffffffffffffffff1682526100d5916060810191604090610df060208201516020850190610d2d565b0151906040818403910152610d4a565b906100d591610db8565b90610e20610e16835190565b8083529160200190565b9081610e326020830284019460200190565b926000915b838310610e4657505050505090565b90919293946020610e69610e6283856001950387528951610e00565b9760200190565b9301930191939290610e37565b60608082526100d59392610eb091610e919190840190610e0a565b73ffffffffffffffffffffffffffffffffffffffff9093166020830152565b60408183039101526000815260200190565b9060005b610ed16100d5845190565b81101561101b57610eee6020610ee7838661062c565b5101610d1a565b600090610efa826106a3565b610f03826106a3565b03610f59575090610f4f610f3a610f5493610f1e848861062c565b51015173ffffffffffffffffffffffffffffffffffffffff1690565b6040610f46848861062c565b5101519061124c565b610ce8565b610ec6565b610f6360016106a3565b610f6c826106a3565b03610f9c575090610f4f610f87610f5493610f1e848861062c565b6040610f93848861062c565b5101519061144d565b610fa660026106a3565b610faf826106a3565b03610fdf575090610f4f610fca610f5493610f1e848861062c565b6040610fd6848861062c565b510151906115f4565b610c4b90610fec60405190565b9182917f32191c2900000000000000000000000000000000000000000000000000000000835260048301610d36565b5090611027600061065c565b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6739161105e61105560405190565b92839283610e76565b0390a1565b1561106a57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608490fd5b156110f657565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608490fd5b6111886100d56100d59290565b6bffffffffffffffffffffffff1690565b156111a057565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608490fd5b6bffffffffffffffffffffffff166bffffffffffffffffffffffff8114610d155760010190565b9190611256815190565b61127260009161126c6112688461050b565b9190565b11611063565b61127a610ca9565b6112838261065c565b6112bc73ffffffffffffffffffffffffffffffffffffffff821673ffffffffffffffffffffffffffffffffffffffff88165b14156110ef565b6112da6112d5846112d08960018701610885565b015490565b61117b565b93846112fa6112e88661117b565b916bffffffffffffffffffffffff1690565b146113b2575b6000945b61130f6100d5835190565b8610156113a85761139c816113978a6113a2948961139161136c826107f58f6113638f9161133d908f61062c565b517fffffffff000000000000000000000000000000000000000000000000000000001690565b9586910161078d565b61138b73ffffffffffffffffffffffffffffffffffffffff8c16610bff565b14611199565b8961197e565b611225565b95610ce8565b94611304565b5050505050509050565b6113bc87846117ff565b611300565b156113c857565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608490fd5b815191929161146460009161126c6112688461050b565b61146c610ca9565b9061149861147c6100bc8361065c565b73ffffffffffffffffffffffffffffffffffffffff85166112b5565b6114ac6112d5826112d08660018701610885565b94856114ba6112e88461117b565b14611559575b6000955b6114cf6100d5835190565b87101561155057611544816113978761154a94876113918a6115068f6107f56114fc61133d87938f61062c565b809681950161078d565b61153e73ffffffffffffffffffffffffffffffffffffffff871673ffffffffffffffffffffffffffffffffffffffff831614156113c1565b8c611cc3565b96610ce8565b956114c4565b50505050509050565b61156384846117ff565b6114c0565b1561156f57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608490fd5b8151600093929061160b9061126c6112688761050b565b61162c611616610ca9565b92611626610bff6100bc8861065c565b14611568565b60005b61163a6100d5835190565b8110156116705780610f4f61165561133d61166b948661062c565b611665886107f583828a0161078d565b86611cc3565b61162f565b5050509050565b67ffffffffffffffff811161022257602090601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b9061052561029883611677565b6116c960246116b2565b7f4c69624469616d6f6e644375743a204e657720666163657420686173206e6f2060208201527f636f646500000000000000000000000000000000000000000000000000000000604082015290565b6100d56116bf565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905b9181191691161790565b9061175e6100d56117659261050b565b8254611720565b9055565b805482101561064657611783600191600052602060002090565b91020190600090565b919060086117449102916117b373ffffffffffffffffffffffffffffffffffffffff841b90565b921b90565b91906117c96100d56117659361087c565b90835461178c565b908154916801000000000000000083101561022257826117f991600161010495018155611769565b906117b8565b9061183c61010492611818611812611718565b84611f74565b6100d560028201916001611836868261182f875490565b9401610885565b0161174e565b6117d1565b907fffffffffffffffffffffffff00000000000000000000000000000000000000009060a01b611744565b6111886100d56100d5926bffffffffffffffffffffffff1690565b906118976100d56117659261186c565b8254611841565b80549192918310156106465760086118bd600492600052602060002090565b8185040193060290565b919060086117449102916117b363ffffffff841b90565b919061191561190f611765937fffffffff000000000000000000000000000000000000000000000000000000001690565b60e01c90565b9083546118c7565b908154916801000000000000000083101561022257826119459160016101049501815561189e565b906118de565b9073ffffffffffffffffffffffffffffffffffffffff90611744565b906119776100d56117659261087c565b825461194b565b8184936119bb6000946119b686610d466101049a60016119c0996119b085820199866119aa8a8d61078d565b01611887565b01610885565b61191d565b61078d565b01611967565b156119cd57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608490fd5b15611a5957565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608490fd5b6100d59060a01c611188565b6100d59054611ade565b6100d56100d56100d5926bffffffffffffffffffffffff1690565b91908203918211610d1557565b6100d5916008021c60e01b90565b906100d59154611b1c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b610104916000916118de565b80548015611bb1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190611bae611ba8838361189e565b90611b64565b55565b611b35565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b90600003611bf35760009055565b611bb6565b6100d59081565b6100d59054611bf8565b6100d5916008021c6100bc565b906100d59154611c09565b610104916000916117b8565b80548015611bb1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190611bae611c658383611769565b90611c21565b919060086117449102916117b37fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841b90565b9190611caf6100d56117659361050b565b908354611c6b565b61010491600091611c9e565b611d789092919283600093611cfb611cdd6100bc8761065c565b73ffffffffffffffffffffffffffffffffffffffff841614156119c6565b611d28611d0a6100bc3061087c565b73ffffffffffffffffffffffffffffffffffffffff84161415611a52565b611da985611da481860193611d4f611d4a84611d44848961078d565b01611aea565b611af4565b94611d61846112d08960018c01610885565b87858a60019c8d94611d728661050b565b90611b0f565b809a611d818290565b8103611e59575b5050611d9f92506119bb93610d4691019e8f610885565b611b70565b611be5565b611db56112688661050b565b14611dc2575b5050505050565b611e1a94611e0f611e0a6002611e149501611de7611dde825490565b611d728961050b565b611dfb88611df58888610885565b01611bff565b88828203611e24575b50505090565b611c2d565b610885565b01611cb7565b3880808080611dbb565b611836611e3d611e37611e519587611769565b90611c16565b611e4b816117f98689611769565b88610885565b388088611e04565b6112d5856119458387611e84611e90611e8a611e989984611e9f9f611e84906119aa9e01998a610885565b0161189e565b90611b2a565b9a8b95610885565b928561078d565b8887858a8938611d88565b60005b838110611ebd5750506000910152565b8181015183820152602001611ead565b611eee611ef7602093610d4693611ee2815190565b80835293849260200190565b95869101611eaa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690565b60208082526100d592910190611ecd565b15611f385750565b610c4b90611f4560405190565b9182917f08c379a000000000000000000000000000000000000000000000000000000000835260048301611f1f565b61010491903b611f87611268600061050b565b11611f3056fea2646970667358221220fc4877dcf7349a5bce46f2e81f0b616e98af3b94b1be3971110ea007861c841b64736f6c63430008130033