Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- GamiFi
- Optimization enabled
- false
- Compiler version
- v0.8.28+commit.7893614a
- EVM Version
- paris
- Verified at
- 2026-01-16T14:48:35.778340Z
contracts/GamiFi.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/Ownable.sol";
import "./PoolManager.sol";
import "./MatchManager.sol";
import "./PrizeManager.sol";
contract GamiFi is Ownable, PoolManager, MatchManager, PrizeManager {
constructor() Ownable(msg.sender) {}
function createPool(
bytes32 poolId,
address tokenAddress
) public onlyOwner returns (address) {
return _createPool(poolId, tokenAddress);
}
function setPoolState(
bytes32 poolId,
PoolState newState
) public override onlyOwner {
super.setPoolState(poolId, newState);
}
function createMatch(
bytes32 poolA,
bytes32 poolB
) public onlyOwner returns (bytes32) {
Pool storage _poolA = pools[poolA];
Pool storage _poolB = pools[poolB];
require(_poolA.isActive, "Token pool A does not exist");
require(_poolB.isActive, "Token pool B does not exist");
require(_poolA.matchId == bytes32(0), "Pool A already in a match");
require(_poolB.matchId == bytes32(0), "Pool B already in a match");
require(poolA != poolB, "Pools must be different");
// Set pool state to match in progress
bytes32 matchId = _createMatch(poolA, poolB);
_matchPools(poolA, poolB, matchId);
_startMatch(poolA, poolB);
return matchId;
}
function endMatch(
bytes32 poolA,
bytes32 poolB,
bytes32 winner,
address[] memory players,
uint256[] memory shares
) public override onlyOwner {
// Set pool state to match ended
setPoolState(poolA, PoolState.MATCH_ENDED);
setPoolState(poolB, PoolState.MATCH_ENDED);
bytes32 matchId = getMatchId(poolA, poolB);
super.endMatch(poolA, poolB, winner, players, shares);
bytes32 _losingToken = getLoser(poolA, poolB);
uint256 _losingTokenBalance = pools[_losingToken].totalFunds;
uint256 _serviceFee = _claimServiceFee(
matchId,
pools[_losingToken].tokenAddress,
_losingTokenBalance
);
_claimFunds(_losingToken, _serviceFee);
}
function claimPrize(bytes32 poolA, bytes32 poolB) public nonReentrant {
bytes32 matchId = getMatchId(poolA, poolB);
Match storage _match = matches[matchId];
require(_match.state == MatchState.MATCH_ENDED, "Match is not over");
bytes32 _winningToken = _match.winner;
bytes32 _losingToken = getLoser(poolA, poolB);
uint256 _losingTokenInitialBalance = pools[_losingToken].totalFunds;
uint256 _playerSharePercentage = getPlayerShare(
poolA,
poolB,
msg.sender
);
uint256 _stakerSharePercentage = getStakerShare(
_winningToken,
msg.sender
);
uint256 _stakerContribution = getContribution(
_winningToken,
msg.sender
);
(
uint256 _claimedWinningToken,
uint256 _claimedLosingToken
) = _claimPrize(
matchId,
pools[_winningToken].tokenAddress,
pools[_losingToken].tokenAddress,
_losingTokenInitialBalance,
_playerSharePercentage,
_stakerSharePercentage,
_stakerContribution
);
_claimFunds(_winningToken, _claimedWinningToken);
_claimFunds(_losingToken, _claimedLosingToken);
}
function deleteMatch(
bytes32 poolA,
bytes32 poolB,
address foundsReceiver
) public onlyOwner {
bytes32 matchId = getMatchId(poolA, poolB);
require(!matches[matchId].isActive, "Match is active");
_deletePool(poolA, foundsReceiver);
_deletePool(poolB, foundsReceiver);
_deleteMatch(matchId);
_deleteMatchClaimRecord(matchId);
}
function setPoolDepositAllowed(
bytes32 poolId,
bool isDepositAllowed
) public onlyOwner {
_setPoolDepositAllowed(poolId, isDepositAllowed);
}
function setPoolWithdrawalAllowed(
bytes32 poolId,
bool isWithdrawalAllowed
) public onlyOwner {
_setPoolWithdrawalAllowed(poolId, isWithdrawalAllowed);
}
}
@openzeppelin/contracts/access/Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* 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 Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
@openzeppelin/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
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);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
@openzeppelin/contracts/utils/Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
@openzeppelin/contracts/utils/ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @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 EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* 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 ReentrancyGuard {
// 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;
uint256 private _status;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_status = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}
contracts/MatchManager.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
// This contract has the responsibility of managing the state of a match
// A match is between two pools
abstract contract MatchManager {
enum MatchState {
PRE_MATCH,
MATCH_IN_PROGRESS,
MATCH_ENDED
}
struct Match {
bytes32 poolA;
bytes32 poolB;
bytes32 winner;
uint256 totalFundsA;
uint256 totalFundsB;
bool isActive;
MatchState state;
mapping(address => uint256) playerShares;
}
mapping(bytes32 => Match) public matches;
event MatchCreated(
bytes32 indexed poolA,
bytes32 indexed poolB,
bytes32 indexed matchId
);
event MatchStarted(
bytes32 indexed poolA,
bytes32 indexed poolB,
bytes32 indexed matchId
);
event MatchEnded(
bytes32 indexed poolA,
bytes32 indexed poolB,
bytes32 indexed matchId
);
function _createMatch(
bytes32 poolA,
bytes32 poolB
) internal returns (bytes32) {
require(poolA != poolB, "Pools must be different");
require(poolA != bytes32(0), "Invalid pool A ID");
require(poolB != bytes32(0), "Invalid pool B ID");
bytes32 matchId = getMatchId(poolA, poolB);
require(!matches[matchId].isActive, "Match already exists");
Match storage newMatch = matches[matchId];
newMatch.poolA = poolA;
newMatch.poolB = poolB;
newMatch.isActive = true;
newMatch.state = MatchState.PRE_MATCH;
emit MatchCreated(poolA, poolB, matchId);
return matchId;
}
function _startMatch(bytes32 poolA, bytes32 poolB) internal {
bytes32 matchId = getMatchId(poolA, poolB);
require(matches[matchId].isActive, "Match does not exist");
require(
matches[matchId].state == MatchState.PRE_MATCH,
"Match already started"
);
matches[matchId].state = MatchState.MATCH_IN_PROGRESS;
emit MatchStarted(poolA, poolB, matchId);
}
function endMatch(
bytes32 poolA,
bytes32 poolB,
bytes32 winner,
address[] memory players,
uint256[] memory shares
) public virtual {
bytes32 matchId = getMatchId(poolA, poolB);
require(matches[matchId].isActive, "Match does not exist");
require(
matches[matchId].state == MatchState.MATCH_IN_PROGRESS,
"Match not in progress"
);
require(winner == poolA || winner == poolB, "Invalid winner address");
require(players.length == shares.length, "Arrays length mismatch");
require(players.length > 0, "No players provided");
Match storage _match = matches[matchId];
_match.winner = winner;
_match.state = MatchState.MATCH_ENDED;
_match.isActive = false;
_setShares(matchId, players, shares);
emit MatchEnded(poolA, poolB, matchId);
}
function _setShares(
bytes32 _matchId,
address[] memory _players,
uint256[] memory _shares
) internal {
require(_players.length == _shares.length, "Arrays length mismatch");
require(_players.length > 0, "Empty arrays");
Match storage _match = matches[_matchId];
uint256 totalSharePercentage;
for (uint256 i = 0; i < _players.length; i++) {
require(_players[i] != address(0), "Invalid player address");
require(_shares[i] > 0, "Invalid share percentage");
totalSharePercentage += _shares[i];
_match.playerShares[_players[i]] = _shares[i];
}
require(totalSharePercentage == 10000, "Total shares must be 100%");
}
function _deleteMatch(bytes32 matchId) internal {
require(matchId != bytes32(0), "Invalid match ID");
delete matches[matchId];
}
function getMatchId(
bytes32 poolA,
bytes32 poolB
) public pure returns (bytes32) {
require(poolA != bytes32(0), "Invalid pool A ID");
require(poolB != bytes32(0), "Invalid pool B ID");
bytes32 pool1 = poolA < poolB ? poolA : poolB;
bytes32 pool2 = poolA < poolB ? poolB : poolA;
return keccak256(abi.encodePacked(pool1, pool2));
}
function getLoser(
bytes32 poolA,
bytes32 poolB
) public view returns (bytes32) {
bytes32 matchId = getMatchId(poolA, poolB);
Match storage _match = matches[matchId];
return _match.winner == poolA ? poolB : poolA;
}
function getPlayerShare(
bytes32 poolA,
bytes32 poolB,
address player
) public view returns (uint256) {
bytes32 matchId = getMatchId(poolA, poolB);
Match storage _match = matches[matchId];
return _match.playerShares[player];
}
}
contracts/PoolManager.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
abstract contract PoolManager is Ownable, ReentrancyGuard {
enum PoolState {
PRE_MATCH,
MATCH_IN_PROGRESS,
MATCH_ENDED
}
struct Pool {
address creator;
address tokenAddress;
uint256 totalFunds;
uint256 remainingFunds;
bool isActive;
PoolState state;
mapping(address => uint256) contributions;
address[] contributors;
bytes32 matchId;
bool isDepositAllowed;
bool isWithdrawalAllowed;
}
mapping(bytes32 => Pool) public pools;
event PoolCreated(
bytes32 indexed poolId,
address indexed tokenAddress,
address indexed creator
);
event FundsDeposited(
bytes32 indexed poolId,
address indexed tokenAddress,
address indexed depositor,
uint256 amount
);
event FundsWithdrawn(
bytes32 indexed poolId,
address indexed tokenAddress,
address indexed withdrawer,
uint256 amount
);
function _createPool(
bytes32 poolId,
address tokenAddress
) internal returns (address) {
require(!pools[poolId].isActive, "Pool already exists");
// Check if it's a ERC20 token
if (tokenAddress != address(0)) {
IERC20 token = IERC20(tokenAddress);
require(token.totalSupply() > 0, "Invalid token address");
}
Pool storage newPool = pools[poolId];
newPool.creator = msg.sender;
newPool.tokenAddress = tokenAddress;
newPool.isActive = true;
newPool.state = PoolState.PRE_MATCH;
emit PoolCreated(poolId, tokenAddress, msg.sender);
return tokenAddress;
}
function _matchPools(
bytes32 _poolA,
bytes32 _poolB,
bytes32 _matchId
) internal {
Pool storage poolA = pools[_poolA];
Pool storage poolB = pools[_poolB];
poolA.matchId = _matchId;
poolB.matchId = _matchId;
poolA.state = PoolState.MATCH_IN_PROGRESS;
poolB.state = PoolState.MATCH_IN_PROGRESS;
}
function setPoolState(bytes32 poolId, PoolState newState) public virtual {
require(pools[poolId].isActive, "Pool does not exist");
pools[poolId].state = newState;
if (newState == PoolState.MATCH_ENDED) {
pools[poolId].remainingFunds = pools[poolId].totalFunds;
}
}
function _claimFunds(bytes32 poolId, uint256 amount) internal {
pools[poolId].remainingFunds -= amount;
}
function depositToPool(
bytes32 poolId,
uint256 amount
) public payable nonReentrant {
Pool storage pool = pools[poolId];
require(pool.isActive, "Pool does not exist");
require(pool.isDepositAllowed, "Deposits are not allowed");
if (pool.tokenAddress == address(0)) {
require(msg.value == amount, "Must send some tokens");
} else {
require(amount > 0, "Must send some tokens");
IERC20 token = IERC20(pool.tokenAddress);
require(
token.transferFrom(msg.sender, address(this), amount),
"Transfer failed"
);
}
pool.totalFunds += amount;
pool.contributions[msg.sender] += amount;
pool.contributors.push(msg.sender);
emit FundsDeposited(poolId, pool.tokenAddress, msg.sender, amount);
}
function withdrawFromPool(
bytes32 poolId,
uint256 amount
) public nonReentrant {
Pool storage pool = pools[poolId];
require(pool.isActive, "Pool is not active");
require(pool.isWithdrawalAllowed, "Withdrawals are not allowed");
require(amount > 0, "Must withdraw some tokens");
require(pool.contributions[msg.sender] >= amount, "Insufficient funds");
pool.totalFunds -= amount;
pool.contributions[msg.sender] -= amount;
if (pool.tokenAddress == address(0)) {
(bool success, ) = payable(msg.sender).call{value: amount}("");
require(success, "Transfer failed");
} else {
IERC20 token = IERC20(pool.tokenAddress);
require(token.transfer(msg.sender, amount), "Transfer failed");
}
emit FundsWithdrawn(poolId, pool.tokenAddress, msg.sender, amount);
}
function getPoolBalance(bytes32 poolId) public view returns (uint256) {
return pools[poolId].totalFunds;
}
function getPoolRemainingFunds(
bytes32 poolId
) public view returns (uint256) {
return pools[poolId].remainingFunds;
}
function getContribution(
bytes32 poolId,
address contributor
) public view returns (uint256) {
return pools[poolId].contributions[contributor];
}
function getStakerShare(
bytes32 poolId,
address contributor
) public view returns (uint256) {
if (pools[poolId].totalFunds == 0) {
return 0;
}
return
(pools[poolId].contributions[contributor] * 10000) /
pools[poolId].totalFunds;
}
function getPoolMatchId(bytes32 poolId) public view returns (bytes32) {
return pools[poolId].matchId;
}
function getPoolContributors(
bytes32 poolId,
uint256 _page,
uint256 _pageSize
) public view returns (address[] memory) {
Pool storage pool = pools[poolId];
uint256 start = _page * _pageSize;
uint256 end = start + _pageSize;
if (end > pool.contributors.length) {
end = pool.contributors.length;
}
address[] memory contributors = new address[](end - start);
for (uint256 i = start; i < end; i++) {
contributors[i - start] = pool.contributors[i];
}
return contributors;
}
function _deletePool(bytes32 poolId, address foundsReceiver) internal {
uint256 remainingFunds = pools[poolId].remainingFunds;
if (pools[poolId].tokenAddress == address(0)) {
(bool success, ) = payable(foundsReceiver).call{
value: remainingFunds
}("");
require(success, "Transfer failed");
} else {
// Withdraw the remaining funds
IERC20 token = IERC20(pools[poolId].tokenAddress);
require(
token.transfer(payable(foundsReceiver), remainingFunds),
"Transfer failed"
);
}
delete pools[poolId];
}
function _setPoolDepositAllowed(
bytes32 poolId,
bool isDepositAllowed
) public {
require(pools[poolId].isActive, "Pool does not exist");
pools[poolId].isDepositAllowed = isDepositAllowed;
}
function _setPoolWithdrawalAllowed(
bytes32 poolId,
bool isWithdrawalAllowed
) public {
require(pools[poolId].isActive, "Pool does not exist");
pools[poolId].isWithdrawalAllowed = isWithdrawalAllowed;
}
function isPoolDepositAllowed(bytes32 poolId) public view returns (bool) {
return pools[poolId].isDepositAllowed;
}
function isPoolWithdrawalAllowed(
bytes32 poolId
) public view returns (bool) {
return pools[poolId].isWithdrawalAllowed;
}
}
contracts/PrizeManager.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
abstract contract PrizeManager is ReentrancyGuard {
struct ClaimRecord {
bool isServiceFeeClaimed;
mapping(address => bool) hasClaimedStakerRefund;
mapping(address => bool) hasClaimedStakerPrize;
mapping(address => bool) hasClaimedPlayerPrize;
}
uint256 public serviceFeePercentage = 1000; //10%
uint256 public stakersPrizePercentage = 8100; //81%
uint256 public playersPrizePercentage = 900; //9%
uint256 private TOT = 10000; //100%
mapping(bytes32 => ClaimRecord) public matchClaimRecords;
event ClaimedServiceFee(
address indexed receiver,
address indexed token,
uint256 amount
);
event ClaimedStakePrice(
address indexed player,
address indexed token,
uint256 amount
);
event ClaimedPlayerPrice(
address indexed player,
address indexed token,
uint256 amount
);
function _claimServiceFee(
bytes32 _matchId,
address _losingToken,
uint256 _losingTokenBalance
) internal nonReentrant returns (uint256) {
require(
matchClaimRecords[_matchId].isServiceFeeClaimed == false,
"Already claimed"
);
matchClaimRecords[_matchId].isServiceFeeClaimed = true;
uint256 totalBalance = _losingTokenBalance;
uint256 feeAmount = (totalBalance * serviceFeePercentage) / TOT;
if (_losingToken == address(0)) {
(bool success, ) = msg.sender.call{value: feeAmount}("");
require(success, "Transfer failed");
} else {
IERC20 token = IERC20(_losingToken);
token.transfer(msg.sender, feeAmount);
}
emit ClaimedServiceFee(msg.sender, _losingToken, feeAmount);
return feeAmount;
}
function _claimPrize(
bytes32 _matchId,
address _winningToken,
address _losingToken,
uint256 _losingTokenInitialBalance,
uint256 _playerSharePercentage,
uint256 _stakerSharePercentage,
uint256 _stakerContribution
)
internal
returns (uint256 _claimableWinningToken, uint256 _claimableLosingToken)
{
require(
matchClaimRecords[_matchId].hasClaimedStakerRefund[msg.sender] ==
false,
"Already claimed"
);
require(
matchClaimRecords[_matchId].hasClaimedStakerPrize[msg.sender] ==
false,
"Already claimed"
);
require(
matchClaimRecords[_matchId].hasClaimedPlayerPrize[msg.sender] ==
false,
"Already claimed"
);
matchClaimRecords[_matchId].hasClaimedStakerRefund[msg.sender] = true;
matchClaimRecords[_matchId].hasClaimedStakerPrize[msg.sender] = true;
matchClaimRecords[_matchId].hasClaimedPlayerPrize[msg.sender] = true;
uint256 claimableStakerPrize = _getClaimableStakerPrize(
_losingTokenInitialBalance,
_stakerSharePercentage
);
uint256 claimablePlayerPrize = _getClaimablePlayerPrize(
_losingTokenInitialBalance,
_playerSharePercentage
);
if (_winningToken == address(0)) {
(bool success, ) = msg.sender.call{value: _stakerContribution}("");
require(success, "Transfer failed");
} else {
IERC20 winningToken = IERC20(_winningToken);
winningToken.transfer(msg.sender, _stakerContribution);
}
if (_losingToken == address(0)) {
(bool success, ) = msg.sender.call{
value: claimableStakerPrize + claimablePlayerPrize
}("");
require(success, "Transfer failed");
} else {
IERC20 losingToken = IERC20(_losingToken);
losingToken.transfer(
msg.sender,
claimableStakerPrize + claimablePlayerPrize
);
}
emit ClaimedStakePrice(msg.sender, _winningToken, _stakerContribution);
emit ClaimedStakePrice(msg.sender, _losingToken, claimableStakerPrize);
emit ClaimedPlayerPrice(msg.sender, _losingToken, claimablePlayerPrize);
return (
_stakerContribution,
claimableStakerPrize + claimablePlayerPrize
);
}
function _getClaimableStakerRefund(
uint256 winningTokenInitialBalance,
uint256 sharePercentage
) internal view returns (uint256) {
uint256 stakerRefund = (winningTokenInitialBalance * sharePercentage) /
TOT;
return stakerRefund;
}
function _getClaimableStakerPrize(
uint256 losingTokenInitialBalance,
uint256 sharePercentage
) internal view returns (uint256) {
// Calculate stakers price (81%)
uint256 totalStakersPrize = (losingTokenInitialBalance *
stakersPrizePercentage);
// Calculate player share of stakers price
uint256 playerPrize = (totalStakersPrize * sharePercentage) /
(TOT * TOT);
return playerPrize;
}
function _getClaimablePlayerPrize(
uint256 losingTokenInitialBalance,
uint256 sharePercentage
) internal view returns (uint256) {
// Calculate player amount (9%)
uint256 totalPlayersPrize = (losingTokenInitialBalance *
playersPrizePercentage);
// Calculate player share of players prize
uint256 playerPrize = (totalPlayersPrize * sharePercentage) /
(TOT * TOT);
return playerPrize;
}
function _deleteMatchClaimRecord(bytes32 _matchId) internal {
delete matchClaimRecords[_matchId];
}
}
Compiler Settings
{"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":false},"libraries":{},"evmVersion":"paris"}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","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":"event","name":"ClaimedPlayerPrice","inputs":[{"type":"address","name":"player","internalType":"address","indexed":true},{"type":"address","name":"token","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ClaimedServiceFee","inputs":[{"type":"address","name":"receiver","internalType":"address","indexed":true},{"type":"address","name":"token","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ClaimedStakePrice","inputs":[{"type":"address","name":"player","internalType":"address","indexed":true},{"type":"address","name":"token","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"FundsDeposited","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32","indexed":true},{"type":"address","name":"tokenAddress","internalType":"address","indexed":true},{"type":"address","name":"depositor","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"FundsWithdrawn","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32","indexed":true},{"type":"address","name":"tokenAddress","internalType":"address","indexed":true},{"type":"address","name":"withdrawer","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"MatchCreated","inputs":[{"type":"bytes32","name":"poolA","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"poolB","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"matchId","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"event","name":"MatchEnded","inputs":[{"type":"bytes32","name":"poolA","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"poolB","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"matchId","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"event","name":"MatchStarted","inputs":[{"type":"bytes32","name":"poolA","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"poolB","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"matchId","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"PoolCreated","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32","indexed":true},{"type":"address","name":"tokenAddress","internalType":"address","indexed":true},{"type":"address","name":"creator","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"_setPoolDepositAllowed","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32"},{"type":"bool","name":"isDepositAllowed","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"_setPoolWithdrawalAllowed","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32"},{"type":"bool","name":"isWithdrawalAllowed","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimPrize","inputs":[{"type":"bytes32","name":"poolA","internalType":"bytes32"},{"type":"bytes32","name":"poolB","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"createMatch","inputs":[{"type":"bytes32","name":"poolA","internalType":"bytes32"},{"type":"bytes32","name":"poolB","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"createPool","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32"},{"type":"address","name":"tokenAddress","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"deleteMatch","inputs":[{"type":"bytes32","name":"poolA","internalType":"bytes32"},{"type":"bytes32","name":"poolB","internalType":"bytes32"},{"type":"address","name":"foundsReceiver","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"depositToPool","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"endMatch","inputs":[{"type":"bytes32","name":"poolA","internalType":"bytes32"},{"type":"bytes32","name":"poolB","internalType":"bytes32"},{"type":"bytes32","name":"winner","internalType":"bytes32"},{"type":"address[]","name":"players","internalType":"address[]"},{"type":"uint256[]","name":"shares","internalType":"uint256[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getContribution","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32"},{"type":"address","name":"contributor","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getLoser","inputs":[{"type":"bytes32","name":"poolA","internalType":"bytes32"},{"type":"bytes32","name":"poolB","internalType":"bytes32"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getMatchId","inputs":[{"type":"bytes32","name":"poolA","internalType":"bytes32"},{"type":"bytes32","name":"poolB","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPlayerShare","inputs":[{"type":"bytes32","name":"poolA","internalType":"bytes32"},{"type":"bytes32","name":"poolB","internalType":"bytes32"},{"type":"address","name":"player","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPoolBalance","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"getPoolContributors","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32"},{"type":"uint256","name":"_page","internalType":"uint256"},{"type":"uint256","name":"_pageSize","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getPoolMatchId","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPoolRemainingFunds","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getStakerShare","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32"},{"type":"address","name":"contributor","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isPoolDepositAllowed","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isPoolWithdrawalAllowed","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"isServiceFeeClaimed","internalType":"bool"}],"name":"matchClaimRecords","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"poolA","internalType":"bytes32"},{"type":"bytes32","name":"poolB","internalType":"bytes32"},{"type":"bytes32","name":"winner","internalType":"bytes32"},{"type":"uint256","name":"totalFundsA","internalType":"uint256"},{"type":"uint256","name":"totalFundsB","internalType":"uint256"},{"type":"bool","name":"isActive","internalType":"bool"},{"type":"uint8","name":"state","internalType":"enum MatchManager.MatchState"}],"name":"matches","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"playersPrizePercentage","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"creator","internalType":"address"},{"type":"address","name":"tokenAddress","internalType":"address"},{"type":"uint256","name":"totalFunds","internalType":"uint256"},{"type":"uint256","name":"remainingFunds","internalType":"uint256"},{"type":"bool","name":"isActive","internalType":"bool"},{"type":"uint8","name":"state","internalType":"enum PoolManager.PoolState"},{"type":"bytes32","name":"matchId","internalType":"bytes32"},{"type":"bool","name":"isDepositAllowed","internalType":"bool"},{"type":"bool","name":"isWithdrawalAllowed","internalType":"bool"}],"name":"pools","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"serviceFeePercentage","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPoolDepositAllowed","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32"},{"type":"bool","name":"isDepositAllowed","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPoolState","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32"},{"type":"uint8","name":"newState","internalType":"enum PoolManager.PoolState"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPoolWithdrawalAllowed","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32"},{"type":"bool","name":"isWithdrawalAllowed","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"stakersPrizePercentage","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawFromPool","inputs":[{"type":"bytes32","name":"poolId","internalType":"bytes32"},{"type":"uint256","name":"amount","internalType":"uint256"}]}]
Contract Creation Code
0x60806040526103e8600455611fa460055561038460065561271060075534801561002857600080fd5b5033600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361009c5760006040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161009391906101bd565b60405180910390fd5b6100ab816100b860201b60201c565b50600180819055506101d8565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101a78261017c565b9050919050565b6101b78161019c565b82525050565b60006020820190506101d260008301846101ae565b92915050565b615657806101e76000396000f3fe6080604052600436106101e35760003560e01c80639dc8cf7311610102578063c7d138cb11610095578063eb239c9111610064578063eb239c9114610787578063ef5672b6146107b0578063f2fde38b146107d9578063f6d735b214610802576101e3565b8063c7d138cb146106a7578063c9b62674146106e4578063dc81f1c81461070d578063ea7cfd8a1461074a576101e3565b8063aacc4010116100d1578063aacc4010146105f0578063b5217bb41461061b578063c0e046bc14610660578063c3a8574c1461068b576101e3565b80639dc8cf731461050a5780639fe9ada314610547578063a1071aed1461058a578063a344d843146105b3576101e3565b80636693643f1161017a57806371f58f151161014957806371f58f15146104645780638da5cb5b1461048d578063931d15a4146104b857806393bf45c6146104e1576101e3565b80636693643f146103aa5780636695c5b8146103e75780636704298414610410578063715018a61461044d576101e3565b80635aa28f6c116101b65780635aa28f6c146102dc5780635abf8f8514610305578063603ef6491461034257806366735fd81461036d576101e3565b806306a03645146101e85780634355b8d2146102255780634953c1c814610262578063550e6ed11461029f575b600080fd5b3480156101f457600080fd5b5061020f600480360381019061020a9190613c44565b61083f565b60405161021c9190613cb0565b60405180910390f35b34801561023157600080fd5b5061024c60048036038101906102479190613ccb565b6108b2565b6040516102599190613d1a565b60405180910390f35b34801561026e57600080fd5b5061028960048036038101906102849190613ccb565b6108f5565b6040516102969190613d1a565b60405180910390f35b3480156102ab57600080fd5b506102c660048036038101906102c19190613d35565b610ad2565b6040516102d39190613cb0565b60405180910390f35b3480156102e857600080fd5b5061030360048036038101906102fe9190613faa565b610af2565b005b34801561031157600080fd5b5061032c60048036038101906103279190613ccb565b610bae565b6040516103399190613d1a565b60405180910390f35b34801561034e57600080fd5b50610357610c93565b6040516103649190613cb0565b60405180910390f35b34801561037957600080fd5b50610394600480360381019061038f919061405d565b610c99565b6040516103a1919061416e565b60405180910390f35b3480156103b657600080fd5b506103d160048036038101906103cc9190614190565b610e07565b6040516103de9190613cb0565b60405180910390f35b3480156103f357600080fd5b5061040e60048036038101906104099190613ccb565b610e65565b005b34801561041c57600080fd5b5061043760048036038101906104329190614190565b611012565b60405161044491906141df565b60405180910390f35b34801561045957600080fd5b5061046261102e565b005b34801561047057600080fd5b5061048b60048036038101906104869190614232565b611042565b005b34801561049957600080fd5b506104a2611058565b6040516104af91906141df565b60405180910390f35b3480156104c457600080fd5b506104df60048036038101906104da9190614232565b611081565b005b3480156104ed57600080fd5b5061050860048036038101906105039190614272565b611116565b005b34801561051657600080fd5b50610531600480360381019061052c9190613d35565b61159a565b60405161053e91906142c1565b60405180910390f35b34801561055357600080fd5b5061056e60048036038101906105699190613d35565b6115c7565b6040516105819796959493929190614353565b60405180910390f35b34801561059657600080fd5b506105b160048036038101906105ac91906143e7565b611623565b005b3480156105bf57600080fd5b506105da60048036038101906105d59190613d35565b611639565b6040516105e79190613d1a565b60405180910390f35b3480156105fc57600080fd5b50610605611659565b6040516106129190613cb0565b60405180910390f35b34801561062757600080fd5b50610642600480360381019061063d9190613d35565b61165f565b6040516106579998979695949392919061446f565b60405180910390f35b34801561066c57600080fd5b50610675611721565b6040516106829190613cb0565b60405180910390f35b6106a560048036038101906106a09190614272565b611727565b005b3480156106b357600080fd5b506106ce60048036038101906106c99190614190565b611b23565b6040516106db9190613cb0565b60405180910390f35b3480156106f057600080fd5b5061070b60048036038101906107069190614232565b611bd6565b005b34801561071957600080fd5b50610734600480360381019061072f9190613d35565b611c6b565b60405161074191906142c1565b60405180910390f35b34801561075657600080fd5b50610771600480360381019061076c9190613d35565b611c98565b60405161077e91906142c1565b60405180910390f35b34801561079357600080fd5b506107ae60048036038101906107a99190613c44565b611cc3565b005b3480156107bc57600080fd5b506107d760048036038101906107d29190614232565b611d69565b005b3480156107e557600080fd5b5061080060048036038101906107fb91906144fc565b611d7f565b005b34801561080e57600080fd5b5061082960048036038101906108249190613d35565b611e05565b6040516108369190613cb0565b60405180910390f35b60008061084c8585610bae565b905060006003600083815260200190815260200160002090508060060160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054925050509392505050565b6000806108bf8484610bae565b90506000600360008381526020019081526020016000209050848160020154146108e957846108eb565b835b9250505092915050565b60006108ff611e25565b600060026000858152602001908152602001600020905060006002600085815260200190815260200160002090508160040160009054906101000a900460ff1661097e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097590614586565b60405180910390fd5b8060040160009054906101000a900460ff166109cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109c6906145f2565b60405180910390fd5b6000801b826007015414610a18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0f9061465e565b60405180910390fd5b6000801b816007015414610a61576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a58906146ca565b60405180910390fd5b838503610aa3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9a90614736565b60405180910390fd5b6000610aaf8686611eac565b9050610abc868683612099565b610ac6868661213a565b80935050505092915050565b600060026000838152602001908152602001600020600201549050919050565b610afa611e25565b610b05856002611623565b610b10846002611623565b6000610b1c8686610bae565b9050610b2b86868686866122a8565b6000610b3787876108b2565b90506000600260008381526020019081526020016000206002015490506000610b97846002600086815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684612524565b9050610ba383826127d0565b505050505050505050565b60008060001b8303610bf5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bec906147a2565b60405180910390fd5b6000801b8203610c3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c319061480e565b60405180910390fd5b6000828410610c495782610c4b565b835b90506000838510610c5c5784610c5e565b835b90508181604051602001610c7392919061484f565b604051602081830303815290604052805190602001209250505092915050565b60045481565b6060600060026000868152602001908152602001600020905060008385610cc091906148aa565b905060008482610cd091906148ec565b90508260060180549050811115610cec57826006018054905090505b60008282610cfa9190614920565b67ffffffffffffffff811115610d1357610d12613d78565b5b604051908082528060200260200182016040528015610d415781602001602082028036833780820191505090505b50905060008390505b82811015610df857846006018181548110610d6857610d67614954565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16828583610da09190614920565b81518110610db157610db0614954565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508080600101915050610d4a565b50809450505050509392505050565b60006002600084815260200190815260200160002060050160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b610e6d612801565b6000610e798383610bae565b90506000600360008381526020019081526020016000209050600280811115610ea557610ea46142dc565b5b8160050160019054906101000a900460ff166002811115610ec957610ec86142dc565b5b14610f09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f00906149cf565b60405180910390fd5b6000816002015490506000610f1e86866108b2565b90506000600260008381526020019081526020016000206002015490506000610f4888883361083f565b90506000610f568533611b23565b90506000610f648633610e07565b9050600080610fe48a600260008b815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008b815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1689898989612847565b91509150610ff288836127d0565b610ffc87826127d0565b5050505050505050505061100e612fdb565b5050565b600061101c611e25565b6110268383612fe4565b905092915050565b611036611e25565b6110406000613282565b565b61104a611e25565b6110548282611081565b5050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6002600083815260200190815260200160002060040160009054906101000a900460ff166110e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110db90614a3b565b60405180910390fd5b806002600084815260200190815260200160002060080160016101000a81548160ff0219169083151502179055505050565b61111e612801565b60006002600084815260200190815260200160002090508060040160009054906101000a900460ff16611186576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117d90614aa7565b60405180910390fd5b8060080160019054906101000a900460ff166111d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ce90614b13565b60405180910390fd5b6000821161121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190614b7f565b60405180910390fd5b818160050160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561129e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129590614beb565b60405180910390fd5b818160020160008282546112b29190614920565b92505081905550818160050160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461130a9190614920565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361141b5760003373ffffffffffffffffffffffffffffffffffffffff168360405161138f90614c3c565b60006040518083038185875af1925050503d80600081146113cc576040519150601f19603f3d011682016040523d82523d6000602084013e6113d1565b606091505b5050905080611415576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140c90614c9d565b60405180910390fd5b50611503565b60008160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33856040518363ffffffff1660e01b815260040161147f929190614cbd565b6020604051808303816000875af115801561149e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c29190614cfb565b611501576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f890614c9d565b60405180910390fd5b505b3373ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16847f4cd16167afcd2e45cd70a8b10d891f374e85f259ef7afd1867fc9be7fcb11331856040516115859190613cb0565b60405180910390a450611596612fdb565b5050565b60006002600083815260200190815260200160002060080160019054906101000a900460ff169050919050565b60036020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050160009054906101000a900460ff16908060050160019054906101000a900460ff16905087565b61162b611e25565b6116358282613346565b5050565b600060026000838152602001908152602001600020600701549050919050565b60055481565b60026020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030154908060040160009054906101000a900460ff16908060040160019054906101000a900460ff16908060070154908060080160009054906101000a900460ff16908060080160019054906101000a900460ff16905089565b60065481565b61172f612801565b60006002600084815260200190815260200160002090508060040160009054906101000a900460ff16611797576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178e90614a3b565b60405180910390fd5b8060080160009054906101000a900460ff166117e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117df90614d74565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361188757813414611882576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187990614de0565b60405180910390fd5b6119b4565b600082116118ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118c190614de0565b60405180910390fd5b60008160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff166323b872dd3330866040518463ffffffff1660e01b815260040161193093929190614e00565b6020604051808303816000875af115801561194f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119739190614cfb565b6119b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a990614c9d565b60405180910390fd5b505b818160020160008282546119c891906148ec565b92505081905550818160050160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a2091906148ec565b9250508190555080600601339080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16847fe40671b740fa5f78e7e7407dc9a0e028808df762f7f97020416b2ac647af2e3f85604051611b0e9190613cb0565b60405180910390a450611b1f612fdb565b5050565b600080600260008581526020019081526020016000206002015403611b4b5760009050611bd0565b60026000848152602001908152602001600020600201546127106002600086815260200190815260200160002060050160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611bc391906148aa565b611bcd9190614e66565b90505b92915050565b6002600083815260200190815260200160002060040160009054906101000a900460ff16611c39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3090614a3b565b60405180910390fd5b806002600084815260200190815260200160002060080160006101000a81548160ff0219169083151502179055505050565b60006002600083815260200190815260200160002060080160009054906101000a900460ff169050919050565b60086020528060005260406000206000915090508060000160009054906101000a900460ff16905081565b611ccb611e25565b6000611cd78484610bae565b90506003600082815260200190815260200160002060050160009054906101000a900460ff1615611d3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3490614ee3565b60405180910390fd5b611d478483613448565b611d518383613448565b611d5a8161375a565b611d6381613808565b50505050565b611d71611e25565b611d7b8282611bd6565b5050565b611d87611e25565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611df95760006040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401611df091906141df565b60405180910390fd5b611e0281613282565b50565b600060026000838152602001908152602001600020600301549050919050565b611e2d613835565b73ffffffffffffffffffffffffffffffffffffffff16611e4b611058565b73ffffffffffffffffffffffffffffffffffffffff1614611eaa57611e6e613835565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401611ea191906141df565b60405180910390fd5b565b6000818303611ef0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ee790614736565b60405180910390fd5b6000801b8303611f35576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f2c906147a2565b60405180910390fd5b6000801b8203611f7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f719061480e565b60405180910390fd5b6000611f868484610bae565b90506003600082815260200190815260200160002060050160009054906101000a900460ff1615611fec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fe390614f4f565b60405180910390fd5b600060036000838152602001908152602001600020905084816000018190555083816001018190555060018160050160006101000a81548160ff02191690831515021790555060008160050160016101000a81548160ff0219169083600281111561205a576120596142dc565b5b02179055508184867ff94047cb2b767481be8aad8cae3c3ce5f432cfe8dd7b23f50e3d18648b4a7b9560405160405180910390a4819250505092915050565b6000600260008581526020019081526020016000209050600060026000858152602001908152602001600020905082826007018190555082816007018190555060018260040160016101000a81548160ff02191690836002811115612101576121006142dc565b5b021790555060018160040160016101000a81548160ff0219169083600281111561212e5761212d6142dc565b5b02179055505050505050565b60006121468383610bae565b90506003600082815260200190815260200160002060050160009054906101000a900460ff166121ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121a290614fbb565b60405180910390fd5b600060028111156121bf576121be6142dc565b5b6003600083815260200190815260200160002060050160019054906101000a900460ff1660028111156121f5576121f46142dc565b5b14612235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161222c90615027565b60405180910390fd5b60016003600083815260200190815260200160002060050160016101000a81548160ff0219169083600281111561226f5761226e6142dc565b5b02179055508082847f29d26f27771059d3fdf99a7ea828394ca3980824b18f47ba9959beb3e9f3d87360405160405180910390a4505050565b60006122b48686610bae565b90506003600082815260200190815260200160002060050160009054906101000a900460ff16612319576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231090614fbb565b60405180910390fd5b6001600281111561232d5761232c6142dc565b5b6003600083815260200190815260200160002060050160019054906101000a900460ff166002811115612363576123626142dc565b5b146123a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161239a90615093565b60405180910390fd5b858414806123b057508484145b6123ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123e6906150ff565b60405180910390fd5b8151835114612433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161242a9061516b565b60405180910390fd5b6000835111612477576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161246e906151d7565b60405180910390fd5b600060036000838152602001908152602001600020905084816002018190555060028160050160016101000a81548160ff021916908360028111156124bf576124be6142dc565b5b021790555060008160050160006101000a81548160ff0219169083151502179055506124ec82858561383d565b8186887fee20e6cf265453dc32c716ce04a1c54c44b9616a1e738f217f515736509aa9dc60405160405180910390a450505050505050565b600061252e612801565b600015156008600086815260200190815260200160002060000160009054906101000a900460ff16151514612598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161258f90615243565b60405180910390fd5b60016008600086815260200190815260200160002060000160006101000a81548160ff02191690831515021790555060008290506000600754600454836125df91906148aa565b6125e99190614e66565b9050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036126d15760003373ffffffffffffffffffffffffffffffffffffffff168260405161264590614c3c565b60006040518083038185875af1925050503d8060008114612682576040519150601f19603f3d011682016040523d82523d6000602084013e612687565b606091505b50509050806126cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c290614c9d565b60405180910390fd5b50612757565b60008590508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401612711929190614cbd565b6020604051808303816000875af1158015612730573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127549190614cfb565b50505b8473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ff0af9bc2c3a4716fef6ce079f5de916f018e0201e2f7052dfeae945801475b2f836040516127b49190613cb0565b60405180910390a380925050506127c9612fdb565b9392505050565b806002600084815260200190815260200160002060030160008282546127f69190614920565b925050819055505050565b60026001540361283d576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600181905550565b60008060001515600860008b815260200190815260200160002060010160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515146128f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128e890615243565b60405180910390fd5b60001515600860008b815260200190815260200160002060020160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514612998576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161298f90615243565b60405180910390fd5b60001515600860008b815260200190815260200160002060030160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514612a3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a3690615243565b60405180910390fd5b6001600860008b815260200190815260200160002060010160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600860008b815260200190815260200160002060020160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600860008b815260200190815260200160002060030160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506000612b8f8786613ace565b90506000612b9d8888613b16565b9050600073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff1603612c855760003373ffffffffffffffffffffffffffffffffffffffff1686604051612bf990614c3c565b60006040518083038185875af1925050503d8060008114612c36576040519150601f19603f3d011682016040523d82523d6000602084013e612c3b565b606091505b5050905080612c7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c7690614c9d565b60405180910390fd5b50612d0b565b60008a90508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33886040518363ffffffff1660e01b8152600401612cc5929190614cbd565b6020604051808303816000875af1158015612ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d089190614cfb565b50505b600073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1603612dfc5760003373ffffffffffffffffffffffffffffffffffffffff168284612d6491906148ec565b604051612d7090614c3c565b60006040518083038185875af1925050503d8060008114612dad576040519150601f19603f3d011682016040523d82523d6000602084013e612db2565b606091505b5050905080612df6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ded90614c9d565b60405180910390fd5b50612e8d565b60008990508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb338486612e2a91906148ec565b6040518363ffffffff1660e01b8152600401612e47929190614cbd565b6020604051808303816000875af1158015612e66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e8a9190614cfb565b50505b8973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f691d3da84f60a8e9f7618970b6df07a3a18b47254d483e44e071f50e8c3cbbfa87604051612eea9190613cb0565b60405180910390a38873ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f691d3da84f60a8e9f7618970b6df07a3a18b47254d483e44e071f50e8c3cbbfa84604051612f4f9190613cb0565b60405180910390a38873ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fde02534236523c2e02492e6cfc4cd7cc6003b1891460f414626d77e7c867551f83604051612fb49190613cb0565b60405180910390a3848183612fc991906148ec565b93509350505097509795505050505050565b60018081905550565b60006002600084815260200190815260200160002060040160009054906101000a900460ff161561304a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613041906152af565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461313657600082905060008173ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130f491906152e4565b11613134576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161312b9061535d565b60405180910390fd5b505b6000600260008581526020019081526020016000209050338160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060018160040160006101000a81548160ff02191690831515021790555060008160040160016101000a81548160ff02191690836002811115613218576132176142dc565b5b02179055503373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16857fc0c143d18100b0ec0b6c08cc52247dd860ffd3fc2af30733326e5f980c19635a60405160405180910390a48291505092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6002600083815260200190815260200160002060040160009054906101000a900460ff166133a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133a090614a3b565b60405180910390fd5b806002600084815260200190815260200160002060040160016101000a81548160ff021916908360028111156133e2576133e16142dc565b5b02179055506002808111156133fa576133f96142dc565b5b81600281111561340d5761340c6142dc565b5b0361344457600260008381526020019081526020016000206002015460026000848152602001908152602001600020600301819055505b5050565b600060026000848152602001908152602001600020600301549050600073ffffffffffffffffffffffffffffffffffffffff166002600085815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361357f5760008273ffffffffffffffffffffffffffffffffffffffff16826040516134f390614c3c565b60006040518083038185875af1925050503d8060008114613530576040519150601f19603f3d011682016040523d82523d6000602084013e613535565b606091505b5050905080613579576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161357090614c9d565b60405180910390fd5b50613679565b60006002600085815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b81526004016135f59291906153dc565b6020604051808303816000875af1158015613614573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136389190614cfb565b613677576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161366e90614c9d565b60405180910390fd5b505b60026000848152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600282016000905560038201600090556004820160006101000a81549060ff02191690556004820160016101000a81549060ff02191690556006820160006137239190613b5e565b60078201600090556008820160006101000a81549060ff02191690556008820160016101000a81549060ff02191690555050505050565b6000801b810361379f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161379690615451565b60405180910390fd5b6003600082815260200190815260200160002060008082016000905560018201600090556002820160009055600382016000905560048201600090556005820160006101000a81549060ff02191690556005820160016101000a81549060ff0219169055505050565b60086000828152602001908152602001600020600080820160006101000a81549060ff0219169055505050565b600033905090565b8051825114613881576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138789061516b565b60405180910390fd5b60008251116138c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138bc906154bd565b60405180910390fd5b6000600360008581526020019081526020016000209050600080600090505b8451811015613a8257600073ffffffffffffffffffffffffffffffffffffffff1685828151811061391857613917614954565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603613976576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161396d90615529565b60405180910390fd5b600084828151811061398b5761398a614954565b5b6020026020010151116139d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139ca90615595565b60405180910390fd5b8381815181106139e6576139e5614954565b5b6020026020010151826139f991906148ec565b9150838181518110613a0e57613a0d614954565b5b6020026020010151836006016000878481518110613a2f57613a2e614954565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080806001019150506138e4565b506127108114613ac7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613abe90615601565b60405180910390fd5b5050505050565b60008060055484613adf91906148aa565b90506000600754600754613af391906148aa565b8483613aff91906148aa565b613b099190614e66565b9050809250505092915050565b60008060065484613b2791906148aa565b90506000600754600754613b3b91906148aa565b8483613b4791906148aa565b613b519190614e66565b9050809250505092915050565b5080546000825590600052602060002090810190613b7c9190613b7f565b50565b5b80821115613b98576000816000905550600101613b80565b5090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b613bc381613bb0565b8114613bce57600080fd5b50565b600081359050613be081613bba565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c1182613be6565b9050919050565b613c2181613c06565b8114613c2c57600080fd5b50565b600081359050613c3e81613c18565b92915050565b600080600060608486031215613c5d57613c5c613ba6565b5b6000613c6b86828701613bd1565b9350506020613c7c86828701613bd1565b9250506040613c8d86828701613c2f565b9150509250925092565b6000819050919050565b613caa81613c97565b82525050565b6000602082019050613cc56000830184613ca1565b92915050565b60008060408385031215613ce257613ce1613ba6565b5b6000613cf085828601613bd1565b9250506020613d0185828601613bd1565b9150509250929050565b613d1481613bb0565b82525050565b6000602082019050613d2f6000830184613d0b565b92915050565b600060208284031215613d4b57613d4a613ba6565b5b6000613d5984828501613bd1565b91505092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613db082613d67565b810181811067ffffffffffffffff82111715613dcf57613dce613d78565b5b80604052505050565b6000613de2613b9c565b9050613dee8282613da7565b919050565b600067ffffffffffffffff821115613e0e57613e0d613d78565b5b602082029050602081019050919050565b600080fd5b6000613e37613e3284613df3565b613dd8565b90508083825260208201905060208402830185811115613e5a57613e59613e1f565b5b835b81811015613e835780613e6f8882613c2f565b845260208401935050602081019050613e5c565b5050509392505050565b600082601f830112613ea257613ea1613d62565b5b8135613eb2848260208601613e24565b91505092915050565b600067ffffffffffffffff821115613ed657613ed5613d78565b5b602082029050602081019050919050565b613ef081613c97565b8114613efb57600080fd5b50565b600081359050613f0d81613ee7565b92915050565b6000613f26613f2184613ebb565b613dd8565b90508083825260208201905060208402830185811115613f4957613f48613e1f565b5b835b81811015613f725780613f5e8882613efe565b845260208401935050602081019050613f4b565b5050509392505050565b600082601f830112613f9157613f90613d62565b5b8135613fa1848260208601613f13565b91505092915050565b600080600080600060a08688031215613fc657613fc5613ba6565b5b6000613fd488828901613bd1565b9550506020613fe588828901613bd1565b9450506040613ff688828901613bd1565b935050606086013567ffffffffffffffff81111561401757614016613bab565b5b61402388828901613e8d565b925050608086013567ffffffffffffffff81111561404457614043613bab565b5b61405088828901613f7c565b9150509295509295909350565b60008060006060848603121561407657614075613ba6565b5b600061408486828701613bd1565b935050602061409586828701613efe565b92505060406140a686828701613efe565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6140e581613c06565b82525050565b60006140f783836140dc565b60208301905092915050565b6000602082019050919050565b600061411b826140b0565b61412581856140bb565b9350614130836140cc565b8060005b8381101561416157815161414888826140eb565b975061415383614103565b925050600181019050614134565b5085935050505092915050565b600060208201905081810360008301526141888184614110565b905092915050565b600080604083850312156141a7576141a6613ba6565b5b60006141b585828601613bd1565b92505060206141c685828601613c2f565b9150509250929050565b6141d981613c06565b82525050565b60006020820190506141f460008301846141d0565b92915050565b60008115159050919050565b61420f816141fa565b811461421a57600080fd5b50565b60008135905061422c81614206565b92915050565b6000806040838503121561424957614248613ba6565b5b600061425785828601613bd1565b92505060206142688582860161421d565b9150509250929050565b6000806040838503121561428957614288613ba6565b5b600061429785828601613bd1565b92505060206142a885828601613efe565b9150509250929050565b6142bb816141fa565b82525050565b60006020820190506142d660008301846142b2565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6003811061431c5761431b6142dc565b5b50565b600081905061432d8261430b565b919050565b600061433d8261431f565b9050919050565b61434d81614332565b82525050565b600060e082019050614368600083018a613d0b565b6143756020830189613d0b565b6143826040830188613d0b565b61438f6060830187613ca1565b61439c6080830186613ca1565b6143a960a08301856142b2565b6143b660c0830184614344565b98975050505050505050565b600381106143cf57600080fd5b50565b6000813590506143e1816143c2565b92915050565b600080604083850312156143fe576143fd613ba6565b5b600061440c85828601613bd1565b925050602061441d858286016143d2565b9150509250929050565b60038110614438576144376142dc565b5b50565b600081905061444982614427565b919050565b60006144598261443b565b9050919050565b6144698161444e565b82525050565b600061012082019050614485600083018c6141d0565b614492602083018b6141d0565b61449f604083018a613ca1565b6144ac6060830189613ca1565b6144b960808301886142b2565b6144c660a0830187614460565b6144d360c0830186613d0b565b6144e060e08301856142b2565b6144ee6101008301846142b2565b9a9950505050505050505050565b60006020828403121561451257614511613ba6565b5b600061452084828501613c2f565b91505092915050565b600082825260208201905092915050565b7f546f6b656e20706f6f6c204120646f6573206e6f742065786973740000000000600082015250565b6000614570601b83614529565b915061457b8261453a565b602082019050919050565b6000602082019050818103600083015261459f81614563565b9050919050565b7f546f6b656e20706f6f6c204220646f6573206e6f742065786973740000000000600082015250565b60006145dc601b83614529565b91506145e7826145a6565b602082019050919050565b6000602082019050818103600083015261460b816145cf565b9050919050565b7f506f6f6c204120616c726561647920696e2061206d6174636800000000000000600082015250565b6000614648601983614529565b915061465382614612565b602082019050919050565b600060208201905081810360008301526146778161463b565b9050919050565b7f506f6f6c204220616c726561647920696e2061206d6174636800000000000000600082015250565b60006146b4601983614529565b91506146bf8261467e565b602082019050919050565b600060208201905081810360008301526146e3816146a7565b9050919050565b7f506f6f6c73206d75737420626520646966666572656e74000000000000000000600082015250565b6000614720601783614529565b915061472b826146ea565b602082019050919050565b6000602082019050818103600083015261474f81614713565b9050919050565b7f496e76616c696420706f6f6c2041204944000000000000000000000000000000600082015250565b600061478c601183614529565b915061479782614756565b602082019050919050565b600060208201905081810360008301526147bb8161477f565b9050919050565b7f496e76616c696420706f6f6c2042204944000000000000000000000000000000600082015250565b60006147f8601183614529565b9150614803826147c2565b602082019050919050565b60006020820190508181036000830152614827816147eb565b9050919050565b6000819050919050565b61484961484482613bb0565b61482e565b82525050565b600061485b8285614838565b60208201915061486b8284614838565b6020820191508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006148b582613c97565b91506148c083613c97565b92508282026148ce81613c97565b915082820484148315176148e5576148e461487b565b5b5092915050565b60006148f782613c97565b915061490283613c97565b925082820190508082111561491a5761491961487b565b5b92915050565b600061492b82613c97565b915061493683613c97565b925082820390508181111561494e5761494d61487b565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4d61746368206973206e6f74206f766572000000000000000000000000000000600082015250565b60006149b9601183614529565b91506149c482614983565b602082019050919050565b600060208201905081810360008301526149e8816149ac565b9050919050565b7f506f6f6c20646f6573206e6f7420657869737400000000000000000000000000600082015250565b6000614a25601383614529565b9150614a30826149ef565b602082019050919050565b60006020820190508181036000830152614a5481614a18565b9050919050565b7f506f6f6c206973206e6f74206163746976650000000000000000000000000000600082015250565b6000614a91601283614529565b9150614a9c82614a5b565b602082019050919050565b60006020820190508181036000830152614ac081614a84565b9050919050565b7f5769746864726177616c7320617265206e6f7420616c6c6f7765640000000000600082015250565b6000614afd601b83614529565b9150614b0882614ac7565b602082019050919050565b60006020820190508181036000830152614b2c81614af0565b9050919050565b7f4d75737420776974686472617720736f6d6520746f6b656e7300000000000000600082015250565b6000614b69601983614529565b9150614b7482614b33565b602082019050919050565b60006020820190508181036000830152614b9881614b5c565b9050919050565b7f496e73756666696369656e742066756e64730000000000000000000000000000600082015250565b6000614bd5601283614529565b9150614be082614b9f565b602082019050919050565b60006020820190508181036000830152614c0481614bc8565b9050919050565b600081905092915050565b50565b6000614c26600083614c0b565b9150614c3182614c16565b600082019050919050565b6000614c4782614c19565b9150819050919050565b7f5472616e73666572206661696c65640000000000000000000000000000000000600082015250565b6000614c87600f83614529565b9150614c9282614c51565b602082019050919050565b60006020820190508181036000830152614cb681614c7a565b9050919050565b6000604082019050614cd260008301856141d0565b614cdf6020830184613ca1565b9392505050565b600081519050614cf581614206565b92915050565b600060208284031215614d1157614d10613ba6565b5b6000614d1f84828501614ce6565b91505092915050565b7f4465706f7369747320617265206e6f7420616c6c6f7765640000000000000000600082015250565b6000614d5e601883614529565b9150614d6982614d28565b602082019050919050565b60006020820190508181036000830152614d8d81614d51565b9050919050565b7f4d7573742073656e6420736f6d6520746f6b656e730000000000000000000000600082015250565b6000614dca601583614529565b9150614dd582614d94565b602082019050919050565b60006020820190508181036000830152614df981614dbd565b9050919050565b6000606082019050614e1560008301866141d0565b614e2260208301856141d0565b614e2f6040830184613ca1565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614e7182613c97565b9150614e7c83613c97565b925082614e8c57614e8b614e37565b5b828204905092915050565b7f4d61746368206973206163746976650000000000000000000000000000000000600082015250565b6000614ecd600f83614529565b9150614ed882614e97565b602082019050919050565b60006020820190508181036000830152614efc81614ec0565b9050919050565b7f4d6174636820616c726561647920657869737473000000000000000000000000600082015250565b6000614f39601483614529565b9150614f4482614f03565b602082019050919050565b60006020820190508181036000830152614f6881614f2c565b9050919050565b7f4d6174636820646f6573206e6f74206578697374000000000000000000000000600082015250565b6000614fa5601483614529565b9150614fb082614f6f565b602082019050919050565b60006020820190508181036000830152614fd481614f98565b9050919050565b7f4d6174636820616c726561647920737461727465640000000000000000000000600082015250565b6000615011601583614529565b915061501c82614fdb565b602082019050919050565b6000602082019050818103600083015261504081615004565b9050919050565b7f4d61746368206e6f7420696e2070726f67726573730000000000000000000000600082015250565b600061507d601583614529565b915061508882615047565b602082019050919050565b600060208201905081810360008301526150ac81615070565b9050919050565b7f496e76616c69642077696e6e6572206164647265737300000000000000000000600082015250565b60006150e9601683614529565b91506150f4826150b3565b602082019050919050565b60006020820190508181036000830152615118816150dc565b9050919050565b7f417272617973206c656e677468206d69736d6174636800000000000000000000600082015250565b6000615155601683614529565b91506151608261511f565b602082019050919050565b6000602082019050818103600083015261518481615148565b9050919050565b7f4e6f20706c61796572732070726f766964656400000000000000000000000000600082015250565b60006151c1601383614529565b91506151cc8261518b565b602082019050919050565b600060208201905081810360008301526151f0816151b4565b9050919050565b7f416c726561647920636c61696d65640000000000000000000000000000000000600082015250565b600061522d600f83614529565b9150615238826151f7565b602082019050919050565b6000602082019050818103600083015261525c81615220565b9050919050565b7f506f6f6c20616c72656164792065786973747300000000000000000000000000600082015250565b6000615299601383614529565b91506152a482615263565b602082019050919050565b600060208201905081810360008301526152c88161528c565b9050919050565b6000815190506152de81613ee7565b92915050565b6000602082840312156152fa576152f9613ba6565b5b6000615308848285016152cf565b91505092915050565b7f496e76616c696420746f6b656e20616464726573730000000000000000000000600082015250565b6000615347601583614529565b915061535282615311565b602082019050919050565b600060208201905081810360008301526153768161533a565b9050919050565b6000819050919050565b60006153a261539d61539884613be6565b61537d565b613be6565b9050919050565b60006153b482615387565b9050919050565b60006153c6826153a9565b9050919050565b6153d6816153bb565b82525050565b60006040820190506153f160008301856153cd565b6153fe6020830184613ca1565b9392505050565b7f496e76616c6964206d6174636820494400000000000000000000000000000000600082015250565b600061543b601083614529565b915061544682615405565b602082019050919050565b6000602082019050818103600083015261546a8161542e565b9050919050565b7f456d707479206172726179730000000000000000000000000000000000000000600082015250565b60006154a7600c83614529565b91506154b282615471565b602082019050919050565b600060208201905081810360008301526154d68161549a565b9050919050565b7f496e76616c696420706c61796572206164647265737300000000000000000000600082015250565b6000615513601683614529565b915061551e826154dd565b602082019050919050565b6000602082019050818103600083015261554281615506565b9050919050565b7f496e76616c69642073686172652070657263656e746167650000000000000000600082015250565b600061557f601883614529565b915061558a82615549565b602082019050919050565b600060208201905081810360008301526155ae81615572565b9050919050565b7f546f74616c20736861726573206d757374206265203130302500000000000000600082015250565b60006155eb601983614529565b91506155f6826155b5565b602082019050919050565b6000602082019050818103600083015261561a816155de565b905091905056fea2646970667358221220f778b579a048ab4894d77ca3146b957530a10b67571799dc91945762f57faaf864736f6c634300081c0033
Deployed ByteCode
0x6080604052600436106101e35760003560e01c80639dc8cf7311610102578063c7d138cb11610095578063eb239c9111610064578063eb239c9114610787578063ef5672b6146107b0578063f2fde38b146107d9578063f6d735b214610802576101e3565b8063c7d138cb146106a7578063c9b62674146106e4578063dc81f1c81461070d578063ea7cfd8a1461074a576101e3565b8063aacc4010116100d1578063aacc4010146105f0578063b5217bb41461061b578063c0e046bc14610660578063c3a8574c1461068b576101e3565b80639dc8cf731461050a5780639fe9ada314610547578063a1071aed1461058a578063a344d843146105b3576101e3565b80636693643f1161017a57806371f58f151161014957806371f58f15146104645780638da5cb5b1461048d578063931d15a4146104b857806393bf45c6146104e1576101e3565b80636693643f146103aa5780636695c5b8146103e75780636704298414610410578063715018a61461044d576101e3565b80635aa28f6c116101b65780635aa28f6c146102dc5780635abf8f8514610305578063603ef6491461034257806366735fd81461036d576101e3565b806306a03645146101e85780634355b8d2146102255780634953c1c814610262578063550e6ed11461029f575b600080fd5b3480156101f457600080fd5b5061020f600480360381019061020a9190613c44565b61083f565b60405161021c9190613cb0565b60405180910390f35b34801561023157600080fd5b5061024c60048036038101906102479190613ccb565b6108b2565b6040516102599190613d1a565b60405180910390f35b34801561026e57600080fd5b5061028960048036038101906102849190613ccb565b6108f5565b6040516102969190613d1a565b60405180910390f35b3480156102ab57600080fd5b506102c660048036038101906102c19190613d35565b610ad2565b6040516102d39190613cb0565b60405180910390f35b3480156102e857600080fd5b5061030360048036038101906102fe9190613faa565b610af2565b005b34801561031157600080fd5b5061032c60048036038101906103279190613ccb565b610bae565b6040516103399190613d1a565b60405180910390f35b34801561034e57600080fd5b50610357610c93565b6040516103649190613cb0565b60405180910390f35b34801561037957600080fd5b50610394600480360381019061038f919061405d565b610c99565b6040516103a1919061416e565b60405180910390f35b3480156103b657600080fd5b506103d160048036038101906103cc9190614190565b610e07565b6040516103de9190613cb0565b60405180910390f35b3480156103f357600080fd5b5061040e60048036038101906104099190613ccb565b610e65565b005b34801561041c57600080fd5b5061043760048036038101906104329190614190565b611012565b60405161044491906141df565b60405180910390f35b34801561045957600080fd5b5061046261102e565b005b34801561047057600080fd5b5061048b60048036038101906104869190614232565b611042565b005b34801561049957600080fd5b506104a2611058565b6040516104af91906141df565b60405180910390f35b3480156104c457600080fd5b506104df60048036038101906104da9190614232565b611081565b005b3480156104ed57600080fd5b5061050860048036038101906105039190614272565b611116565b005b34801561051657600080fd5b50610531600480360381019061052c9190613d35565b61159a565b60405161053e91906142c1565b60405180910390f35b34801561055357600080fd5b5061056e60048036038101906105699190613d35565b6115c7565b6040516105819796959493929190614353565b60405180910390f35b34801561059657600080fd5b506105b160048036038101906105ac91906143e7565b611623565b005b3480156105bf57600080fd5b506105da60048036038101906105d59190613d35565b611639565b6040516105e79190613d1a565b60405180910390f35b3480156105fc57600080fd5b50610605611659565b6040516106129190613cb0565b60405180910390f35b34801561062757600080fd5b50610642600480360381019061063d9190613d35565b61165f565b6040516106579998979695949392919061446f565b60405180910390f35b34801561066c57600080fd5b50610675611721565b6040516106829190613cb0565b60405180910390f35b6106a560048036038101906106a09190614272565b611727565b005b3480156106b357600080fd5b506106ce60048036038101906106c99190614190565b611b23565b6040516106db9190613cb0565b60405180910390f35b3480156106f057600080fd5b5061070b60048036038101906107069190614232565b611bd6565b005b34801561071957600080fd5b50610734600480360381019061072f9190613d35565b611c6b565b60405161074191906142c1565b60405180910390f35b34801561075657600080fd5b50610771600480360381019061076c9190613d35565b611c98565b60405161077e91906142c1565b60405180910390f35b34801561079357600080fd5b506107ae60048036038101906107a99190613c44565b611cc3565b005b3480156107bc57600080fd5b506107d760048036038101906107d29190614232565b611d69565b005b3480156107e557600080fd5b5061080060048036038101906107fb91906144fc565b611d7f565b005b34801561080e57600080fd5b5061082960048036038101906108249190613d35565b611e05565b6040516108369190613cb0565b60405180910390f35b60008061084c8585610bae565b905060006003600083815260200190815260200160002090508060060160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054925050509392505050565b6000806108bf8484610bae565b90506000600360008381526020019081526020016000209050848160020154146108e957846108eb565b835b9250505092915050565b60006108ff611e25565b600060026000858152602001908152602001600020905060006002600085815260200190815260200160002090508160040160009054906101000a900460ff1661097e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097590614586565b60405180910390fd5b8060040160009054906101000a900460ff166109cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109c6906145f2565b60405180910390fd5b6000801b826007015414610a18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0f9061465e565b60405180910390fd5b6000801b816007015414610a61576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a58906146ca565b60405180910390fd5b838503610aa3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9a90614736565b60405180910390fd5b6000610aaf8686611eac565b9050610abc868683612099565b610ac6868661213a565b80935050505092915050565b600060026000838152602001908152602001600020600201549050919050565b610afa611e25565b610b05856002611623565b610b10846002611623565b6000610b1c8686610bae565b9050610b2b86868686866122a8565b6000610b3787876108b2565b90506000600260008381526020019081526020016000206002015490506000610b97846002600086815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684612524565b9050610ba383826127d0565b505050505050505050565b60008060001b8303610bf5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bec906147a2565b60405180910390fd5b6000801b8203610c3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c319061480e565b60405180910390fd5b6000828410610c495782610c4b565b835b90506000838510610c5c5784610c5e565b835b90508181604051602001610c7392919061484f565b604051602081830303815290604052805190602001209250505092915050565b60045481565b6060600060026000868152602001908152602001600020905060008385610cc091906148aa565b905060008482610cd091906148ec565b90508260060180549050811115610cec57826006018054905090505b60008282610cfa9190614920565b67ffffffffffffffff811115610d1357610d12613d78565b5b604051908082528060200260200182016040528015610d415781602001602082028036833780820191505090505b50905060008390505b82811015610df857846006018181548110610d6857610d67614954565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16828583610da09190614920565b81518110610db157610db0614954565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508080600101915050610d4a565b50809450505050509392505050565b60006002600084815260200190815260200160002060050160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b610e6d612801565b6000610e798383610bae565b90506000600360008381526020019081526020016000209050600280811115610ea557610ea46142dc565b5b8160050160019054906101000a900460ff166002811115610ec957610ec86142dc565b5b14610f09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f00906149cf565b60405180910390fd5b6000816002015490506000610f1e86866108b2565b90506000600260008381526020019081526020016000206002015490506000610f4888883361083f565b90506000610f568533611b23565b90506000610f648633610e07565b9050600080610fe48a600260008b815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008b815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1689898989612847565b91509150610ff288836127d0565b610ffc87826127d0565b5050505050505050505061100e612fdb565b5050565b600061101c611e25565b6110268383612fe4565b905092915050565b611036611e25565b6110406000613282565b565b61104a611e25565b6110548282611081565b5050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6002600083815260200190815260200160002060040160009054906101000a900460ff166110e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110db90614a3b565b60405180910390fd5b806002600084815260200190815260200160002060080160016101000a81548160ff0219169083151502179055505050565b61111e612801565b60006002600084815260200190815260200160002090508060040160009054906101000a900460ff16611186576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117d90614aa7565b60405180910390fd5b8060080160019054906101000a900460ff166111d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ce90614b13565b60405180910390fd5b6000821161121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190614b7f565b60405180910390fd5b818160050160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561129e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129590614beb565b60405180910390fd5b818160020160008282546112b29190614920565b92505081905550818160050160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461130a9190614920565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361141b5760003373ffffffffffffffffffffffffffffffffffffffff168360405161138f90614c3c565b60006040518083038185875af1925050503d80600081146113cc576040519150601f19603f3d011682016040523d82523d6000602084013e6113d1565b606091505b5050905080611415576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140c90614c9d565b60405180910390fd5b50611503565b60008160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33856040518363ffffffff1660e01b815260040161147f929190614cbd565b6020604051808303816000875af115801561149e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c29190614cfb565b611501576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f890614c9d565b60405180910390fd5b505b3373ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16847f4cd16167afcd2e45cd70a8b10d891f374e85f259ef7afd1867fc9be7fcb11331856040516115859190613cb0565b60405180910390a450611596612fdb565b5050565b60006002600083815260200190815260200160002060080160019054906101000a900460ff169050919050565b60036020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050160009054906101000a900460ff16908060050160019054906101000a900460ff16905087565b61162b611e25565b6116358282613346565b5050565b600060026000838152602001908152602001600020600701549050919050565b60055481565b60026020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030154908060040160009054906101000a900460ff16908060040160019054906101000a900460ff16908060070154908060080160009054906101000a900460ff16908060080160019054906101000a900460ff16905089565b60065481565b61172f612801565b60006002600084815260200190815260200160002090508060040160009054906101000a900460ff16611797576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178e90614a3b565b60405180910390fd5b8060080160009054906101000a900460ff166117e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117df90614d74565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361188757813414611882576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187990614de0565b60405180910390fd5b6119b4565b600082116118ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118c190614de0565b60405180910390fd5b60008160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff166323b872dd3330866040518463ffffffff1660e01b815260040161193093929190614e00565b6020604051808303816000875af115801561194f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119739190614cfb565b6119b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a990614c9d565b60405180910390fd5b505b818160020160008282546119c891906148ec565b92505081905550818160050160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a2091906148ec565b9250508190555080600601339080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16847fe40671b740fa5f78e7e7407dc9a0e028808df762f7f97020416b2ac647af2e3f85604051611b0e9190613cb0565b60405180910390a450611b1f612fdb565b5050565b600080600260008581526020019081526020016000206002015403611b4b5760009050611bd0565b60026000848152602001908152602001600020600201546127106002600086815260200190815260200160002060050160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611bc391906148aa565b611bcd9190614e66565b90505b92915050565b6002600083815260200190815260200160002060040160009054906101000a900460ff16611c39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3090614a3b565b60405180910390fd5b806002600084815260200190815260200160002060080160006101000a81548160ff0219169083151502179055505050565b60006002600083815260200190815260200160002060080160009054906101000a900460ff169050919050565b60086020528060005260406000206000915090508060000160009054906101000a900460ff16905081565b611ccb611e25565b6000611cd78484610bae565b90506003600082815260200190815260200160002060050160009054906101000a900460ff1615611d3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3490614ee3565b60405180910390fd5b611d478483613448565b611d518383613448565b611d5a8161375a565b611d6381613808565b50505050565b611d71611e25565b611d7b8282611bd6565b5050565b611d87611e25565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611df95760006040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401611df091906141df565b60405180910390fd5b611e0281613282565b50565b600060026000838152602001908152602001600020600301549050919050565b611e2d613835565b73ffffffffffffffffffffffffffffffffffffffff16611e4b611058565b73ffffffffffffffffffffffffffffffffffffffff1614611eaa57611e6e613835565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401611ea191906141df565b60405180910390fd5b565b6000818303611ef0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ee790614736565b60405180910390fd5b6000801b8303611f35576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f2c906147a2565b60405180910390fd5b6000801b8203611f7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f719061480e565b60405180910390fd5b6000611f868484610bae565b90506003600082815260200190815260200160002060050160009054906101000a900460ff1615611fec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fe390614f4f565b60405180910390fd5b600060036000838152602001908152602001600020905084816000018190555083816001018190555060018160050160006101000a81548160ff02191690831515021790555060008160050160016101000a81548160ff0219169083600281111561205a576120596142dc565b5b02179055508184867ff94047cb2b767481be8aad8cae3c3ce5f432cfe8dd7b23f50e3d18648b4a7b9560405160405180910390a4819250505092915050565b6000600260008581526020019081526020016000209050600060026000858152602001908152602001600020905082826007018190555082816007018190555060018260040160016101000a81548160ff02191690836002811115612101576121006142dc565b5b021790555060018160040160016101000a81548160ff0219169083600281111561212e5761212d6142dc565b5b02179055505050505050565b60006121468383610bae565b90506003600082815260200190815260200160002060050160009054906101000a900460ff166121ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121a290614fbb565b60405180910390fd5b600060028111156121bf576121be6142dc565b5b6003600083815260200190815260200160002060050160019054906101000a900460ff1660028111156121f5576121f46142dc565b5b14612235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161222c90615027565b60405180910390fd5b60016003600083815260200190815260200160002060050160016101000a81548160ff0219169083600281111561226f5761226e6142dc565b5b02179055508082847f29d26f27771059d3fdf99a7ea828394ca3980824b18f47ba9959beb3e9f3d87360405160405180910390a4505050565b60006122b48686610bae565b90506003600082815260200190815260200160002060050160009054906101000a900460ff16612319576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231090614fbb565b60405180910390fd5b6001600281111561232d5761232c6142dc565b5b6003600083815260200190815260200160002060050160019054906101000a900460ff166002811115612363576123626142dc565b5b146123a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161239a90615093565b60405180910390fd5b858414806123b057508484145b6123ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123e6906150ff565b60405180910390fd5b8151835114612433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161242a9061516b565b60405180910390fd5b6000835111612477576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161246e906151d7565b60405180910390fd5b600060036000838152602001908152602001600020905084816002018190555060028160050160016101000a81548160ff021916908360028111156124bf576124be6142dc565b5b021790555060008160050160006101000a81548160ff0219169083151502179055506124ec82858561383d565b8186887fee20e6cf265453dc32c716ce04a1c54c44b9616a1e738f217f515736509aa9dc60405160405180910390a450505050505050565b600061252e612801565b600015156008600086815260200190815260200160002060000160009054906101000a900460ff16151514612598576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161258f90615243565b60405180910390fd5b60016008600086815260200190815260200160002060000160006101000a81548160ff02191690831515021790555060008290506000600754600454836125df91906148aa565b6125e99190614e66565b9050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036126d15760003373ffffffffffffffffffffffffffffffffffffffff168260405161264590614c3c565b60006040518083038185875af1925050503d8060008114612682576040519150601f19603f3d011682016040523d82523d6000602084013e612687565b606091505b50509050806126cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c290614c9d565b60405180910390fd5b50612757565b60008590508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401612711929190614cbd565b6020604051808303816000875af1158015612730573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127549190614cfb565b50505b8473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ff0af9bc2c3a4716fef6ce079f5de916f018e0201e2f7052dfeae945801475b2f836040516127b49190613cb0565b60405180910390a380925050506127c9612fdb565b9392505050565b806002600084815260200190815260200160002060030160008282546127f69190614920565b925050819055505050565b60026001540361283d576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600181905550565b60008060001515600860008b815260200190815260200160002060010160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515146128f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128e890615243565b60405180910390fd5b60001515600860008b815260200190815260200160002060020160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514612998576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161298f90615243565b60405180910390fd5b60001515600860008b815260200190815260200160002060030160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514612a3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a3690615243565b60405180910390fd5b6001600860008b815260200190815260200160002060010160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600860008b815260200190815260200160002060020160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600860008b815260200190815260200160002060030160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506000612b8f8786613ace565b90506000612b9d8888613b16565b9050600073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff1603612c855760003373ffffffffffffffffffffffffffffffffffffffff1686604051612bf990614c3c565b60006040518083038185875af1925050503d8060008114612c36576040519150601f19603f3d011682016040523d82523d6000602084013e612c3b565b606091505b5050905080612c7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c7690614c9d565b60405180910390fd5b50612d0b565b60008a90508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33886040518363ffffffff1660e01b8152600401612cc5929190614cbd565b6020604051808303816000875af1158015612ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d089190614cfb565b50505b600073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1603612dfc5760003373ffffffffffffffffffffffffffffffffffffffff168284612d6491906148ec565b604051612d7090614c3c565b60006040518083038185875af1925050503d8060008114612dad576040519150601f19603f3d011682016040523d82523d6000602084013e612db2565b606091505b5050905080612df6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ded90614c9d565b60405180910390fd5b50612e8d565b60008990508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb338486612e2a91906148ec565b6040518363ffffffff1660e01b8152600401612e47929190614cbd565b6020604051808303816000875af1158015612e66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e8a9190614cfb565b50505b8973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f691d3da84f60a8e9f7618970b6df07a3a18b47254d483e44e071f50e8c3cbbfa87604051612eea9190613cb0565b60405180910390a38873ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f691d3da84f60a8e9f7618970b6df07a3a18b47254d483e44e071f50e8c3cbbfa84604051612f4f9190613cb0565b60405180910390a38873ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fde02534236523c2e02492e6cfc4cd7cc6003b1891460f414626d77e7c867551f83604051612fb49190613cb0565b60405180910390a3848183612fc991906148ec565b93509350505097509795505050505050565b60018081905550565b60006002600084815260200190815260200160002060040160009054906101000a900460ff161561304a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613041906152af565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461313657600082905060008173ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130f491906152e4565b11613134576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161312b9061535d565b60405180910390fd5b505b6000600260008581526020019081526020016000209050338160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060018160040160006101000a81548160ff02191690831515021790555060008160040160016101000a81548160ff02191690836002811115613218576132176142dc565b5b02179055503373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16857fc0c143d18100b0ec0b6c08cc52247dd860ffd3fc2af30733326e5f980c19635a60405160405180910390a48291505092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6002600083815260200190815260200160002060040160009054906101000a900460ff166133a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133a090614a3b565b60405180910390fd5b806002600084815260200190815260200160002060040160016101000a81548160ff021916908360028111156133e2576133e16142dc565b5b02179055506002808111156133fa576133f96142dc565b5b81600281111561340d5761340c6142dc565b5b0361344457600260008381526020019081526020016000206002015460026000848152602001908152602001600020600301819055505b5050565b600060026000848152602001908152602001600020600301549050600073ffffffffffffffffffffffffffffffffffffffff166002600085815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361357f5760008273ffffffffffffffffffffffffffffffffffffffff16826040516134f390614c3c565b60006040518083038185875af1925050503d8060008114613530576040519150601f19603f3d011682016040523d82523d6000602084013e613535565b606091505b5050905080613579576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161357090614c9d565b60405180910390fd5b50613679565b60006002600085815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b81526004016135f59291906153dc565b6020604051808303816000875af1158015613614573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136389190614cfb565b613677576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161366e90614c9d565b60405180910390fd5b505b60026000848152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600282016000905560038201600090556004820160006101000a81549060ff02191690556004820160016101000a81549060ff02191690556006820160006137239190613b5e565b60078201600090556008820160006101000a81549060ff02191690556008820160016101000a81549060ff02191690555050505050565b6000801b810361379f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161379690615451565b60405180910390fd5b6003600082815260200190815260200160002060008082016000905560018201600090556002820160009055600382016000905560048201600090556005820160006101000a81549060ff02191690556005820160016101000a81549060ff0219169055505050565b60086000828152602001908152602001600020600080820160006101000a81549060ff0219169055505050565b600033905090565b8051825114613881576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138789061516b565b60405180910390fd5b60008251116138c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138bc906154bd565b60405180910390fd5b6000600360008581526020019081526020016000209050600080600090505b8451811015613a8257600073ffffffffffffffffffffffffffffffffffffffff1685828151811061391857613917614954565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603613976576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161396d90615529565b60405180910390fd5b600084828151811061398b5761398a614954565b5b6020026020010151116139d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139ca90615595565b60405180910390fd5b8381815181106139e6576139e5614954565b5b6020026020010151826139f991906148ec565b9150838181518110613a0e57613a0d614954565b5b6020026020010151836006016000878481518110613a2f57613a2e614954565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080806001019150506138e4565b506127108114613ac7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613abe90615601565b60405180910390fd5b5050505050565b60008060055484613adf91906148aa565b90506000600754600754613af391906148aa565b8483613aff91906148aa565b613b099190614e66565b9050809250505092915050565b60008060065484613b2791906148aa565b90506000600754600754613b3b91906148aa565b8483613b4791906148aa565b613b519190614e66565b9050809250505092915050565b5080546000825590600052602060002090810190613b7c9190613b7f565b50565b5b80821115613b98576000816000905550600101613b80565b5090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b613bc381613bb0565b8114613bce57600080fd5b50565b600081359050613be081613bba565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c1182613be6565b9050919050565b613c2181613c06565b8114613c2c57600080fd5b50565b600081359050613c3e81613c18565b92915050565b600080600060608486031215613c5d57613c5c613ba6565b5b6000613c6b86828701613bd1565b9350506020613c7c86828701613bd1565b9250506040613c8d86828701613c2f565b9150509250925092565b6000819050919050565b613caa81613c97565b82525050565b6000602082019050613cc56000830184613ca1565b92915050565b60008060408385031215613ce257613ce1613ba6565b5b6000613cf085828601613bd1565b9250506020613d0185828601613bd1565b9150509250929050565b613d1481613bb0565b82525050565b6000602082019050613d2f6000830184613d0b565b92915050565b600060208284031215613d4b57613d4a613ba6565b5b6000613d5984828501613bd1565b91505092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613db082613d67565b810181811067ffffffffffffffff82111715613dcf57613dce613d78565b5b80604052505050565b6000613de2613b9c565b9050613dee8282613da7565b919050565b600067ffffffffffffffff821115613e0e57613e0d613d78565b5b602082029050602081019050919050565b600080fd5b6000613e37613e3284613df3565b613dd8565b90508083825260208201905060208402830185811115613e5a57613e59613e1f565b5b835b81811015613e835780613e6f8882613c2f565b845260208401935050602081019050613e5c565b5050509392505050565b600082601f830112613ea257613ea1613d62565b5b8135613eb2848260208601613e24565b91505092915050565b600067ffffffffffffffff821115613ed657613ed5613d78565b5b602082029050602081019050919050565b613ef081613c97565b8114613efb57600080fd5b50565b600081359050613f0d81613ee7565b92915050565b6000613f26613f2184613ebb565b613dd8565b90508083825260208201905060208402830185811115613f4957613f48613e1f565b5b835b81811015613f725780613f5e8882613efe565b845260208401935050602081019050613f4b565b5050509392505050565b600082601f830112613f9157613f90613d62565b5b8135613fa1848260208601613f13565b91505092915050565b600080600080600060a08688031215613fc657613fc5613ba6565b5b6000613fd488828901613bd1565b9550506020613fe588828901613bd1565b9450506040613ff688828901613bd1565b935050606086013567ffffffffffffffff81111561401757614016613bab565b5b61402388828901613e8d565b925050608086013567ffffffffffffffff81111561404457614043613bab565b5b61405088828901613f7c565b9150509295509295909350565b60008060006060848603121561407657614075613ba6565b5b600061408486828701613bd1565b935050602061409586828701613efe565b92505060406140a686828701613efe565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6140e581613c06565b82525050565b60006140f783836140dc565b60208301905092915050565b6000602082019050919050565b600061411b826140b0565b61412581856140bb565b9350614130836140cc565b8060005b8381101561416157815161414888826140eb565b975061415383614103565b925050600181019050614134565b5085935050505092915050565b600060208201905081810360008301526141888184614110565b905092915050565b600080604083850312156141a7576141a6613ba6565b5b60006141b585828601613bd1565b92505060206141c685828601613c2f565b9150509250929050565b6141d981613c06565b82525050565b60006020820190506141f460008301846141d0565b92915050565b60008115159050919050565b61420f816141fa565b811461421a57600080fd5b50565b60008135905061422c81614206565b92915050565b6000806040838503121561424957614248613ba6565b5b600061425785828601613bd1565b92505060206142688582860161421d565b9150509250929050565b6000806040838503121561428957614288613ba6565b5b600061429785828601613bd1565b92505060206142a885828601613efe565b9150509250929050565b6142bb816141fa565b82525050565b60006020820190506142d660008301846142b2565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6003811061431c5761431b6142dc565b5b50565b600081905061432d8261430b565b919050565b600061433d8261431f565b9050919050565b61434d81614332565b82525050565b600060e082019050614368600083018a613d0b565b6143756020830189613d0b565b6143826040830188613d0b565b61438f6060830187613ca1565b61439c6080830186613ca1565b6143a960a08301856142b2565b6143b660c0830184614344565b98975050505050505050565b600381106143cf57600080fd5b50565b6000813590506143e1816143c2565b92915050565b600080604083850312156143fe576143fd613ba6565b5b600061440c85828601613bd1565b925050602061441d858286016143d2565b9150509250929050565b60038110614438576144376142dc565b5b50565b600081905061444982614427565b919050565b60006144598261443b565b9050919050565b6144698161444e565b82525050565b600061012082019050614485600083018c6141d0565b614492602083018b6141d0565b61449f604083018a613ca1565b6144ac6060830189613ca1565b6144b960808301886142b2565b6144c660a0830187614460565b6144d360c0830186613d0b565b6144e060e08301856142b2565b6144ee6101008301846142b2565b9a9950505050505050505050565b60006020828403121561451257614511613ba6565b5b600061452084828501613c2f565b91505092915050565b600082825260208201905092915050565b7f546f6b656e20706f6f6c204120646f6573206e6f742065786973740000000000600082015250565b6000614570601b83614529565b915061457b8261453a565b602082019050919050565b6000602082019050818103600083015261459f81614563565b9050919050565b7f546f6b656e20706f6f6c204220646f6573206e6f742065786973740000000000600082015250565b60006145dc601b83614529565b91506145e7826145a6565b602082019050919050565b6000602082019050818103600083015261460b816145cf565b9050919050565b7f506f6f6c204120616c726561647920696e2061206d6174636800000000000000600082015250565b6000614648601983614529565b915061465382614612565b602082019050919050565b600060208201905081810360008301526146778161463b565b9050919050565b7f506f6f6c204220616c726561647920696e2061206d6174636800000000000000600082015250565b60006146b4601983614529565b91506146bf8261467e565b602082019050919050565b600060208201905081810360008301526146e3816146a7565b9050919050565b7f506f6f6c73206d75737420626520646966666572656e74000000000000000000600082015250565b6000614720601783614529565b915061472b826146ea565b602082019050919050565b6000602082019050818103600083015261474f81614713565b9050919050565b7f496e76616c696420706f6f6c2041204944000000000000000000000000000000600082015250565b600061478c601183614529565b915061479782614756565b602082019050919050565b600060208201905081810360008301526147bb8161477f565b9050919050565b7f496e76616c696420706f6f6c2042204944000000000000000000000000000000600082015250565b60006147f8601183614529565b9150614803826147c2565b602082019050919050565b60006020820190508181036000830152614827816147eb565b9050919050565b6000819050919050565b61484961484482613bb0565b61482e565b82525050565b600061485b8285614838565b60208201915061486b8284614838565b6020820191508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006148b582613c97565b91506148c083613c97565b92508282026148ce81613c97565b915082820484148315176148e5576148e461487b565b5b5092915050565b60006148f782613c97565b915061490283613c97565b925082820190508082111561491a5761491961487b565b5b92915050565b600061492b82613c97565b915061493683613c97565b925082820390508181111561494e5761494d61487b565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4d61746368206973206e6f74206f766572000000000000000000000000000000600082015250565b60006149b9601183614529565b91506149c482614983565b602082019050919050565b600060208201905081810360008301526149e8816149ac565b9050919050565b7f506f6f6c20646f6573206e6f7420657869737400000000000000000000000000600082015250565b6000614a25601383614529565b9150614a30826149ef565b602082019050919050565b60006020820190508181036000830152614a5481614a18565b9050919050565b7f506f6f6c206973206e6f74206163746976650000000000000000000000000000600082015250565b6000614a91601283614529565b9150614a9c82614a5b565b602082019050919050565b60006020820190508181036000830152614ac081614a84565b9050919050565b7f5769746864726177616c7320617265206e6f7420616c6c6f7765640000000000600082015250565b6000614afd601b83614529565b9150614b0882614ac7565b602082019050919050565b60006020820190508181036000830152614b2c81614af0565b9050919050565b7f4d75737420776974686472617720736f6d6520746f6b656e7300000000000000600082015250565b6000614b69601983614529565b9150614b7482614b33565b602082019050919050565b60006020820190508181036000830152614b9881614b5c565b9050919050565b7f496e73756666696369656e742066756e64730000000000000000000000000000600082015250565b6000614bd5601283614529565b9150614be082614b9f565b602082019050919050565b60006020820190508181036000830152614c0481614bc8565b9050919050565b600081905092915050565b50565b6000614c26600083614c0b565b9150614c3182614c16565b600082019050919050565b6000614c4782614c19565b9150819050919050565b7f5472616e73666572206661696c65640000000000000000000000000000000000600082015250565b6000614c87600f83614529565b9150614c9282614c51565b602082019050919050565b60006020820190508181036000830152614cb681614c7a565b9050919050565b6000604082019050614cd260008301856141d0565b614cdf6020830184613ca1565b9392505050565b600081519050614cf581614206565b92915050565b600060208284031215614d1157614d10613ba6565b5b6000614d1f84828501614ce6565b91505092915050565b7f4465706f7369747320617265206e6f7420616c6c6f7765640000000000000000600082015250565b6000614d5e601883614529565b9150614d6982614d28565b602082019050919050565b60006020820190508181036000830152614d8d81614d51565b9050919050565b7f4d7573742073656e6420736f6d6520746f6b656e730000000000000000000000600082015250565b6000614dca601583614529565b9150614dd582614d94565b602082019050919050565b60006020820190508181036000830152614df981614dbd565b9050919050565b6000606082019050614e1560008301866141d0565b614e2260208301856141d0565b614e2f6040830184613ca1565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614e7182613c97565b9150614e7c83613c97565b925082614e8c57614e8b614e37565b5b828204905092915050565b7f4d61746368206973206163746976650000000000000000000000000000000000600082015250565b6000614ecd600f83614529565b9150614ed882614e97565b602082019050919050565b60006020820190508181036000830152614efc81614ec0565b9050919050565b7f4d6174636820616c726561647920657869737473000000000000000000000000600082015250565b6000614f39601483614529565b9150614f4482614f03565b602082019050919050565b60006020820190508181036000830152614f6881614f2c565b9050919050565b7f4d6174636820646f6573206e6f74206578697374000000000000000000000000600082015250565b6000614fa5601483614529565b9150614fb082614f6f565b602082019050919050565b60006020820190508181036000830152614fd481614f98565b9050919050565b7f4d6174636820616c726561647920737461727465640000000000000000000000600082015250565b6000615011601583614529565b915061501c82614fdb565b602082019050919050565b6000602082019050818103600083015261504081615004565b9050919050565b7f4d61746368206e6f7420696e2070726f67726573730000000000000000000000600082015250565b600061507d601583614529565b915061508882615047565b602082019050919050565b600060208201905081810360008301526150ac81615070565b9050919050565b7f496e76616c69642077696e6e6572206164647265737300000000000000000000600082015250565b60006150e9601683614529565b91506150f4826150b3565b602082019050919050565b60006020820190508181036000830152615118816150dc565b9050919050565b7f417272617973206c656e677468206d69736d6174636800000000000000000000600082015250565b6000615155601683614529565b91506151608261511f565b602082019050919050565b6000602082019050818103600083015261518481615148565b9050919050565b7f4e6f20706c61796572732070726f766964656400000000000000000000000000600082015250565b60006151c1601383614529565b91506151cc8261518b565b602082019050919050565b600060208201905081810360008301526151f0816151b4565b9050919050565b7f416c726561647920636c61696d65640000000000000000000000000000000000600082015250565b600061522d600f83614529565b9150615238826151f7565b602082019050919050565b6000602082019050818103600083015261525c81615220565b9050919050565b7f506f6f6c20616c72656164792065786973747300000000000000000000000000600082015250565b6000615299601383614529565b91506152a482615263565b602082019050919050565b600060208201905081810360008301526152c88161528c565b9050919050565b6000815190506152de81613ee7565b92915050565b6000602082840312156152fa576152f9613ba6565b5b6000615308848285016152cf565b91505092915050565b7f496e76616c696420746f6b656e20616464726573730000000000000000000000600082015250565b6000615347601583614529565b915061535282615311565b602082019050919050565b600060208201905081810360008301526153768161533a565b9050919050565b6000819050919050565b60006153a261539d61539884613be6565b61537d565b613be6565b9050919050565b60006153b482615387565b9050919050565b60006153c6826153a9565b9050919050565b6153d6816153bb565b82525050565b60006040820190506153f160008301856153cd565b6153fe6020830184613ca1565b9392505050565b7f496e76616c6964206d6174636820494400000000000000000000000000000000600082015250565b600061543b601083614529565b915061544682615405565b602082019050919050565b6000602082019050818103600083015261546a8161542e565b9050919050565b7f456d707479206172726179730000000000000000000000000000000000000000600082015250565b60006154a7600c83614529565b91506154b282615471565b602082019050919050565b600060208201905081810360008301526154d68161549a565b9050919050565b7f496e76616c696420706c61796572206164647265737300000000000000000000600082015250565b6000615513601683614529565b915061551e826154dd565b602082019050919050565b6000602082019050818103600083015261554281615506565b9050919050565b7f496e76616c69642073686172652070657263656e746167650000000000000000600082015250565b600061557f601883614529565b915061558a82615549565b602082019050919050565b600060208201905081810360008301526155ae81615572565b9050919050565b7f546f74616c20736861726573206d757374206265203130302500000000000000600082015250565b60006155eb601983614529565b91506155f6826155b5565b602082019050919050565b6000602082019050818103600083015261561a816155de565b905091905056fea2646970667358221220f778b579a048ab4894d77ca3146b957530a10b67571799dc91945762f57faaf864736f6c634300081c0033