- Contract name:
- Staking2a
- Optimization enabled
- true
- Compiler version
- v0.8.23+commit.f704f362
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2025-03-20T09:57:08.370454Z
src/Staking2a.sol
// SPDX-License-Identifier: UNLICENSEDpragma solidity ^0.8.23;import {IStaking2a} from "./interfaces/IStaking2a.sol";import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";/// @title Smart contract for staking and locking ERC20 tokens./// @author Giorgi Abuladzecontract Staking2a isIStaking2a,UUPSUpgradeable,AccessControlUpgradeable,Ownable2StepUpgradeable,ReentrancyGuardUpgradeable{using SafeERC20 for IERC20;bytes32 public constant WHITELISTED_ROLE = keccak256("WHITELISTED_ROLE");bytes32 public constant WHITELIST_ADMIN_ROLE = keccak256("WHITELIST_ADMIN_ROLE");/// @notice variable to keep track of all activity types that were used when creating locks./// is updated in lock method after creating the lock.uint256 internal allActivitiesMask;bool internal whitelistEnabled;/// @notice A struct that represents a stake lock operation.struct StakeLockOp {uint256 amount;uint256 deadline;uint256 flags;}/// @notice A struck that represents an unstake operationstruct UnstakeOp {uint256 amount;
lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)pragma solidity ^0.8.20;/*** @dev This is the interface that {BeaconProxy} expects of its beacon.*/interface IBeacon {/*** @dev Must return an address that can be used as a delegate call target.** {UpgradeableBeacon} will check that this address is a contract.*/function implementation() external view returns (address);}
lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)pragma solidity ^0.8.20;import {IAccessControl} from "@openzeppelin/contracts/access/IAccessControl.sol";import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";import {ERC165Upgradeable} from "../utils/introspection/ERC165Upgradeable.sol";import {Initializable} from "../proxy/utils/Initializable.sol";/*** @dev Contract module that allows children to implement role-based access* control mechanisms. This is a lightweight version that doesn't allow enumerating role* members except through off-chain means by accessing the contract event logs. Some* applications may benefit from on-chain enumerability, for those cases see* {AccessControlEnumerable}.** Roles are referred to by their `bytes32` identifier. These should be exposed* in the external API and be unique. The best way to achieve this is by* using `public constant` hash digests:** ```solidity* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");* ```** Roles can be used to represent a set of permissions. To restrict access to a* function call, use {hasRole}:** ```solidity* function foo() public {* require(hasRole(MY_ROLE, msg.sender));* ...* }* ```** Roles can be granted and revoked dynamically via the {grantRole} and* {revokeRole} functions. Each role has an associated admin role, and only* accounts that have a role's admin role can call {grantRole} and {revokeRole}.** By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means* that only accounts with this role will be able to grant or revoke other
lib/openzeppelin-contracts/contracts/access/IAccessControl.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol)pragma solidity ^0.8.20;/*** @dev External interface of AccessControl declared to support ERC165 detection.*/interface IAccessControl {/*** @dev The `account` is missing a role.*/error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);/*** @dev The caller of a function is not the expected one.** NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.*/error AccessControlBadConfirmation();/*** @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`** `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite* {RoleAdminChanged} not being emitted signaling this.*/event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);/*** @dev Emitted when `account` is granted `role`.** `sender` is the account that originated the contract call, an admin role* bearer except when using {AccessControl-_setupRole}.*/event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);/*** @dev Emitted when `account` is revoked `role`.** `sender` is the account that originated the contract call:
lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol)pragma solidity ^0.8.20;import {OwnableUpgradeable} from "./OwnableUpgradeable.sol";import {Initializable} from "../proxy/utils/Initializable.sol";/*** @dev Contract module which provides access control mechanism, where* there is an account (an owner) that can be granted exclusive access to* specific functions.** The initial owner is specified at deployment time in the constructor for `Ownable`. This* can later be changed with {transferOwnership} and {acceptOwnership}.** This module is used through inheritance. It will make available all functions* from parent (Ownable).*/abstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {/// @custom:storage-location erc7201:openzeppelin.storage.Ownable2Stepstruct Ownable2StepStorage {address _pendingOwner;}// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable2Step")) - 1)) & ~bytes32(uint256(0xff))bytes32 private constant Ownable2StepStorageLocation = 0x237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00;function _getOwnable2StepStorage() private pure returns (Ownable2StepStorage storage $) {assembly {$.slot := Ownable2StepStorageLocation}}event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);function __Ownable2Step_init() internal onlyInitializing {}function __Ownable2Step_init_unchained() internal onlyInitializing {}
lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)pragma solidity ^0.8.20;import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";import {Initializable} from "../proxy/utils/Initializable.sol";/*** @dev Contract module which provides a basic access control mechanism, where* there is an account (an owner) that can be granted exclusive access to* specific functions.** The initial owner is set to the address provided by the deployer. This can* later be changed with {transferOwnership}.** This module is used through inheritance. It will make available the modifier* `onlyOwner`, which can be applied to your functions to restrict their use to* the owner.*/abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {/// @custom:storage-location erc7201:openzeppelin.storage.Ownablestruct OwnableStorage {address _owner;}// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable")) - 1)) & ~bytes32(uint256(0xff))bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;function _getOwnableStorage() private pure returns (OwnableStorage storage $) {assembly {$.slot := OwnableStorageLocation}}/*** @dev The caller account is not authorized to perform an operation.*/error OwnableUnauthorizedAccount(address account);/**
lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)pragma solidity ^0.8.20;/*** @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.** The initialization functions use a version number. Once a version number is used, it is consumed and cannot be* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in* case an upgrade adds a module that needs to be initialized.** For example:** [.hljs-theme-light.nopadding]* ```solidity* contract MyToken is ERC20Upgradeable {* function initialize() initializer public {* __ERC20_init("MyToken", "MTK");* }* }** contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {* function initializeV2() reinitializer(2) public {* __ERC20Permit_init("MyToken");* }* }* ```** TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.** CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.** [CAUTION]* ====* Avoid leaving a contract uninitialized.
lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/UUPSUpgradeable.sol)pragma solidity ^0.8.20;import {IERC1822Proxiable} from "@openzeppelin/contracts/interfaces/draft-IERC1822.sol";import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";import {Initializable} from "./Initializable.sol";/*** @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an* {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.** A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is* reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing* `UUPSUpgradeable` with a custom implementation of upgrades.** The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.*/abstract contract UUPSUpgradeable is Initializable, IERC1822Proxiable {/// @custom:oz-upgrades-unsafe-allow state-variable-immutableaddress private immutable __self = address(this);/*** @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgradeTo(address)`* and `upgradeToAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called,* while `upgradeToAndCall` will invoke the `receive` function if the second argument is the empty byte string.* If the getter returns `"5.0.0"`, only `upgradeToAndCall(address,bytes)` is present, and the second argument must* be the empty byte string if no function should be called, making it impossible to invoke the `receive` function* during an upgrade.*/string public constant UPGRADE_INTERFACE_VERSION = "5.0.0";/*** @dev The call is from an unauthorized context.*/error UUPSUnauthorizedCallContext();/*** @dev The storage `slot` is unsupported as a UUID.*/
lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)pragma solidity ^0.8.20;import {Initializable} from "../proxy/utils/Initializable.sol";/*** @dev Provides information about the current execution context, including the* sender of the transaction and its data. While these are generally available* via msg.sender and msg.data, they should not be accessed in such a direct* manner, since when dealing with meta-transactions the account sending and* paying for execution may not be the actual sender (as far as an application* is concerned).** This contract is only required for intermediate, library-like contracts.*/abstract contract ContextUpgradeable is Initializable {function __Context_init() internal onlyInitializing {}function __Context_init_unchained() internal onlyInitializing {}function _msgSender() internal view virtual returns (address) {return msg.sender;}function _msgData() internal view virtual returns (bytes calldata) {return msg.data;}function _contextSuffixLength() internal view virtual returns (uint256) {return 0;}}
lib/openzeppelin-contracts-upgradeable/contracts/utils/ReentrancyGuardUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)pragma solidity ^0.8.20;import {Initializable} from "../proxy/utils/Initializable.sol";/*** @dev Contract module that helps prevent reentrant calls to a function.** Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier* available, which can be applied to functions to make sure there are no nested* (reentrant) calls to them.** Note that because there is a single `nonReentrant` guard, functions marked as* `nonReentrant` may not call one another. This can be worked around by making* those functions `private`, and then adding `external` `nonReentrant` entry* points to them.** TIP: If you would like to learn more about reentrancy and alternative ways* to protect against it, check out our blog post* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].*/abstract contract ReentrancyGuardUpgradeable is Initializable {// Booleans are more expensive than uint256 or any type that takes up a full// word because each write operation emits an extra SLOAD to first read the// slot's contents, replace the bits taken up by the boolean, and then write// back. This is the compiler's defense against contract upgrades and// pointer aliasing, and it cannot be disabled.// The values being non-zero value makes deployment a bit more expensive,// but in exchange the refund on every call to nonReentrant will be lower in// amount. Since refunds are capped to a percentage of the total// transaction's gas, it is best to keep them low in cases like this one, to// increase the likelihood of the full refund coming into effect.uint256 private constant NOT_ENTERED = 1;uint256 private constant ENTERED = 2;/// @custom:storage-location erc7201:openzeppelin.storage.ReentrancyGuardstruct ReentrancyGuardStorage {uint256 _status;}
lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165Upgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)pragma solidity ^0.8.20;import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";import {Initializable} from "../../proxy/utils/Initializable.sol";/*** @dev Implementation of the {IERC165} interface.** Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check* for the additional interface id that will be supported. For example:** ```solidity* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);* }* ```*/abstract contract ERC165Upgradeable is Initializable, IERC165 {function __ERC165_init() internal onlyInitializing {}function __ERC165_init_unchained() internal onlyInitializing {}/*** @dev See {IERC165-supportsInterface}.*/function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {return interfaceId == type(IERC165).interfaceId;}}
lib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC1822.sol)pragma solidity ^0.8.20;/*** @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified* proxy whose upgrades are fully controlled by the current implementation.*/interface IERC1822Proxiable {/*** @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation* address.** IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this* function revert if invoked through a proxy.*/function proxiableUUID() external view returns (bytes32);}
lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Utils.sol)pragma solidity ^0.8.20;import {IBeacon} from "../beacon/IBeacon.sol";import {Address} from "../../utils/Address.sol";import {StorageSlot} from "../../utils/StorageSlot.sol";/*** @dev This abstract contract provides getters and event emitting update functions for* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.*/library ERC1967Utils {// We re-declare ERC-1967 events here because they can't be used directly from IERC1967.// This will be fixed in Solidity 0.8.21. At that point we should remove these events./*** @dev Emitted when the implementation is upgraded.*/event Upgraded(address indexed implementation);/*** @dev Emitted when the admin account has changed.*/event AdminChanged(address previousAdmin, address newAdmin);/*** @dev Emitted when the beacon is changed.*/event BeaconUpgraded(address indexed beacon);/*** @dev Storage slot with the address of the current implementation.* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1.*/// solhint-disable-next-line private-vars-leading-underscorebytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;/*** @dev The `implementation` of the proxy is invalid.*/
lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)pragma solidity ^0.8.20;/*** @dev Interface of the ERC20 standard as defined in the EIP.*/interface IERC20 {/*** @dev Emitted when `value` tokens are moved from one account (`from`) to* another (`to`).** Note that `value` may be zero.*/event Transfer(address indexed from, address indexed to, uint256 value);/*** @dev Emitted when the allowance of a `spender` for an `owner` is set by* a call to {approve}. `value` is the new allowance.*/event Approval(address indexed owner, address indexed spender, uint256 value);/*** @dev Returns the value of tokens in existence.*/function totalSupply() external view returns (uint256);/*** @dev Returns the value of tokens owned by `account`.*/function balanceOf(address account) external view returns (uint256);/*** @dev Moves a `value` amount of tokens from the caller's account to `to`.** Returns a boolean value indicating whether the operation succeeded.** Emits a {Transfer} event.*/function transfer(address to, uint256 value) external returns (bool);
lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)pragma solidity ^0.8.20;/*** @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].** Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't* need to send a transaction, and thus is not required to hold Ether at all.** ==== Security Considerations** There are two important considerations concerning the use of `permit`. The first is that a valid permit signature* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be* considered as an intention to spend the allowance in any specific way. The second is that because permits have* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be* generally recommended is:** ```solidity* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}* doThing(..., value);* }** function doThing(..., uint256 value) public {* token.safeTransferFrom(msg.sender, address(this), value);* ...* }* ```** Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also* {SafeERC20-safeTransferFrom}).** Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so* contracts should have entry points that don't rely on permit.*/
lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)pragma solidity ^0.8.20;import {IERC20} from "../IERC20.sol";import {IERC20Permit} from "../extensions/IERC20Permit.sol";import {Address} from "../../../utils/Address.sol";/*** @title SafeERC20* @dev Wrappers around ERC20 operations that throw on failure (when the token* contract returns false). Tokens that return no value (and instead revert or* throw on failure) are also supported, non-reverting calls are assumed to be* successful.* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.*/library SafeERC20 {using Address for address;/*** @dev An operation with an ERC20 token failed.*/error SafeERC20FailedOperation(address token);/*** @dev Indicates a failed `decreaseAllowance` request.*/error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);/*** @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,* non-reverting calls are assumed to be successful.*/function safeTransfer(IERC20 token, address to, uint256 value) internal {_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));}/*** @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
lib/openzeppelin-contracts/contracts/utils/Address.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)pragma solidity ^0.8.20;/*** @dev Collection of functions related to the address type*/library Address {/*** @dev The ETH balance of the account is not enough to perform the operation.*/error AddressInsufficientBalance(address account);/*** @dev There's no code at `target` (it is not a contract).*/error AddressEmptyCode(address target);/*** @dev A call to an address target failed. The target may have reverted.*/error FailedInnerCall();/*** @dev Replacement for Solidity's `transfer`: sends `amount` wei to* `recipient`, forwarding all available gas and reverting on errors.** https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost* of certain opcodes, possibly making contracts go over the 2300 gas limit* imposed by `transfer`, making them unable to receive funds via* `transfer`. {sendValue} removes this limitation.** https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].** IMPORTANT: because control is transferred to `recipient`, care must be* taken to not create reentrancy vulnerabilities. Consider using* {ReentrancyGuard} or the* https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].*/function sendValue(address payable recipient, uint256 amount) internal {
lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol)// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.pragma solidity ^0.8.20;/*** @dev Library for reading and writing primitive types to specific storage slots.** Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.* This library helps with reading and writing to such slots without the need for inline assembly.** The functions in this library return Slot structs that contain a `value` member that can be used to read or write.** Example usage to set ERC1967 implementation slot:* ```solidity* contract ERC1967 {* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;** function _getImplementation() internal view returns (address) {* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;* }** function _setImplementation(address newImplementation) internal {* require(newImplementation.code.length > 0);* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;* }* }* ```*/library StorageSlot {struct AddressSlot {address value;}struct BooleanSlot {bool value;}struct Bytes32Slot {bytes32 value;
lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)pragma solidity ^0.8.20;/*** @dev Interface of the ERC165 standard, as defined in the* https://eips.ethereum.org/EIPS/eip-165[EIP].** Implementers can declare support of contract interfaces, which can then be* queried by others ({ERC165Checker}).** For an implementation, see {ERC165}.*/interface IERC165 {/*** @dev Returns true if this contract implements the interface defined by* `interfaceId`. See the corresponding* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]* to learn more about how these ids are created.** This function call must use less than 30 000 gas.*/function supportsInterface(bytes4 interfaceId) external view returns (bool);}
src/interfaces/IStaking2a.sol
// SPDX-License-Identifier: UNLICENSEDpragma solidity ^0.8.23;import {IStaking2aEvents} from "./IStaking2aEvents.sol";import {IStaking2aTypes} from "./IStaking2aTypes.sol";interface IStaking2a is IStaking2aEvents, IStaking2aTypes {// Stake tokensfunction stake(address staker, uint256 amount, address token) external;// Lock stake or update the deadline of the lockfunction lock(address staker,address token,uint256 lockAmount,uint256 lockDeadline,uint256 lockFlags,uint256 excludedActivities) external;// Lock stake or update the deadline of the lock, returns index of the reused lockfunction lock(address staker,address token,uint256 amount,uint256 deadline,uint256 flags,uint256 excludedActivities,bool flexible,bool exemptFromCooldownPeriod) external returns (uint256);// Creates a new lock.function createNewLock(address staker,address token,uint256 amount,uint256 deadline,uint256 flags,bool flexible,bool exemptFromCooldown
src/interfaces/IStaking2aEvents.sol
// SPDX-License-Identifier: UNLICENSEDpragma solidity ^0.8.23;interface IStaking2aEvents {event Stake(address indexed staker, address indexed token, uint256 amount);event LockStake(address indexed staker, address indexed token, uint256 amount, uint256 deadline, uint256 flags);event LockReleased(address indexed staker, address indexed token, uint256 amount, uint256 deadline, address releaser, uint256 idx);event Unstake(address indexed staker, address indexed token, uint256 amount, uint256 claimableAt);event UnstakePariodUpdated(uint256 newPeriod);event ExemptFromCooldownPeriodUpdated(uint256 newMask);event Claim(address indexed staker, address indexed token, uint256 amount);}
src/interfaces/IStaking2aTypes.sol
// SPDX-License-Identifier: UNLICENSEDpragma solidity ^0.8.23;interface IStaking2aTypes {struct StakeDataResponse {uint256 totalStake;uint256 totalUnstakable;uint256 totalLocked;uint256 totalLockedFlexible;uint256 totalClaimable;uint256 totalPendingUnstake;uint256 totalExemptFromCooldownPeriod;uint256[] totalLockedPerEventType;}}
Contract ABI
[{"type":"constructor","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"DEFAULT_ADMIN_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"UPGRADE_INTERFACE_VERSION","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"WHITELISTED_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"WHITELIST_ADMIN_ROLE","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"bool","name":"","internalType":"bool"},{"type":"bool","name":"","internalType":"bool"}],"name":"checkStakeForActivity","inputs":[{"type":"address","name":"staker","internalType":"address"},{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"deadline","internalType":"uint256"},{"type":"uint256","name":"excludedActivities","internalType":"uint256"},{"type":"bool","name":"flexible","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"checkStakeForActivity","inputs":[{"type":"address","name":"staker","internalType":"address"},{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"excludedActivities","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claim","inputs":[{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claim","inputs":[{"type":"address","name":"staker","internalType":"address"},{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"createNewLock","inputs":[{"type":"address","name":"staker","internalType":"address"},{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"deadline","internalType":"uint256"},{"type":"uint256","name":"flags","internalType":"uint256"},{"type":"bool","name":"flexible","internalType":"bool"},{"type":"bool","name":"exemptFromCooldownPeriod","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getClaimableStake","inputs":[{"type":"address","name":"staker","internalType":"address"},{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getRoleAdmin","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getStake","inputs":[{"type":"address","name":"staker","internalType":"address"},{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct IStaking2aTypes.StakeDataResponse","components":[{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256[]"}]}],"name":"getStakeData","inputs":[{"type":"address","name":"staker","internalType":"address"},{"type":"address","name":"token","internalType":"address"},{"type":"bool","name":"perEventType","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"tuple","name":"","internalType":"struct IStaking2aTypes.StakeDataResponse","components":[{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256"},{"type":"uint256[]"}]}],"name":"getStakeDataLatest","inputs":[{"type":"address","name":"staker","internalType":"address"},{"type":"address","name":"token","internalType":"address"},{"type":"bool","name":"perEventType","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTotalStake","inputs":[{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTotalStakers","inputs":[{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"grantRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"hasRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"lock","inputs":[{"type":"address","name":"staker","internalType":"address"},{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"deadline","internalType":"uint256"},{"type":"uint256","name":"flags","internalType":"uint256"},{"type":"uint256","name":"excludedActivities","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lock","inputs":[{"type":"address","name":"staker","internalType":"address"},{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"deadline","internalType":"uint256"},{"type":"uint256","name":"flags","internalType":"uint256"},{"type":"uint256","name":"excludedActivities","internalType":"uint256"},{"type":"bool","name":"flexible","internalType":"bool"},{"type":"bool","name":"exemptFromCooldownPeriod","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"pendingOwner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"proxiableUUID","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"releaseLock","inputs":[{"type":"address","name":"staker","internalType":"address"},{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"lockIdx","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"callerConfirmation","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revokeRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setUnstakePeriod","inputs":[{"type":"uint256","name":"newPeriod","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"stake","inputs":[{"type":"address","name":"staker","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"stake","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsInterface","inputs":[{"type":"bytes4","name":"interfaceId","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unstake","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unstake","inputs":[{"type":"address","name":"staker","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"unstakePeriod","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[],"name":"upgradeToAndCall","inputs":[{"type":"address","name":"newImplementation","internalType":"address"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"event","name":"Claim","inputs":[{"type":"address","name":"staker","indexed":true},{"type":"address","name":"token","indexed":true},{"type":"uint256","name":"amount","indexed":false}],"anonymous":false},{"type":"event","name":"ExemptFromCooldownPeriodUpdated","inputs":[{"type":"uint256","name":"newMask","indexed":false}],"anonymous":false},{"type":"event","name":"Initialized","inputs":[{"type":"uint64","name":"version","indexed":false}],"anonymous":false},{"type":"event","name":"LockReleased","inputs":[{"type":"address","name":"staker","indexed":true},{"type":"address","name":"token","indexed":true},{"type":"uint256","name":"amount","indexed":false},{"type":"uint256","name":"deadline","indexed":false},{"type":"address","name":"releaser","indexed":false},{"type":"uint256","name":"idx","indexed":false}],"anonymous":false},{"type":"event","name":"LockStake","inputs":[{"type":"address","name":"staker","indexed":true},{"type":"address","name":"token","indexed":true},{"type":"uint256","name":"amount","indexed":false},{"type":"uint256","name":"deadline","indexed":false},{"type":"uint256","name":"flags","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferStarted","inputs":[{"type":"address","name":"previousOwner","indexed":true},{"type":"address","name":"newOwner","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","indexed":true},{"type":"address","name":"newOwner","indexed":true}],"anonymous":false},{"type":"event","name":"RoleAdminChanged","inputs":[{"type":"bytes32","name":"role","indexed":true},{"type":"bytes32","name":"previousAdminRole","indexed":true},{"type":"bytes32","name":"newAdminRole","indexed":true}],"anonymous":false},{"type":"event","name":"RoleGranted","inputs":[{"type":"bytes32","name":"role","indexed":true},{"type":"address","name":"account","indexed":true},{"type":"address","name":"sender","indexed":true}],"anonymous":false},{"type":"event","name":"RoleRevoked","inputs":[{"type":"bytes32","name":"role","indexed":true},{"type":"address","name":"account","indexed":true},{"type":"address","name":"sender","indexed":true}],"anonymous":false},{"type":"event","name":"Stake","inputs":[{"type":"address","name":"staker","indexed":true},{"type":"address","name":"token","indexed":true},{"type":"uint256","name":"amount","indexed":false}],"anonymous":false},{"type":"event","name":"Unstake","inputs":[{"type":"address","name":"staker","indexed":true},{"type":"address","name":"token","indexed":true},{"type":"uint256","name":"amount","indexed":false},{"type":"uint256","name":"claimableAt","indexed":false}],"anonymous":false},{"type":"event","name":"UnstakePariodUpdated","inputs":[{"type":"uint256","name":"newPeriod","indexed":false}],"anonymous":false},{"type":"event","name":"Upgraded","inputs":[{"type":"address","name":"implementation","indexed":true}],"anonymous":false},{"type":"error","name":"AccessControlBadConfirmation","inputs":[]},{"type":"error","name":"AccessControlUnauthorizedAccount","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"bytes32","name":"neededRole","internalType":"bytes32"}]},{"type":"error","name":"AddressEmptyCode","inputs":[{"type":"address","name":"target","internalType":"address"}]},{"type":"error","name":"AddressInsufficientBalance","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"error","name":"ERC1967InvalidImplementation","inputs":[{"type":"address","name":"implementation","internalType":"address"}]},{"type":"error","name":"ERC1967NonPayable","inputs":[]},{"type":"error","name":"FailedInnerCall","inputs":[]},{"type":"error","name":"InvalidInitialization","inputs":[]},{"type":"error","name":"NotInitializing","inputs":[]},{"type":"error","name":"OwnableInvalidOwner","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"error","name":"OwnableUnauthorizedAccount","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"error","name":"ReentrancyGuardReentrantCall","inputs":[]},{"type":"error","name":"SafeERC20FailedOperation","inputs":[{"type":"address","name":"token","internalType":"address"}]},{"type":"error","name":"UUPSUnauthorizedCallContext","inputs":[]},{"type":"error","name":"UUPSUnsupportedProxiableUUID","inputs":[{"type":"bytes32","name":"slot","internalType":"bytes32"}]}]
Contract Creation Code
0x60a06040523060805234801562000014575f80fd5b506200001f62000025565b620000d9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff1615620000765760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b0390811614620000d65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b608051615222620001005f395f8181613093015281816130bc01526131fb01526152225ff3fe608060405260043610610228575f3560e01c80637acb775711610129578063ad3cb1cc116100a8578063e4aa64ab1161006d578063e4aa64ab146106da578063eb5d5c43146106ef578063f2fde38b1461070e578063fe400f4b1461072d578063ff979fb11461074c575f80fd5b8063ad3cb1cc1461062c578063c97a184f14610669578063d547741f14610688578063d9caed12146106a7578063e30c3978146106c6575f80fd5b80638da5cb5b116100ee5780638da5cb5b1461059057806391d14854146105bc578063926e31d6146105db578063a19f10d0146105fa578063a217fddf14610619575f80fd5b80637acb7757146104da5780638129fc1c146104f957806381af051d1461050d57806382dda22d1461052c5780638381e18214610571575f80fd5b80632f2ff15d116101b5578063715018a61161017a578063715018a614610437578063762f0b861461044b57806379ba5097146104875780637a3226ec1461049b5780637a3d9499146104bb575f80fd5b80632f2ff15d1461039f57806336568abe146103be5780634f1ef286146103dd57806352d1902d146103f057806354202c4e14610404575f80fd5b80631e83409a116101fb5780631e83409a146102f557806321c0b34214610316578063222bf70614610335578063248a9ca314610361578063294091cd14610380575f80fd5b806301ffc9a71461022c578063118413a814610260578063143bf65c1461028d5780631e7ff8f6146102c1575b5f80fd5b348015610237575f80fd5b5061024b610246366004614aee565b61076b565b60405190151581526020015b60405180910390f35b34801561026b575f80fd5b5061027f61027a366004614b30565b6107a1565b604051908152602001610257565b348015610298575f80fd5b5061027f6102a7366004614b61565b6001600160a01b03165f9081526004602052604090205490565b3480156102cc575f80fd5b5061027f6102db366004614b61565b6001600160a01b03165f9081526003602052604090205490565b348015610300575f80fd5b5061031461030f366004614b61565b610942565b005b348015610321575f80fd5b50610314610330366004614b30565b610ae2565b348015610340575f80fd5b5061035461034f366004614b87565b610cce565b6040516102579190614bcb565b34801561036c575f80fd5b5061027f61037b366004614c66565b610ceb565b34801561038b575f80fd5b5061031461039a366004614c7d565b610d0b565b3480156103aa575f80fd5b506103146103b9366004614cb6565b610d77565b3480156103c9575f80fd5b506103146103d8366004614cb6565b610d99565b6103146103eb366004614ceb565b610dcc565b3480156103fb575f80fd5b5061027f610de7565b34801561040f575f80fd5b5061027f7f28f5a99355973cc89255b8c4ac88405f27c78ded7608b040ee77a8bdf44d15e281565b348015610442575f80fd5b50610314610e02565b348015610456575f80fd5b5061046a610465366004614da7565b610e15565b604080519384529115156020840152151590820152606001610257565b348015610492575f80fd5b50610314611110565b3480156104a6575f80fd5b5061027f5f805160206151cd83398151915281565b3480156104c6575f80fd5b506103146104d5366004614e06565b611155565b3480156104e5575f80fd5b506103146104f4366004614cb6565b61140e565b348015610504575f80fd5b50610314611437565b348015610518575f80fd5b50610354610527366004614b87565b6115db565b348015610537575f80fd5b5061027f610546366004614b30565b6001600160a01b039081165f9081526002602081815260408084209590941683529390935220015490565b34801561057c575f80fd5b5061031461058b366004614cb6565b611a47565b34801561059b575f80fd5b506105a4611d2c565b6040516001600160a01b039091168152602001610257565b3480156105c7575f80fd5b5061024b6105d6366004614cb6565b611d60565b3480156105e6575f80fd5b506103146105f5366004614c7d565b611d96565b348015610605575f80fd5b50610314610614366004614e3f565b6120d5565b348015610624575f80fd5b5061027f5f81565b348015610637575f80fd5b5061065c604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516102579190614ed3565b348015610674575f80fd5b50610314610683366004614c66565b61212c565b348015610693575f80fd5b506103146106a2366004614cb6565b61216f565b3480156106b2575f80fd5b506103146106c1366004614e06565b61218b565b3480156106d1575f80fd5b506105a4612250565b3480156106e5575f80fd5b5061027f60055481565b3480156106fa575f80fd5b50610314610709366004614f05565b612278565b348015610719575f80fd5b50610314610728366004614b61565b6125a7565b348015610738575f80fd5b5061027f610747366004614f56565b61262c565b348015610757575f80fd5b5061024b610766366004614fd2565b612961565b5f6001600160e01b03198216637965db0b60e01b148061079b57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001600160a01b0381165f9081526002602090815260408083203380855292528220839060068101845b815481101561090e57428282815481106107e7576107e7615011565b905f5260205f20906002020160010154111561080f578061080781615039565b9150506107cb565b81818154811061082157610821615011565b905f5260205f2090600202015f0154836003015f8282546108429190615051565b9250508190555081818154811061085b5761085b615011565b905f5260205f2090600202015f0154836008015f82825461087c9190615064565b90915550508154829061089190600190615064565b815481106108a1576108a1615011565b905f5260205f2090600202018282815481106108bf576108bf615011565b5f9182526020909120825460029092020190815560019182015491015581548290806108ed576108ed615077565b5f8281526020812060025f19909301928302018181556001015590556107cb565b505050506001600160a01b039283165f90815260026020908152604080832096909516825294909452505090206003015490565b61094a612c61565b6001600160a01b0381165f9081526002602090815260408083203380855292528220909183919060068201905b8154811015610aba574282828154811061099357610993615011565b905f5260205f2090600202016001015411156109bb57806109b381615039565b915050610977565b8181815481106109cd576109cd615011565b905f5260205f2090600202015f0154836003015f8282546109ee9190615051565b92505081905550818181548110610a0757610a07615011565b905f5260205f2090600202015f0154836008015f828254610a289190615064565b909155505081548290610a3d90600190615064565b81548110610a4d57610a4d615011565b905f5260205f209060020201828281548110610a6b57610a6b615011565b5f918252602090912082546002909202019081556001918201549101558154829080610a9957610a99615077565b5f8281526020812060025f1990930192830201818155600101559055610977565b505050610ac73384612c98565b5050610adf60015f805160206151ad83398151915255565b50565b610aea612c61565b60015460ff1615610b3157610b0c5f805160206151cd83398151915233611d60565b610b315760405162461bcd60e51b8152600401610b289061508b565b60405180910390fd5b6001600160a01b038082165f9081526002602090815260408083209386168352929052908120839183919060068201905b8154811015610ca55742828281548110610b7e57610b7e615011565b905f5260205f209060020201600101541115610ba65780610b9e81615039565b915050610b62565b818181548110610bb857610bb8615011565b905f5260205f2090600202015f0154836003015f828254610bd99190615051565b92505081905550818181548110610bf257610bf2615011565b905f5260205f2090600202015f0154836008015f828254610c139190615064565b909155505081548290610c2890600190615064565b81548110610c3857610c38615011565b905f5260205f209060020201828281548110610c5657610c56615011565b5f918252602090912082546002909202019081556001918201549101558154829080610c8457610c84615077565b5f8281526020812060025f1990930192830201818155600101559055610b62565b505050610cb28484612c98565b5050610cca60015f805160206151ad83398151915255565b5050565b610cd6614ab0565b610ce1848484612d69565b90505b9392505050565b5f9081525f8051602061518d833981519152602052604090206001015490565b610d13612c61565b60015460ff1615610d5157610d355f805160206151cd83398151915233611d60565b610d515760405162461bcd60e51b8152600401610b289061508b565b610d5c838383612e24565b610d7260015f805160206151ad83398151915255565b505050565b610d8082610ceb565b610d8981612f64565b610d938383612f6e565b50505050565b6001600160a01b0381163314610dc25760405163334bd91960e11b815260040160405180910390fd5b610d72828261300f565b610dd4613088565b610ddd8261312c565b610cca8282613134565b5f610df06131f0565b505f8051602061516d83398151915290565b610e0a613239565b610e135f61326b565b565b6001600160a01b038086165f908152600260209081526040808320938a168352929052908120819081908990899080845b81548110156110eb5742828281548110610e6257610e62615011565b905f5260205f209060030201600101541115610e8a5780610e8281615039565b915050610e46565b5f81815260048401602052604090205460ff1615610ee057818181548110610eb457610eb4615011565b905f5260205f2090600302015f0154836005015f828254610ed59190615064565b90915550610f199050565b818181548110610ef257610ef2615011565b905f5260205f2090600302015f0154836007015f828254610f139190615051565b90915550505b5f81815260098401602052604090205460ff1615610f6a57818181548110610f4357610f43615011565b905f5260205f2090600302015f015483600a015f828254610f649190615051565b90915550505b815460048401905f90610f7f90600190615064565b815260208082019290925260409081015f908120548482526004870193849052918120805460ff191660ff9093161515929092179091558354610fc490600190615064565b815260208101919091526040015f908120805460ff191690558254600985019190610ff190600190615064565b815260208082019290925260409081015f908120548482526009870193849052918120805460ff191660ff909316151592909217909155835461103690600190615064565b815260208101919091526040015f20805460ff191690558154829061105d90600190615064565b8154811061106d5761106d615011565b905f5260205f20906003020182828154811061108b5761108b615011565b5f918252602090912082546003909202019081556001808301549082015560029182015491015581548290806110c3576110c3615077565b5f8281526020812060035f199093019283020181815560018101829055600201559055610e46565b5050506110fc8b8b8b8b8b8b6132a3565b945094509450505096509650969350505050565b338061111a612250565b6001600160a01b03161461114c5760405163118cdaa760e01b81526001600160a01b0382166004820152602401610b28565b610adf8161326b565b60015460ff1615611193576111775f805160206151cd83398151915233611d60565b6111935760405162461bcd60e51b8152600401610b289061508b565b6001600160a01b038083165f908152600260209081526040808320938716835292905290812080549091908290849081106111d0576111d0615011565b905f5260205f2090600302015f015411801561120e57505f815f0183815481106111fc576111fc615011565b905f5260205f20906003020160010154115b801561123c57505f815f01838154811061122a5761122a615011565b905f5260205f20906003020160020154115b6112705760405162461bcd60e51b8152602060048201526005602482015264092989288b60db1b6044820152606401610b28565b5f82815260048201602052604090205460ff166112b55760405162461bcd60e51b815260206004820152600360248201526226272360e91b6044820152606401610b28565b826001600160a01b0316846001600160a01b03167f9dba03accf66a1bf272e6301fd9885f6f80ca6856d90366beb73084ff13a0b52835f0185815481106112fe576112fe615011565b905f5260205f2090600302015f0154845f01868154811061132157611321615011565b5f91825260209182902060016003909202010154604080519384529183015233908201526060810186905260800160405180910390a3805f01828154811061136b5761136b615011565b905f5260205f2090600302015f0154816005015f82825461138c9190615064565b909155505080545f908290849081106113a7576113a7615011565b5f918252602082206003909102019190915581548290849081106113cd576113cd615011565b905f5260205f209060030201600101819055505f815f0183815481106113f5576113f5615011565b905f5260205f2090600302016002018190555050505050565b611416612c61565b611421338383612e24565b610cca60015f805160206151ad83398151915255565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff165f8115801561147c5750825b90505f8267ffffffffffffffff1660011480156114985750303b155b9050811580156114a6575080155b156114c45760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156114ee57845460ff60401b1916600160401b1785555b6114f73361351e565b6114ff61352f565b6115095f33612f6e565b506115347f28f5a99355973cc89255b8c4ac88405f27c78ded7608b040ee77a8bdf44d15e233610d77565b61156b5f805160206151cd8339815191527f28f5a99355973cc89255b8c4ac88405f27c78ded7608b040ee77a8bdf44d15e2613537565b6115825f805160206151cd83398151915233610d77565b6001805460ff19168117905583156115d457845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050565b6115e3614ab0565b6001600160a01b038084165f9081526002602090815260408083209388168352929052908120859185919081905b81548110156118b6574282828154811061162d5761162d615011565b905f5260205f209060030201600101541115611655578061164d81615039565b915050611611565b5f81815260048401602052604090205460ff16156116ab5781818154811061167f5761167f615011565b905f5260205f2090600302015f0154836005015f8282546116a09190615064565b909155506116e49050565b8181815481106116bd576116bd615011565b905f5260205f2090600302015f0154836007015f8282546116de9190615051565b90915550505b5f81815260098401602052604090205460ff16156117355781818154811061170e5761170e615011565b905f5260205f2090600302015f015483600a015f82825461172f9190615051565b90915550505b815460048401905f9061174a90600190615064565b815260208082019290925260409081015f908120548482526004870193849052918120805460ff191660ff909316151592909217909155835461178f90600190615064565b815260208101919091526040015f908120805460ff1916905582546009850191906117bc90600190615064565b815260208082019290925260409081015f908120548482526009870193849052918120805460ff191660ff909316151592909217909155835461180190600190615064565b815260208101919091526040015f20805460ff191690558154829061182890600190615064565b8154811061183857611838615011565b905f5260205f20906003020182828154811061185657611856615011565b5f9182526020909120825460039092020190815560018083015490820155600291820154910155815482908061188e5761188e615077565b5f8281526020812060035f199093019283020181815560018101829055600201559055611611565b5050506001600160a01b038086165f908152600260209081526040808320938a168352929052908120879187919060068201905b8154811015611a2d574282828154811061190657611906615011565b905f5260205f20906002020160010154111561192e578061192681615039565b9150506118ea565b81818154811061194057611940615011565b905f5260205f2090600202015f0154836003015f8282546119619190615051565b9250508190555081818154811061197a5761197a615011565b905f5260205f2090600202015f0154836008015f82825461199b9190615064565b9091555050815482906119b090600190615064565b815481106119c0576119c0615011565b905f5260205f2090600202018282815481106119de576119de615011565b5f918252602090912082546002909202019081556001918201549101558154829080611a0c57611a0c615077565b5f8281526020812060025f19909301928302018181556001015590556118ea565b505050611a3b888888612d69565b98975050505050505050565b611a4f612c61565b6001600160a01b0381165f9081526002602090815260408083203380855292528220909183919081905b8154811015611d1e5742828281548110611a9557611a95615011565b905f5260205f209060030201600101541115611abd5780611ab581615039565b915050611a79565b5f81815260048401602052604090205460ff1615611b1357818181548110611ae757611ae7615011565b905f5260205f2090600302015f0154836005015f828254611b089190615064565b90915550611b4c9050565b818181548110611b2557611b25615011565b905f5260205f2090600302015f0154836007015f828254611b469190615051565b90915550505b5f81815260098401602052604090205460ff1615611b9d57818181548110611b7657611b76615011565b905f5260205f2090600302015f015483600a015f828254611b979190615051565b90915550505b815460048401905f90611bb290600190615064565b815260208082019290925260409081015f908120548482526004870193849052918120805460ff191660ff9093161515929092179091558354611bf790600190615064565b815260208101919091526040015f908120805460ff191690558254600985019190611c2490600190615064565b815260208082019290925260409081015f908120548482526009870193849052918120805460ff191660ff9093161515929092179091558354611c6990600190615064565b815260208101919091526040015f20805460ff1916905581548290611c9090600190615064565b81548110611ca057611ca0615011565b905f5260205f209060030201828281548110611cbe57611cbe615011565b5f91825260209091208254600390920201908155600180830154908201556002918201549101558154829080611cf657611cf6615077565b5f8281526020812060035f199093019283020181815560018101829055600201559055611a79565b505050610cb2338585613597565b5f807f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993005b546001600160a01b031692915050565b5f9182525f8051602061518d833981519152602090815260408084206001600160a01b0393909316845291905290205460ff1690565b611d9e612c61565b60015460ff1615611ddc57611dc05f805160206151cd83398151915233611d60565b611ddc5760405162461bcd60e51b8152600401610b289061508b565b6001600160a01b038082165f9081526002602090815260408083209387168352929052908120849183919081905b81548110156120af5742828281548110611e2657611e26615011565b905f5260205f209060030201600101541115611e4e5780611e4681615039565b915050611e0a565b5f81815260048401602052604090205460ff1615611ea457818181548110611e7857611e78615011565b905f5260205f2090600302015f0154836005015f828254611e999190615064565b90915550611edd9050565b818181548110611eb657611eb6615011565b905f5260205f2090600302015f0154836007015f828254611ed79190615051565b90915550505b5f81815260098401602052604090205460ff1615611f2e57818181548110611f0757611f07615011565b905f5260205f2090600302015f015483600a015f828254611f289190615051565b90915550505b815460048401905f90611f4390600190615064565b815260208082019290925260409081015f908120548482526004870193849052918120805460ff191660ff9093161515929092179091558354611f8890600190615064565b815260208101919091526040015f908120805460ff191690558254600985019190611fb590600190615064565b815260208082019290925260409081015f908120548482526009870193849052918120805460ff191660ff9093161515929092179091558354611ffa90600190615064565b815260208101919091526040015f20805460ff191690558154829061202190600190615064565b8154811061203157612031615011565b905f5260205f20906003020182828154811061204f5761204f615011565b5f9182526020909120825460039092020190815560018083015490820155600291820154910155815482908061208757612087615077565b5f8281526020812060035f199093019283020181815560018101829055600201559055611e0a565b5050506120bd858585613597565b5050610d7260015f805160206151ad83398151915255565b60015460ff1615612113576120f75f805160206151cd83398151915233611d60565b6121135760405162461bcd60e51b8152600401610b289061508b565b61212287878787878787613a06565b5050505050505050565b612134613239565b60058190556040518181527fd4af69124fa9990e5d807ba37f0803baf57b8cb6efc81a76f2481dd30da0592e9060200160405180910390a150565b61217882610ceb565b61218181612f64565b610d93838361300f565b612193612c61565b61219b613239565b6001600160a01b0383165f818152600360205260408082205490516370a0823160e01b81523060048201529092906370a0823190602401602060405180830381865afa1580156121ed573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061221191906150a7565b905061221d8282615064565b83111561223c5760405162461bcd60e51b8152600401610b28906150be565b6120bd6001600160a01b0386168585613c25565b5f807f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00611d50565b60015460ff16156122b65761229a5f805160206151cd83398151915233611d60565b6122b65760405162461bcd60e51b8152600401610b289061508b565b6001600160a01b038086165f908152600260209081526040808320938a168352929052908120879187919081905b8154811015612589574282828154811061230057612300615011565b905f5260205f209060030201600101541115612328578061232081615039565b9150506122e4565b5f81815260048401602052604090205460ff161561237e5781818154811061235257612352615011565b905f5260205f2090600302015f0154836005015f8282546123739190615064565b909155506123b79050565b81818154811061239057612390615011565b905f5260205f2090600302015f0154836007015f8282546123b19190615051565b90915550505b5f81815260098401602052604090205460ff1615612408578181815481106123e1576123e1615011565b905f5260205f2090600302015f015483600a015f8282546124029190615051565b90915550505b815460048401905f9061241d90600190615064565b815260208082019290925260409081015f908120548482526004870193849052918120805460ff191660ff909316151592909217909155835461246290600190615064565b815260208101919091526040015f908120805460ff19169055825460098501919061248f90600190615064565b815260208082019290925260409081015f908120548482526009870193849052918120805460ff191660ff90931615159290921790915583546124d490600190615064565b815260208101919091526040015f20805460ff19169055815482906124fb90600190615064565b8154811061250b5761250b615011565b905f5260205f20906003020182828154811061252957612529615011565b5f9182526020909120825460039092020190815560018083015490820155600291820154910155815482908061256157612561615077565b5f8281526020812060035f1990930192830201818155600181018290556002015590556122e4565b50505061259c8888888888885f80613c84565b505050505050505050565b6125af613239565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b0319166001600160a01b03831690811782556125f3611d2c565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a35050565b6001545f9060ff161561266c576126505f805160206151cd83398151915233611d60565b61266c5760405162461bcd60e51b8152600401610b289061508b565b6001600160a01b038089165f908152600260209081526040808320938d1683529290529081208a918a919081905b815481101561293f57428282815481106126b6576126b6615011565b905f5260205f2090600302016001015411156126de57806126d681615039565b91505061269a565b5f81815260048401602052604090205460ff16156127345781818154811061270857612708615011565b905f5260205f2090600302015f0154836005015f8282546127299190615064565b9091555061276d9050565b81818154811061274657612746615011565b905f5260205f2090600302015f0154836007015f8282546127679190615051565b90915550505b5f81815260098401602052604090205460ff16156127be5781818154811061279757612797615011565b905f5260205f2090600302015f015483600a015f8282546127b89190615051565b90915550505b815460048401905f906127d390600190615064565b815260208082019290925260409081015f908120548482526004870193849052918120805460ff191660ff909316151592909217909155835461281890600190615064565b815260208101919091526040015f908120805460ff19169055825460098501919061284590600190615064565b815260208082019290925260409081015f908120548482526009870193849052918120805460ff191660ff909316151592909217909155835461288a90600190615064565b815260208101919091526040015f20805460ff19169055815482906128b190600190615064565b815481106128c1576128c1615011565b905f5260205f2090600302018282815481106128df576128df615011565b5f9182526020909120825460039092020190815560018083015490820155600291820154910155815482908061291757612917615077565b5f8281526020812060035f19909301928302018181556001810182905560020155905561269a565b5050506129528b8b8b8b8b8b8b8b613c84565b9b9a5050505050505050505050565b6001600160a01b038084165f90815260026020908152604080832093881683529290529081208590859080845b8154811015612c3357428282815481106129aa576129aa615011565b905f5260205f2090600302016001015411156129d257806129ca81615039565b91505061298e565b5f81815260048401602052604090205460ff1615612a28578181815481106129fc576129fc615011565b905f5260205f2090600302015f0154836005015f828254612a1d9190615064565b90915550612a619050565b818181548110612a3a57612a3a615011565b905f5260205f2090600302015f0154836007015f828254612a5b9190615051565b90915550505b5f81815260098401602052604090205460ff1615612ab257818181548110612a8b57612a8b615011565b905f5260205f2090600302015f015483600a015f828254612aac9190615051565b90915550505b815460048401905f90612ac790600190615064565b815260208082019290925260409081015f908120548482526004870193849052918120805460ff191660ff9093161515929092179091558354612b0c90600190615064565b815260208101919091526040015f908120805460ff191690558254600985019190612b3990600190615064565b815260208082019290925260409081015f908120548482526009870193849052918120805460ff191660ff9093161515929092179091558354612b7e90600190615064565b815260208101919091526040015f20805460ff1916905581548290612ba590600190615064565b81548110612bb557612bb5615011565b905f5260205f209060030201828281548110612bd357612bd3615011565b5f91825260209091208254600390920201908155600180830154908201556002918201549101558154829080612c0b57612c0b615077565b5f8281526020812060035f19909301928302018181556001810182905560020155905561298e565b5050505f80612c46898989428a5f6132a3565b92509250508180612c545750805b9998505050505050505050565b5f805160206151ad833981519152805460011901612c9257604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b6001600160a01b038082165f9081526002602090815260408083209386168352929052206003810154612cf25760405162461bcd60e51b81526020600482015260026024820152614e4360f01b6044820152606401610b28565b6003810154612d0d906001600160a01b038416908590613c25565b816001600160a01b0316836001600160a01b03167f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd9870688360030154604051612d5691815260200190565b60405180910390a35f6003909101555050565b612d71614ab0565b6001600160a01b038084165f90815260026020908152604080832093881683529290529081209083612db057604080515f815260208101909152612dba565b612dba8686614534565b60408051610100810182526002850154808252600786015460208301819052939450909291830191612deb91615064565b8152600584015460208201526003840154604082015260088401546060820152600a90930154608084015260a090920152949350505050565b5f8211612e435760405162461bcd60e51b8152600401610b28906150be565b612e586001600160a01b03821684308561464c565b6001600160a01b038082165f9081526002602081815260408084209488168452939052918120918201549003612eb1576001600160a01b0382165f908152600460205260408120805491612eab83615039565b91905055505b82816002015f828254612ec49190615051565b9250508190555082816007015f828254612ede9190615051565b90915550506001600160a01b0382165f9081526003602052604081208054859290612f0a908490615051565b92505081905550816001600160a01b0316846001600160a01b03167f99039fcf0a98f484616c5196ee8b2ecfa971babf0b519848289ea4db381f85f785604051612f5691815260200190565b60405180910390a350505050565b610adf8133614685565b5f5f8051602061518d833981519152612f878484611d60565b613006575f848152602082815260408083206001600160a01b03871684529091529020805460ff19166001179055612fbc3390565b6001600160a01b0316836001600160a01b0316857f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4600191505061079b565b5f91505061079b565b5f5f8051602061518d8339815191526130288484611d60565b15613006575f848152602082815260408083206001600160a01b0387168085529252808320805460ff1916905551339287917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4600191505061079b565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061310e57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166131025f8051602061516d833981519152546001600160a01b031690565b6001600160a01b031614155b15610e135760405163703e46dd60e11b815260040160405180910390fd5b610adf613239565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561318e575060408051601f3d908101601f1916820190925261318b918101906150a7565b60015b6131b657604051634c9c8ce360e01b81526001600160a01b0383166004820152602401610b28565b5f8051602061516d83398151915281146131e657604051632a87526960e21b815260048101829052602401610b28565b610d7283836146be565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610e135760405163703e46dd60e11b815260040160405180910390fd5b33613242611d2c565b6001600160a01b031614610e135760405163118cdaa760e01b8152336004820152602401610b28565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b0319168155610cca82614713565b5f805f428610156132c65760405162461bcd60e51b8152600401610b28906150da565b6001600160a01b038089165f908152600260209081526040808320938d1683529290529081209054860361330857600701545f93508392508711159050613512565b805f5b81548110156134d5575f8883838154811061332857613328615011565b905f5260205f2090600302016002015416116134cd575f81815260048401602052604090205487151560ff90911615150361344b578982828154811061337057613370615011565b905f5260205f2090600302015f015403613395579450600193505f9250613512915050565b898282815481106133a8576133a8615011565b905f5260205f2090600302015f0154101561343a575f8282815481106133d0576133d0615011565b905f5260205f2090600302015f01548b6133ea9190615064565b90505f88613401578185600701541015905061341b565b81856005015486600201546134169190615064565b101590505b80613426575f613428565b825b97509550508415935061351292505050565b9450600193505f9250613512915050565b5f81815260048401602052604090205460ff161515871515146134cd578982828154811061347b5761347b615011565b905f5260205f2090600302015f01541480156134b75750888282815481106134a5576134a5615011565b905f5260205f20906003020160010154145b156134cd579450600193505f9250613512915050565b60010161330b565b50856134f05750600701545f93508392508711159050613512565b5f80836005015484600201546135069190615064565b8b111594509450945050505b96509650969350505050565b613526614783565b610adf816147cc565b610e13614783565b5f8051602061518d8339815191525f61354f84610ceb565b5f85815260208490526040808220600101869055519192508491839187917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a450505050565b5f82116135b65760405162461bcd60e51b8152600401610b28906150be565b6001600160a01b038082165f90815260026020908152604080832093871683529290522060078101548311156136145760405162461bcd60e51b815260206004820152600360248201526249413160e81b6044820152606401610b28565b82816005015482600701546136299190615064565b101561365d5760405162461bcd60e51b815260206004820152600360248201526224a09960e91b6044820152606401610b28565b5f6005544261366c9190615051565b905081600a01545f0361376e57604080518082019091528481526020808201838152600685018054600181810183555f928352938220945160029182029095019485559151939092019290925590830180548692906136cc908490615064565b9250508190555083826007015f8282546136e69190615064565b9250508190555083826008015f8282546137009190615051565b90915550506001600160a01b0383165f908152600360205260408120805486929061372c908490615064565b909155505060408051858152602081018390526001600160a01b0380861692908816915f8051602061514d833981519152910160405180910390a35050505050565b81600a015484116138455783826002015f82825461378c9190615064565b9250508190555083826007015f8282546137a69190615064565b9250508190555083826003015f8282546137c09190615051565b925050819055508382600a015f8282546137da9190615064565b90915550506001600160a01b0383165f9081526003602052604081208054869290613806908490615064565b9091555050604080518581524260208201526001600160a01b0380861692908816915f8051602061514d833981519152910160405180910390a36115d4565b5f82600a0154856138569190615064565b9050808360050154846007015461386d9190615064565b10156138a15760405162461bcd60e51b815260206004820152600360248201526249413360e81b6044820152606401610b28565b604080518082019091528181526020808201848152600686018054600181810183555f9283529382209451600290910290940193845590519290910191909155600a840154600385018054919290916138fb908490615051565b9091555050600a830180545f9182905560028501805491928892613920908490615064565b9250508190555085846007015f82825461393a9190615064565b9250508190555081846008015f8282546139549190615051565b90915550506001600160a01b0385165f9081526003602052604081208054889290613980908490615064565b9091555050604080518281524260208201526001600160a01b0380881692908a16915f8051602061514d833981519152910160405180910390a3846001600160a01b0316876001600160a01b03165f8051602061514d83398151915284866040516139f5929190918252602082015260400190565b60405180910390a350505050505050565b5f42851015613a275760405162461bcd60e51b8152600401610b28906150da565b6001600160a01b038088165f908152600260209081526040808320938c16835292905290812090613a57826147fd565b905081600a015481613a699190615064565b881115613ad65780881115613aa55760405162461bcd60e51b8152602060048201526002602482015261495360f01b6044820152606401610b28565b600a820154613ab49082615064565b613abe9089615064565b82600a015f828254613ad09190615064565b90915550505b6040805160608101825289815260208082018a81529282018981528554600181810188555f88815293842094516003909202909401908155935184840155516002909301929092558354879260048601929091613b339190615064565b815260208101919091526040015f908120805460ff191692151592909217909155825485916009850191613b6990600190615064565b815260208101919091526040015f20805460ff191691151591909117905584613ba55787826007015f828254613b9f9190615064565b90915550505b8415613bc45787826005015f828254613bbe9190615051565b90915550505b5f80548717905560408051898152602081018990529081018790526001600160a01b038a811691908c16905f8051602061512d8339815191529060600160405180910390a38154613c1790600190615064565b9a9950505050505050505050565b6040516001600160a01b03838116602483015260448201839052610d7291859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050614830565b5f42861015613ca55760405162461bcd60e51b8152600401610b28906150da565b6001600160a01b038089165f908152600260209081526040808320938d16835292905290812090548503613cea57613ce28a8a8a8a8a8989613a06565b915050611a3b565b805f5b8154811015614524575f87838381548110613d0a57613d0a615011565b905f5260205f20906003020160020154161161451c575f81815260048401602052604090205486151560ff9091161515036143e55789828281548110613d5257613d52615011565b905f5260205f2090600302015f015403613eb75788828281548110613d7957613d79615011565b905f5260205f209060030201600101541015613db65788828281548110613da257613da2615011565b905f5260205f209060030201600101819055505b87828281548110613dc957613dc9615011565b5f918252602080832060039290920290910160020180549390931790925580548a1781558281526009850190915260409020805460ff191686151517905581546001600160a01b038c811691908e16905f8051602061512d83398151915290859085908110613e3a57613e3a615011565b905f5260205f2090600302015f0154858581548110613e5b57613e5b615011565b905f5260205f20906003020160010154868681548110613e7d57613e7d615011565b5f91825260209182902060026003909202010154604080519485529184019290925282015260600160405180910390a39250611a3b915050565b89828281548110613eca57613eca615011565b905f5260205f2090600302015f015410156141be575f828281548110613ef257613ef2615011565b905f5260205f2090600302015f01548b613f0c9190615064565b905086613f6b578084600701541015613f4d5760405162461bcd60e51b815260206004820152600360248201526224a99960e91b6044820152606401610b28565b80846007015f828254613f609190615064565b90915550613fcd9050565b8084600501548560020154613f809190615064565b1015613fb45760405162461bcd60e51b815260206004820152600360248201526249533360e81b6044820152606401610b28565b80846005015f828254613fc79190615051565b90915550505b5f613fd7856147fd565b90505f85600a0154118015613ff95750600a850154613ff69082615064565b82115b1561402f57600a85015461400d9082615064565b6140179083615064565b85600a015f8282546140299190615064565b90915550505b8b84848154811061404257614042615011565b905f5260205f2090600302015f01819055508a84848154811061406757614067615011565b905f5260205f2090600302016001015410156140a4578a84848154811061409057614090615011565b905f5260205f209060030201600101819055505b898484815481106140b7576140b7615011565b905f5260205f2090600302016002015f8282541792505081905550895f80828254179250508190555086856009015f8581526020019081526020015f205f6101000a81548160ff0219169083151502179055508c6001600160a01b03168e6001600160a01b03165f8051602061512d83398151915286868154811061413e5761413e615011565b905f5260205f2090600302015f015487878154811061415f5761415f615011565b905f5260205f2090600302016001015488888154811061418157614181615011565b5f91825260209182902060026003909202010154604080519485529184019290925282015260600160405180910390a38295505050505050611a3b565b888282815481106141d1576141d1615011565b905f5260205f20906003020160010154106141f95787828281548110613dc957613dc9615011565b8982828154811061420c5761420c615011565b905f5260205f2090600302015f015f8282546142289190615064565b925050819055508a6001600160a01b03168c6001600160a01b03165f8051602061512d83398151915284848154811061426357614263615011565b905f5260205f2090600302015f015485858154811061428457614284615011565b905f5260205f209060030201600101548686815481106142a6576142a6615011565b5f91825260209182902060026003909202010154604080519485529184019290925282015260600160405180910390a3604080516060810182528b815260208082018c81529282018b81528654600181810189555f898152938420945160039092029094019081559351848401555160029093019290925584548892600487019290916143339190615064565b815260208101919091526040015f908120805460ff19169215159290921790915583548691600986019161436990600190615064565b815260208082019290925260409081015f20805460ff19169315159390931790925581518c81529081018b90529081018990526001600160a01b038c811691908e16905f8051602061512d8339815191529060600160405180910390a35f80548917905582546143db90600190615064565b9350505050611a3b565b5f81815260048401602052604090205460ff1615158615151461451c578982828154811061441557614415615011565b905f5260205f2090600302015f015414801561445157508882828154811061443f5761443f615011565b905f5260205f20906003020160010154145b1561451c57856144aa575f8181526004840160205260408120805460ff19168815151790556007840180548c929061448a908490615064565b9250508190555089836005015f8282546144a49190615064565b90915550505b5f83600a01541180156144cf575082600a015483600701546144cc9190615064565b8a115b15613db65782600a015483600701546144e89190615064565b6144f2908b615064565b83600a015f8282546145049190615064565b909155505087828281548110613dc957613dc9615011565b600101613ced565b506129528b8b8b8b8b8a8a613a06565b6001600160a01b038082165f90815260026020908152604080832093861683529290529081208154606092829161456c906001615051565b67ffffffffffffffff81111561458457614584614cd7565b6040519080825280602002602001820160405280156145ad578160200160208202803683370190505b5090505f5b8254811015614642575f8382815481106145ce576145ce615011565b5f918252602082206002600390920201908101548154919350915b5f54811015614632576001811b83811615614629578287828151811061461157614611615011565b602002602001018181516146259190615051565b9052505b506001016145e9565b5050600190920191506145b29050565b5095945050505050565b6040516001600160a01b038481166024830152838116604483015260648201839052610d939186918216906323b872dd90608401613c52565b61468f8282611d60565b610cca5760405163e2517d3f60e01b81526001600160a01b038216600482015260248101839052604401610b28565b6146c782614891565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a280511561470b57610d7282826148f4565b610cca614966565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16610e1357604051631afcd79f60e31b815260040160405180910390fd5b6147d4614783565b6001600160a01b03811661114c57604051631e4fbdf760e01b81525f6004820152602401610b28565b5f816007015482600201546148129190615064565b826005015483600201546148269190615064565b61079b9190615064565b5f6148446001600160a01b03841683614985565b905080515f1415801561486857508080602001905181019061486691906150f6565b155b15610d7257604051635274afe760e01b81526001600160a01b0384166004820152602401610b28565b806001600160a01b03163b5f036148c657604051634c9c8ce360e01b81526001600160a01b0382166004820152602401610b28565b5f8051602061516d83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b60605f80846001600160a01b0316846040516149109190615111565b5f60405180830381855af49150503d805f8114614948576040519150601f19603f3d011682016040523d82523d5f602084013e61494d565b606091505b509150915061495d858383614992565b95945050505050565b3415610e135760405163b398979f60e01b815260040160405180910390fd5b6060610ce483835f6149ee565b6060826149a7576149a282614a87565b610ce4565b81511580156149be57506001600160a01b0384163b155b156149e757604051639996b31560e01b81526001600160a01b0385166004820152602401610b28565b5080610ce4565b606081471015614a135760405163cd78605960e01b8152306004820152602401610b28565b5f80856001600160a01b03168486604051614a2e9190615111565b5f6040518083038185875af1925050503d805f8114614a68576040519150601f19603f3d011682016040523d82523d5f602084013e614a6d565b606091505b5091509150614a7d868383614992565b9695505050505050565b805115614a975780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6040518061010001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b5f60208284031215614afe575f80fd5b81356001600160e01b031981168114610ce4575f80fd5b80356001600160a01b0381168114614b2b575f80fd5b919050565b5f8060408385031215614b41575f80fd5b614b4a83614b15565b9150614b5860208401614b15565b90509250929050565b5f60208284031215614b71575f80fd5b610ce482614b15565b8015158114610adf575f80fd5b5f805f60608486031215614b99575f80fd5b614ba284614b15565b9250614bb060208501614b15565b91506040840135614bc081614b7a565b809150509250925092565b5f602080835261012083018451828501528185015160408501526040850151606085015260608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e08501516101008081870152508181518084526101408701915084830193505f92505b80831015614c5b5783518252928401926001929092019190840190614c3b565b509695505050505050565b5f60208284031215614c76575f80fd5b5035919050565b5f805f60608486031215614c8f575f80fd5b614c9884614b15565b925060208401359150614cad60408501614b15565b90509250925092565b5f8060408385031215614cc7575f80fd5b82359150614b5860208401614b15565b634e487b7160e01b5f52604160045260245ffd5b5f8060408385031215614cfc575f80fd5b614d0583614b15565b9150602083013567ffffffffffffffff80821115614d21575f80fd5b818501915085601f830112614d34575f80fd5b813581811115614d4657614d46614cd7565b604051601f8201601f19908116603f01168101908382118183101715614d6e57614d6e614cd7565b81604052828152886020848701011115614d86575f80fd5b826020860160208301375f6020848301015280955050505050509250929050565b5f805f805f8060c08789031215614dbc575f80fd5b614dc587614b15565b9550614dd360208801614b15565b945060408701359350606087013592506080870135915060a0870135614df881614b7a565b809150509295509295509295565b5f805f60608486031215614e18575f80fd5b614e2184614b15565b9250614e2f60208501614b15565b9150604084013590509250925092565b5f805f805f805f60e0888a031215614e55575f80fd5b614e5e88614b15565b9650614e6c60208901614b15565b955060408801359450606088013593506080880135925060a0880135614e9181614b7a565b915060c0880135614ea181614b7a565b8091505092959891949750929550565b5f5b83811015614ecb578181015183820152602001614eb3565b50505f910152565b602081525f8251806020840152614ef1816040850160208701614eb1565b601f01601f19169190910160400192915050565b5f805f805f8060c08789031215614f1a575f80fd5b614f2387614b15565b9550614f3160208801614b15565b95989597505050506040840135936060810135936080820135935060a0909101359150565b5f805f805f805f80610100898b031215614f6e575f80fd5b614f7789614b15565b9750614f8560208a01614b15565b965060408901359550606089013594506080890135935060a0890135925060c0890135614fb181614b7a565b915060e0890135614fc181614b7a565b809150509295985092959890939650565b5f805f8060808587031215614fe5575f80fd5b614fee85614b15565b9350614ffc60208601614b15565b93969395505050506040820135916060013590565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f6001820161504a5761504a615025565b5060010190565b8082018082111561079b5761079b615025565b8181038181111561079b5761079b615025565b634e487b7160e01b5f52603160045260245ffd5b6020808252600290820152614f5760f01b604082015260600190565b5f602082840312156150b7575f80fd5b5051919050565b602080825260029082015261494160f01b604082015260600190565b602080825260029082015261125160f21b604082015260600190565b5f60208284031215615106575f80fd5b8151610ce481614b7a565b5f8251615122818460208701614eb1565b919091019291505056feb2bf263171bf12e27eaf3102830b76e2ed053f6ce1a1c6b49ddc634a608c563b18edd09e80386cd99df397e2e0d87d2bb259423eae08645e776321a36fe680ef360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268009b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f008429d542926e6695b59ac6fbdcd9b37e8b1aeb757afab06ab60b1bb5878c3b49a2646970667358221220acc83442b9fabdec93dda33631f25b78ef340d915bae6ce862ce459a75b08e4564736f6c63430008170033
Deployed ByteCode
0x608060405260043610610228575f3560e01c80637acb775711610129578063ad3cb1cc116100a8578063e4aa64ab1161006d578063e4aa64ab146106da578063eb5d5c43146106ef578063f2fde38b1461070e578063fe400f4b1461072d578063ff979fb11461074c575f80fd5b8063ad3cb1cc1461062c578063c97a184f14610669578063d547741f14610688578063d9caed12146106a7578063e30c3978146106c6575f80fd5b80638da5cb5b116100ee5780638da5cb5b1461059057806391d14854146105bc578063926e31d6146105db578063a19f10d0146105fa578063a217fddf14610619575f80fd5b80637acb7757146104da5780638129fc1c146104f957806381af051d1461050d57806382dda22d1461052c5780638381e18214610571575f80fd5b80632f2ff15d116101b5578063715018a61161017a578063715018a614610437578063762f0b861461044b57806379ba5097146104875780637a3226ec1461049b5780637a3d9499146104bb575f80fd5b80632f2ff15d1461039f57806336568abe146103be5780634f1ef286146103dd57806352d1902d146103f057806354202c4e14610404575f80fd5b80631e83409a116101fb5780631e83409a146102f557806321c0b34214610316578063222bf70614610335578063248a9ca314610361578063294091cd14610380575f80fd5b806301ffc9a71461022c578063118413a814610260578063143bf65c1461028d5780631e7ff8f6146102c1575b5f80fd5b348015610237575f80fd5b5061024b610246366004614aee565b61076b565b60405190151581526020015b60405180910390f35b34801561026b575f80fd5b5061027f61027a366004614b30565b6107a1565b604051908152602001610257565b348015610298575f80fd5b5061027f6102a7366004614b61565b6001600160a01b03165f9081526004602052604090205490565b3480156102cc575f80fd5b5061027f6102db366004614b61565b6001600160a01b03165f9081526003602052604090205490565b348015610300575f80fd5b5061031461030f366004614b61565b610942565b005b348015610321575f80fd5b50610314610330366004614b30565b610ae2565b348015610340575f80fd5b5061035461034f366004614b87565b610cce565b6040516102579190614bcb565b34801561036c575f80fd5b5061027f61037b366004614c66565b610ceb565b34801561038b575f80fd5b5061031461039a366004614c7d565b610d0b565b3480156103aa575f80fd5b506103146103b9366004614cb6565b610d77565b3480156103c9575f80fd5b506103146103d8366004614cb6565b610d99565b6103146103eb366004614ceb565b610dcc565b3480156103fb575f80fd5b5061027f610de7565b34801561040f575f80fd5b5061027f7f28f5a99355973cc89255b8c4ac88405f27c78ded7608b040ee77a8bdf44d15e281565b348015610442575f80fd5b50610314610e02565b348015610456575f80fd5b5061046a610465366004614da7565b610e15565b604080519384529115156020840152151590820152606001610257565b348015610492575f80fd5b50610314611110565b3480156104a6575f80fd5b5061027f5f805160206151cd83398151915281565b3480156104c6575f80fd5b506103146104d5366004614e06565b611155565b3480156104e5575f80fd5b506103146104f4366004614cb6565b61140e565b348015610504575f80fd5b50610314611437565b348015610518575f80fd5b50610354610527366004614b87565b6115db565b348015610537575f80fd5b5061027f610546366004614b30565b6001600160a01b039081165f9081526002602081815260408084209590941683529390935220015490565b34801561057c575f80fd5b5061031461058b366004614cb6565b611a47565b34801561059b575f80fd5b506105a4611d2c565b6040516001600160a01b039091168152602001610257565b3480156105c7575f80fd5b5061024b6105d6366004614cb6565b611d60565b3480156105e6575f80fd5b506103146105f5366004614c7d565b611d96565b348015610605575f80fd5b50610314610614366004614e3f565b6120d5565b348015610624575f80fd5b5061027f5f81565b348015610637575f80fd5b5061065c604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516102579190614ed3565b348015610674575f80fd5b50610314610683366004614c66565b61212c565b348015610693575f80fd5b506103146106a2366004614cb6565b61216f565b3480156106b2575f80fd5b506103146106c1366004614e06565b61218b565b3480156106d1575f80fd5b506105a4612250565b3480156106e5575f80fd5b5061027f60055481565b3480156106fa575f80fd5b50610314610709366004614f05565b612278565b348015610719575f80fd5b50610314610728366004614b61565b6125a7565b348015610738575f80fd5b5061027f610747366004614f56565b61262c565b348015610757575f80fd5b5061024b610766366004614fd2565b612961565b5f6001600160e01b03198216637965db0b60e01b148061079b57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001600160a01b0381165f9081526002602090815260408083203380855292528220839060068101845b815481101561090e57428282815481106107e7576107e7615011565b905f5260205f20906002020160010154111561080f578061080781615039565b9150506107cb565b81818154811061082157610821615011565b905f5260205f2090600202015f0154836003015f8282546108429190615051565b9250508190555081818154811061085b5761085b615011565b905f5260205f2090600202015f0154836008015f82825461087c9190615064565b90915550508154829061089190600190615064565b815481106108a1576108a1615011565b905f5260205f2090600202018282815481106108bf576108bf615011565b5f9182526020909120825460029092020190815560019182015491015581548290806108ed576108ed615077565b5f8281526020812060025f19909301928302018181556001015590556107cb565b505050506001600160a01b039283165f90815260026020908152604080832096909516825294909452505090206003015490565b61094a612c61565b6001600160a01b0381165f9081526002602090815260408083203380855292528220909183919060068201905b8154811015610aba574282828154811061099357610993615011565b905f5260205f2090600202016001015411156109bb57806109b381615039565b915050610977565b8181815481106109cd576109cd615011565b905f5260205f2090600202015f0154836003015f8282546109ee9190615051565b92505081905550818181548110610a0757610a07615011565b905f5260205f2090600202015f0154836008015f828254610a289190615064565b909155505081548290610a3d90600190615064565b81548110610a4d57610a4d615011565b905f5260205f209060020201828281548110610a6b57610a6b615011565b5f918252602090912082546002909202019081556001918201549101558154829080610a9957610a99615077565b5f8281526020812060025f1990930192830201818155600101559055610977565b505050610ac73384612c98565b5050610adf60015f805160206151ad83398151915255565b50565b610aea612c61565b60015460ff1615610b3157610b0c5f805160206151cd83398151915233611d60565b610b315760405162461bcd60e51b8152600401610b289061508b565b60405180910390fd5b6001600160a01b038082165f9081526002602090815260408083209386168352929052908120839183919060068201905b8154811015610ca55742828281548110610b7e57610b7e615011565b905f5260205f209060020201600101541115610ba65780610b9e81615039565b915050610b62565b818181548110610bb857610bb8615011565b905f5260205f2090600202015f0154836003015f828254610bd99190615051565b92505081905550818181548110610bf257610bf2615011565b905f5260205f2090600202015f0154836008015f828254610c139190615064565b909155505081548290610c2890600190615064565b81548110610c3857610c38615011565b905f5260205f209060020201828281548110610c5657610c56615011565b5f918252602090912082546002909202019081556001918201549101558154829080610c8457610c84615077565b5f8281526020812060025f1990930192830201818155600101559055610b62565b505050610cb28484612c98565b5050610cca60015f805160206151ad83398151915255565b5050565b610cd6614ab0565b610ce1848484612d69565b90505b9392505050565b5f9081525f8051602061518d833981519152602052604090206001015490565b610d13612c61565b60015460ff1615610d5157610d355f805160206151cd83398151915233611d60565b610d515760405162461bcd60e51b8152600401610b289061508b565b610d5c838383612e24565b610d7260015f805160206151ad83398151915255565b505050565b610d8082610ceb565b610d8981612f64565b610d938383612f6e565b50505050565b6001600160a01b0381163314610dc25760405163334bd91960e11b815260040160405180910390fd5b610d72828261300f565b610dd4613088565b610ddd8261312c565b610cca8282613134565b5f610df06131f0565b505f8051602061516d83398151915290565b610e0a613239565b610e135f61326b565b565b6001600160a01b038086165f908152600260209081526040808320938a168352929052908120819081908990899080845b81548110156110eb5742828281548110610e6257610e62615011565b905f5260205f209060030201600101541115610e8a5780610e8281615039565b915050610e46565b5f81815260048401602052604090205460ff1615610ee057818181548110610eb457610eb4615011565b905f5260205f2090600302015f0154836005015f828254610ed59190615064565b90915550610f199050565b818181548110610ef257610ef2615011565b905f5260205f2090600302015f0154836007015f828254610f139190615051565b90915550505b5f81815260098401602052604090205460ff1615610f6a57818181548110610f4357610f43615011565b905f5260205f2090600302015f015483600a015f828254610f649190615051565b90915550505b815460048401905f90610f7f90600190615064565b815260208082019290925260409081015f908120548482526004870193849052918120805460ff191660ff9093161515929092179091558354610fc490600190615064565b815260208101919091526040015f908120805460ff191690558254600985019190610ff190600190615064565b815260208082019290925260409081015f908120548482526009870193849052918120805460ff191660ff909316151592909217909155835461103690600190615064565b815260208101919091526040015f20805460ff191690558154829061105d90600190615064565b8154811061106d5761106d615011565b905f5260205f20906003020182828154811061108b5761108b615011565b5f918252602090912082546003909202019081556001808301549082015560029182015491015581548290806110c3576110c3615077565b5f8281526020812060035f199093019283020181815560018101829055600201559055610e46565b5050506110fc8b8b8b8b8b8b6132a3565b945094509450505096509650969350505050565b338061111a612250565b6001600160a01b03161461114c5760405163118cdaa760e01b81526001600160a01b0382166004820152602401610b28565b610adf8161326b565b60015460ff1615611193576111775f805160206151cd83398151915233611d60565b6111935760405162461bcd60e51b8152600401610b289061508b565b6001600160a01b038083165f908152600260209081526040808320938716835292905290812080549091908290849081106111d0576111d0615011565b905f5260205f2090600302015f015411801561120e57505f815f0183815481106111fc576111fc615011565b905f5260205f20906003020160010154115b801561123c57505f815f01838154811061122a5761122a615011565b905f5260205f20906003020160020154115b6112705760405162461bcd60e51b8152602060048201526005602482015264092989288b60db1b6044820152606401610b28565b5f82815260048201602052604090205460ff166112b55760405162461bcd60e51b815260206004820152600360248201526226272360e91b6044820152606401610b28565b826001600160a01b0316846001600160a01b03167f9dba03accf66a1bf272e6301fd9885f6f80ca6856d90366beb73084ff13a0b52835f0185815481106112fe576112fe615011565b905f5260205f2090600302015f0154845f01868154811061132157611321615011565b5f91825260209182902060016003909202010154604080519384529183015233908201526060810186905260800160405180910390a3805f01828154811061136b5761136b615011565b905f5260205f2090600302015f0154816005015f82825461138c9190615064565b909155505080545f908290849081106113a7576113a7615011565b5f918252602082206003909102019190915581548290849081106113cd576113cd615011565b905f5260205f209060030201600101819055505f815f0183815481106113f5576113f5615011565b905f5260205f2090600302016002018190555050505050565b611416612c61565b611421338383612e24565b610cca60015f805160206151ad83398151915255565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff165f8115801561147c5750825b90505f8267ffffffffffffffff1660011480156114985750303b155b9050811580156114a6575080155b156114c45760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156114ee57845460ff60401b1916600160401b1785555b6114f73361351e565b6114ff61352f565b6115095f33612f6e565b506115347f28f5a99355973cc89255b8c4ac88405f27c78ded7608b040ee77a8bdf44d15e233610d77565b61156b5f805160206151cd8339815191527f28f5a99355973cc89255b8c4ac88405f27c78ded7608b040ee77a8bdf44d15e2613537565b6115825f805160206151cd83398151915233610d77565b6001805460ff19168117905583156115d457845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050565b6115e3614ab0565b6001600160a01b038084165f9081526002602090815260408083209388168352929052908120859185919081905b81548110156118b6574282828154811061162d5761162d615011565b905f5260205f209060030201600101541115611655578061164d81615039565b915050611611565b5f81815260048401602052604090205460ff16156116ab5781818154811061167f5761167f615011565b905f5260205f2090600302015f0154836005015f8282546116a09190615064565b909155506116e49050565b8181815481106116bd576116bd615011565b905f5260205f2090600302015f0154836007015f8282546116de9190615051565b90915550505b5f81815260098401602052604090205460ff16156117355781818154811061170e5761170e615011565b905f5260205f2090600302015f015483600a015f82825461172f9190615051565b90915550505b815460048401905f9061174a90600190615064565b815260208082019290925260409081015f908120548482526004870193849052918120805460ff191660ff909316151592909217909155835461178f90600190615064565b815260208101919091526040015f908120805460ff1916905582546009850191906117bc90600190615064565b815260208082019290925260409081015f908120548482526009870193849052918120805460ff191660ff909316151592909217909155835461180190600190615064565b815260208101919091526040015f20805460ff191690558154829061182890600190615064565b8154811061183857611838615011565b905f5260205f20906003020182828154811061185657611856615011565b5f9182526020909120825460039092020190815560018083015490820155600291820154910155815482908061188e5761188e615077565b5f8281526020812060035f199093019283020181815560018101829055600201559055611611565b5050506001600160a01b038086165f908152600260209081526040808320938a168352929052908120879187919060068201905b8154811015611a2d574282828154811061190657611906615011565b905f5260205f20906002020160010154111561192e578061192681615039565b9150506118ea565b81818154811061194057611940615011565b905f5260205f2090600202015f0154836003015f8282546119619190615051565b9250508190555081818154811061197a5761197a615011565b905f5260205f2090600202015f0154836008015f82825461199b9190615064565b9091555050815482906119b090600190615064565b815481106119c0576119c0615011565b905f5260205f2090600202018282815481106119de576119de615011565b5f918252602090912082546002909202019081556001918201549101558154829080611a0c57611a0c615077565b5f8281526020812060025f19909301928302018181556001015590556118ea565b505050611a3b888888612d69565b98975050505050505050565b611a4f612c61565b6001600160a01b0381165f9081526002602090815260408083203380855292528220909183919081905b8154811015611d1e5742828281548110611a9557611a95615011565b905f5260205f209060030201600101541115611abd5780611ab581615039565b915050611a79565b5f81815260048401602052604090205460ff1615611b1357818181548110611ae757611ae7615011565b905f5260205f2090600302015f0154836005015f828254611b089190615064565b90915550611b4c9050565b818181548110611b2557611b25615011565b905f5260205f2090600302015f0154836007015f828254611b469190615051565b90915550505b5f81815260098401602052604090205460ff1615611b9d57818181548110611b7657611b76615011565b905f5260205f2090600302015f015483600a015f828254611b979190615051565b90915550505b815460048401905f90611bb290600190615064565b815260208082019290925260409081015f908120548482526004870193849052918120805460ff191660ff9093161515929092179091558354611bf790600190615064565b815260208101919091526040015f908120805460ff191690558254600985019190611c2490600190615064565b815260208082019290925260409081015f908120548482526009870193849052918120805460ff191660ff9093161515929092179091558354611c6990600190615064565b815260208101919091526040015f20805460ff1916905581548290611c9090600190615064565b81548110611ca057611ca0615011565b905f5260205f209060030201828281548110611cbe57611cbe615011565b5f91825260209091208254600390920201908155600180830154908201556002918201549101558154829080611cf657611cf6615077565b5f8281526020812060035f199093019283020181815560018101829055600201559055611a79565b505050610cb2338585613597565b5f807f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993005b546001600160a01b031692915050565b5f9182525f8051602061518d833981519152602090815260408084206001600160a01b0393909316845291905290205460ff1690565b611d9e612c61565b60015460ff1615611ddc57611dc05f805160206151cd83398151915233611d60565b611ddc5760405162461bcd60e51b8152600401610b289061508b565b6001600160a01b038082165f9081526002602090815260408083209387168352929052908120849183919081905b81548110156120af5742828281548110611e2657611e26615011565b905f5260205f209060030201600101541115611e4e5780611e4681615039565b915050611e0a565b5f81815260048401602052604090205460ff1615611ea457818181548110611e7857611e78615011565b905f5260205f2090600302015f0154836005015f828254611e999190615064565b90915550611edd9050565b818181548110611eb657611eb6615011565b905f5260205f2090600302015f0154836007015f828254611ed79190615051565b90915550505b5f81815260098401602052604090205460ff1615611f2e57818181548110611f0757611f07615011565b905f5260205f2090600302015f015483600a015f828254611f289190615051565b90915550505b815460048401905f90611f4390600190615064565b815260208082019290925260409081015f908120548482526004870193849052918120805460ff191660ff9093161515929092179091558354611f8890600190615064565b815260208101919091526040015f908120805460ff191690558254600985019190611fb590600190615064565b815260208082019290925260409081015f908120548482526009870193849052918120805460ff191660ff9093161515929092179091558354611ffa90600190615064565b815260208101919091526040015f20805460ff191690558154829061202190600190615064565b8154811061203157612031615011565b905f5260205f20906003020182828154811061204f5761204f615011565b5f9182526020909120825460039092020190815560018083015490820155600291820154910155815482908061208757612087615077565b5f8281526020812060035f199093019283020181815560018101829055600201559055611e0a565b5050506120bd858585613597565b5050610d7260015f805160206151ad83398151915255565b60015460ff1615612113576120f75f805160206151cd83398151915233611d60565b6121135760405162461bcd60e51b8152600401610b289061508b565b61212287878787878787613a06565b5050505050505050565b612134613239565b60058190556040518181527fd4af69124fa9990e5d807ba37f0803baf57b8cb6efc81a76f2481dd30da0592e9060200160405180910390a150565b61217882610ceb565b61218181612f64565b610d93838361300f565b612193612c61565b61219b613239565b6001600160a01b0383165f818152600360205260408082205490516370a0823160e01b81523060048201529092906370a0823190602401602060405180830381865afa1580156121ed573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061221191906150a7565b905061221d8282615064565b83111561223c5760405162461bcd60e51b8152600401610b28906150be565b6120bd6001600160a01b0386168585613c25565b5f807f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00611d50565b60015460ff16156122b65761229a5f805160206151cd83398151915233611d60565b6122b65760405162461bcd60e51b8152600401610b289061508b565b6001600160a01b038086165f908152600260209081526040808320938a168352929052908120879187919081905b8154811015612589574282828154811061230057612300615011565b905f5260205f209060030201600101541115612328578061232081615039565b9150506122e4565b5f81815260048401602052604090205460ff161561237e5781818154811061235257612352615011565b905f5260205f2090600302015f0154836005015f8282546123739190615064565b909155506123b79050565b81818154811061239057612390615011565b905f5260205f2090600302015f0154836007015f8282546123b19190615051565b90915550505b5f81815260098401602052604090205460ff1615612408578181815481106123e1576123e1615011565b905f5260205f2090600302015f015483600a015f8282546124029190615051565b90915550505b815460048401905f9061241d90600190615064565b815260208082019290925260409081015f908120548482526004870193849052918120805460ff191660ff909316151592909217909155835461246290600190615064565b815260208101919091526040015f908120805460ff19169055825460098501919061248f90600190615064565b815260208082019290925260409081015f908120548482526009870193849052918120805460ff191660ff90931615159290921790915583546124d490600190615064565b815260208101919091526040015f20805460ff19169055815482906124fb90600190615064565b8154811061250b5761250b615011565b905f5260205f20906003020182828154811061252957612529615011565b5f9182526020909120825460039092020190815560018083015490820155600291820154910155815482908061256157612561615077565b5f8281526020812060035f1990930192830201818155600181018290556002015590556122e4565b50505061259c8888888888885f80613c84565b505050505050505050565b6125af613239565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b0319166001600160a01b03831690811782556125f3611d2c565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a35050565b6001545f9060ff161561266c576126505f805160206151cd83398151915233611d60565b61266c5760405162461bcd60e51b8152600401610b289061508b565b6001600160a01b038089165f908152600260209081526040808320938d1683529290529081208a918a919081905b815481101561293f57428282815481106126b6576126b6615011565b905f5260205f2090600302016001015411156126de57806126d681615039565b91505061269a565b5f81815260048401602052604090205460ff16156127345781818154811061270857612708615011565b905f5260205f2090600302015f0154836005015f8282546127299190615064565b9091555061276d9050565b81818154811061274657612746615011565b905f5260205f2090600302015f0154836007015f8282546127679190615051565b90915550505b5f81815260098401602052604090205460ff16156127be5781818154811061279757612797615011565b905f5260205f2090600302015f015483600a015f8282546127b89190615051565b90915550505b815460048401905f906127d390600190615064565b815260208082019290925260409081015f908120548482526004870193849052918120805460ff191660ff909316151592909217909155835461281890600190615064565b815260208101919091526040015f908120805460ff19169055825460098501919061284590600190615064565b815260208082019290925260409081015f908120548482526009870193849052918120805460ff191660ff909316151592909217909155835461288a90600190615064565b815260208101919091526040015f20805460ff19169055815482906128b190600190615064565b815481106128c1576128c1615011565b905f5260205f2090600302018282815481106128df576128df615011565b5f9182526020909120825460039092020190815560018083015490820155600291820154910155815482908061291757612917615077565b5f8281526020812060035f19909301928302018181556001810182905560020155905561269a565b5050506129528b8b8b8b8b8b8b8b613c84565b9b9a5050505050505050505050565b6001600160a01b038084165f90815260026020908152604080832093881683529290529081208590859080845b8154811015612c3357428282815481106129aa576129aa615011565b905f5260205f2090600302016001015411156129d257806129ca81615039565b91505061298e565b5f81815260048401602052604090205460ff1615612a28578181815481106129fc576129fc615011565b905f5260205f2090600302015f0154836005015f828254612a1d9190615064565b90915550612a619050565b818181548110612a3a57612a3a615011565b905f5260205f2090600302015f0154836007015f828254612a5b9190615051565b90915550505b5f81815260098401602052604090205460ff1615612ab257818181548110612a8b57612a8b615011565b905f5260205f2090600302015f015483600a015f828254612aac9190615051565b90915550505b815460048401905f90612ac790600190615064565b815260208082019290925260409081015f908120548482526004870193849052918120805460ff191660ff9093161515929092179091558354612b0c90600190615064565b815260208101919091526040015f908120805460ff191690558254600985019190612b3990600190615064565b815260208082019290925260409081015f908120548482526009870193849052918120805460ff191660ff9093161515929092179091558354612b7e90600190615064565b815260208101919091526040015f20805460ff1916905581548290612ba590600190615064565b81548110612bb557612bb5615011565b905f5260205f209060030201828281548110612bd357612bd3615011565b5f91825260209091208254600390920201908155600180830154908201556002918201549101558154829080612c0b57612c0b615077565b5f8281526020812060035f19909301928302018181556001810182905560020155905561298e565b5050505f80612c46898989428a5f6132a3565b92509250508180612c545750805b9998505050505050505050565b5f805160206151ad833981519152805460011901612c9257604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b6001600160a01b038082165f9081526002602090815260408083209386168352929052206003810154612cf25760405162461bcd60e51b81526020600482015260026024820152614e4360f01b6044820152606401610b28565b6003810154612d0d906001600160a01b038416908590613c25565b816001600160a01b0316836001600160a01b03167f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd9870688360030154604051612d5691815260200190565b60405180910390a35f6003909101555050565b612d71614ab0565b6001600160a01b038084165f90815260026020908152604080832093881683529290529081209083612db057604080515f815260208101909152612dba565b612dba8686614534565b60408051610100810182526002850154808252600786015460208301819052939450909291830191612deb91615064565b8152600584015460208201526003840154604082015260088401546060820152600a90930154608084015260a090920152949350505050565b5f8211612e435760405162461bcd60e51b8152600401610b28906150be565b612e586001600160a01b03821684308561464c565b6001600160a01b038082165f9081526002602081815260408084209488168452939052918120918201549003612eb1576001600160a01b0382165f908152600460205260408120805491612eab83615039565b91905055505b82816002015f828254612ec49190615051565b9250508190555082816007015f828254612ede9190615051565b90915550506001600160a01b0382165f9081526003602052604081208054859290612f0a908490615051565b92505081905550816001600160a01b0316846001600160a01b03167f99039fcf0a98f484616c5196ee8b2ecfa971babf0b519848289ea4db381f85f785604051612f5691815260200190565b60405180910390a350505050565b610adf8133614685565b5f5f8051602061518d833981519152612f878484611d60565b613006575f848152602082815260408083206001600160a01b03871684529091529020805460ff19166001179055612fbc3390565b6001600160a01b0316836001600160a01b0316857f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4600191505061079b565b5f91505061079b565b5f5f8051602061518d8339815191526130288484611d60565b15613006575f848152602082815260408083206001600160a01b0387168085529252808320805460ff1916905551339287917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4600191505061079b565b306001600160a01b037f000000000000000000000000d1bafa7a246f5685cd22a563fd20fb164faf0a4c16148061310e57507f000000000000000000000000d1bafa7a246f5685cd22a563fd20fb164faf0a4c6001600160a01b03166131025f8051602061516d833981519152546001600160a01b031690565b6001600160a01b031614155b15610e135760405163703e46dd60e11b815260040160405180910390fd5b610adf613239565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561318e575060408051601f3d908101601f1916820190925261318b918101906150a7565b60015b6131b657604051634c9c8ce360e01b81526001600160a01b0383166004820152602401610b28565b5f8051602061516d83398151915281146131e657604051632a87526960e21b815260048101829052602401610b28565b610d7283836146be565b306001600160a01b037f000000000000000000000000d1bafa7a246f5685cd22a563fd20fb164faf0a4c1614610e135760405163703e46dd60e11b815260040160405180910390fd5b33613242611d2c565b6001600160a01b031614610e135760405163118cdaa760e01b8152336004820152602401610b28565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b0319168155610cca82614713565b5f805f428610156132c65760405162461bcd60e51b8152600401610b28906150da565b6001600160a01b038089165f908152600260209081526040808320938d1683529290529081209054860361330857600701545f93508392508711159050613512565b805f5b81548110156134d5575f8883838154811061332857613328615011565b905f5260205f2090600302016002015416116134cd575f81815260048401602052604090205487151560ff90911615150361344b578982828154811061337057613370615011565b905f5260205f2090600302015f015403613395579450600193505f9250613512915050565b898282815481106133a8576133a8615011565b905f5260205f2090600302015f0154101561343a575f8282815481106133d0576133d0615011565b905f5260205f2090600302015f01548b6133ea9190615064565b90505f88613401578185600701541015905061341b565b81856005015486600201546134169190615064565b101590505b80613426575f613428565b825b97509550508415935061351292505050565b9450600193505f9250613512915050565b5f81815260048401602052604090205460ff161515871515146134cd578982828154811061347b5761347b615011565b905f5260205f2090600302015f01541480156134b75750888282815481106134a5576134a5615011565b905f5260205f20906003020160010154145b156134cd579450600193505f9250613512915050565b60010161330b565b50856134f05750600701545f93508392508711159050613512565b5f80836005015484600201546135069190615064565b8b111594509450945050505b96509650969350505050565b613526614783565b610adf816147cc565b610e13614783565b5f8051602061518d8339815191525f61354f84610ceb565b5f85815260208490526040808220600101869055519192508491839187917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a450505050565b5f82116135b65760405162461bcd60e51b8152600401610b28906150be565b6001600160a01b038082165f90815260026020908152604080832093871683529290522060078101548311156136145760405162461bcd60e51b815260206004820152600360248201526249413160e81b6044820152606401610b28565b82816005015482600701546136299190615064565b101561365d5760405162461bcd60e51b815260206004820152600360248201526224a09960e91b6044820152606401610b28565b5f6005544261366c9190615051565b905081600a01545f0361376e57604080518082019091528481526020808201838152600685018054600181810183555f928352938220945160029182029095019485559151939092019290925590830180548692906136cc908490615064565b9250508190555083826007015f8282546136e69190615064565b9250508190555083826008015f8282546137009190615051565b90915550506001600160a01b0383165f908152600360205260408120805486929061372c908490615064565b909155505060408051858152602081018390526001600160a01b0380861692908816915f8051602061514d833981519152910160405180910390a35050505050565b81600a015484116138455783826002015f82825461378c9190615064565b9250508190555083826007015f8282546137a69190615064565b9250508190555083826003015f8282546137c09190615051565b925050819055508382600a015f8282546137da9190615064565b90915550506001600160a01b0383165f9081526003602052604081208054869290613806908490615064565b9091555050604080518581524260208201526001600160a01b0380861692908816915f8051602061514d833981519152910160405180910390a36115d4565b5f82600a0154856138569190615064565b9050808360050154846007015461386d9190615064565b10156138a15760405162461bcd60e51b815260206004820152600360248201526249413360e81b6044820152606401610b28565b604080518082019091528181526020808201848152600686018054600181810183555f9283529382209451600290910290940193845590519290910191909155600a840154600385018054919290916138fb908490615051565b9091555050600a830180545f9182905560028501805491928892613920908490615064565b9250508190555085846007015f82825461393a9190615064565b9250508190555081846008015f8282546139549190615051565b90915550506001600160a01b0385165f9081526003602052604081208054889290613980908490615064565b9091555050604080518281524260208201526001600160a01b0380881692908a16915f8051602061514d833981519152910160405180910390a3846001600160a01b0316876001600160a01b03165f8051602061514d83398151915284866040516139f5929190918252602082015260400190565b60405180910390a350505050505050565b5f42851015613a275760405162461bcd60e51b8152600401610b28906150da565b6001600160a01b038088165f908152600260209081526040808320938c16835292905290812090613a57826147fd565b905081600a015481613a699190615064565b881115613ad65780881115613aa55760405162461bcd60e51b8152602060048201526002602482015261495360f01b6044820152606401610b28565b600a820154613ab49082615064565b613abe9089615064565b82600a015f828254613ad09190615064565b90915550505b6040805160608101825289815260208082018a81529282018981528554600181810188555f88815293842094516003909202909401908155935184840155516002909301929092558354879260048601929091613b339190615064565b815260208101919091526040015f908120805460ff191692151592909217909155825485916009850191613b6990600190615064565b815260208101919091526040015f20805460ff191691151591909117905584613ba55787826007015f828254613b9f9190615064565b90915550505b8415613bc45787826005015f828254613bbe9190615051565b90915550505b5f80548717905560408051898152602081018990529081018790526001600160a01b038a811691908c16905f8051602061512d8339815191529060600160405180910390a38154613c1790600190615064565b9a9950505050505050505050565b6040516001600160a01b03838116602483015260448201839052610d7291859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050614830565b5f42861015613ca55760405162461bcd60e51b8152600401610b28906150da565b6001600160a01b038089165f908152600260209081526040808320938d16835292905290812090548503613cea57613ce28a8a8a8a8a8989613a06565b915050611a3b565b805f5b8154811015614524575f87838381548110613d0a57613d0a615011565b905f5260205f20906003020160020154161161451c575f81815260048401602052604090205486151560ff9091161515036143e55789828281548110613d5257613d52615011565b905f5260205f2090600302015f015403613eb75788828281548110613d7957613d79615011565b905f5260205f209060030201600101541015613db65788828281548110613da257613da2615011565b905f5260205f209060030201600101819055505b87828281548110613dc957613dc9615011565b5f918252602080832060039290920290910160020180549390931790925580548a1781558281526009850190915260409020805460ff191686151517905581546001600160a01b038c811691908e16905f8051602061512d83398151915290859085908110613e3a57613e3a615011565b905f5260205f2090600302015f0154858581548110613e5b57613e5b615011565b905f5260205f20906003020160010154868681548110613e7d57613e7d615011565b5f91825260209182902060026003909202010154604080519485529184019290925282015260600160405180910390a39250611a3b915050565b89828281548110613eca57613eca615011565b905f5260205f2090600302015f015410156141be575f828281548110613ef257613ef2615011565b905f5260205f2090600302015f01548b613f0c9190615064565b905086613f6b578084600701541015613f4d5760405162461bcd60e51b815260206004820152600360248201526224a99960e91b6044820152606401610b28565b80846007015f828254613f609190615064565b90915550613fcd9050565b8084600501548560020154613f809190615064565b1015613fb45760405162461bcd60e51b815260206004820152600360248201526249533360e81b6044820152606401610b28565b80846005015f828254613fc79190615051565b90915550505b5f613fd7856147fd565b90505f85600a0154118015613ff95750600a850154613ff69082615064565b82115b1561402f57600a85015461400d9082615064565b6140179083615064565b85600a015f8282546140299190615064565b90915550505b8b84848154811061404257614042615011565b905f5260205f2090600302015f01819055508a84848154811061406757614067615011565b905f5260205f2090600302016001015410156140a4578a84848154811061409057614090615011565b905f5260205f209060030201600101819055505b898484815481106140b7576140b7615011565b905f5260205f2090600302016002015f8282541792505081905550895f80828254179250508190555086856009015f8581526020019081526020015f205f6101000a81548160ff0219169083151502179055508c6001600160a01b03168e6001600160a01b03165f8051602061512d83398151915286868154811061413e5761413e615011565b905f5260205f2090600302015f015487878154811061415f5761415f615011565b905f5260205f2090600302016001015488888154811061418157614181615011565b5f91825260209182902060026003909202010154604080519485529184019290925282015260600160405180910390a38295505050505050611a3b565b888282815481106141d1576141d1615011565b905f5260205f20906003020160010154106141f95787828281548110613dc957613dc9615011565b8982828154811061420c5761420c615011565b905f5260205f2090600302015f015f8282546142289190615064565b925050819055508a6001600160a01b03168c6001600160a01b03165f8051602061512d83398151915284848154811061426357614263615011565b905f5260205f2090600302015f015485858154811061428457614284615011565b905f5260205f209060030201600101548686815481106142a6576142a6615011565b5f91825260209182902060026003909202010154604080519485529184019290925282015260600160405180910390a3604080516060810182528b815260208082018c81529282018b81528654600181810189555f898152938420945160039092029094019081559351848401555160029093019290925584548892600487019290916143339190615064565b815260208101919091526040015f908120805460ff19169215159290921790915583548691600986019161436990600190615064565b815260208082019290925260409081015f20805460ff19169315159390931790925581518c81529081018b90529081018990526001600160a01b038c811691908e16905f8051602061512d8339815191529060600160405180910390a35f80548917905582546143db90600190615064565b9350505050611a3b565b5f81815260048401602052604090205460ff1615158615151461451c578982828154811061441557614415615011565b905f5260205f2090600302015f015414801561445157508882828154811061443f5761443f615011565b905f5260205f20906003020160010154145b1561451c57856144aa575f8181526004840160205260408120805460ff19168815151790556007840180548c929061448a908490615064565b9250508190555089836005015f8282546144a49190615064565b90915550505b5f83600a01541180156144cf575082600a015483600701546144cc9190615064565b8a115b15613db65782600a015483600701546144e89190615064565b6144f2908b615064565b83600a015f8282546145049190615064565b909155505087828281548110613dc957613dc9615011565b600101613ced565b506129528b8b8b8b8b8a8a613a06565b6001600160a01b038082165f90815260026020908152604080832093861683529290529081208154606092829161456c906001615051565b67ffffffffffffffff81111561458457614584614cd7565b6040519080825280602002602001820160405280156145ad578160200160208202803683370190505b5090505f5b8254811015614642575f8382815481106145ce576145ce615011565b5f918252602082206002600390920201908101548154919350915b5f54811015614632576001811b83811615614629578287828151811061461157614611615011565b602002602001018181516146259190615051565b9052505b506001016145e9565b5050600190920191506145b29050565b5095945050505050565b6040516001600160a01b038481166024830152838116604483015260648201839052610d939186918216906323b872dd90608401613c52565b61468f8282611d60565b610cca5760405163e2517d3f60e01b81526001600160a01b038216600482015260248101839052604401610b28565b6146c782614891565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a280511561470b57610d7282826148f4565b610cca614966565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16610e1357604051631afcd79f60e31b815260040160405180910390fd5b6147d4614783565b6001600160a01b03811661114c57604051631e4fbdf760e01b81525f6004820152602401610b28565b5f816007015482600201546148129190615064565b826005015483600201546148269190615064565b61079b9190615064565b5f6148446001600160a01b03841683614985565b905080515f1415801561486857508080602001905181019061486691906150f6565b155b15610d7257604051635274afe760e01b81526001600160a01b0384166004820152602401610b28565b806001600160a01b03163b5f036148c657604051634c9c8ce360e01b81526001600160a01b0382166004820152602401610b28565b5f8051602061516d83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b60605f80846001600160a01b0316846040516149109190615111565b5f60405180830381855af49150503d805f8114614948576040519150601f19603f3d011682016040523d82523d5f602084013e61494d565b606091505b509150915061495d858383614992565b95945050505050565b3415610e135760405163b398979f60e01b815260040160405180910390fd5b6060610ce483835f6149ee565b6060826149a7576149a282614a87565b610ce4565b81511580156149be57506001600160a01b0384163b155b156149e757604051639996b31560e01b81526001600160a01b0385166004820152602401610b28565b5080610ce4565b606081471015614a135760405163cd78605960e01b8152306004820152602401610b28565b5f80856001600160a01b03168486604051614a2e9190615111565b5f6040518083038185875af1925050503d805f8114614a68576040519150601f19603f3d011682016040523d82523d5f602084013e614a6d565b606091505b5091509150614a7d868383614992565b9695505050505050565b805115614a975780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6040518061010001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b5f60208284031215614afe575f80fd5b81356001600160e01b031981168114610ce4575f80fd5b80356001600160a01b0381168114614b2b575f80fd5b919050565b5f8060408385031215614b41575f80fd5b614b4a83614b15565b9150614b5860208401614b15565b90509250929050565b5f60208284031215614b71575f80fd5b610ce482614b15565b8015158114610adf575f80fd5b5f805f60608486031215614b99575f80fd5b614ba284614b15565b9250614bb060208501614b15565b91506040840135614bc081614b7a565b809150509250925092565b5f602080835261012083018451828501528185015160408501526040850151606085015260608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e08501516101008081870152508181518084526101408701915084830193505f92505b80831015614c5b5783518252928401926001929092019190840190614c3b565b509695505050505050565b5f60208284031215614c76575f80fd5b5035919050565b5f805f60608486031215614c8f575f80fd5b614c9884614b15565b925060208401359150614cad60408501614b15565b90509250925092565b5f8060408385031215614cc7575f80fd5b82359150614b5860208401614b15565b634e487b7160e01b5f52604160045260245ffd5b5f8060408385031215614cfc575f80fd5b614d0583614b15565b9150602083013567ffffffffffffffff80821115614d21575f80fd5b818501915085601f830112614d34575f80fd5b813581811115614d4657614d46614cd7565b604051601f8201601f19908116603f01168101908382118183101715614d6e57614d6e614cd7565b81604052828152886020848701011115614d86575f80fd5b826020860160208301375f6020848301015280955050505050509250929050565b5f805f805f8060c08789031215614dbc575f80fd5b614dc587614b15565b9550614dd360208801614b15565b945060408701359350606087013592506080870135915060a0870135614df881614b7a565b809150509295509295509295565b5f805f60608486031215614e18575f80fd5b614e2184614b15565b9250614e2f60208501614b15565b9150604084013590509250925092565b5f805f805f805f60e0888a031215614e55575f80fd5b614e5e88614b15565b9650614e6c60208901614b15565b955060408801359450606088013593506080880135925060a0880135614e9181614b7a565b915060c0880135614ea181614b7a565b8091505092959891949750929550565b5f5b83811015614ecb578181015183820152602001614eb3565b50505f910152565b602081525f8251806020840152614ef1816040850160208701614eb1565b601f01601f19169190910160400192915050565b5f805f805f8060c08789031215614f1a575f80fd5b614f2387614b15565b9550614f3160208801614b15565b95989597505050506040840135936060810135936080820135935060a0909101359150565b5f805f805f805f80610100898b031215614f6e575f80fd5b614f7789614b15565b9750614f8560208a01614b15565b965060408901359550606089013594506080890135935060a0890135925060c0890135614fb181614b7a565b915060e0890135614fc181614b7a565b809150509295985092959890939650565b5f805f8060808587031215614fe5575f80fd5b614fee85614b15565b9350614ffc60208601614b15565b93969395505050506040820135916060013590565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f6001820161504a5761504a615025565b5060010190565b8082018082111561079b5761079b615025565b8181038181111561079b5761079b615025565b634e487b7160e01b5f52603160045260245ffd5b6020808252600290820152614f5760f01b604082015260600190565b5f602082840312156150b7575f80fd5b5051919050565b602080825260029082015261494160f01b604082015260600190565b602080825260029082015261125160f21b604082015260600190565b5f60208284031215615106575f80fd5b8151610ce481614b7a565b5f8251615122818460208701614eb1565b919091019291505056feb2bf263171bf12e27eaf3102830b76e2ed053f6ce1a1c6b49ddc634a608c563b18edd09e80386cd99df397e2e0d87d2bb259423eae08645e776321a36fe680ef360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268009b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f008429d542926e6695b59ac6fbdcd9b37e8b1aeb757afab06ab60b1bb5878c3b49a2646970667358221220acc83442b9fabdec93dda33631f25b78ef340d915bae6ce862ce459a75b08e4564736f6c63430008170033