Source Code
Overview
S Balance
S Value
$0.00Cross-Chain Transactions
Loading...
Loading
Contract Name:
PumpFactory
Compiler Version
v0.8.31+commit.fd3a2265
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
interface IUniswapV2Factory {
function getPair(address tokenA, address tokenB) external view returns (address pair);
}
interface IRouter {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidityETH(
address token, uint amountTokenDesired, uint amountTokenMin,
uint amountETHMin, address to, uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
}
interface IERC20LP {
function balanceOf(address) external view returns (uint256);
function transfer(address, uint256) external returns (bool);
}
/// @title PumpStyleToken - Pump.fun Style Bonding Curve
contract PumpStyleToken is ERC20, ReentrancyGuard {
string public description;
string public imageURI;
address public creator;
address public factory;
uint256 public virtualEthReserve;
uint256 public virtualTokenReserve;
uint256 public realEthReserve;
bool public graduated;
uint256 public graduationMarketCapUSD;
uint256 public nativeTokenPriceUSD;
address public dexRouter;
uint256 public tradingFeePercent;
address public feeCollector;
uint256 public collectedFees;
uint256 constant SCALE = 1e18;
uint256 constant SUPPLY_CAP = 1_000_000_000 * 1e18;
uint256 constant MAX_BUY_PERCENT = 2000; // Max 20% of virtual token reserve per tx (anti-whale)
event Bought(address indexed buyer, uint256 tokens, uint256 cost);
event Sold(address indexed seller, uint256 tokens, uint256 refund);
event Graduated(address indexed token, uint256 ethAmount, uint256 tokenAmount, bool liquiditySuccess);
event LPBurned(address indexed pair, uint256 amount);
event FeeCollected(string indexed feeType, uint256 amount);
event NativePriceUpdated(uint256 oldPrice, uint256 newPrice);
constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) {
factory = msg.sender;
}
function initialize(
string memory _desc,
string memory _img,
address _creator,
address _feeCollector,
address _dexRouter,
uint256 _tradingFee,
uint256 _gradCap,
uint256 _vEth,
uint256 _vTokens,
uint256 _nativePrice
) external {
require(msg.sender == factory, "Only factory");
require(creator == address(0), "Already initialized");
description = _desc;
imageURI = _img;
creator = _creator;
feeCollector = _feeCollector;
dexRouter = _dexRouter;
require(feeCollector != address(0), "Zero fee collector");
require(dexRouter != address(0), "Zero router");
require(_tradingFee <= 1000, "Fee too high"); // Max 10%
tradingFeePercent = _tradingFee;
require(_gradCap > 0, "Zero graduation cap");
graduationMarketCapUSD = _gradCap;
require(_vEth > 0 && _vTokens > 0, "Zero virtual reserves");
virtualEthReserve = _vEth;
virtualTokenReserve = _vTokens;
require(_nativePrice > 0, "Zero native price");
nativeTokenPriceUSD = _nativePrice;
}
function getReserves() public view returns (uint256 eth, uint256 tokens) {
eth = virtualEthReserve + realEthReserve;
// Underflow protection
uint256 supply = totalSupply();
tokens = supply >= virtualTokenReserve ? 0 : virtualTokenReserve - supply;
}
function getPrice() public view returns (uint256) {
(uint256 eth, uint256 tokens) = getReserves();
return tokens > 0 ? (eth * SCALE) / tokens : 0;
}
function getMarketCapUSD() public view returns (uint256) {
return (totalSupply() * getPrice() * nativeTokenPriceUSD) / (SCALE * SCALE);
}
function tokensOut(uint256 ethIn) public view returns (uint256) {
(uint256 eth, uint256 tokens) = getReserves();
uint256 out = (tokens * ethIn) / (eth + ethIn);
return out > tokens ? tokens : out;
}
function ethOut(uint256 tokensIn) public view returns (uint256) {
(uint256 eth, uint256 tokens) = getReserves();
uint256 out = (eth * tokensIn) / (tokens + tokensIn);
return out > realEthReserve ? realEthReserve : out;
}
function buy(uint256 minTokens) external payable nonReentrant {
require(!graduated && msg.value > 0, "Invalid");
uint256 fee = (msg.value * tradingFeePercent) / 10000;
uint256 net = msg.value - fee;
uint256 tokens = tokensOut(net);
// Anti-whale: max 5% of virtual token reserve per tx
uint256 maxTokens = (virtualTokenReserve * MAX_BUY_PERCENT) / 10000;
require(tokens <= maxTokens, "Exceeds max buy");
require(tokens >= minTokens && totalSupply() + tokens <= SUPPLY_CAP, "Slippage/Cap");
realEthReserve += net;
collectedFees += fee;
emit FeeCollected("buy", fee);
_mint(msg.sender, tokens);
emit Bought(msg.sender, tokens, net);
if (getMarketCapUSD() >= graduationMarketCapUSD) {
_graduate();
}
}
function sell(uint256 amount, uint256 minEth) external nonReentrant {
require(!graduated && balanceOf(msg.sender) >= amount, "Invalid");
uint256 eth = ethOut(amount);
uint256 fee = (eth * tradingFeePercent) / 10000;
uint256 net = eth - fee;
require(net >= minEth && realEthReserve >= eth, "Slippage/Liq");
realEthReserve -= eth;
collectedFees += fee;
emit FeeCollected("sell", fee);
_burn(msg.sender, amount);
(bool success, ) = payable(msg.sender).call{value: net}("");
require(success, "ETH transfer failed");
emit Sold(msg.sender, amount, net);
}
function _graduate() private {
graduated = true;
bool liquiditySuccess = false;
uint256 ethLiq = (realEthReserve * 95) / 100;
uint256 tokens = totalSupply() / 2;
// Check SUPPLY_CAP before minting
require(totalSupply() + tokens <= SUPPLY_CAP, "Graduation exceeds cap");
_mint(address(this), tokens);
_approve(address(this), dexRouter, tokens);
(bool sent, ) = payable(feeCollector).call{value: realEthReserve - ethLiq}("");
if (!sent) {
collectedFees += (realEthReserve - ethLiq);
emit FeeCollected("graduation_failed", realEthReserve - ethLiq);
} else {
emit FeeCollected("graduation", realEthReserve - ethLiq);
}
// Try to add liquidity - if it fails, save ETH to collectedFees for recovery
// Use 90% minimums to protect against malicious router
uint256 minTokens = tokens * 90 / 100;
uint256 minEth = ethLiq * 90 / 100;
try IRouter(dexRouter).addLiquidityETH{value: ethLiq}(
address(this), tokens, minTokens, minEth, address(this), block.timestamp + 3600
) returns (uint256 amountToken, uint256 amountETH, uint256 liq) {
// Validate returned amounts
require(amountToken >= minTokens, "Insufficient token liquidity");
require(amountETH >= minEth, "Insufficient ETH liquidity");
address weth = IRouter(dexRouter).WETH();
address pair = IUniswapV2Factory(IRouter(dexRouter).factory()).getPair(address(this), weth);
if (pair != address(0) && liq > 0) {
// Verify actual LP token transfer by checking balance before/after
uint256 balanceBefore = IERC20LP(pair).balanceOf(address(0xdead));
bool success = IERC20LP(pair).transfer(address(0xdead), liq);
require(success, "LP Burn failed");
uint256 balanceAfter = IERC20LP(pair).balanceOf(address(0xdead));
require(balanceAfter == balanceBefore + liq, "LP tokens not burned");
emit LPBurned(pair, liq);
liquiditySuccess = true;
}
} catch {
// Liquidity failed - save ETH for manual recovery
collectedFees += ethLiq;
emit FeeCollected("liquidity_failed", ethLiq);
// Burn the minted tokens to prevent inflation
_burn(address(this), tokens);
}
realEthReserve = 0;
emit Graduated(address(this), ethLiq, tokens, liquiditySuccess);
}
function updateNativePrice(uint256 price) external {
require(msg.sender == factory, "Factory");
require(price > 0, "Zero price");
uint256 oldPrice = nativeTokenPriceUSD;
nativeTokenPriceUSD = price;
emit NativePriceUpdated(oldPrice, price);
}
function withdrawFees() external nonReentrant {
require(msg.sender == feeCollector, "Collector");
uint256 amt = collectedFees;
require(amt > 0, "No fees");
collectedFees = 0;
(bool success, ) = payable(feeCollector).call{value: amt}("");
require(success, "Transfer failed");
}
// Only accept ETH from router during graduation
receive() external payable {
require(msg.sender == dexRouter, "Direct ETH not allowed");
}
}
/// @title PumpFactory
contract PumpFactory is Ownable, ReentrancyGuard {
uint256 public creationFee = 0.001 ether;
uint256 public tradingFeePercent = 100;
address public feeCollector;
uint256 public graduationMarketCapUSD = 1e17;
uint256 public virtualEthReserve = 1 ether;
uint256 public virtualTokenReserve = 800_000_000 * 1e18;
address public dexRouter = 0x9B3336186a38E1b6c21955d112dbb0343Ee061eE;
uint256 public nativeTokenPriceUSD = 75 * 1e16;
address[] public tokens;
event TokenCreated(address indexed token, string name, address creator);
constructor() Ownable(msg.sender) {
feeCollector = msg.sender;
}
function createToken(
string memory name,
string memory symbol,
string memory desc,
string memory img
) external payable nonReentrant returns (address) {
require(msg.value >= creationFee, "Fee");
PumpStyleToken t = new PumpStyleToken(name, symbol);
t.initialize(
desc, img, msg.sender, feeCollector, dexRouter,
tradingFeePercent, graduationMarketCapUSD,
virtualEthReserve, virtualTokenReserve, nativeTokenPriceUSD
);
tokens.push(address(t));
emit TokenCreated(address(t), name, msg.sender);
return address(t);
}
function setCreationFee(uint256 f) external onlyOwner { creationFee = f; }
function setTradingFee(uint256 f) external onlyOwner {
require(f <= 1000, "Max 10%"); // Safety cap
tradingFeePercent = f;
}
function setFeeCollector(address a) external onlyOwner {
require(a != address(0), "Zero address");
feeCollector = a;
}
function setGraduationCap(uint256 c) external onlyOwner {
require(c > 0, "Zero cap");
graduationMarketCapUSD = c;
}
function setVirtualReserves(uint256 e, uint256 t) external onlyOwner {
require(e > 0 && t > 0, "Zero reserves");
virtualEthReserve = e;
virtualTokenReserve = t;
}
function setDexRouter(address r) external onlyOwner {
require(r != address(0), "Zero address");
dexRouter = r;
}
function setNativePrice(uint256 p) external onlyOwner {
require(p > 0, "Zero price");
nativeTokenPriceUSD = p;
}
function withdraw() external onlyOwner {
(bool success, ) = payable(owner()).call{value: address(this).balance}("");
require(success, "Withdraw failed");
}
function tokenCount() external view returns (uint256) { return tokens.length; }
// Reject direct ETH - only accept via createToken
receive() external payable {
revert("Use createToken");
}
}// 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;
}
}// 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);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "./IERC20.sol";
import {IERC20Metadata} from "./extensions/IERC20Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC-20
* applications.
*/
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
mapping(address account => uint256) private _balances;
mapping(address account => mapping(address spender => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* Both values are immutable: they can only be set once during construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual returns (uint8) {
return 18;
}
/// @inheritdoc IERC20
function totalSupply() public view virtual returns (uint256) {
return _totalSupply;
}
/// @inheritdoc IERC20
function balanceOf(address account) public view virtual returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `value`.
*/
function transfer(address to, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_transfer(owner, to, value);
return true;
}
/// @inheritdoc IERC20
function allowance(address owner, address spender) public view virtual returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, value);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Skips emitting an {Approval} event indicating an allowance update. This is not
* required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `value`.
* - the caller must have allowance for ``from``'s tokens of at least
* `value`.
*/
function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, value);
_transfer(from, to, value);
return true;
}
/**
* @dev Moves a `value` amount of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _transfer(address from, address to, uint256 value) internal {
if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (to == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(from, to, value);
}
/**
* @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
* (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
* this function.
*
* Emits a {Transfer} event.
*/
function _update(address from, address to, uint256 value) internal virtual {
if (from == address(0)) {
// Overflow check required: The rest of the code assumes that totalSupply never overflows
_totalSupply += value;
} else {
uint256 fromBalance = _balances[from];
if (fromBalance < value) {
revert ERC20InsufficientBalance(from, fromBalance, value);
}
unchecked {
// Overflow not possible: value <= fromBalance <= totalSupply.
_balances[from] = fromBalance - value;
}
}
if (to == address(0)) {
unchecked {
// Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
_totalSupply -= value;
}
} else {
unchecked {
// Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
_balances[to] += value;
}
}
emit Transfer(from, to, value);
}
/**
* @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
* Relies on the `_update` mechanism
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _mint(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(address(0), account, value);
}
/**
* @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
* Relies on the `_update` mechanism.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead
*/
function _burn(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidSender(address(0));
}
_update(account, address(0), value);
}
/**
* @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
*/
function _approve(address owner, address spender, uint256 value) internal {
_approve(owner, spender, value, true);
}
/**
* @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
*
* By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
* `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
* `Approval` event during `transferFrom` operations.
*
* Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
* true using the following override:
*
* ```solidity
* function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
* super._approve(owner, spender, value, true);
* }
* ```
*
* Requirements are the same as {_approve}.
*/
function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
if (owner == address(0)) {
revert ERC20InvalidApprover(address(0));
}
if (spender == address(0)) {
revert ERC20InvalidSpender(address(0));
}
_allowances[owner][spender] = value;
if (emitEvent) {
emit Approval(owner, spender, value);
}
}
/**
* @dev Updates `owner`'s allowance for `spender` based on spent `value`.
*
* Does not update the allowance value in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Does not emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance < type(uint256).max) {
if (currentAllowance < value) {
revert ERC20InsufficientAllowance(spender, currentAllowance, value);
}
unchecked {
_approve(owner, spender, currentAllowance - value, false);
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/draft-IERC6093.sol)
pragma solidity >=0.8.4;
/**
* @dev Standard ERC-20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
*/
interface IERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC-721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
*/
interface IERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC-1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
*/
interface IERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/
error ERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}// 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;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity >=0.6.2;
import {IERC20} from "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC-20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @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);
}{
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": []
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"address","name":"creator","type":"address"}],"name":"TokenCreated","type":"event"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"desc","type":"string"},{"internalType":"string","name":"img","type":"string"}],"name":"createToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"creationFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dexRouter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeCollector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"graduationMarketCapUSD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nativeTokenPriceUSD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"f","type":"uint256"}],"name":"setCreationFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"r","type":"address"}],"name":"setDexRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"a","type":"address"}],"name":"setFeeCollector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"c","type":"uint256"}],"name":"setGraduationCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"p","type":"uint256"}],"name":"setNativePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"f","type":"uint256"}],"name":"setTradingFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"e","type":"uint256"},{"internalType":"uint256","name":"t","type":"uint256"}],"name":"setVirtualReserves","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradingFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"virtualEthReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"virtualTokenReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
608060405266038d7ea4c68000600255606460035567016345785d8a0000600555670de0b6b3a76400006006556b0295be96e640669720000000600755739b3336186a38e1b6c21955d112dbb0343ee061ee60085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550670a688906bd8b00006009553480156100a7575f5ffd5b50335f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610119575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016101109190610275565b60405180910390fd5b6101288161017560201b60201c565b50600180819055503360045f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061028e565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61025f82610236565b9050919050565b61026f81610255565b82525050565b5f6020820190506102885f830184610266565b92915050565b615da78061029b5f395ff3fe608060405260043610610138575f3560e01c80639f181b5e116100aa578063b99b3b021161006e578063b99b3b0214610404578063c372855f1461042c578063c415b95c14610454578063dce0b4e41461047e578063f2fde38b146104a8578063f72f863b146104d057610178565b80639f181b5e14610332578063a07696591461035c578063a42dce801461038c578063b0d54bcf146103b4578063b7d86225146103dc57610178565b806352b86d2b116100fc57806352b86d2b1461024c5780636ecd3d2b14610276578063715018a6146102a05780638da5cb5b146102b6578063905f80dd146102e057806392807f581461030857610178565b80630758d9241461017c5780632a324027146101a6578063343ee3b7146101d05780633ccfd60b146101fa5780634f64b2be1461021057610178565b36610178576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161016f90610e20565b60405180910390fd5b5f5ffd5b348015610187575f5ffd5b506101906104f8565b60405161019d9190610e7d565b60405180910390f35b3480156101b1575f5ffd5b506101ba61051d565b6040516101c79190610eae565b60405180910390f35b3480156101db575f5ffd5b506101e4610523565b6040516101f19190610eae565b60405180910390f35b348015610205575f5ffd5b5061020e610529565b005b34801561021b575f5ffd5b5061023660048036038101906102319190610f02565b6105e3565b6040516102439190610e7d565b60405180910390f35b348015610257575f5ffd5b5061026061061e565b60405161026d9190610eae565b60405180910390f35b348015610281575f5ffd5b5061028a610624565b6040516102979190610eae565b60405180910390f35b3480156102ab575f5ffd5b506102b461062a565b005b3480156102c1575f5ffd5b506102ca61063d565b6040516102d79190610e7d565b60405180910390f35b3480156102eb575f5ffd5b5061030660048036038101906103019190610f02565b610664565b005b348015610313575f5ffd5b5061031c6106b8565b6040516103299190610eae565b60405180910390f35b34801561033d575f5ffd5b506103466106be565b6040516103539190610eae565b60405180910390f35b61037660048036038101906103719190611069565b6106ca565b6040516103839190610e7d565b60405180910390f35b348015610397575f5ffd5b506103b260048036038101906103ad9190611167565b6108d6565b005b3480156103bf575f5ffd5b506103da60048036038101906103d59190610f02565b61098f565b005b3480156103e7575f5ffd5b5061040260048036038101906103fd9190610f02565b6109e6565b005b34801561040f575f5ffd5b5061042a60048036038101906104259190611192565b6109f8565b005b348015610437575f5ffd5b50610452600480360381019061044d9190610f02565b610a5f565b005b34801561045f575f5ffd5b50610468610ab3565b6040516104759190610e7d565b60405180910390f35b348015610489575f5ffd5b50610492610ad8565b60405161049f9190610eae565b60405180910390f35b3480156104b3575f5ffd5b506104ce60048036038101906104c99190611167565b610ade565b005b3480156104db575f5ffd5b506104f660048036038101906104f19190611167565b610b62565b005b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035481565b60075481565b610531610c1b565b5f61053a61063d565b73ffffffffffffffffffffffffffffffffffffffff164760405161055d906111fd565b5f6040518083038185875af1925050503d805f8114610597576040519150601f19603f3d011682016040523d82523d5f602084013e61059c565b606091505b50509050806105e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d79061125b565b60405180910390fd5b50565b600a81815481106105f2575f80fd5b905f5260205f20015f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60065481565b60055481565b610632610c1b565b61063b5f610ca2565b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61066c610c1b565b5f81116106ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106a5906112c3565b60405180910390fd5b8060098190555050565b60095481565b5f600a80549050905090565b5f6106d3610d63565b600254341015610718576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161070f9061132b565b60405180910390fd5b5f858560405161072790610db9565b610732929190611399565b604051809103905ff08015801561074b573d5f5f3e3d5ffd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663219f3fb985853360045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166003546005546006546007546009546040518b63ffffffff1660e01b81526004016107e59a999897969594939291906113ce565b5f604051808303815f87803b1580156107fc575f5ffd5b505af115801561080e573d5f5f3e3d5ffd5b50505050600a81908060018154018082558091505060019003905f5260205f20015f9091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65c408ab3eabf948b3319c775b6751f39394d5705851b1b63185de0d006fcc7087336040516108ba929190611476565b60405180910390a2809150506108ce610da9565b949350505050565b6108de610c1b565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361094c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610943906114ee565b60405180910390fd5b8060045f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610997610c1b565b6103e88111156109dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d390611556565b60405180910390fd5b8060038190555050565b6109ee610c1b565b8060028190555050565b610a00610c1b565b5f82118015610a0e57505f81115b610a4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a44906115be565b60405180910390fd5b81600681905550806007819055505050565b610a67610c1b565b5f8111610aa9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa090611626565b60405180910390fd5b8060058190555050565b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60025481565b610ae6610c1b565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610b56575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401610b4d9190610e7d565b60405180910390fd5b610b5f81610ca2565b50565b610b6a610c1b565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610bd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bcf906114ee565b60405180910390fd5b8060085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610c23610db2565b73ffffffffffffffffffffffffffffffffffffffff16610c4161063d565b73ffffffffffffffffffffffffffffffffffffffff1614610ca057610c64610db2565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610c979190610e7d565b60405180910390fd5b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600260015403610d9f576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600181905550565b60018081905550565b5f33905090565b61472d8061164583390190565b5f82825260208201905092915050565b7f55736520637265617465546f6b656e00000000000000000000000000000000005f82015250565b5f610e0a600f83610dc6565b9150610e1582610dd6565b602082019050919050565b5f6020820190508181035f830152610e3781610dfe565b9050919050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610e6782610e3e565b9050919050565b610e7781610e5d565b82525050565b5f602082019050610e905f830184610e6e565b92915050565b5f819050919050565b610ea881610e96565b82525050565b5f602082019050610ec15f830184610e9f565b92915050565b5f604051905090565b5f5ffd5b5f5ffd5b610ee181610e96565b8114610eeb575f5ffd5b50565b5f81359050610efc81610ed8565b92915050565b5f60208284031215610f1757610f16610ed0565b5b5f610f2484828501610eee565b91505092915050565b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610f7b82610f35565b810181811067ffffffffffffffff82111715610f9a57610f99610f45565b5b80604052505050565b5f610fac610ec7565b9050610fb88282610f72565b919050565b5f67ffffffffffffffff821115610fd757610fd6610f45565b5b610fe082610f35565b9050602081019050919050565b828183375f83830152505050565b5f61100d61100884610fbd565b610fa3565b90508281526020810184848401111561102957611028610f31565b5b611034848285610fed565b509392505050565b5f82601f8301126110505761104f610f2d565b5b8135611060848260208601610ffb565b91505092915050565b5f5f5f5f6080858703121561108157611080610ed0565b5b5f85013567ffffffffffffffff81111561109e5761109d610ed4565b5b6110aa8782880161103c565b945050602085013567ffffffffffffffff8111156110cb576110ca610ed4565b5b6110d78782880161103c565b935050604085013567ffffffffffffffff8111156110f8576110f7610ed4565b5b6111048782880161103c565b925050606085013567ffffffffffffffff81111561112557611124610ed4565b5b6111318782880161103c565b91505092959194509250565b61114681610e5d565b8114611150575f5ffd5b50565b5f813590506111618161113d565b92915050565b5f6020828403121561117c5761117b610ed0565b5b5f61118984828501611153565b91505092915050565b5f5f604083850312156111a8576111a7610ed0565b5b5f6111b585828601610eee565b92505060206111c685828601610eee565b9150509250929050565b5f81905092915050565b50565b5f6111e85f836111d0565b91506111f3826111da565b5f82019050919050565b5f611207826111dd565b9150819050919050565b7f5769746864726177206661696c656400000000000000000000000000000000005f82015250565b5f611245600f83610dc6565b915061125082611211565b602082019050919050565b5f6020820190508181035f83015261127281611239565b9050919050565b7f5a65726f207072696365000000000000000000000000000000000000000000005f82015250565b5f6112ad600a83610dc6565b91506112b882611279565b602082019050919050565b5f6020820190508181035f8301526112da816112a1565b9050919050565b7f46656500000000000000000000000000000000000000000000000000000000005f82015250565b5f611315600383610dc6565b9150611320826112e1565b602082019050919050565b5f6020820190508181035f83015261134281611309565b9050919050565b5f81519050919050565b8281835e5f83830152505050565b5f61136b82611349565b6113758185610dc6565b9350611385818560208601611353565b61138e81610f35565b840191505092915050565b5f6040820190508181035f8301526113b18185611361565b905081810360208301526113c58184611361565b90509392505050565b5f610140820190508181035f8301526113e7818d611361565b905081810360208301526113fb818c611361565b905061140a604083018b610e6e565b611417606083018a610e6e565b6114246080830189610e6e565b61143160a0830188610e9f565b61143e60c0830187610e9f565b61144b60e0830186610e9f565b611459610100830185610e9f565b611467610120830184610e9f565b9b9a5050505050505050505050565b5f6040820190508181035f83015261148e8185611361565b905061149d6020830184610e6e565b9392505050565b7f5a65726f206164647265737300000000000000000000000000000000000000005f82015250565b5f6114d8600c83610dc6565b91506114e3826114a4565b602082019050919050565b5f6020820190508181035f830152611505816114cc565b9050919050565b7f4d617820313025000000000000000000000000000000000000000000000000005f82015250565b5f611540600783610dc6565b915061154b8261150c565b602082019050919050565b5f6020820190508181035f83015261156d81611534565b9050919050565b7f5a65726f207265736572766573000000000000000000000000000000000000005f82015250565b5f6115a8600d83610dc6565b91506115b382611574565b602082019050919050565b5f6020820190508181035f8301526115d58161159c565b9050919050565b7f5a65726f206361700000000000000000000000000000000000000000000000005f82015250565b5f611610600883610dc6565b915061161b826115dc565b602082019050919050565b5f6020820190508181035f83015261163d81611604565b905091905056fe608060405234801561000f575f5ffd5b5060405161472d38038061472d833981810160405281019061003191906101f1565b818181600390816100429190610477565b5080600490816100529190610477565b50505060016005819055503360095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050610546565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610103826100bd565b810181811067ffffffffffffffff82111715610122576101216100cd565b5b80604052505050565b5f6101346100a4565b905061014082826100fa565b919050565b5f67ffffffffffffffff82111561015f5761015e6100cd565b5b610168826100bd565b9050602081019050919050565b8281835e5f83830152505050565b5f61019561019084610145565b61012b565b9050828152602081018484840111156101b1576101b06100b9565b5b6101bc848285610175565b509392505050565b5f82601f8301126101d8576101d76100b5565b5b81516101e8848260208601610183565b91505092915050565b5f5f60408385031215610207576102066100ad565b5b5f83015167ffffffffffffffff811115610224576102236100b1565b5b610230858286016101c4565b925050602083015167ffffffffffffffff811115610251576102506100b1565b5b61025d858286016101c4565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806102b557607f821691505b6020821081036102c8576102c7610271565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261032a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102ef565b61033486836102ef565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61037861037361036e8461034c565b610355565b61034c565b9050919050565b5f819050919050565b6103918361035e565b6103a561039d8261037f565b8484546102fb565b825550505050565b5f5f905090565b6103bc6103ad565b6103c7818484610388565b505050565b5b818110156103ea576103df5f826103b4565b6001810190506103cd565b5050565b601f82111561042f57610400816102ce565b610409846102e0565b81016020851015610418578190505b61042c610424856102e0565b8301826103cc565b50505b505050565b5f82821c905092915050565b5f61044f5f1984600802610434565b1980831691505092915050565b5f6104678383610440565b9150826002028217905092915050565b61048082610267565b67ffffffffffffffff811115610499576104986100cd565b5b6104a3825461029e565b6104ae8282856103ee565b5f60209050601f8311600181146104df575f84156104cd578287015190505b6104d7858261045c565b86555061053e565b601f1984166104ed866102ce565b5f5b82811015610514578489015182556001820191506020850194506020810190506104ef565b86831015610531578489015161052d601f891682610440565b8355505b6001600288020188555050505b505050505050565b6141da806105535f395ff3fe6080604052600436106101f1575f3560e01c80636ecd3d2b1161010c578063adf554991161009f578063d2178c441161006e578063d2178c4414610778578063d79875eb146107a2578063d96a094a146107ca578063dd62ed3e146107e6578063e7c2b7721461082257610287565b8063adf55499146106c0578063c415b95c146106e8578063c45a015514610712578063c6f0df9c1461073c57610287565b806392807f58116100db57806392807f581461060657806395d89b411461063057806398d5fdca1461065a578063a9059cbb1461068457610287565b80636ecd3d2b1461054c57806370a08231146105765780637284e416146105b25780639003adfe146105dc57610287565b806323b872dd11610184578063343ee3b711610153578063343ee3b7146104a657806341dfa3e4146104d0578063476343ee1461050c57806352b86d2b1461052257610287565b806323b872dd146103ec5780632a324027146104285780632ab04c7b14610452578063313ce5671461047c57610287565b8063095ea7b3116101c0578063095ea7b314610334578063135d088d1461037057806318160ddd1461039a578063219f3fb9146103c457610287565b806302d05d3f1461028b57806306fdde03146102b55780630758d924146102df5780630902f1ac1461030957610287565b366102875760105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610285576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027c90612a3d565b60405180910390fd5b005b5f5ffd5b348015610296575f5ffd5b5061029f61084c565b6040516102ac9190612a9a565b60405180910390f35b3480156102c0575f5ffd5b506102c9610871565b6040516102d69190612b13565b60405180910390f35b3480156102ea575f5ffd5b506102f3610901565b6040516103009190612a9a565b60405180910390f35b348015610314575f5ffd5b5061031d610926565b60405161032b929190612b4b565b60405180910390f35b34801561033f575f5ffd5b5061035a60048036038101906103559190612bd7565b61096b565b6040516103679190612c2f565b60405180910390f35b34801561037b575f5ffd5b5061038461098d565b6040516103919190612b13565b60405180910390f35b3480156103a5575f5ffd5b506103ae610a19565b6040516103bb9190612c48565b60405180910390f35b3480156103cf575f5ffd5b506103ea60048036038101906103e59190612d8d565b610a22565b005b3480156103f7575f5ffd5b50610412600480360381019061040d9190612e9e565b610e83565b60405161041f9190612c2f565b60405180910390f35b348015610433575f5ffd5b5061043c610eb1565b6040516104499190612c48565b60405180910390f35b34801561045d575f5ffd5b50610466610eb7565b6040516104739190612c48565b60405180910390f35b348015610487575f5ffd5b50610490610ebd565b60405161049d9190612f09565b60405180910390f35b3480156104b1575f5ffd5b506104ba610ec5565b6040516104c79190612c48565b60405180910390f35b3480156104db575f5ffd5b506104f660048036038101906104f19190612f22565b610ecb565b6040516105039190612c48565b60405180910390f35b348015610517575f5ffd5b50610520610f1c565b005b34801561052d575f5ffd5b506105366110d7565b6040516105439190612c48565b60405180910390f35b348015610557575f5ffd5b506105606110dd565b60405161056d9190612c48565b60405180910390f35b348015610581575f5ffd5b5061059c60048036038101906105979190612f4d565b6110e3565b6040516105a99190612c48565b60405180910390f35b3480156105bd575f5ffd5b506105c6611128565b6040516105d39190612b13565b60405180910390f35b3480156105e7575f5ffd5b506105f06111b4565b6040516105fd9190612c48565b60405180910390f35b348015610611575f5ffd5b5061061a6111ba565b6040516106279190612c48565b60405180910390f35b34801561063b575f5ffd5b506106446111c0565b6040516106519190612b13565b60405180910390f35b348015610665575f5ffd5b5061066e611250565b60405161067b9190612c48565b60405180910390f35b34801561068f575f5ffd5b506106aa60048036038101906106a59190612bd7565b611293565b6040516106b79190612c2f565b60405180910390f35b3480156106cb575f5ffd5b506106e660048036038101906106e19190612f22565b6112b5565b005b3480156106f3575f5ffd5b506106fc6113d0565b6040516107099190612a9a565b60405180910390f35b34801561071d575f5ffd5b506107266113f5565b6040516107339190612a9a565b60405180910390f35b348015610747575f5ffd5b50610762600480360381019061075d9190612f22565b61141a565b60405161076f9190612c48565b60405180910390f35b348015610783575f5ffd5b5061078c611467565b6040516107999190612c48565b60405180910390f35b3480156107ad575f5ffd5b506107c860048036038101906107c39190612f78565b6114b2565b005b6107e460048036038101906107df9190612f22565b611734565b005b3480156107f1575f5ffd5b5061080c60048036038101906108079190612fb6565b61199c565b6040516108199190612c48565b60405180910390f35b34801561082d575f5ffd5b50610836611a1e565b6040516108439190612c2f565b60405180910390f35b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606003805461088090613021565b80601f01602080910402602001604051908101604052809291908181526020018280546108ac90613021565b80156108f75780601f106108ce576101008083540402835291602001916108f7565b820191905f5260205f20905b8154815290600101906020018083116108da57829003601f168201915b5050505050905090565b60105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f600c54600a54610938919061307e565b91505f610943610a19565b9050600b548110156109625780600b5461095d91906130b1565b610964565b5f5b9150509091565b5f5f610975611a30565b9050610982818585611a37565b600191505092915050565b6007805461099a90613021565b80601f01602080910402602001604051908101604052809291908181526020018280546109c690613021565b8015610a115780601f106109e857610100808354040283529160200191610a11565b820191905f5260205f20905b8154815290600101906020018083116109f457829003601f168201915b505050505081565b5f600254905090565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ab1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa89061312e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff1660085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b40576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3790613196565b60405180910390fd5b8960069081610b4f9190613354565b508860079081610b5f9190613354565b508760085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508660125f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508560105f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505f73ffffffffffffffffffffffffffffffffffffffff1660125f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610caf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca69061346d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff1660105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610d3e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d35906134d5565b60405180910390fd5b6103e8851115610d83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7a9061353d565b60405180910390fd5b846011819055505f8411610dcc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc3906135a5565b60405180910390fd5b83600e819055505f83118015610de157505f82115b610e20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e179061360d565b60405180910390fd5b82600a8190555081600b819055505f8111610e70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6790613675565b60405180910390fd5b80600f8190555050505050505050505050565b5f5f610e8d611a30565b9050610e9a858285611a49565b610ea5858585611adc565b60019150509392505050565b60115481565b600c5481565b5f6012905090565b600b5481565b5f5f5f610ed6610926565b915091505f8482610ee7919061307e565b8584610ef39190613693565b610efd9190613701565b9050600c548111610f0e5780610f12565b600c545b9350505050919050565b610f24611bcc565b60125f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610fb3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610faa9061377b565b60405180910390fd5b5f60135490505f8111610ffb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff2906137e3565b60405180910390fd5b5f6013819055505f60125f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16826040516110489061382e565b5f6040518083038185875af1925050503d805f8114611082576040519150601f19603f3d011682016040523d82523d5f602084013e611087565b606091505b50509050806110cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c29061388c565b60405180910390fd5b50506110d5611c12565b565b600a5481565b600e5481565b5f5f5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b6006805461113590613021565b80601f016020809104026020016040519081016040528092919081815260200182805461116190613021565b80156111ac5780601f10611183576101008083540402835291602001916111ac565b820191905f5260205f20905b81548152906001019060200180831161118f57829003601f168201915b505050505081565b60135481565b600f5481565b6060600480546111cf90613021565b80601f01602080910402602001604051908101604052809291908181526020018280546111fb90613021565b80156112465780601f1061121d57610100808354040283529160200191611246565b820191905f5260205f20905b81548152906001019060200180831161122957829003601f168201915b5050505050905090565b5f5f5f61125b610926565b915091505f811161126c575f61128c565b80670de0b6b3a7640000836112819190613693565b61128b9190613701565b5b9250505090565b5f5f61129d611a30565b90506112aa818585611adc565b600191505092915050565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611344576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133b906138f4565b60405180910390fd5b5f8111611386576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137d9061395c565b60405180910390fd5b5f600f54905081600f819055507f40175eba104d8383c936ec96a9da297986b13a86e5b2a19296171b11533e59ce81836040516113c4929190612b4b565b60405180910390a15050565b60125f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f5f611425610926565b915091505f8483611436919061307e565b85836114429190613693565b61144c9190613701565b905081811161145b578061145d565b815b9350505050919050565b5f670de0b6b3a76400008061147c9190613693565b600f54611487611250565b61148f610a19565b6114999190613693565b6114a39190613693565b6114ad9190613701565b905090565b6114ba611bcc565b600d5f9054906101000a900460ff161580156114de5750816114db336110e3565b10155b61151d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611514906139c4565b60405180910390fd5b5f61152783610ecb565b90505f6127106011548361153b9190613693565b6115459190613701565b90505f818361155491906130b1565b9050838110158015611568575082600c5410155b6115a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159e90613a2c565b60405180910390fd5b82600c5f8282546115b891906130b1565b925050819055508160135f8282546115d0919061307e565b925050819055506040516115e390613a9e565b60405180910390207f51ebdfe330aa1c0cdfa8921a1d30675876212cfcee513cf408aec9bf96edb1848360405161161a9190612c48565b60405180910390a261162c3386611c1c565b5f3373ffffffffffffffffffffffffffffffffffffffff16826040516116519061382e565b5f6040518083038185875af1925050503d805f811461168b576040519150601f19603f3d011682016040523d82523d5f602084013e611690565b606091505b50509050806116d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116cb90613afc565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167fbac9694ac0daa55169abd117086fe32c89401d9a3b15dd1d34e55e0aa4e47a9d878460405161171c929190612b4b565b60405180910390a250505050611730611c12565b5050565b61173c611bcc565b600d5f9054906101000a900460ff1615801561175757505f34115b611796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178d906139c4565b60405180910390fd5b5f612710601154346117a89190613693565b6117b29190613701565b90505f81346117c191906130b1565b90505f6117cd8261141a565b90505f6127106107d0600b546117e39190613693565b6117ed9190613701565b905080821115611832576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182990613b64565b60405180910390fd5b84821015801561186057506b033b2e3c9fd0803ce800000082611853610a19565b61185d919061307e565b11155b61189f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161189690613bcc565b60405180910390fd5b82600c5f8282546118b0919061307e565b925050819055508360135f8282546118c8919061307e565b925050819055506040516118db90613c34565b60405180910390207f51ebdfe330aa1c0cdfa8921a1d30675876212cfcee513cf408aec9bf96edb184856040516119129190612c48565b60405180910390a26119243383611c9b565b3373ffffffffffffffffffffffffffffffffffffffff167fa9a40dec7a304e5915d11358b968c1e8d365992abf20f82285d1df1b30c8e24c838560405161196c929190612b4b565b60405180910390a2600e5461197f611467565b1061198d5761198c611d1a565b5b50505050611999611c12565b50565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b600d5f9054906101000a900460ff1681565b5f33905090565b611a4483838360016125fb565b505050565b5f611a54848461199c565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811015611ad65781811015611ac7578281836040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401611abe93929190613c48565b60405180910390fd5b611ad584848484035f6125fb565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611b4c575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401611b439190612a9a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611bbc575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401611bb39190612a9a565b60405180910390fd5b611bc78383836127ca565b505050565b600260055403611c08576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600581905550565b6001600581905550565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611c8c575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401611c839190612a9a565b60405180910390fd5b611c97825f836127ca565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611d0b575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401611d029190612a9a565b60405180910390fd5b611d165f83836127ca565b5050565b6001600d5f6101000a81548160ff0219169083151502179055505f5f90505f6064605f600c54611d4a9190613693565b611d549190613701565b90505f6002611d61610a19565b611d6b9190613701565b90506b033b2e3c9fd0803ce800000081611d83610a19565b611d8d919061307e565b1115611dce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dc590613cc7565b60405180910390fd5b611dd83082611c9b565b611e043060105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683611a37565b5f60125f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1683600c54611e4b91906130b1565b604051611e579061382e565b5f6040518083038185875af1925050503d805f8114611e91576040519150601f19603f3d011682016040523d82523d5f602084013e611e96565b606091505b5050905080611f215782600c54611ead91906130b1565b60135f828254611ebd919061307e565b92505081905550604051611ed090613d2f565b60405180910390207f51ebdfe330aa1c0cdfa8921a1d30675876212cfcee513cf408aec9bf96edb18484600c54611f0791906130b1565b604051611f149190612c48565b60405180910390a2611f7a565b604051611f2d90613d8d565b60405180910390207f51ebdfe330aa1c0cdfa8921a1d30675876212cfcee513cf408aec9bf96edb18484600c54611f6491906130b1565b604051611f719190612c48565b60405180910390a25b5f6064605a84611f8a9190613693565b611f949190613701565b90505f6064605a86611fa69190613693565b611fb09190613701565b905060105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f305d719863087868630610e1042612003919061307e565b6040518863ffffffff1660e01b815260040161202496959493929190613da1565b60606040518083038185885af19350505050801561206057506040513d601f19601f8201168201806040525081019061205d9190613e14565b60015b6120d6578460135f828254612075919061307e565b9250508190555060405161208890613eae565b60405180910390207f51ebdfe330aa1c0cdfa8921a1d30675876212cfcee513cf408aec9bf96edb184866040516120bf9190612c48565b60405180910390a26120d13085611c1c565b61259a565b84831015612119576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161211090613f0c565b60405180910390fd5b8382101561215c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161215390613f74565b60405180910390fd5b5f60105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121c7573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121eb9190613fa6565b90505f60105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015612258573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061227c9190613fa6565b73ffffffffffffffffffffffffffffffffffffffff1663e6a4390530846040518363ffffffff1660e01b81526004016122b6929190613fd1565b602060405180830381865afa1580156122d1573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122f59190613fa6565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561233257505f83115b15612594575f8173ffffffffffffffffffffffffffffffffffffffff166370a0823161dead6040518263ffffffff1660e01b81526004016123739190612a9a565b602060405180830381865afa15801561238e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123b29190613ff8565b90505f8273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb61dead876040518363ffffffff1660e01b81526004016123f2929190614023565b6020604051808303815f875af115801561240e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124329190614074565b905080612474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161246b906140e9565b60405180910390fd5b5f8373ffffffffffffffffffffffffffffffffffffffff166370a0823161dead6040518263ffffffff1660e01b81526004016124b09190612a9a565b602060405180830381865afa1580156124cb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124ef9190613ff8565b905085836124fd919061307e565b811461253e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161253590614151565b60405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff167fe0618a3fe7eb627a24df9d59eb05ba9750f8feb54aeb8909fdd35c62efd34572876040516125849190612c48565b60405180910390a260019d505050505b50505050505b5f600c819055503073ffffffffffffffffffffffffffffffffffffffff167f2f0a8c77fb8ab6f607336131943410589c9f0456c3d9a3f310f7143a7bc1d9198686896040516125eb9392919061416f565b60405180910390a2505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361266b575f6040517fe602df050000000000000000000000000000000000000000000000000000000081526004016126629190612a9a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036126db575f6040517f94280d620000000000000000000000000000000000000000000000000000000081526004016126d29190612a9a565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555080156127c4578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516127bb9190612c48565b60405180910390a35b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361281a578060025f82825461280e919061307e565b925050819055506128e8565b5f5f5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050818110156128a3578381836040517fe450d38c00000000000000000000000000000000000000000000000000000000815260040161289a93929190613c48565b60405180910390fd5b8181035f5f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361292f578060025f8282540392505081905550612979565b805f5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516129d69190612c48565b60405180910390a3505050565b5f82825260208201905092915050565b7f44697265637420455448206e6f7420616c6c6f776564000000000000000000005f82015250565b5f612a276016836129e3565b9150612a32826129f3565b602082019050919050565b5f6020820190508181035f830152612a5481612a1b565b9050919050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612a8482612a5b565b9050919050565b612a9481612a7a565b82525050565b5f602082019050612aad5f830184612a8b565b92915050565b5f81519050919050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f612ae582612ab3565b612aef81856129e3565b9350612aff818560208601612abd565b612b0881612acb565b840191505092915050565b5f6020820190508181035f830152612b2b8184612adb565b905092915050565b5f819050919050565b612b4581612b33565b82525050565b5f604082019050612b5e5f830185612b3c565b612b6b6020830184612b3c565b9392505050565b5f604051905090565b5f5ffd5b5f5ffd5b612b8c81612a7a565b8114612b96575f5ffd5b50565b5f81359050612ba781612b83565b92915050565b612bb681612b33565b8114612bc0575f5ffd5b50565b5f81359050612bd181612bad565b92915050565b5f5f60408385031215612bed57612bec612b7b565b5b5f612bfa85828601612b99565b9250506020612c0b85828601612bc3565b9150509250929050565b5f8115159050919050565b612c2981612c15565b82525050565b5f602082019050612c425f830184612c20565b92915050565b5f602082019050612c5b5f830184612b3c565b92915050565b5f5ffd5b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612c9f82612acb565b810181811067ffffffffffffffff82111715612cbe57612cbd612c69565b5b80604052505050565b5f612cd0612b72565b9050612cdc8282612c96565b919050565b5f67ffffffffffffffff821115612cfb57612cfa612c69565b5b612d0482612acb565b9050602081019050919050565b828183375f83830152505050565b5f612d31612d2c84612ce1565b612cc7565b905082815260208101848484011115612d4d57612d4c612c65565b5b612d58848285612d11565b509392505050565b5f82601f830112612d7457612d73612c61565b5b8135612d84848260208601612d1f565b91505092915050565b5f5f5f5f5f5f5f5f5f5f6101408b8d031215612dac57612dab612b7b565b5b5f8b013567ffffffffffffffff811115612dc957612dc8612b7f565b5b612dd58d828e01612d60565b9a505060208b013567ffffffffffffffff811115612df657612df5612b7f565b5b612e028d828e01612d60565b9950506040612e138d828e01612b99565b9850506060612e248d828e01612b99565b9750506080612e358d828e01612b99565b96505060a0612e468d828e01612bc3565b95505060c0612e578d828e01612bc3565b94505060e0612e688d828e01612bc3565b935050610100612e7a8d828e01612bc3565b925050610120612e8c8d828e01612bc3565b9150509295989b9194979a5092959850565b5f5f5f60608486031215612eb557612eb4612b7b565b5b5f612ec286828701612b99565b9350506020612ed386828701612b99565b9250506040612ee486828701612bc3565b9150509250925092565b5f60ff82169050919050565b612f0381612eee565b82525050565b5f602082019050612f1c5f830184612efa565b92915050565b5f60208284031215612f3757612f36612b7b565b5b5f612f4484828501612bc3565b91505092915050565b5f60208284031215612f6257612f61612b7b565b5b5f612f6f84828501612b99565b91505092915050565b5f5f60408385031215612f8e57612f8d612b7b565b5b5f612f9b85828601612bc3565b9250506020612fac85828601612bc3565b9150509250929050565b5f5f60408385031215612fcc57612fcb612b7b565b5b5f612fd985828601612b99565b9250506020612fea85828601612b99565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061303857607f821691505b60208210810361304b5761304a612ff4565b5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61308882612b33565b915061309383612b33565b92508282019050808211156130ab576130aa613051565b5b92915050565b5f6130bb82612b33565b91506130c683612b33565b92508282039050818111156130de576130dd613051565b5b92915050565b7f4f6e6c7920666163746f727900000000000000000000000000000000000000005f82015250565b5f613118600c836129e3565b9150613123826130e4565b602082019050919050565b5f6020820190508181035f8301526131458161310c565b9050919050565b7f416c726561647920696e697469616c697a6564000000000000000000000000005f82015250565b5f6131806013836129e3565b915061318b8261314c565b602082019050919050565b5f6020820190508181035f8301526131ad81613174565b9050919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026132107fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826131d5565b61321a86836131d5565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61325561325061324b84612b33565b613232565b612b33565b9050919050565b5f819050919050565b61326e8361323b565b61328261327a8261325c565b8484546131e1565b825550505050565b5f5f905090565b61329961328a565b6132a4818484613265565b505050565b5b818110156132c7576132bc5f82613291565b6001810190506132aa565b5050565b601f82111561330c576132dd816131b4565b6132e6846131c6565b810160208510156132f5578190505b613309613301856131c6565b8301826132a9565b50505b505050565b5f82821c905092915050565b5f61332c5f1984600802613311565b1980831691505092915050565b5f613344838361331d565b9150826002028217905092915050565b61335d82612ab3565b67ffffffffffffffff81111561337657613375612c69565b5b6133808254613021565b61338b8282856132cb565b5f60209050601f8311600181146133bc575f84156133aa578287015190505b6133b48582613339565b86555061341b565b601f1984166133ca866131b4565b5f5b828110156133f1578489015182556001820191506020850194506020810190506133cc565b8683101561340e578489015161340a601f89168261331d565b8355505b6001600288020188555050505b505050505050565b7f5a65726f2066656520636f6c6c6563746f7200000000000000000000000000005f82015250565b5f6134576012836129e3565b915061346282613423565b602082019050919050565b5f6020820190508181035f8301526134848161344b565b9050919050565b7f5a65726f20726f757465720000000000000000000000000000000000000000005f82015250565b5f6134bf600b836129e3565b91506134ca8261348b565b602082019050919050565b5f6020820190508181035f8301526134ec816134b3565b9050919050565b7f46656520746f6f206869676800000000000000000000000000000000000000005f82015250565b5f613527600c836129e3565b9150613532826134f3565b602082019050919050565b5f6020820190508181035f8301526135548161351b565b9050919050565b7f5a65726f2067726164756174696f6e20636170000000000000000000000000005f82015250565b5f61358f6013836129e3565b915061359a8261355b565b602082019050919050565b5f6020820190508181035f8301526135bc81613583565b9050919050565b7f5a65726f207669727475616c20726573657276657300000000000000000000005f82015250565b5f6135f76015836129e3565b9150613602826135c3565b602082019050919050565b5f6020820190508181035f830152613624816135eb565b9050919050565b7f5a65726f206e61746976652070726963650000000000000000000000000000005f82015250565b5f61365f6011836129e3565b915061366a8261362b565b602082019050919050565b5f6020820190508181035f83015261368c81613653565b9050919050565b5f61369d82612b33565b91506136a883612b33565b92508282026136b681612b33565b915082820484148315176136cd576136cc613051565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61370b82612b33565b915061371683612b33565b925082613726576137256136d4565b5b828204905092915050565b7f436f6c6c6563746f7200000000000000000000000000000000000000000000005f82015250565b5f6137656009836129e3565b915061377082613731565b602082019050919050565b5f6020820190508181035f83015261379281613759565b9050919050565b7f4e6f2066656573000000000000000000000000000000000000000000000000005f82015250565b5f6137cd6007836129e3565b91506137d882613799565b602082019050919050565b5f6020820190508181035f8301526137fa816137c1565b9050919050565b5f81905092915050565b50565b5f6138195f83613801565b91506138248261380b565b5f82019050919050565b5f6138388261380e565b9150819050919050565b7f5472616e73666572206661696c656400000000000000000000000000000000005f82015250565b5f613876600f836129e3565b915061388182613842565b602082019050919050565b5f6020820190508181035f8301526138a38161386a565b9050919050565b7f466163746f7279000000000000000000000000000000000000000000000000005f82015250565b5f6138de6007836129e3565b91506138e9826138aa565b602082019050919050565b5f6020820190508181035f83015261390b816138d2565b9050919050565b7f5a65726f207072696365000000000000000000000000000000000000000000005f82015250565b5f613946600a836129e3565b915061395182613912565b602082019050919050565b5f6020820190508181035f8301526139738161393a565b9050919050565b7f496e76616c6964000000000000000000000000000000000000000000000000005f82015250565b5f6139ae6007836129e3565b91506139b98261397a565b602082019050919050565b5f6020820190508181035f8301526139db816139a2565b9050919050565b7f536c6970706167652f4c697100000000000000000000000000000000000000005f82015250565b5f613a16600c836129e3565b9150613a21826139e2565b602082019050919050565b5f6020820190508181035f830152613a4381613a0a565b9050919050565b5f81905092915050565b7f73656c6c000000000000000000000000000000000000000000000000000000005f82015250565b5f613a88600483613a4a565b9150613a9382613a54565b600482019050919050565b5f613aa882613a7c565b9150819050919050565b7f455448207472616e73666572206661696c6564000000000000000000000000005f82015250565b5f613ae66013836129e3565b9150613af182613ab2565b602082019050919050565b5f6020820190508181035f830152613b1381613ada565b9050919050565b7f45786365656473206d61782062757900000000000000000000000000000000005f82015250565b5f613b4e600f836129e3565b9150613b5982613b1a565b602082019050919050565b5f6020820190508181035f830152613b7b81613b42565b9050919050565b7f536c6970706167652f43617000000000000000000000000000000000000000005f82015250565b5f613bb6600c836129e3565b9150613bc182613b82565b602082019050919050565b5f6020820190508181035f830152613be381613baa565b9050919050565b7f62757900000000000000000000000000000000000000000000000000000000005f82015250565b5f613c1e600383613a4a565b9150613c2982613bea565b600382019050919050565b5f613c3e82613c12565b9150819050919050565b5f606082019050613c5b5f830186612a8b565b613c686020830185612b3c565b613c756040830184612b3c565b949350505050565b7f47726164756174696f6e206578636565647320636170000000000000000000005f82015250565b5f613cb16016836129e3565b9150613cbc82613c7d565b602082019050919050565b5f6020820190508181035f830152613cde81613ca5565b9050919050565b7f67726164756174696f6e5f6661696c65640000000000000000000000000000005f82015250565b5f613d19601183613a4a565b9150613d2482613ce5565b601182019050919050565b5f613d3982613d0d565b9150819050919050565b7f67726164756174696f6e000000000000000000000000000000000000000000005f82015250565b5f613d77600a83613a4a565b9150613d8282613d43565b600a82019050919050565b5f613d9782613d6b565b9150819050919050565b5f60c082019050613db45f830189612a8b565b613dc16020830188612b3c565b613dce6040830187612b3c565b613ddb6060830186612b3c565b613de86080830185612a8b565b613df560a0830184612b3c565b979650505050505050565b5f81519050613e0e81612bad565b92915050565b5f5f5f60608486031215613e2b57613e2a612b7b565b5b5f613e3886828701613e00565b9350506020613e4986828701613e00565b9250506040613e5a86828701613e00565b9150509250925092565b7f6c69717569646974795f6661696c6564000000000000000000000000000000005f82015250565b5f613e98601083613a4a565b9150613ea382613e64565b601082019050919050565b5f613eb882613e8c565b9150819050919050565b7f496e73756666696369656e7420746f6b656e206c6971756964697479000000005f82015250565b5f613ef6601c836129e3565b9150613f0182613ec2565b602082019050919050565b5f6020820190508181035f830152613f2381613eea565b9050919050565b7f496e73756666696369656e7420455448206c69717569646974790000000000005f82015250565b5f613f5e601a836129e3565b9150613f6982613f2a565b602082019050919050565b5f6020820190508181035f830152613f8b81613f52565b9050919050565b5f81519050613fa081612b83565b92915050565b5f60208284031215613fbb57613fba612b7b565b5b5f613fc884828501613f92565b91505092915050565b5f604082019050613fe45f830185612a8b565b613ff16020830184612a8b565b9392505050565b5f6020828403121561400d5761400c612b7b565b5b5f61401a84828501613e00565b91505092915050565b5f6040820190506140365f830185612a8b565b6140436020830184612b3c565b9392505050565b61405381612c15565b811461405d575f5ffd5b50565b5f8151905061406e8161404a565b92915050565b5f6020828403121561408957614088612b7b565b5b5f61409684828501614060565b91505092915050565b7f4c50204275726e206661696c65640000000000000000000000000000000000005f82015250565b5f6140d3600e836129e3565b91506140de8261409f565b602082019050919050565b5f6020820190508181035f830152614100816140c7565b9050919050565b7f4c5020746f6b656e73206e6f74206275726e65640000000000000000000000005f82015250565b5f61413b6014836129e3565b915061414682614107565b602082019050919050565b5f6020820190508181035f8301526141688161412f565b9050919050565b5f6060820190506141825f830186612b3c565b61418f6020830185612b3c565b61419c6040830184612c20565b94935050505056fea2646970667358221220b71678527f05b79a7bd238a7a4b0af4e15aaf09cd210b68a3b2bc6240d7e518d64736f6c634300081f0033a2646970667358221220d0e63d1b66f14f71e93168bcfb2a4622802b0144924a3492ba56692ba4ae8ddb64736f6c634300081f0033
Deployed Bytecode
0x608060405260043610610138575f3560e01c80639f181b5e116100aa578063b99b3b021161006e578063b99b3b0214610404578063c372855f1461042c578063c415b95c14610454578063dce0b4e41461047e578063f2fde38b146104a8578063f72f863b146104d057610178565b80639f181b5e14610332578063a07696591461035c578063a42dce801461038c578063b0d54bcf146103b4578063b7d86225146103dc57610178565b806352b86d2b116100fc57806352b86d2b1461024c5780636ecd3d2b14610276578063715018a6146102a05780638da5cb5b146102b6578063905f80dd146102e057806392807f581461030857610178565b80630758d9241461017c5780632a324027146101a6578063343ee3b7146101d05780633ccfd60b146101fa5780634f64b2be1461021057610178565b36610178576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161016f90610e20565b60405180910390fd5b5f5ffd5b348015610187575f5ffd5b506101906104f8565b60405161019d9190610e7d565b60405180910390f35b3480156101b1575f5ffd5b506101ba61051d565b6040516101c79190610eae565b60405180910390f35b3480156101db575f5ffd5b506101e4610523565b6040516101f19190610eae565b60405180910390f35b348015610205575f5ffd5b5061020e610529565b005b34801561021b575f5ffd5b5061023660048036038101906102319190610f02565b6105e3565b6040516102439190610e7d565b60405180910390f35b348015610257575f5ffd5b5061026061061e565b60405161026d9190610eae565b60405180910390f35b348015610281575f5ffd5b5061028a610624565b6040516102979190610eae565b60405180910390f35b3480156102ab575f5ffd5b506102b461062a565b005b3480156102c1575f5ffd5b506102ca61063d565b6040516102d79190610e7d565b60405180910390f35b3480156102eb575f5ffd5b5061030660048036038101906103019190610f02565b610664565b005b348015610313575f5ffd5b5061031c6106b8565b6040516103299190610eae565b60405180910390f35b34801561033d575f5ffd5b506103466106be565b6040516103539190610eae565b60405180910390f35b61037660048036038101906103719190611069565b6106ca565b6040516103839190610e7d565b60405180910390f35b348015610397575f5ffd5b506103b260048036038101906103ad9190611167565b6108d6565b005b3480156103bf575f5ffd5b506103da60048036038101906103d59190610f02565b61098f565b005b3480156103e7575f5ffd5b5061040260048036038101906103fd9190610f02565b6109e6565b005b34801561040f575f5ffd5b5061042a60048036038101906104259190611192565b6109f8565b005b348015610437575f5ffd5b50610452600480360381019061044d9190610f02565b610a5f565b005b34801561045f575f5ffd5b50610468610ab3565b6040516104759190610e7d565b60405180910390f35b348015610489575f5ffd5b50610492610ad8565b60405161049f9190610eae565b60405180910390f35b3480156104b3575f5ffd5b506104ce60048036038101906104c99190611167565b610ade565b005b3480156104db575f5ffd5b506104f660048036038101906104f19190611167565b610b62565b005b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035481565b60075481565b610531610c1b565b5f61053a61063d565b73ffffffffffffffffffffffffffffffffffffffff164760405161055d906111fd565b5f6040518083038185875af1925050503d805f8114610597576040519150601f19603f3d011682016040523d82523d5f602084013e61059c565b606091505b50509050806105e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d79061125b565b60405180910390fd5b50565b600a81815481106105f2575f80fd5b905f5260205f20015f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60065481565b60055481565b610632610c1b565b61063b5f610ca2565b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61066c610c1b565b5f81116106ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106a5906112c3565b60405180910390fd5b8060098190555050565b60095481565b5f600a80549050905090565b5f6106d3610d63565b600254341015610718576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161070f9061132b565b60405180910390fd5b5f858560405161072790610db9565b610732929190611399565b604051809103905ff08015801561074b573d5f5f3e3d5ffd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663219f3fb985853360045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166003546005546006546007546009546040518b63ffffffff1660e01b81526004016107e59a999897969594939291906113ce565b5f604051808303815f87803b1580156107fc575f5ffd5b505af115801561080e573d5f5f3e3d5ffd5b50505050600a81908060018154018082558091505060019003905f5260205f20015f9091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f65c408ab3eabf948b3319c775b6751f39394d5705851b1b63185de0d006fcc7087336040516108ba929190611476565b60405180910390a2809150506108ce610da9565b949350505050565b6108de610c1b565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361094c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610943906114ee565b60405180910390fd5b8060045f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610997610c1b565b6103e88111156109dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d390611556565b60405180910390fd5b8060038190555050565b6109ee610c1b565b8060028190555050565b610a00610c1b565b5f82118015610a0e57505f81115b610a4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a44906115be565b60405180910390fd5b81600681905550806007819055505050565b610a67610c1b565b5f8111610aa9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa090611626565b60405180910390fd5b8060058190555050565b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60025481565b610ae6610c1b565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610b56575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401610b4d9190610e7d565b60405180910390fd5b610b5f81610ca2565b50565b610b6a610c1b565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610bd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bcf906114ee565b60405180910390fd5b8060085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610c23610db2565b73ffffffffffffffffffffffffffffffffffffffff16610c4161063d565b73ffffffffffffffffffffffffffffffffffffffff1614610ca057610c64610db2565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610c979190610e7d565b60405180910390fd5b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600260015403610d9f576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600181905550565b60018081905550565b5f33905090565b61472d8061164583390190565b5f82825260208201905092915050565b7f55736520637265617465546f6b656e00000000000000000000000000000000005f82015250565b5f610e0a600f83610dc6565b9150610e1582610dd6565b602082019050919050565b5f6020820190508181035f830152610e3781610dfe565b9050919050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610e6782610e3e565b9050919050565b610e7781610e5d565b82525050565b5f602082019050610e905f830184610e6e565b92915050565b5f819050919050565b610ea881610e96565b82525050565b5f602082019050610ec15f830184610e9f565b92915050565b5f604051905090565b5f5ffd5b5f5ffd5b610ee181610e96565b8114610eeb575f5ffd5b50565b5f81359050610efc81610ed8565b92915050565b5f60208284031215610f1757610f16610ed0565b5b5f610f2484828501610eee565b91505092915050565b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610f7b82610f35565b810181811067ffffffffffffffff82111715610f9a57610f99610f45565b5b80604052505050565b5f610fac610ec7565b9050610fb88282610f72565b919050565b5f67ffffffffffffffff821115610fd757610fd6610f45565b5b610fe082610f35565b9050602081019050919050565b828183375f83830152505050565b5f61100d61100884610fbd565b610fa3565b90508281526020810184848401111561102957611028610f31565b5b611034848285610fed565b509392505050565b5f82601f8301126110505761104f610f2d565b5b8135611060848260208601610ffb565b91505092915050565b5f5f5f5f6080858703121561108157611080610ed0565b5b5f85013567ffffffffffffffff81111561109e5761109d610ed4565b5b6110aa8782880161103c565b945050602085013567ffffffffffffffff8111156110cb576110ca610ed4565b5b6110d78782880161103c565b935050604085013567ffffffffffffffff8111156110f8576110f7610ed4565b5b6111048782880161103c565b925050606085013567ffffffffffffffff81111561112557611124610ed4565b5b6111318782880161103c565b91505092959194509250565b61114681610e5d565b8114611150575f5ffd5b50565b5f813590506111618161113d565b92915050565b5f6020828403121561117c5761117b610ed0565b5b5f61118984828501611153565b91505092915050565b5f5f604083850312156111a8576111a7610ed0565b5b5f6111b585828601610eee565b92505060206111c685828601610eee565b9150509250929050565b5f81905092915050565b50565b5f6111e85f836111d0565b91506111f3826111da565b5f82019050919050565b5f611207826111dd565b9150819050919050565b7f5769746864726177206661696c656400000000000000000000000000000000005f82015250565b5f611245600f83610dc6565b915061125082611211565b602082019050919050565b5f6020820190508181035f83015261127281611239565b9050919050565b7f5a65726f207072696365000000000000000000000000000000000000000000005f82015250565b5f6112ad600a83610dc6565b91506112b882611279565b602082019050919050565b5f6020820190508181035f8301526112da816112a1565b9050919050565b7f46656500000000000000000000000000000000000000000000000000000000005f82015250565b5f611315600383610dc6565b9150611320826112e1565b602082019050919050565b5f6020820190508181035f83015261134281611309565b9050919050565b5f81519050919050565b8281835e5f83830152505050565b5f61136b82611349565b6113758185610dc6565b9350611385818560208601611353565b61138e81610f35565b840191505092915050565b5f6040820190508181035f8301526113b18185611361565b905081810360208301526113c58184611361565b90509392505050565b5f610140820190508181035f8301526113e7818d611361565b905081810360208301526113fb818c611361565b905061140a604083018b610e6e565b611417606083018a610e6e565b6114246080830189610e6e565b61143160a0830188610e9f565b61143e60c0830187610e9f565b61144b60e0830186610e9f565b611459610100830185610e9f565b611467610120830184610e9f565b9b9a5050505050505050505050565b5f6040820190508181035f83015261148e8185611361565b905061149d6020830184610e6e565b9392505050565b7f5a65726f206164647265737300000000000000000000000000000000000000005f82015250565b5f6114d8600c83610dc6565b91506114e3826114a4565b602082019050919050565b5f6020820190508181035f830152611505816114cc565b9050919050565b7f4d617820313025000000000000000000000000000000000000000000000000005f82015250565b5f611540600783610dc6565b915061154b8261150c565b602082019050919050565b5f6020820190508181035f83015261156d81611534565b9050919050565b7f5a65726f207265736572766573000000000000000000000000000000000000005f82015250565b5f6115a8600d83610dc6565b91506115b382611574565b602082019050919050565b5f6020820190508181035f8301526115d58161159c565b9050919050565b7f5a65726f206361700000000000000000000000000000000000000000000000005f82015250565b5f611610600883610dc6565b915061161b826115dc565b602082019050919050565b5f6020820190508181035f83015261163d81611604565b905091905056fe608060405234801561000f575f5ffd5b5060405161472d38038061472d833981810160405281019061003191906101f1565b818181600390816100429190610477565b5080600490816100529190610477565b50505060016005819055503360095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050610546565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610103826100bd565b810181811067ffffffffffffffff82111715610122576101216100cd565b5b80604052505050565b5f6101346100a4565b905061014082826100fa565b919050565b5f67ffffffffffffffff82111561015f5761015e6100cd565b5b610168826100bd565b9050602081019050919050565b8281835e5f83830152505050565b5f61019561019084610145565b61012b565b9050828152602081018484840111156101b1576101b06100b9565b5b6101bc848285610175565b509392505050565b5f82601f8301126101d8576101d76100b5565b5b81516101e8848260208601610183565b91505092915050565b5f5f60408385031215610207576102066100ad565b5b5f83015167ffffffffffffffff811115610224576102236100b1565b5b610230858286016101c4565b925050602083015167ffffffffffffffff811115610251576102506100b1565b5b61025d858286016101c4565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806102b557607f821691505b6020821081036102c8576102c7610271565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261032a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102ef565b61033486836102ef565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61037861037361036e8461034c565b610355565b61034c565b9050919050565b5f819050919050565b6103918361035e565b6103a561039d8261037f565b8484546102fb565b825550505050565b5f5f905090565b6103bc6103ad565b6103c7818484610388565b505050565b5b818110156103ea576103df5f826103b4565b6001810190506103cd565b5050565b601f82111561042f57610400816102ce565b610409846102e0565b81016020851015610418578190505b61042c610424856102e0565b8301826103cc565b50505b505050565b5f82821c905092915050565b5f61044f5f1984600802610434565b1980831691505092915050565b5f6104678383610440565b9150826002028217905092915050565b61048082610267565b67ffffffffffffffff811115610499576104986100cd565b5b6104a3825461029e565b6104ae8282856103ee565b5f60209050601f8311600181146104df575f84156104cd578287015190505b6104d7858261045c565b86555061053e565b601f1984166104ed866102ce565b5f5b82811015610514578489015182556001820191506020850194506020810190506104ef565b86831015610531578489015161052d601f891682610440565b8355505b6001600288020188555050505b505050505050565b6141da806105535f395ff3fe6080604052600436106101f1575f3560e01c80636ecd3d2b1161010c578063adf554991161009f578063d2178c441161006e578063d2178c4414610778578063d79875eb146107a2578063d96a094a146107ca578063dd62ed3e146107e6578063e7c2b7721461082257610287565b8063adf55499146106c0578063c415b95c146106e8578063c45a015514610712578063c6f0df9c1461073c57610287565b806392807f58116100db57806392807f581461060657806395d89b411461063057806398d5fdca1461065a578063a9059cbb1461068457610287565b80636ecd3d2b1461054c57806370a08231146105765780637284e416146105b25780639003adfe146105dc57610287565b806323b872dd11610184578063343ee3b711610153578063343ee3b7146104a657806341dfa3e4146104d0578063476343ee1461050c57806352b86d2b1461052257610287565b806323b872dd146103ec5780632a324027146104285780632ab04c7b14610452578063313ce5671461047c57610287565b8063095ea7b3116101c0578063095ea7b314610334578063135d088d1461037057806318160ddd1461039a578063219f3fb9146103c457610287565b806302d05d3f1461028b57806306fdde03146102b55780630758d924146102df5780630902f1ac1461030957610287565b366102875760105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610285576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027c90612a3d565b60405180910390fd5b005b5f5ffd5b348015610296575f5ffd5b5061029f61084c565b6040516102ac9190612a9a565b60405180910390f35b3480156102c0575f5ffd5b506102c9610871565b6040516102d69190612b13565b60405180910390f35b3480156102ea575f5ffd5b506102f3610901565b6040516103009190612a9a565b60405180910390f35b348015610314575f5ffd5b5061031d610926565b60405161032b929190612b4b565b60405180910390f35b34801561033f575f5ffd5b5061035a60048036038101906103559190612bd7565b61096b565b6040516103679190612c2f565b60405180910390f35b34801561037b575f5ffd5b5061038461098d565b6040516103919190612b13565b60405180910390f35b3480156103a5575f5ffd5b506103ae610a19565b6040516103bb9190612c48565b60405180910390f35b3480156103cf575f5ffd5b506103ea60048036038101906103e59190612d8d565b610a22565b005b3480156103f7575f5ffd5b50610412600480360381019061040d9190612e9e565b610e83565b60405161041f9190612c2f565b60405180910390f35b348015610433575f5ffd5b5061043c610eb1565b6040516104499190612c48565b60405180910390f35b34801561045d575f5ffd5b50610466610eb7565b6040516104739190612c48565b60405180910390f35b348015610487575f5ffd5b50610490610ebd565b60405161049d9190612f09565b60405180910390f35b3480156104b1575f5ffd5b506104ba610ec5565b6040516104c79190612c48565b60405180910390f35b3480156104db575f5ffd5b506104f660048036038101906104f19190612f22565b610ecb565b6040516105039190612c48565b60405180910390f35b348015610517575f5ffd5b50610520610f1c565b005b34801561052d575f5ffd5b506105366110d7565b6040516105439190612c48565b60405180910390f35b348015610557575f5ffd5b506105606110dd565b60405161056d9190612c48565b60405180910390f35b348015610581575f5ffd5b5061059c60048036038101906105979190612f4d565b6110e3565b6040516105a99190612c48565b60405180910390f35b3480156105bd575f5ffd5b506105c6611128565b6040516105d39190612b13565b60405180910390f35b3480156105e7575f5ffd5b506105f06111b4565b6040516105fd9190612c48565b60405180910390f35b348015610611575f5ffd5b5061061a6111ba565b6040516106279190612c48565b60405180910390f35b34801561063b575f5ffd5b506106446111c0565b6040516106519190612b13565b60405180910390f35b348015610665575f5ffd5b5061066e611250565b60405161067b9190612c48565b60405180910390f35b34801561068f575f5ffd5b506106aa60048036038101906106a59190612bd7565b611293565b6040516106b79190612c2f565b60405180910390f35b3480156106cb575f5ffd5b506106e660048036038101906106e19190612f22565b6112b5565b005b3480156106f3575f5ffd5b506106fc6113d0565b6040516107099190612a9a565b60405180910390f35b34801561071d575f5ffd5b506107266113f5565b6040516107339190612a9a565b60405180910390f35b348015610747575f5ffd5b50610762600480360381019061075d9190612f22565b61141a565b60405161076f9190612c48565b60405180910390f35b348015610783575f5ffd5b5061078c611467565b6040516107999190612c48565b60405180910390f35b3480156107ad575f5ffd5b506107c860048036038101906107c39190612f78565b6114b2565b005b6107e460048036038101906107df9190612f22565b611734565b005b3480156107f1575f5ffd5b5061080c60048036038101906108079190612fb6565b61199c565b6040516108199190612c48565b60405180910390f35b34801561082d575f5ffd5b50610836611a1e565b6040516108439190612c2f565b60405180910390f35b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606003805461088090613021565b80601f01602080910402602001604051908101604052809291908181526020018280546108ac90613021565b80156108f75780601f106108ce576101008083540402835291602001916108f7565b820191905f5260205f20905b8154815290600101906020018083116108da57829003601f168201915b5050505050905090565b60105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f600c54600a54610938919061307e565b91505f610943610a19565b9050600b548110156109625780600b5461095d91906130b1565b610964565b5f5b9150509091565b5f5f610975611a30565b9050610982818585611a37565b600191505092915050565b6007805461099a90613021565b80601f01602080910402602001604051908101604052809291908181526020018280546109c690613021565b8015610a115780601f106109e857610100808354040283529160200191610a11565b820191905f5260205f20905b8154815290600101906020018083116109f457829003601f168201915b505050505081565b5f600254905090565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ab1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa89061312e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff1660085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b40576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3790613196565b60405180910390fd5b8960069081610b4f9190613354565b508860079081610b5f9190613354565b508760085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508660125f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508560105f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505f73ffffffffffffffffffffffffffffffffffffffff1660125f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610caf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca69061346d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff1660105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610d3e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d35906134d5565b60405180910390fd5b6103e8851115610d83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7a9061353d565b60405180910390fd5b846011819055505f8411610dcc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc3906135a5565b60405180910390fd5b83600e819055505f83118015610de157505f82115b610e20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e179061360d565b60405180910390fd5b82600a8190555081600b819055505f8111610e70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6790613675565b60405180910390fd5b80600f8190555050505050505050505050565b5f5f610e8d611a30565b9050610e9a858285611a49565b610ea5858585611adc565b60019150509392505050565b60115481565b600c5481565b5f6012905090565b600b5481565b5f5f5f610ed6610926565b915091505f8482610ee7919061307e565b8584610ef39190613693565b610efd9190613701565b9050600c548111610f0e5780610f12565b600c545b9350505050919050565b610f24611bcc565b60125f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610fb3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610faa9061377b565b60405180910390fd5b5f60135490505f8111610ffb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff2906137e3565b60405180910390fd5b5f6013819055505f60125f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16826040516110489061382e565b5f6040518083038185875af1925050503d805f8114611082576040519150601f19603f3d011682016040523d82523d5f602084013e611087565b606091505b50509050806110cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c29061388c565b60405180910390fd5b50506110d5611c12565b565b600a5481565b600e5481565b5f5f5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b6006805461113590613021565b80601f016020809104026020016040519081016040528092919081815260200182805461116190613021565b80156111ac5780601f10611183576101008083540402835291602001916111ac565b820191905f5260205f20905b81548152906001019060200180831161118f57829003601f168201915b505050505081565b60135481565b600f5481565b6060600480546111cf90613021565b80601f01602080910402602001604051908101604052809291908181526020018280546111fb90613021565b80156112465780601f1061121d57610100808354040283529160200191611246565b820191905f5260205f20905b81548152906001019060200180831161122957829003601f168201915b5050505050905090565b5f5f5f61125b610926565b915091505f811161126c575f61128c565b80670de0b6b3a7640000836112819190613693565b61128b9190613701565b5b9250505090565b5f5f61129d611a30565b90506112aa818585611adc565b600191505092915050565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611344576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133b906138f4565b60405180910390fd5b5f8111611386576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137d9061395c565b60405180910390fd5b5f600f54905081600f819055507f40175eba104d8383c936ec96a9da297986b13a86e5b2a19296171b11533e59ce81836040516113c4929190612b4b565b60405180910390a15050565b60125f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f5f611425610926565b915091505f8483611436919061307e565b85836114429190613693565b61144c9190613701565b905081811161145b578061145d565b815b9350505050919050565b5f670de0b6b3a76400008061147c9190613693565b600f54611487611250565b61148f610a19565b6114999190613693565b6114a39190613693565b6114ad9190613701565b905090565b6114ba611bcc565b600d5f9054906101000a900460ff161580156114de5750816114db336110e3565b10155b61151d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611514906139c4565b60405180910390fd5b5f61152783610ecb565b90505f6127106011548361153b9190613693565b6115459190613701565b90505f818361155491906130b1565b9050838110158015611568575082600c5410155b6115a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159e90613a2c565b60405180910390fd5b82600c5f8282546115b891906130b1565b925050819055508160135f8282546115d0919061307e565b925050819055506040516115e390613a9e565b60405180910390207f51ebdfe330aa1c0cdfa8921a1d30675876212cfcee513cf408aec9bf96edb1848360405161161a9190612c48565b60405180910390a261162c3386611c1c565b5f3373ffffffffffffffffffffffffffffffffffffffff16826040516116519061382e565b5f6040518083038185875af1925050503d805f811461168b576040519150601f19603f3d011682016040523d82523d5f602084013e611690565b606091505b50509050806116d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116cb90613afc565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167fbac9694ac0daa55169abd117086fe32c89401d9a3b15dd1d34e55e0aa4e47a9d878460405161171c929190612b4b565b60405180910390a250505050611730611c12565b5050565b61173c611bcc565b600d5f9054906101000a900460ff1615801561175757505f34115b611796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178d906139c4565b60405180910390fd5b5f612710601154346117a89190613693565b6117b29190613701565b90505f81346117c191906130b1565b90505f6117cd8261141a565b90505f6127106107d0600b546117e39190613693565b6117ed9190613701565b905080821115611832576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182990613b64565b60405180910390fd5b84821015801561186057506b033b2e3c9fd0803ce800000082611853610a19565b61185d919061307e565b11155b61189f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161189690613bcc565b60405180910390fd5b82600c5f8282546118b0919061307e565b925050819055508360135f8282546118c8919061307e565b925050819055506040516118db90613c34565b60405180910390207f51ebdfe330aa1c0cdfa8921a1d30675876212cfcee513cf408aec9bf96edb184856040516119129190612c48565b60405180910390a26119243383611c9b565b3373ffffffffffffffffffffffffffffffffffffffff167fa9a40dec7a304e5915d11358b968c1e8d365992abf20f82285d1df1b30c8e24c838560405161196c929190612b4b565b60405180910390a2600e5461197f611467565b1061198d5761198c611d1a565b5b50505050611999611c12565b50565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b600d5f9054906101000a900460ff1681565b5f33905090565b611a4483838360016125fb565b505050565b5f611a54848461199c565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811015611ad65781811015611ac7578281836040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401611abe93929190613c48565b60405180910390fd5b611ad584848484035f6125fb565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611b4c575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401611b439190612a9a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611bbc575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401611bb39190612a9a565b60405180910390fd5b611bc78383836127ca565b505050565b600260055403611c08576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600581905550565b6001600581905550565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611c8c575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401611c839190612a9a565b60405180910390fd5b611c97825f836127ca565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611d0b575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401611d029190612a9a565b60405180910390fd5b611d165f83836127ca565b5050565b6001600d5f6101000a81548160ff0219169083151502179055505f5f90505f6064605f600c54611d4a9190613693565b611d549190613701565b90505f6002611d61610a19565b611d6b9190613701565b90506b033b2e3c9fd0803ce800000081611d83610a19565b611d8d919061307e565b1115611dce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dc590613cc7565b60405180910390fd5b611dd83082611c9b565b611e043060105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683611a37565b5f60125f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1683600c54611e4b91906130b1565b604051611e579061382e565b5f6040518083038185875af1925050503d805f8114611e91576040519150601f19603f3d011682016040523d82523d5f602084013e611e96565b606091505b5050905080611f215782600c54611ead91906130b1565b60135f828254611ebd919061307e565b92505081905550604051611ed090613d2f565b60405180910390207f51ebdfe330aa1c0cdfa8921a1d30675876212cfcee513cf408aec9bf96edb18484600c54611f0791906130b1565b604051611f149190612c48565b60405180910390a2611f7a565b604051611f2d90613d8d565b60405180910390207f51ebdfe330aa1c0cdfa8921a1d30675876212cfcee513cf408aec9bf96edb18484600c54611f6491906130b1565b604051611f719190612c48565b60405180910390a25b5f6064605a84611f8a9190613693565b611f949190613701565b90505f6064605a86611fa69190613693565b611fb09190613701565b905060105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f305d719863087868630610e1042612003919061307e565b6040518863ffffffff1660e01b815260040161202496959493929190613da1565b60606040518083038185885af19350505050801561206057506040513d601f19601f8201168201806040525081019061205d9190613e14565b60015b6120d6578460135f828254612075919061307e565b9250508190555060405161208890613eae565b60405180910390207f51ebdfe330aa1c0cdfa8921a1d30675876212cfcee513cf408aec9bf96edb184866040516120bf9190612c48565b60405180910390a26120d13085611c1c565b61259a565b84831015612119576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161211090613f0c565b60405180910390fd5b8382101561215c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161215390613f74565b60405180910390fd5b5f60105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121c7573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121eb9190613fa6565b90505f60105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015612258573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061227c9190613fa6565b73ffffffffffffffffffffffffffffffffffffffff1663e6a4390530846040518363ffffffff1660e01b81526004016122b6929190613fd1565b602060405180830381865afa1580156122d1573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122f59190613fa6565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561233257505f83115b15612594575f8173ffffffffffffffffffffffffffffffffffffffff166370a0823161dead6040518263ffffffff1660e01b81526004016123739190612a9a565b602060405180830381865afa15801561238e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123b29190613ff8565b90505f8273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb61dead876040518363ffffffff1660e01b81526004016123f2929190614023565b6020604051808303815f875af115801561240e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124329190614074565b905080612474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161246b906140e9565b60405180910390fd5b5f8373ffffffffffffffffffffffffffffffffffffffff166370a0823161dead6040518263ffffffff1660e01b81526004016124b09190612a9a565b602060405180830381865afa1580156124cb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124ef9190613ff8565b905085836124fd919061307e565b811461253e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161253590614151565b60405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff167fe0618a3fe7eb627a24df9d59eb05ba9750f8feb54aeb8909fdd35c62efd34572876040516125849190612c48565b60405180910390a260019d505050505b50505050505b5f600c819055503073ffffffffffffffffffffffffffffffffffffffff167f2f0a8c77fb8ab6f607336131943410589c9f0456c3d9a3f310f7143a7bc1d9198686896040516125eb9392919061416f565b60405180910390a2505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361266b575f6040517fe602df050000000000000000000000000000000000000000000000000000000081526004016126629190612a9a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036126db575f6040517f94280d620000000000000000000000000000000000000000000000000000000081526004016126d29190612a9a565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555080156127c4578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516127bb9190612c48565b60405180910390a35b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361281a578060025f82825461280e919061307e565b925050819055506128e8565b5f5f5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050818110156128a3578381836040517fe450d38c00000000000000000000000000000000000000000000000000000000815260040161289a93929190613c48565b60405180910390fd5b8181035f5f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361292f578060025f8282540392505081905550612979565b805f5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516129d69190612c48565b60405180910390a3505050565b5f82825260208201905092915050565b7f44697265637420455448206e6f7420616c6c6f776564000000000000000000005f82015250565b5f612a276016836129e3565b9150612a32826129f3565b602082019050919050565b5f6020820190508181035f830152612a5481612a1b565b9050919050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612a8482612a5b565b9050919050565b612a9481612a7a565b82525050565b5f602082019050612aad5f830184612a8b565b92915050565b5f81519050919050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f612ae582612ab3565b612aef81856129e3565b9350612aff818560208601612abd565b612b0881612acb565b840191505092915050565b5f6020820190508181035f830152612b2b8184612adb565b905092915050565b5f819050919050565b612b4581612b33565b82525050565b5f604082019050612b5e5f830185612b3c565b612b6b6020830184612b3c565b9392505050565b5f604051905090565b5f5ffd5b5f5ffd5b612b8c81612a7a565b8114612b96575f5ffd5b50565b5f81359050612ba781612b83565b92915050565b612bb681612b33565b8114612bc0575f5ffd5b50565b5f81359050612bd181612bad565b92915050565b5f5f60408385031215612bed57612bec612b7b565b5b5f612bfa85828601612b99565b9250506020612c0b85828601612bc3565b9150509250929050565b5f8115159050919050565b612c2981612c15565b82525050565b5f602082019050612c425f830184612c20565b92915050565b5f602082019050612c5b5f830184612b3c565b92915050565b5f5ffd5b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612c9f82612acb565b810181811067ffffffffffffffff82111715612cbe57612cbd612c69565b5b80604052505050565b5f612cd0612b72565b9050612cdc8282612c96565b919050565b5f67ffffffffffffffff821115612cfb57612cfa612c69565b5b612d0482612acb565b9050602081019050919050565b828183375f83830152505050565b5f612d31612d2c84612ce1565b612cc7565b905082815260208101848484011115612d4d57612d4c612c65565b5b612d58848285612d11565b509392505050565b5f82601f830112612d7457612d73612c61565b5b8135612d84848260208601612d1f565b91505092915050565b5f5f5f5f5f5f5f5f5f5f6101408b8d031215612dac57612dab612b7b565b5b5f8b013567ffffffffffffffff811115612dc957612dc8612b7f565b5b612dd58d828e01612d60565b9a505060208b013567ffffffffffffffff811115612df657612df5612b7f565b5b612e028d828e01612d60565b9950506040612e138d828e01612b99565b9850506060612e248d828e01612b99565b9750506080612e358d828e01612b99565b96505060a0612e468d828e01612bc3565b95505060c0612e578d828e01612bc3565b94505060e0612e688d828e01612bc3565b935050610100612e7a8d828e01612bc3565b925050610120612e8c8d828e01612bc3565b9150509295989b9194979a5092959850565b5f5f5f60608486031215612eb557612eb4612b7b565b5b5f612ec286828701612b99565b9350506020612ed386828701612b99565b9250506040612ee486828701612bc3565b9150509250925092565b5f60ff82169050919050565b612f0381612eee565b82525050565b5f602082019050612f1c5f830184612efa565b92915050565b5f60208284031215612f3757612f36612b7b565b5b5f612f4484828501612bc3565b91505092915050565b5f60208284031215612f6257612f61612b7b565b5b5f612f6f84828501612b99565b91505092915050565b5f5f60408385031215612f8e57612f8d612b7b565b5b5f612f9b85828601612bc3565b9250506020612fac85828601612bc3565b9150509250929050565b5f5f60408385031215612fcc57612fcb612b7b565b5b5f612fd985828601612b99565b9250506020612fea85828601612b99565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061303857607f821691505b60208210810361304b5761304a612ff4565b5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61308882612b33565b915061309383612b33565b92508282019050808211156130ab576130aa613051565b5b92915050565b5f6130bb82612b33565b91506130c683612b33565b92508282039050818111156130de576130dd613051565b5b92915050565b7f4f6e6c7920666163746f727900000000000000000000000000000000000000005f82015250565b5f613118600c836129e3565b9150613123826130e4565b602082019050919050565b5f6020820190508181035f8301526131458161310c565b9050919050565b7f416c726561647920696e697469616c697a6564000000000000000000000000005f82015250565b5f6131806013836129e3565b915061318b8261314c565b602082019050919050565b5f6020820190508181035f8301526131ad81613174565b9050919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026132107fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826131d5565b61321a86836131d5565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61325561325061324b84612b33565b613232565b612b33565b9050919050565b5f819050919050565b61326e8361323b565b61328261327a8261325c565b8484546131e1565b825550505050565b5f5f905090565b61329961328a565b6132a4818484613265565b505050565b5b818110156132c7576132bc5f82613291565b6001810190506132aa565b5050565b601f82111561330c576132dd816131b4565b6132e6846131c6565b810160208510156132f5578190505b613309613301856131c6565b8301826132a9565b50505b505050565b5f82821c905092915050565b5f61332c5f1984600802613311565b1980831691505092915050565b5f613344838361331d565b9150826002028217905092915050565b61335d82612ab3565b67ffffffffffffffff81111561337657613375612c69565b5b6133808254613021565b61338b8282856132cb565b5f60209050601f8311600181146133bc575f84156133aa578287015190505b6133b48582613339565b86555061341b565b601f1984166133ca866131b4565b5f5b828110156133f1578489015182556001820191506020850194506020810190506133cc565b8683101561340e578489015161340a601f89168261331d565b8355505b6001600288020188555050505b505050505050565b7f5a65726f2066656520636f6c6c6563746f7200000000000000000000000000005f82015250565b5f6134576012836129e3565b915061346282613423565b602082019050919050565b5f6020820190508181035f8301526134848161344b565b9050919050565b7f5a65726f20726f757465720000000000000000000000000000000000000000005f82015250565b5f6134bf600b836129e3565b91506134ca8261348b565b602082019050919050565b5f6020820190508181035f8301526134ec816134b3565b9050919050565b7f46656520746f6f206869676800000000000000000000000000000000000000005f82015250565b5f613527600c836129e3565b9150613532826134f3565b602082019050919050565b5f6020820190508181035f8301526135548161351b565b9050919050565b7f5a65726f2067726164756174696f6e20636170000000000000000000000000005f82015250565b5f61358f6013836129e3565b915061359a8261355b565b602082019050919050565b5f6020820190508181035f8301526135bc81613583565b9050919050565b7f5a65726f207669727475616c20726573657276657300000000000000000000005f82015250565b5f6135f76015836129e3565b9150613602826135c3565b602082019050919050565b5f6020820190508181035f830152613624816135eb565b9050919050565b7f5a65726f206e61746976652070726963650000000000000000000000000000005f82015250565b5f61365f6011836129e3565b915061366a8261362b565b602082019050919050565b5f6020820190508181035f83015261368c81613653565b9050919050565b5f61369d82612b33565b91506136a883612b33565b92508282026136b681612b33565b915082820484148315176136cd576136cc613051565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61370b82612b33565b915061371683612b33565b925082613726576137256136d4565b5b828204905092915050565b7f436f6c6c6563746f7200000000000000000000000000000000000000000000005f82015250565b5f6137656009836129e3565b915061377082613731565b602082019050919050565b5f6020820190508181035f83015261379281613759565b9050919050565b7f4e6f2066656573000000000000000000000000000000000000000000000000005f82015250565b5f6137cd6007836129e3565b91506137d882613799565b602082019050919050565b5f6020820190508181035f8301526137fa816137c1565b9050919050565b5f81905092915050565b50565b5f6138195f83613801565b91506138248261380b565b5f82019050919050565b5f6138388261380e565b9150819050919050565b7f5472616e73666572206661696c656400000000000000000000000000000000005f82015250565b5f613876600f836129e3565b915061388182613842565b602082019050919050565b5f6020820190508181035f8301526138a38161386a565b9050919050565b7f466163746f7279000000000000000000000000000000000000000000000000005f82015250565b5f6138de6007836129e3565b91506138e9826138aa565b602082019050919050565b5f6020820190508181035f83015261390b816138d2565b9050919050565b7f5a65726f207072696365000000000000000000000000000000000000000000005f82015250565b5f613946600a836129e3565b915061395182613912565b602082019050919050565b5f6020820190508181035f8301526139738161393a565b9050919050565b7f496e76616c6964000000000000000000000000000000000000000000000000005f82015250565b5f6139ae6007836129e3565b91506139b98261397a565b602082019050919050565b5f6020820190508181035f8301526139db816139a2565b9050919050565b7f536c6970706167652f4c697100000000000000000000000000000000000000005f82015250565b5f613a16600c836129e3565b9150613a21826139e2565b602082019050919050565b5f6020820190508181035f830152613a4381613a0a565b9050919050565b5f81905092915050565b7f73656c6c000000000000000000000000000000000000000000000000000000005f82015250565b5f613a88600483613a4a565b9150613a9382613a54565b600482019050919050565b5f613aa882613a7c565b9150819050919050565b7f455448207472616e73666572206661696c6564000000000000000000000000005f82015250565b5f613ae66013836129e3565b9150613af182613ab2565b602082019050919050565b5f6020820190508181035f830152613b1381613ada565b9050919050565b7f45786365656473206d61782062757900000000000000000000000000000000005f82015250565b5f613b4e600f836129e3565b9150613b5982613b1a565b602082019050919050565b5f6020820190508181035f830152613b7b81613b42565b9050919050565b7f536c6970706167652f43617000000000000000000000000000000000000000005f82015250565b5f613bb6600c836129e3565b9150613bc182613b82565b602082019050919050565b5f6020820190508181035f830152613be381613baa565b9050919050565b7f62757900000000000000000000000000000000000000000000000000000000005f82015250565b5f613c1e600383613a4a565b9150613c2982613bea565b600382019050919050565b5f613c3e82613c12565b9150819050919050565b5f606082019050613c5b5f830186612a8b565b613c686020830185612b3c565b613c756040830184612b3c565b949350505050565b7f47726164756174696f6e206578636565647320636170000000000000000000005f82015250565b5f613cb16016836129e3565b9150613cbc82613c7d565b602082019050919050565b5f6020820190508181035f830152613cde81613ca5565b9050919050565b7f67726164756174696f6e5f6661696c65640000000000000000000000000000005f82015250565b5f613d19601183613a4a565b9150613d2482613ce5565b601182019050919050565b5f613d3982613d0d565b9150819050919050565b7f67726164756174696f6e000000000000000000000000000000000000000000005f82015250565b5f613d77600a83613a4a565b9150613d8282613d43565b600a82019050919050565b5f613d9782613d6b565b9150819050919050565b5f60c082019050613db45f830189612a8b565b613dc16020830188612b3c565b613dce6040830187612b3c565b613ddb6060830186612b3c565b613de86080830185612a8b565b613df560a0830184612b3c565b979650505050505050565b5f81519050613e0e81612bad565b92915050565b5f5f5f60608486031215613e2b57613e2a612b7b565b5b5f613e3886828701613e00565b9350506020613e4986828701613e00565b9250506040613e5a86828701613e00565b9150509250925092565b7f6c69717569646974795f6661696c6564000000000000000000000000000000005f82015250565b5f613e98601083613a4a565b9150613ea382613e64565b601082019050919050565b5f613eb882613e8c565b9150819050919050565b7f496e73756666696369656e7420746f6b656e206c6971756964697479000000005f82015250565b5f613ef6601c836129e3565b9150613f0182613ec2565b602082019050919050565b5f6020820190508181035f830152613f2381613eea565b9050919050565b7f496e73756666696369656e7420455448206c69717569646974790000000000005f82015250565b5f613f5e601a836129e3565b9150613f6982613f2a565b602082019050919050565b5f6020820190508181035f830152613f8b81613f52565b9050919050565b5f81519050613fa081612b83565b92915050565b5f60208284031215613fbb57613fba612b7b565b5b5f613fc884828501613f92565b91505092915050565b5f604082019050613fe45f830185612a8b565b613ff16020830184612a8b565b9392505050565b5f6020828403121561400d5761400c612b7b565b5b5f61401a84828501613e00565b91505092915050565b5f6040820190506140365f830185612a8b565b6140436020830184612b3c565b9392505050565b61405381612c15565b811461405d575f5ffd5b50565b5f8151905061406e8161404a565b92915050565b5f6020828403121561408957614088612b7b565b5b5f61409684828501614060565b91505092915050565b7f4c50204275726e206661696c65640000000000000000000000000000000000005f82015250565b5f6140d3600e836129e3565b91506140de8261409f565b602082019050919050565b5f6020820190508181035f830152614100816140c7565b9050919050565b7f4c5020746f6b656e73206e6f74206275726e65640000000000000000000000005f82015250565b5f61413b6014836129e3565b915061414682614107565b602082019050919050565b5f6020820190508181035f8301526141688161412f565b9050919050565b5f6060820190506141825f830186612b3c565b61418f6020830185612b3c565b61419c6040830184612c20565b94935050505056fea2646970667358221220b71678527f05b79a7bd238a7a4b0af4e15aaf09cd210b68a3b2bc6240d7e518d64736f6c634300081f0033a2646970667358221220d0e63d1b66f14f71e93168bcfb2a4622802b0144924a3492ba56692ba4ae8ddb64736f6c634300081f0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in S
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.