Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 60 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Set Approval For... | 72359097 | 425 days ago | IN | 0 MNT | 0.00443025 | ||||
| Transfer From | 72094279 | 431 days ago | IN | 0 MNT | 0.00886045 | ||||
| Transfer From | 72094268 | 431 days ago | IN | 0 MNT | 0.00721853 | ||||
| Set Approval For... | 71423820 | 447 days ago | IN | 0 MNT | 0.00543209 | ||||
| Assault | 69242342 | 497 days ago | IN | 0 MNT | 0.02668424 | ||||
| Debilitate | 69242294 | 497 days ago | IN | 0 MNT | 0.02661993 | ||||
| Assault | 69242263 | 497 days ago | IN | 0 MNT | 0.0238439 | ||||
| Set Addresses | 69241280 | 497 days ago | IN | 0 MNT | 0.00393679 | ||||
| Assault | 68891473 | 506 days ago | IN | 0 MNT | 0.02392294 | ||||
| Assault | 68891396 | 506 days ago | IN | 0 MNT | 0.02397515 | ||||
| Assault | 68891352 | 506 days ago | IN | 0 MNT | 0.03107383 | ||||
| Set Charge | 68891222 | 506 days ago | IN | 0 MNT | 0.00449876 | ||||
| Set Addresses | 68891197 | 506 days ago | IN | 0 MNT | 0.00850337 | ||||
| Update Base URI | 68891162 | 506 days ago | IN | 0 MNT | 0.00855877 | ||||
| Set Tax | 68891044 | 506 days ago | IN | 0 MNT | 0.01415732 | ||||
| Add Currency | 68890981 | 506 days ago | IN | 0 MNT | 0.00509248 | ||||
| Add Currency | 68890937 | 506 days ago | IN | 0 MNT | 0.00642794 | ||||
| Migrate Mint | 67587175 | 536 days ago | IN | 0 MNT | 0.00573517 | ||||
| Migrate Mint | 67587157 | 536 days ago | IN | 0 MNT | 0.00596906 | ||||
| Migrate Mint | 67587140 | 536 days ago | IN | 0 MNT | 0.01098248 | ||||
| Migrate Mint | 67587123 | 536 days ago | IN | 0 MNT | 0.01120469 | ||||
| Migrate Mint | 67587103 | 536 days ago | IN | 0 MNT | 0.0112049 | ||||
| Migrate Mint | 67587087 | 536 days ago | IN | 0 MNT | 0.01121299 | ||||
| Migrate Mint | 67587066 | 536 days ago | IN | 0 MNT | 0.00577133 | ||||
| Migrate Mint | 67587051 | 536 days ago | IN | 0 MNT | 0.00575242 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
battledog
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/**
*Submitted for verification at mantlescan.xyz on 2024-08-24
*/
// SPDX-License-Identifier: No license
// File: @openzeppelin/contracts/security/ReentrancyGuard.sol
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract 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;
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
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// 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;
}
}
// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
// File: @openzeppelin/contracts/token/ERC20/IERC20.sol
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` 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 amount) 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 `amount` 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 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` 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 amount) external returns (bool);
}
// File: abdk-libraries-solidity/ABDKMath64x64.sol
/*
* ABDK Math 64.64 Smart Contract Library. Copyright © 2019 by ABDK Consulting.
* Author: Mikhail Vladimirov <[email protected]>
*/
pragma solidity ^0.8.0;
/**
* Smart contract library of mathematical functions operating with signed
* 64.64-bit fixed point numbers. Signed 64.64-bit fixed point number is
* basically a simple fraction whose numerator is signed 128-bit integer and
* denominator is 2^64. As long as denominator is always the same, there is no
* need to store it, thus in Solidity signed 64.64-bit fixed point numbers are
* represented by int128 type holding only the numerator.
*/
library ABDKMath64x64 {
/*
* Minimum value signed 64.64-bit fixed point number may have.
*/
int128 private constant MIN_64x64 = -0x80000000000000000000000000000000;
/*
* Maximum value signed 64.64-bit fixed point number may have.
*/
int128 private constant MAX_64x64 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
/**
* Convert signed 256-bit integer number into signed 64.64-bit fixed point
* number. Revert on overflow.
*
* @param x signed 256-bit integer number
* @return signed 64.64-bit fixed point number
*/
function fromInt (int256 x) internal pure returns (int128) {
unchecked {
require (x >= -0x8000000000000000 && x <= 0x7FFFFFFFFFFFFFFF);
return int128 (x << 64);
}
}
/**
* Convert signed 64.64 fixed point number into signed 64-bit integer number
* rounding down.
*
* @param x signed 64.64-bit fixed point number
* @return signed 64-bit integer number
*/
function toInt (int128 x) internal pure returns (int64) {
unchecked {
return int64 (x >> 64);
}
}
/**
* Convert unsigned 256-bit integer number into signed 64.64-bit fixed point
* number. Revert on overflow.
*
* @param x unsigned 256-bit integer number
* @return signed 64.64-bit fixed point number
*/
function fromUInt (uint256 x) internal pure returns (int128) {
unchecked {
require (x <= 0x7FFFFFFFFFFFFFFF);
return int128 (int256 (x << 64));
}
}
/**
* Convert signed 64.64 fixed point number into unsigned 64-bit integer
* number rounding down. Revert on underflow.
*
* @param x signed 64.64-bit fixed point number
* @return unsigned 64-bit integer number
*/
function toUInt (int128 x) internal pure returns (uint64) {
unchecked {
require (x >= 0);
return uint64 (uint128 (x >> 64));
}
}
/**
* Convert signed 128.128 fixed point number into signed 64.64-bit fixed point
* number rounding down. Revert on overflow.
*
* @param x signed 128.128-bin fixed point number
* @return signed 64.64-bit fixed point number
*/
function from128x128 (int256 x) internal pure returns (int128) {
unchecked {
int256 result = x >> 64;
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
/**
* Convert signed 64.64 fixed point number into signed 128.128 fixed point
* number.
*
* @param x signed 64.64-bit fixed point number
* @return signed 128.128 fixed point number
*/
function to128x128 (int128 x) internal pure returns (int256) {
unchecked {
return int256 (x) << 64;
}
}
/**
* Calculate x + y. Revert on overflow.
*
* @param x signed 64.64-bit fixed point number
* @param y signed 64.64-bit fixed point number
* @return signed 64.64-bit fixed point number
*/
function add (int128 x, int128 y) internal pure returns (int128) {
unchecked {
int256 result = int256(x) + y;
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
/**
* Calculate x - y. Revert on overflow.
*
* @param x signed 64.64-bit fixed point number
* @param y signed 64.64-bit fixed point number
* @return signed 64.64-bit fixed point number
*/
function sub (int128 x, int128 y) internal pure returns (int128) {
unchecked {
int256 result = int256(x) - y;
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
/**
* Calculate x * y rounding down. Revert on overflow.
*
* @param x signed 64.64-bit fixed point number
* @param y signed 64.64-bit fixed point number
* @return signed 64.64-bit fixed point number
*/
function mul (int128 x, int128 y) internal pure returns (int128) {
unchecked {
int256 result = int256(x) * y >> 64;
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
/**
* Calculate x * y rounding towards zero, where x is signed 64.64 fixed point
* number and y is signed 256-bit integer number. Revert on overflow.
*
* @param x signed 64.64 fixed point number
* @param y signed 256-bit integer number
* @return signed 256-bit integer number
*/
function muli (int128 x, int256 y) internal pure returns (int256) {
unchecked {
if (x == MIN_64x64) {
require (y >= -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF &&
y <= 0x1000000000000000000000000000000000000000000000000);
return -y << 63;
} else {
bool negativeResult = false;
if (x < 0) {
x = -x;
negativeResult = true;
}
if (y < 0) {
y = -y; // We rely on overflow behavior here
negativeResult = !negativeResult;
}
uint256 absoluteResult = mulu (x, uint256 (y));
if (negativeResult) {
require (absoluteResult <=
0x8000000000000000000000000000000000000000000000000000000000000000);
return -int256 (absoluteResult); // We rely on overflow behavior here
} else {
require (absoluteResult <=
0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
return int256 (absoluteResult);
}
}
}
}
/**
* Calculate x * y rounding down, where x is signed 64.64 fixed point number
* and y is unsigned 256-bit integer number. Revert on overflow.
*
* @param x signed 64.64 fixed point number
* @param y unsigned 256-bit integer number
* @return unsigned 256-bit integer number
*/
function mulu (int128 x, uint256 y) internal pure returns (uint256) {
unchecked {
if (y == 0) return 0;
require (x >= 0);
uint256 lo = (uint256 (int256 (x)) * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64;
uint256 hi = uint256 (int256 (x)) * (y >> 128);
require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
hi <<= 64;
require (hi <=
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - lo);
return hi + lo;
}
}
/**
* Calculate x / y rounding towards zero. Revert on overflow or when y is
* zero.
*
* @param x signed 64.64-bit fixed point number
* @param y signed 64.64-bit fixed point number
* @return signed 64.64-bit fixed point number
*/
function div (int128 x, int128 y) internal pure returns (int128) {
unchecked {
require (y != 0);
int256 result = (int256 (x) << 64) / y;
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
/**
* Calculate x / y rounding towards zero, where x and y are signed 256-bit
* integer numbers. Revert on overflow or when y is zero.
*
* @param x signed 256-bit integer number
* @param y signed 256-bit integer number
* @return signed 64.64-bit fixed point number
*/
function divi (int256 x, int256 y) internal pure returns (int128) {
unchecked {
require (y != 0);
bool negativeResult = false;
if (x < 0) {
x = -x; // We rely on overflow behavior here
negativeResult = true;
}
if (y < 0) {
y = -y; // We rely on overflow behavior here
negativeResult = !negativeResult;
}
uint128 absoluteResult = divuu (uint256 (x), uint256 (y));
if (negativeResult) {
require (absoluteResult <= 0x80000000000000000000000000000000);
return -int128 (absoluteResult); // We rely on overflow behavior here
} else {
require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
return int128 (absoluteResult); // We rely on overflow behavior here
}
}
}
/**
* Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
* integer numbers. Revert on overflow or when y is zero.
*
* @param x unsigned 256-bit integer number
* @param y unsigned 256-bit integer number
* @return signed 64.64-bit fixed point number
*/
function divu (uint256 x, uint256 y) internal pure returns (int128) {
unchecked {
require (y != 0);
uint128 result = divuu (x, y);
require (result <= uint128 (MAX_64x64));
return int128 (result);
}
}
/**
* Calculate -x. Revert on overflow.
*
* @param x signed 64.64-bit fixed point number
* @return signed 64.64-bit fixed point number
*/
function neg (int128 x) internal pure returns (int128) {
unchecked {
require (x != MIN_64x64);
return -x;
}
}
/**
* Calculate |x|. Revert on overflow.
*
* @param x signed 64.64-bit fixed point number
* @return signed 64.64-bit fixed point number
*/
function abs (int128 x) internal pure returns (int128) {
unchecked {
require (x != MIN_64x64);
return x < 0 ? -x : x;
}
}
/**
* Calculate 1 / x rounding towards zero. Revert on overflow or when x is
* zero.
*
* @param x signed 64.64-bit fixed point number
* @return signed 64.64-bit fixed point number
*/
function inv (int128 x) internal pure returns (int128) {
unchecked {
require (x != 0);
int256 result = int256 (0x100000000000000000000000000000000) / x;
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
/**
* Calculate arithmetics average of x and y, i.e. (x + y) / 2 rounding down.
*
* @param x signed 64.64-bit fixed point number
* @param y signed 64.64-bit fixed point number
* @return signed 64.64-bit fixed point number
*/
function avg (int128 x, int128 y) internal pure returns (int128) {
unchecked {
return int128 ((int256 (x) + int256 (y)) >> 1);
}
}
/**
* Calculate geometric average of x and y, i.e. sqrt (x * y) rounding down.
* Revert on overflow or in case x * y is negative.
*
* @param x signed 64.64-bit fixed point number
* @param y signed 64.64-bit fixed point number
* @return signed 64.64-bit fixed point number
*/
function gavg (int128 x, int128 y) internal pure returns (int128) {
unchecked {
int256 m = int256 (x) * int256 (y);
require (m >= 0);
require (m <
0x4000000000000000000000000000000000000000000000000000000000000000);
return int128 (sqrtu (uint256 (m)));
}
}
/**
* Calculate x^y assuming 0^0 is 1, where x is signed 64.64 fixed point number
* and y is unsigned 256-bit integer number. Revert on overflow.
*
* @param x signed 64.64-bit fixed point number
* @param y uint256 value
* @return signed 64.64-bit fixed point number
*/
function pow (int128 x, uint256 y) internal pure returns (int128) {
unchecked {
bool negative = x < 0 && y & 1 == 1;
uint256 absX = uint128 (x < 0 ? -x : x);
uint256 absResult;
absResult = 0x100000000000000000000000000000000;
if (absX <= 0x10000000000000000) {
absX <<= 63;
while (y != 0) {
if (y & 0x1 != 0) {
absResult = absResult * absX >> 127;
}
absX = absX * absX >> 127;
if (y & 0x2 != 0) {
absResult = absResult * absX >> 127;
}
absX = absX * absX >> 127;
if (y & 0x4 != 0) {
absResult = absResult * absX >> 127;
}
absX = absX * absX >> 127;
if (y & 0x8 != 0) {
absResult = absResult * absX >> 127;
}
absX = absX * absX >> 127;
y >>= 4;
}
absResult >>= 64;
} else {
uint256 absXShift = 63;
if (absX < 0x1000000000000000000000000) { absX <<= 32; absXShift -= 32; }
if (absX < 0x10000000000000000000000000000) { absX <<= 16; absXShift -= 16; }
if (absX < 0x1000000000000000000000000000000) { absX <<= 8; absXShift -= 8; }
if (absX < 0x10000000000000000000000000000000) { absX <<= 4; absXShift -= 4; }
if (absX < 0x40000000000000000000000000000000) { absX <<= 2; absXShift -= 2; }
if (absX < 0x80000000000000000000000000000000) { absX <<= 1; absXShift -= 1; }
uint256 resultShift = 0;
while (y != 0) {
require (absXShift < 64);
if (y & 0x1 != 0) {
absResult = absResult * absX >> 127;
resultShift += absXShift;
if (absResult > 0x100000000000000000000000000000000) {
absResult >>= 1;
resultShift += 1;
}
}
absX = absX * absX >> 127;
absXShift <<= 1;
if (absX >= 0x100000000000000000000000000000000) {
absX >>= 1;
absXShift += 1;
}
y >>= 1;
}
require (resultShift < 64);
absResult >>= 64 - resultShift;
}
int256 result = negative ? -int256 (absResult) : int256 (absResult);
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
/**
* Calculate sqrt (x) rounding down. Revert if x < 0.
*
* @param x signed 64.64-bit fixed point number
* @return signed 64.64-bit fixed point number
*/
function sqrt (int128 x) internal pure returns (int128) {
unchecked {
require (x >= 0);
return int128 (sqrtu (uint256 (int256 (x)) << 64));
}
}
/**
* Calculate binary logarithm of x. Revert if x <= 0.
*
* @param x signed 64.64-bit fixed point number
* @return signed 64.64-bit fixed point number
*/
function log_2 (int128 x) internal pure returns (int128) {
unchecked {
require (x > 0);
int256 msb = 0;
int256 xc = x;
if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; }
if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
if (xc >= 0x10000) { xc >>= 16; msb += 16; }
if (xc >= 0x100) { xc >>= 8; msb += 8; }
if (xc >= 0x10) { xc >>= 4; msb += 4; }
if (xc >= 0x4) { xc >>= 2; msb += 2; }
if (xc >= 0x2) msb += 1; // No need to shift xc anymore
int256 result = msb - 64 << 64;
uint256 ux = uint256 (int256 (x)) << uint256 (127 - msb);
for (int256 bit = 0x8000000000000000; bit > 0; bit >>= 1) {
ux *= ux;
uint256 b = ux >> 255;
ux >>= 127 + b;
result += bit * int256 (b);
}
return int128 (result);
}
}
/**
* Calculate natural logarithm of x. Revert if x <= 0.
*
* @param x signed 64.64-bit fixed point number
* @return signed 64.64-bit fixed point number
*/
function ln (int128 x) internal pure returns (int128) {
unchecked {
require (x > 0);
return int128 (int256 (
uint256 (int256 (log_2 (x))) * 0xB17217F7D1CF79ABC9E3B39803F2F6AF >> 128));
}
}
/**
* Calculate binary exponent of x. Revert on overflow.
*
* @param x signed 64.64-bit fixed point number
* @return signed 64.64-bit fixed point number
*/
function exp_2 (int128 x) internal pure returns (int128) {
unchecked {
require (x < 0x400000000000000000); // Overflow
if (x < -0x400000000000000000) return 0; // Underflow
uint256 result = 0x80000000000000000000000000000000;
if (x & 0x8000000000000000 > 0)
result = result * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128;
if (x & 0x4000000000000000 > 0)
result = result * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128;
if (x & 0x2000000000000000 > 0)
result = result * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128;
if (x & 0x1000000000000000 > 0)
result = result * 0x10B5586CF9890F6298B92B71842A98363 >> 128;
if (x & 0x800000000000000 > 0)
result = result * 0x1059B0D31585743AE7C548EB68CA417FD >> 128;
if (x & 0x400000000000000 > 0)
result = result * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128;
if (x & 0x200000000000000 > 0)
result = result * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128;
if (x & 0x100000000000000 > 0)
result = result * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128;
if (x & 0x80000000000000 > 0)
result = result * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128;
if (x & 0x40000000000000 > 0)
result = result * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128;
if (x & 0x20000000000000 > 0)
result = result * 0x100162F3904051FA128BCA9C55C31E5DF >> 128;
if (x & 0x10000000000000 > 0)
result = result * 0x1000B175EFFDC76BA38E31671CA939725 >> 128;
if (x & 0x8000000000000 > 0)
result = result * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128;
if (x & 0x4000000000000 > 0)
result = result * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128;
if (x & 0x2000000000000 > 0)
result = result * 0x1000162E525EE054754457D5995292026 >> 128;
if (x & 0x1000000000000 > 0)
result = result * 0x10000B17255775C040618BF4A4ADE83FC >> 128;
if (x & 0x800000000000 > 0)
result = result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128;
if (x & 0x400000000000 > 0)
result = result * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128;
if (x & 0x200000000000 > 0)
result = result * 0x10000162E43F4F831060E02D839A9D16D >> 128;
if (x & 0x100000000000 > 0)
result = result * 0x100000B1721BCFC99D9F890EA06911763 >> 128;
if (x & 0x80000000000 > 0)
result = result * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128;
if (x & 0x40000000000 > 0)
result = result * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128;
if (x & 0x20000000000 > 0)
result = result * 0x100000162E430E5A18F6119E3C02282A5 >> 128;
if (x & 0x10000000000 > 0)
result = result * 0x1000000B1721835514B86E6D96EFD1BFE >> 128;
if (x & 0x8000000000 > 0)
result = result * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128;
if (x & 0x4000000000 > 0)
result = result * 0x10000002C5C8601CC6B9E94213C72737A >> 128;
if (x & 0x2000000000 > 0)
result = result * 0x1000000162E42FFF037DF38AA2B219F06 >> 128;
if (x & 0x1000000000 > 0)
result = result * 0x10000000B17217FBA9C739AA5819F44F9 >> 128;
if (x & 0x800000000 > 0)
result = result * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128;
if (x & 0x400000000 > 0)
result = result * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128;
if (x & 0x200000000 > 0)
result = result * 0x10000000162E42FF0999CE3541B9FFFCF >> 128;
if (x & 0x100000000 > 0)
result = result * 0x100000000B17217F80F4EF5AADDA45554 >> 128;
if (x & 0x80000000 > 0)
result = result * 0x10000000058B90BFBF8479BD5A81B51AD >> 128;
if (x & 0x40000000 > 0)
result = result * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128;
if (x & 0x20000000 > 0)
result = result * 0x100000000162E42FEFB2FED257559BDAA >> 128;
if (x & 0x10000000 > 0)
result = result * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128;
if (x & 0x8000000 > 0)
result = result * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128;
if (x & 0x4000000 > 0)
result = result * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128;
if (x & 0x2000000 > 0)
result = result * 0x1000000000162E42FEFA494F1478FDE05 >> 128;
if (x & 0x1000000 > 0)
result = result * 0x10000000000B17217F7D20CF927C8E94C >> 128;
if (x & 0x800000 > 0)
result = result * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128;
if (x & 0x400000 > 0)
result = result * 0x100000000002C5C85FDF477B662B26945 >> 128;
if (x & 0x200000 > 0)
result = result * 0x10000000000162E42FEFA3AE53369388C >> 128;
if (x & 0x100000 > 0)
result = result * 0x100000000000B17217F7D1D351A389D40 >> 128;
if (x & 0x80000 > 0)
result = result * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128;
if (x & 0x40000 > 0)
result = result * 0x1000000000002C5C85FDF4741BEA6E77E >> 128;
if (x & 0x20000 > 0)
result = result * 0x100000000000162E42FEFA39FE95583C2 >> 128;
if (x & 0x10000 > 0)
result = result * 0x1000000000000B17217F7D1CFB72B45E1 >> 128;
if (x & 0x8000 > 0)
result = result * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128;
if (x & 0x4000 > 0)
result = result * 0x10000000000002C5C85FDF473E242EA38 >> 128;
if (x & 0x2000 > 0)
result = result * 0x1000000000000162E42FEFA39F02B772C >> 128;
if (x & 0x1000 > 0)
result = result * 0x10000000000000B17217F7D1CF7D83C1A >> 128;
if (x & 0x800 > 0)
result = result * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128;
if (x & 0x400 > 0)
result = result * 0x100000000000002C5C85FDF473DEA871F >> 128;
if (x & 0x200 > 0)
result = result * 0x10000000000000162E42FEFA39EF44D91 >> 128;
if (x & 0x100 > 0)
result = result * 0x100000000000000B17217F7D1CF79E949 >> 128;
if (x & 0x80 > 0)
result = result * 0x10000000000000058B90BFBE8E7BCE544 >> 128;
if (x & 0x40 > 0)
result = result * 0x1000000000000002C5C85FDF473DE6ECA >> 128;
if (x & 0x20 > 0)
result = result * 0x100000000000000162E42FEFA39EF366F >> 128;
if (x & 0x10 > 0)
result = result * 0x1000000000000000B17217F7D1CF79AFA >> 128;
if (x & 0x8 > 0)
result = result * 0x100000000000000058B90BFBE8E7BCD6D >> 128;
if (x & 0x4 > 0)
result = result * 0x10000000000000002C5C85FDF473DE6B2 >> 128;
if (x & 0x2 > 0)
result = result * 0x1000000000000000162E42FEFA39EF358 >> 128;
if (x & 0x1 > 0)
result = result * 0x10000000000000000B17217F7D1CF79AB >> 128;
result >>= uint256 (int256 (63 - (x >> 64)));
require (result <= uint256 (int256 (MAX_64x64)));
return int128 (int256 (result));
}
}
/**
* Calculate natural exponent of x. Revert on overflow.
*
* @param x signed 64.64-bit fixed point number
* @return signed 64.64-bit fixed point number
*/
function exp (int128 x) internal pure returns (int128) {
unchecked {
require (x < 0x400000000000000000); // Overflow
if (x < -0x400000000000000000) return 0; // Underflow
return exp_2 (
int128 (int256 (x) * 0x171547652B82FE1777D0FFDA0D23A7D12 >> 128));
}
}
/**
* Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
* integer numbers. Revert on overflow or when y is zero.
*
* @param x unsigned 256-bit integer number
* @param y unsigned 256-bit integer number
* @return unsigned 64.64-bit fixed point number
*/
function divuu (uint256 x, uint256 y) private pure returns (uint128) {
unchecked {
require (y != 0);
uint256 result;
if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
result = (x << 64) / y;
else {
uint256 msb = 192;
uint256 xc = x >> 192;
if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
if (xc >= 0x10000) { xc >>= 16; msb += 16; }
if (xc >= 0x100) { xc >>= 8; msb += 8; }
if (xc >= 0x10) { xc >>= 4; msb += 4; }
if (xc >= 0x4) { xc >>= 2; msb += 2; }
if (xc >= 0x2) msb += 1; // No need to shift xc anymore
result = (x << 255 - msb) / ((y - 1 >> msb - 191) + 1);
require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
uint256 hi = result * (y >> 128);
uint256 lo = result * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
uint256 xh = x >> 192;
uint256 xl = x << 64;
if (xl < lo) xh -= 1;
xl -= lo; // We rely on overflow behavior here
lo = hi << 128;
if (xl < lo) xh -= 1;
xl -= lo; // We rely on overflow behavior here
result += xh == hi >> 128 ? xl / y : 1;
}
require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
return uint128 (result);
}
}
/**
* Calculate sqrt (x) rounding down, where x is unsigned 256-bit integer
* number.
*
* @param x unsigned 256-bit integer number
* @return unsigned 128-bit integer number
*/
function sqrtu (uint256 x) private pure returns (uint128) {
unchecked {
if (x == 0) return 0;
else {
uint256 xx = x;
uint256 r = 1;
if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; }
if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; }
if (xx >= 0x100000000) { xx >>= 32; r <<= 16; }
if (xx >= 0x10000) { xx >>= 16; r <<= 8; }
if (xx >= 0x100) { xx >>= 8; r <<= 4; }
if (xx >= 0x10) { xx >>= 4; r <<= 2; }
if (xx >= 0x4) { r <<= 1; }
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1; // Seven iterations should be enough
uint256 r1 = x / r;
return uint128 (r < r1 ? r : r1);
}
}
}
}
// File: @openzeppelin/contracts/utils/math/SafeMath.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
// File: @openzeppelin/contracts/utils/math/SignedMath.sol
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard signed math utilities missing in the Solidity language.
*/
library SignedMath {
/**
* @dev Returns the largest of two signed numbers.
*/
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two signed numbers.
*/
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two signed numbers without overflow.
* The result is rounded towards zero.
*/
function average(int256 a, int256 b) internal pure returns (int256) {
// Formula from the book "Hacker's Delight"
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
/**
* @dev Returns the absolute unsigned value of a signed value.
*/
function abs(int256 n) internal pure returns (uint256) {
unchecked {
// must be unchecked in order to support `n = type(int256).min`
return uint256(n >= 0 ? n : -n);
}
}
}
// File: @openzeppelin/contracts/utils/math/Math.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1, "Math: mulDiv overflow");
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
// File: @openzeppelin/contracts/utils/Strings.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `int256` to its ASCII `string` decimal representation.
*/
function toString(int256 value) internal pure returns (string memory) {
return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
/**
* @dev Returns true if the two strings are equal.
*/
function equal(string memory a, string memory b) internal pure returns (bool) {
return keccak256(bytes(a)) == keccak256(bytes(b));
}
}
// File: @openzeppelin/contracts/utils/Context.sol
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @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;
}
}
// File: @openzeppelin/contracts/access/Ownable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
/**
* @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.
*
* By default, the owner account will be the one that deploys the contract. 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;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @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 {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @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 {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_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);
}
}
// File: @openzeppelin/contracts/utils/Address.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
// File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
// File: @openzeppelin/contracts/utils/introspection/IERC165.sol
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
// File: @openzeppelin/contracts/utils/introspection/ERC165.sol
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
// File: @openzeppelin/contracts/token/ERC721/IERC721.sol
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
* or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
* understand this adds an external call which potentially creates a reentrancy vulnerability.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)
pragma solidity ^0.8.0;
/**
* @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Enumerable is IERC721 {
/**
* @dev Returns the total amount of tokens stored by the contract.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns a token ID owned by `owner` at a given `index` of its token list.
* Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);
/**
* @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
* Use along with {totalSupply} to enumerate all tokens.
*/
function tokenByIndex(uint256 index) external view returns (uint256);
}
// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)
pragma solidity ^0.8.0;
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Metadata is IERC721 {
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
}
// File: @openzeppelin/contracts/token/ERC721/ERC721.sol
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)
pragma solidity ^0.8.0;
/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
* the Metadata extension, but not including the Enumerable extension, which is available separately as
* {ERC721Enumerable}.
*/
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Mapping from token ID to owner address
mapping(uint256 => address) private _owners;
// Mapping owner address to token count
mapping(address => uint256) private _balances;
// Mapping from token ID to approved address
mapping(uint256 => address) private _tokenApprovals;
// Mapping from owner to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721-balanceOf}.
*/
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: address zero is not a valid owner");
return _balances[owner];
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _ownerOf(tokenId);
require(owner != address(0), "ERC721: invalid token ID");
return owner;
}
/**
* @dev See {IERC721Metadata-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
_requireMinted(tokenId);
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
/**
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overridden in child contracts.
*/
function _baseURI() internal view virtual returns (string memory) {
return "";
}
/**
* @dev See {IERC721-approve}.
*/
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not token owner or approved for all"
);
_approve(to, tokenId);
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
_requireMinted(tokenId);
return _tokenApprovals[tokenId];
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/
function transferFrom(address from, address to, uint256 tokenId) public virtual override {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");
_safeTransfer(from, to, tokenId, data);
}
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* `data` is additional data, it has no specified format and it is sent in call to `to`.
*
* This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
* implement alternative mechanisms to perform token transfer, such as signature-based.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
}
/**
* @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
*/
function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
return _owners[tokenId];
}
/**
* @dev Returns whether `tokenId` exists.
*
* Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
*
* Tokens start existing when they are minted (`_mint`),
* and stop existing when they are burned (`_burn`).
*/
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _ownerOf(tokenId) != address(0);
}
/**
* @dev Returns whether `spender` is allowed to manage `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
}
/**
* @dev Safely mints `tokenId` and transfers it to `to`.
*
* Requirements:
*
* - `tokenId` must not exist.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
/**
* @dev Mints `tokenId` and transfers it to `to`.
*
* WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
*
* Requirements:
*
* - `tokenId` must not exist.
* - `to` cannot be the zero address.
*
* Emits a {Transfer} event.
*/
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId, 1);
// Check that tokenId was not minted by `_beforeTokenTransfer` hook
require(!_exists(tokenId), "ERC721: token already minted");
unchecked {
// Will not overflow unless all 2**256 token ids are minted to the same owner.
// Given that tokens are minted one by one, it is impossible in practice that
// this ever happens. Might change if we allow batch minting.
// The ERC fails to describe this case.
_balances[to] += 1;
}
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
_afterTokenTransfer(address(0), to, tokenId, 1);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
* This is an internal function that does not check if the sender is authorized to operate on the token.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId, 1);
// Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
owner = ERC721.ownerOf(tokenId);
// Clear approvals
delete _tokenApprovals[tokenId];
unchecked {
// Cannot overflow, as that would require more tokens to be burned/transferred
// out than the owner initially received through minting and transferring in.
_balances[owner] -= 1;
}
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
_afterTokenTransfer(owner, address(0), tokenId, 1);
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
* As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
*
* Emits a {Transfer} event.
*/
function _transfer(address from, address to, uint256 tokenId) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId, 1);
// Check that tokenId was not transferred by `_beforeTokenTransfer` hook
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
// Clear approvals from the previous owner
delete _tokenApprovals[tokenId];
unchecked {
// `_balances[from]` cannot overflow for the same reason as described in `_burn`:
// `from`'s balance is the number of token held, which is at least one before the current
// transfer.
// `_balances[to]` could overflow in the conditions described in `_mint`. That would require
// all 2**256 token ids to be minted, which in practice is impossible.
_balances[from] -= 1;
_balances[to] += 1;
}
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
_afterTokenTransfer(from, to, tokenId, 1);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* Emits an {Approval} event.
*/
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits an {ApprovalForAll} event.
*/
function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {
require(owner != operator, "ERC721: approve to caller");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Reverts if the `tokenId` has not been minted yet.
*/
function _requireMinted(uint256 tokenId) internal view virtual {
require(_exists(tokenId), "ERC721: invalid token ID");
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
* The call is not executed if the target address is not a contract.
*
* @param from address representing the previous owner of the given token ID
* @param to target address that will receive the tokens
* @param tokenId uint256 ID of the token to be transferred
* @param data bytes optional data to send along with the call
* @return bool whether the call correctly returned the expected magic value
*/
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory data
) private returns (bool) {
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
/// @solidity memory-safe-assembly
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
/**
* @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is
* used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
* - When `from` is zero, the tokens will be minted for `to`.
* - When `to` is zero, ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
* - `batchSize` is non-zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}
/**
* @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
* used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
* - When `from` is zero, the tokens were minted for `to`.
* - When `to` is zero, ``from``'s tokens were burned.
* - `from` and `to` are never both zero.
* - `batchSize` is non-zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}
/**
* @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
*
* WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant
* being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such
* that `ownerOf(tokenId)` is `a`.
*/
// solhint-disable-next-line func-name-mixedcase
function __unsafe_increaseBalance(address account, uint256 amount) internal {
_balances[account] += amount;
}
}
// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol)
pragma solidity ^0.8.0;
/**
* @dev This implements an optional extension of {ERC721} defined in the EIP that adds
* enumerability of all the token ids in the contract as well as all token ids owned by each
* account.
*/
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
// Mapping from owner to list of owned token IDs
mapping(address => mapping(uint256 => uint256)) private _ownedTokens;
// Mapping from token ID to index of the owner tokens list
mapping(uint256 => uint256) private _ownedTokensIndex;
// Array with all token ids, used for enumeration
uint256[] private _allTokens;
// Mapping from token id to position in the allTokens array
mapping(uint256 => uint256) private _allTokensIndex;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
return _ownedTokens[owner][index];
}
/**
* @dev See {IERC721Enumerable-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _allTokens.length;
}
/**
* @dev See {IERC721Enumerable-tokenByIndex}.
*/
function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
return _allTokens[index];
}
/**
* @dev See {ERC721-_beforeTokenTransfer}.
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 firstTokenId,
uint256 batchSize
) internal virtual override {
super._beforeTokenTransfer(from, to, firstTokenId, batchSize);
if (batchSize > 1) {
// Will only trigger during construction. Batch transferring (minting) is not available afterwards.
revert("ERC721Enumerable: consecutive transfers not supported");
}
uint256 tokenId = firstTokenId;
if (from == address(0)) {
_addTokenToAllTokensEnumeration(tokenId);
} else if (from != to) {
_removeTokenFromOwnerEnumeration(from, tokenId);
}
if (to == address(0)) {
_removeTokenFromAllTokensEnumeration(tokenId);
} else if (to != from) {
_addTokenToOwnerEnumeration(to, tokenId);
}
}
/**
* @dev Private function to add a token to this extension's ownership-tracking data structures.
* @param to address representing the new owner of the given token ID
* @param tokenId uint256 ID of the token to be added to the tokens list of the given address
*/
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
uint256 length = ERC721.balanceOf(to);
_ownedTokens[to][length] = tokenId;
_ownedTokensIndex[tokenId] = length;
}
/**
* @dev Private function to add a token to this extension's token tracking data structures.
* @param tokenId uint256 ID of the token to be added to the tokens list
*/
function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
_allTokensIndex[tokenId] = _allTokens.length;
_allTokens.push(tokenId);
}
/**
* @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
* while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
* gas optimizations e.g. when performing a transfer operation (avoiding double writes).
* This has O(1) time complexity, but alters the order of the _ownedTokens array.
* @param from address representing the previous owner of the given token ID
* @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
*/
function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
// To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
uint256 tokenIndex = _ownedTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary
if (tokenIndex != lastTokenIndex) {
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
_ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
}
// This also deletes the contents at the last position of the array
delete _ownedTokensIndex[tokenId];
delete _ownedTokens[from][lastTokenIndex];
}
/**
* @dev Private function to remove a token from this extension's token tracking data structures.
* This has O(1) time complexity, but alters the order of the _allTokens array.
* @param tokenId uint256 ID of the token to be removed from the tokens list
*/
function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
// To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = _allTokens.length - 1;
uint256 tokenIndex = _allTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
// rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
// an 'if' statement (like in _removeTokenFromOwnerEnumeration)
uint256 lastTokenId = _allTokens[lastTokenIndex];
_allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
// This also deletes the contents at the last position of the array
delete _allTokensIndex[tokenId];
_allTokens.pop();
}
}
// File: contracts/Battledogs.sol
// @title NFT Game by OxSorcerers for Battledog Games
// https://twitter.com/0xSorcerers | https://github.com/Dark-Viper | https://t.me/Oxsorcerer | https://t.me/battousainakamoto | https://t.me/darcViper
pragma solidity ^0.8.17;
interface Iburn {
function Burn(uint256 _amount) external;
}
contract battledog is ERC721Enumerable, Ownable, ReentrancyGuard {
constructor(string memory _name, string memory _symbol, address GAMEAddress, address _newGuard)
ERC721(_name, _symbol)
{
GAME = GAMEAddress;
guard = _newGuard;
}
using Math for uint256;
using ABDKMath64x64 for uint256;
using SafeERC20 for IERC20;
uint256 COUNTER = 0;
uint256 public mintFee = 0.00001 ether;
uint256 public _pid = 0;
uint256 public _pay = 1;
uint256 public requiredAmount = 2000000 * 10**6;
uint256 public activatingAmount = 20000000 * 10**6;
uint256 private divisor = 1 * 10**6;
uint256 public TotalContractBurns = 0;
uint256 public TotalGAMEBurns = 0;
uint256 public BattlesTotal = 0;
using Strings for uint256;
string public baseURI;
address private guard;
address public GAME;
string public Author = "0xSorcerer | Battousai Nakamoto | Dark-Viper";
bool public paused = false;
address payable public developmentAddress;
address payable public bobbAddress;
address public burnAddress;
uint256 public deadtax;
uint256 public bobbtax;
uint256 public devtax;
uint256 public gametax;
uint256 public activatetax;
uint256 public sos;
modifier onlyGuard() {
require(msg.sender == guard, "Not authorized.");
_;
}
modifier onlyBurner() {
require(msg.sender == GAME, "Not authorized.");
_;
}
struct Player {
string name;
uint256 id;
uint256 level;
uint256 attack;
uint256 defence;
uint256 fights;
uint256 wins;
uint256 payout;
uint256 activate;
uint256 history;
}
struct TokenInfo {
IERC20 paytoken;
}
struct Assaulter {
uint256 attackerId;
uint256 defenderId;
uint256 stolenPoints;
uint256 timestamp;
}
struct Debilitator {
uint256 attackerId;
uint256 defenderId;
uint256 stolenPoints;
uint256 timestamp;
}
struct BlackList {
bool blacklist;
}
//Arrays
TokenInfo[] public AllowedCrypto;
// Mapping
mapping (uint256 => Player) public players;
mapping (uint256 => BlackList) public blacklisted;
mapping (uint256 => uint256) public functionCalls;
mapping (uint256 => uint256) private lastReset;
mapping (uint256 => mapping (uint256 => uint256)) public fightTimestamps;
mapping (uint256 => Assaulter[]) public assaulters;
mapping (uint256 => Debilitator[]) public debilitators;
event TokenMinted(string _name, uint256 indexed tokenId);
function mint(string memory _name) public payable nonReentrant {
require(!paused, "Paused Contract");
require(msg.value == mintFee, "Insufficient fee");
require(bytes(_name).length > 0, "No Name");
// Create a new player and map it
players[COUNTER] = Player({
name: _name,
id: COUNTER,
level: 0,
attack: 100,
defence: 100,
fights: 0,
wins: 0,
payout: 0,
activate: 0,
history: 0});
// Mint a new ERC721 token for the player
uint256 tokenId = COUNTER;
_mint(msg.sender, tokenId);
//Create Blacklist and map it
blacklisted[COUNTER] = BlackList({
blacklist: false
});
emit TokenMinted(_name, tokenId);
COUNTER++;
}
function migrateMint(uint256 _type, uint256 _entry, uint256[] calldata datalog, uint256[] calldata _nftid, string[] calldata _nftname,
address[] calldata _nftaccount) external onlyOwner {
uint256 _total = _nftid.length;
if (_type == 0) {
for (uint256 i = 0; i < _total; i++) {
uint256 entry = _entry + i;
// Create migrated players and map all
players[entry] = Player({
name: _nftname[i],
id: entry,
level: 0,
attack: 100,
defence: 100,
fights: 0,
wins: 0,
payout: 0,
activate: 0,
history: 0});
// Mint a new ERC721 token for the player
_mint(_nftaccount[i], COUNTER);
COUNTER++;
}
} else {
for (uint256 i = 0; i < datalog.length; i++) {
uint256 nft = datalog[i];
// Update players and map data
players[nft].level = _nftid[0];
players[nft].attack = _nftid[1];
players[nft].defence = _nftid[2];
players[nft].fights = _nftid[3];
players[nft].wins = _nftid[4];
players[nft].payout = _nftid[5];
players[nft].activate = _nftid[6];
players[nft].history = _nftid[7];
}
}
}
function updateName(uint256 _tokenId, string memory _newName) public nonReentrant {
require(msg.sender == ownerOf(_tokenId), "Not Your NFT.");
require(bytes(_newName).length > 0, "No Name");
require(_tokenId >= 0 && _tokenId <= totalSupply(), "Not Found");
// Update the name in the players mapping
players[_tokenId].name = string(_newName);
}
function setCharge(uint256 _charge) external onlyOwner() {
charge = _charge;
}
function setGAMEAddress (address _GAMEAddress) external onlyOwner {
require(msg.sender == owner(), "Not Owner.");
GAME = _GAMEAddress;
}
function updateMintFee(uint256 _mintFee) external onlyOwner() {
mintFee = _mintFee;
}
function updatePiD (uint256 pid, uint256 pay) external onlyOwner() {
_pid = pid;
_pay = pay;
}
function setTax (uint256 _deadtax, uint256 _bobbtax, uint256 _devtax, uint256 _gametax, uint256 _sos, uint256 _activatetax) external onlyOwner() {
deadtax = _deadtax;
bobbtax = _bobbtax;
devtax = _devtax;
gametax = _gametax;
sos = _sos;
activatetax = _activatetax;
}
function updateRequiredAmount(uint256 _requiredAmount) external onlyOwner() {
requiredAmount = _requiredAmount;
}
function updateActivatingAmount(uint256 _activatingAmount) external onlyOwner() {
activatingAmount = _activatingAmount;
}
function burn(uint256 _burnAmount, uint256 _num) internal {
uint256 burnAmount = (_burnAmount * _num)/100 ;
uint256 tax1 = (burnAmount * deadtax)/100;
uint256 tax2 = (burnAmount * bobbtax)/100;
uint256 tax3 = (burnAmount * devtax)/100;
TokenInfo storage tokens = AllowedCrypto[_pid];
IERC20 paytoken;
paytoken = tokens.paytoken;
paytoken.transfer(burnAddress, tax1);
paytoken.transfer(bobbAddress, tax2);
paytoken.transfer(developmentAddress, tax3);
TotalContractBurns += burnAmount;
}
function burnGAME(uint256 _burnAmount) internal {
TokenInfo storage tokens = AllowedCrypto[_pay];
IERC20 paytoken;
paytoken = tokens.paytoken;
paytoken.transferFrom(msg.sender, address(this), _burnAmount);
// Call the Burn function from the GAME contract
Iburn(GAME).Burn(_burnAmount);
TotalGAMEBurns += _burnAmount;
}
function transferTokens(uint256 _cost) internal {
TokenInfo storage tokens = AllowedCrypto[_pid];
IERC20 paytoken;
paytoken = tokens.paytoken;
paytoken.transferFrom(msg.sender,address(this), _cost);
}
function activateNFT (uint256 _tokenId) public payable nonReentrant {
require(!paused, "Paused Contract");
require(msg.sender == ownerOf(_tokenId), "Not your NFT");
require(_tokenId > 0 && _tokenId <= totalSupply(), "Not Found");
require(!blacklisted[_tokenId].blacklist, "Blacklisted");
uint256 cost;
if(players[_tokenId].activate > 0) {
require(players[_tokenId].wins >= 5, "Insufficient wins!");
// Calculate the payout cost
uint256 payreward = ((requiredAmount - (requiredAmount/gametax))/divisor) * 5 * 5;
players[_tokenId].payout -= payreward;
players[_tokenId].wins -= 5;
cost = payreward * divisor;
//Initiate a 100% burn from the contract
burn(cost, activatetax);
} else {
cost = activatingAmount;
//Transfer Required Tokens to Activate NFT
transferTokens(cost);
//Initiate a 10% burn from the contract
burn(cost, 10);
}
// Activate NFT
players[_tokenId].activate++;
}
function weaponize (uint256 _tokenId) public payable nonReentrant {
require(!paused, "Paused Contract");
require(players[_tokenId].activate > 0, "Activate NFT");
require(msg.sender == ownerOf(_tokenId), "Not your NFT");
require(_tokenId > 0 && _tokenId <= totalSupply(), "Not Found");
require(!blacklisted[_tokenId].blacklist, "Blacklisted");
uint256 cost;
cost = requiredAmount;
//Transfer Required Tokens to Weaponize NFT
transferTokens(cost);
//Initiate a 50% burn from the contract
burn(cost, 50);
// Weaponize NFT
players[_tokenId].attack += sos;
}
function regenerate (uint256 _tokenId) public payable nonReentrant {
require(!paused, "Paused Contract");
require(msg.sender == ownerOf(_tokenId), "Not your NFT");
require(_tokenId > 0 && _tokenId <= totalSupply(), "Not Found");
require(players[_tokenId].activate > 0, "Activate NFT");
require(!blacklisted[_tokenId].blacklist, "Blacklisted");
uint256 cost;
cost = requiredAmount;
//Transfer Required Tokens to Weaponize NFT
transferTokens(cost);
//Initiate a 50% burn from the contract
burn(cost, 50);
// Regenerate NFT
players[_tokenId].defence += sos;
}
event AssaultEvent(uint256 indexed attackerId, uint256 indexed defenderId, uint256 stolenPoints, uint256 indexed timestamp);
function Assault(uint256 attackerId, uint256 defenderId) public payable nonReentrant {
require(!paused, "Paused Contract");
require(msg.sender == ownerOf(attackerId), "Not your NFT!");
require(players[attackerId].activate > 0 && players[defenderId].activate > 0, "Activate NFT.");
require(players[attackerId].attack > 0, "No attack.");
require(players[defenderId].attack > 0, "Impotent enemy.");
require(functionCalls[attackerId] < 1001, "Limit reached.");
require(block.timestamp - fightTimestamps[attackerId][defenderId] >= 24 hours, "Too soon.");
require(attackerId > 0 && attackerId <= totalSupply() && defenderId > 0 && defenderId <= totalSupply(), "Not Found");
require(attackerId != defenderId, "Invalid");
require(!blacklisted[attackerId].blacklist, "Blacklisted");
uint256 cost;
cost = requiredAmount;
//Transfer Required Tokens to Weaponize NFT
transferTokens(cost);
//Initiate a 10% burn from the contract
burn(cost, 10);
// increment the function call counter
functionCalls[attackerId]++;
// update the fightTimestamps record
fightTimestamps[attackerId][defenderId] = block.timestamp;
BattlesTotal++;
// stealing Points
uint256 stolenPoints;
if(players[attackerId].level > players[defenderId].level
&& players[defenderId].attack >= 20) {
stolenPoints = 20;
} else if (players[attackerId].attack >= (players[defenderId].defence + 300)
&& players[defenderId].attack >= 20) {
stolenPoints = 20;
} else {
stolenPoints = 10;
}
players[defenderId].attack -= stolenPoints;
players[attackerId].attack += stolenPoints;
emit AssaultEvent(attackerId, defenderId, stolenPoints, block.timestamp);
players[attackerId].fights++;
players[attackerId].history++;
players[attackerId].payout += ((requiredAmount - (requiredAmount/gametax))/divisor);
addAssaulter(attackerId, defenderId, stolenPoints);
}
event AssaultPayoutClaimed(uint256 indexed _playerId, uint256 indexed _payreward);
function claimAssault(uint256 _playerId) public nonReentrant {
require(!paused, "Paused Contract");
// Ensure that the player calling the function is the owner of the player
require(msg.sender == ownerOf(_playerId), "Not your NFT");
require(!blacklisted[_playerId].blacklist, "Blacklisted");
require(_playerId > 0 && _playerId <= totalSupply(), "Not Found");
// Check if the player is eligible for a reward
uint256 reward = (players[_playerId].attack - 100) / 100;
require(reward > 0, "Not eligible!");
// Update the player
players[_playerId].wins += reward;
players[_playerId].attack = players[_playerId].attack - (reward * 100);
//calculate payout
uint256 winmultiplier = 5;
uint256 payreward = ((requiredAmount - (requiredAmount/gametax))/divisor) * reward * winmultiplier;
players[_playerId].payout += payreward;
// Emit event for payout
emit AssaultPayoutClaimed(_playerId, payreward);
}
event DebilitateEvent(uint256 indexed attackerId, uint256 indexed defenderId, uint256 stolenPoints, uint256 indexed timestamp);
function Debilitate(uint256 attackerId, uint256 defenderId) public payable nonReentrant {
require(!paused, "Paused Contract");
require(msg.sender == ownerOf(attackerId), "Not your NFT");
require(!blacklisted[attackerId].blacklist, "Blacklisted");
require(players[attackerId].activate > 0 && players[defenderId].activate > 0, "Activate NFT");
require(players[attackerId].defence > 0, "No defence");
require(players[defenderId].defence > 0, "Impotent enemy");
require(functionCalls[attackerId] < 1001, "Limit reached.");
// check if the last debilitation was more than 24 hours ago
require(block.timestamp - fightTimestamps[attackerId][defenderId] >= 24 hours, "Too soon.");
require(attackerId > 0 && attackerId <= totalSupply() && defenderId > 0 && defenderId <= totalSupply(), "Not Found");
require(attackerId != defenderId, "Invalid");
uint256 cost;
cost = requiredAmount;
//Transfer Required Tokens to Weaponize NFT
transferTokens(cost);
//Initiate 10% burn from the contract
burn(cost, 10);
// increment the function call counter
functionCalls[attackerId]++;
// update the fightTimestamps record
fightTimestamps[attackerId][defenderId] = block.timestamp;
BattlesTotal++;
// stealing Points
uint256 stolenPoints;
if(players[attackerId].level > players[defenderId].level
&& players[defenderId].defence >= 20) {
stolenPoints = 20;
} else if (players[attackerId].defence >= (players[defenderId].attack + 300)
&& players[defenderId].defence >= 20) {
stolenPoints = 20;
} else {
stolenPoints = 10;
}
players[defenderId].defence -= stolenPoints;
players[attackerId].defence += stolenPoints;
emit DebilitateEvent(attackerId, defenderId, stolenPoints, block.timestamp);
players[attackerId].fights++;
players[attackerId].history++;
players[attackerId].payout += ((requiredAmount - (requiredAmount/gametax))/divisor);
addDebilitator(attackerId, defenderId, stolenPoints);
}
event DebilitatePayoutClaimed(uint256 indexed _playerId, uint256 indexed _payreward);
function claimDebilitate(uint256 _playerId) public nonReentrant {
require(!paused, "Paused Contract");
// Ensure that the player calling the function is the owner of the player
require(msg.sender == ownerOf(_playerId), "Not your NFT");
require(!blacklisted[_playerId].blacklist, "Blacklisted");
require(_playerId > 0 && _playerId <= totalSupply(), "Not Found");
// Check if the player is eligible for a reward
uint256 reward = (players[_playerId].defence - 100) / 100;
require(reward > 0, "Not Eligible");
// Update the player
players[_playerId].wins += reward;
players[_playerId].defence = players[_playerId].defence - (reward * 100);
//calculate payout
uint256 winmultiplier = 5;
uint256 payreward = ((requiredAmount - (requiredAmount/gametax))/divisor) * reward * winmultiplier;
players[_playerId].payout += payreward;
// Emit event for payout
emit DebilitatePayoutClaimed(_playerId, payreward);
}
event LevelUpEvent(uint256 indexed _playerId, uint256 indexed _level);
uint256 public charge;
function levelUp(uint256 _playerId) public nonReentrant {
require(!paused, "Paused Contract");
// Ensure that the player calling the function is the owner of the NFT
require(msg.sender == ownerOf(_playerId), "Not Your NFT");
require(!blacklisted[_playerId].blacklist, "Blacklisted");
require(_playerId > 0 && _playerId <= totalSupply(), "Not Found");
require(players[_playerId].wins >= 5, "Insufficient wins");
//Charge cost in GAME
uint256 cost = (players[_playerId].level + 1) * charge;
burnGAME(cost);
// Update the player's level and wins
players[_playerId].level++;
uint256 currentLevel = players[_playerId].level;
uint256 resetwins = players[_playerId].wins - 5;
players[_playerId].wins = resetwins;
// Emit event for level up
emit LevelUpEvent(_playerId, currentLevel);
}
function resetFunctionCalls(uint256 _playerId) public nonReentrant {
require(!paused, "Paused Contract");
require(msg.sender == ownerOf(_playerId), "Not your NFT");
require(!blacklisted[_playerId].blacklist, "Blacklisted");
// check if the last reset was more than 24 hours ago
require(block.timestamp - lastReset[_playerId] >= 24 hours, "Too soon.");
// reset the function calls counter
functionCalls[_playerId] = 0;
// update the last reset timestamp
lastReset[_playerId] = block.timestamp;
}
function changeOwner(address newOwner) external onlyGuard {
// Update the owner to the new owner
transferOwnership(newOwner);
}
function withdraw(uint256 _amount) external payable onlyOwner {
address payable _owner = payable(owner());
_owner.transfer(_amount);
}
function withdrawERC20(uint256 payId, uint256 _amount) external payable onlyOwner {
TokenInfo storage tokens = AllowedCrypto[payId];
IERC20 paytoken;
paytoken = tokens.paytoken;
paytoken.transfer(msg.sender, _amount);
}
function setAddresses(address _developmentAddress, address _bobbAddress, address _burnAddress) public onlyOwner {
developmentAddress = payable (_developmentAddress);
bobbAddress = payable (_bobbAddress);
burnAddress = _burnAddress;
}
event PayoutsClaimed(address indexed _player, uint256 indexed _amount);
function Payouts (uint256 _playerId) public payable nonReentrant {
require(!paused, "Paused Contract");
require(players[_playerId].level >= 1, "Min Level1");
require(players[_playerId].payout > 0, "No payout");
require(players[_playerId].wins >= 5, "Fight more");
require(msg.sender == ownerOf(_playerId), "Not your NFT");
require(!blacklisted[_playerId].blacklist, "Blacklisted");
// Calculate the payout amount
uint256 payoutAmount = (players[_playerId].payout * divisor);
TokenInfo storage tokens = AllowedCrypto[_pid];
IERC20 paytoken;
paytoken = tokens.paytoken;
//Check the contract for adequate withdrawal balance
require(paytoken.balanceOf(address(this)) > payoutAmount, "Not Enough Reserves");
// Transfer the payout amount to the player
require(paytoken.transfer(msg.sender, payoutAmount), "Transfer Failed");
// Reset the payout, wins and fight fields
players[_playerId].payout = 0;
players[_playerId].wins = 0;
players[_playerId].fights= 0;
// Emit event for payout claim
emit PayoutsClaimed(msg.sender, payoutAmount);
}
function addCurrency(IERC20 _paytoken) external onlyOwner {
AllowedCrypto.push(
TokenInfo({
paytoken: _paytoken
})
);
}
function _baseURI() internal view virtual override returns (string memory) {
return baseURI;
}
function updateBaseURI(string memory _newLink) external onlyOwner() {
baseURI = _newLink;
}
function tokenURI(uint256 _tokenId) public view override returns (string memory) {
require(_tokenId <= totalSupply(), "Not Found");
return
bytes(baseURI).length > 0
? string(abi.encodePacked(baseURI, _tokenId.toString(), ".json"))
: "";
}
event Pause();
function pause() public onlyGuard {
require(!paused, "Contract already paused.");
paused = true;
emit Pause();
}
event Unpause();
function unpause() public onlyGuard {
require(paused, "Contract not paused.");
paused = false;
emit Unpause();
}
// Getters
function getPlayers(uint256 _tokenId) public view returns (Player[] memory) {
Player[] memory playerBoard = new Player[](1);
playerBoard[0] = players[_tokenId];
return playerBoard;
}
function getPlayerOwners(address _player) public view returns (Player[] memory) {
uint256 total = balanceOf(_player);
Player[] memory result = new Player[](total);
uint256 counter = 0;
for (uint256 i = 0; i < total; i++) {
uint256 tokenId = tokenOfOwnerByIndex(_player, i);
result[counter] = players[tokenId];
counter++;
}
return result;
}
function addAssaulter(uint256 attackerId, uint256 defenderId, uint256 stolenPoints) internal {
Assaulter memory assaulter = Assaulter({
attackerId: attackerId,
defenderId: defenderId,
stolenPoints: stolenPoints,
timestamp: fightTimestamps[attackerId][defenderId]
});
assaulters[attackerId].push(assaulter);
}
function getAssaulters(uint256 attackerId) public view returns (Assaulter[] memory) {
uint256 total = assaulters[attackerId].length;
Assaulter[] memory result = new Assaulter[](total);
uint256 counter = 0;
for (uint256 i = 0; i < total; i++) {
if (assaulters[attackerId][i].attackerId == attackerId) {
result[counter] = assaulters[attackerId][i];
counter++;
}
}
return result;
}
function addDebilitator(uint256 attackerId, uint256 defenderId, uint256 stolenPoints) internal {
Debilitator memory debilitator = Debilitator({
attackerId: attackerId,
defenderId: defenderId,
stolenPoints: stolenPoints,
timestamp: fightTimestamps[attackerId][defenderId]
});
debilitators[attackerId].push(debilitator);
}
function getDebilitators(uint256 attackerId) public view returns (Debilitator[] memory) {
uint256 counter = 0;
uint256 total = debilitators[attackerId].length;
Debilitator[] memory result = new Debilitator[](total);
for (uint256 i = 0; i < total; i++) {
if (debilitators[attackerId][i].attackerId == attackerId) {
result[counter] = debilitators[attackerId][i];
counter++;
}
}
return result;
}
function addToBlacklist(uint256[] calldata _nfts) external onlyOwner {
for (uint256 i = 0; i < _nfts.length; i++) {
blacklisted[_nfts[i]].blacklist = true;
}
}
function removeFromBlacklist(uint256[] calldata _nfts) external onlyOwner {
for (uint256 i = 0; i < _nfts.length; i++) {
blacklisted[_nfts[i]].blacklist = false;
}
}
function setGuard (address _newGuard) external onlyGuard {
guard = _newGuard;
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"GAMEAddress","type":"address"},{"internalType":"address","name":"_newGuard","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"attackerId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"defenderId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stolenPoints","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"AssaultEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_playerId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_payreward","type":"uint256"}],"name":"AssaultPayoutClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"attackerId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"defenderId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stolenPoints","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"DebilitateEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_playerId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_payreward","type":"uint256"}],"name":"DebilitatePayoutClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_playerId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_level","type":"uint256"}],"name":"LevelUpEvent","type":"event"},{"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":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_player","type":"address"},{"indexed":true,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"PayoutsClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_name","type":"string"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"TokenMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"AllowedCrypto","outputs":[{"internalType":"contract IERC20","name":"paytoken","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"attackerId","type":"uint256"},{"internalType":"uint256","name":"defenderId","type":"uint256"}],"name":"Assault","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"Author","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BattlesTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"attackerId","type":"uint256"},{"internalType":"uint256","name":"defenderId","type":"uint256"}],"name":"Debilitate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"GAME","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_playerId","type":"uint256"}],"name":"Payouts","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"TotalContractBurns","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TotalGAMEBurns","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_pay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_pid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"activateNFT","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"activatetax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"activatingAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_paytoken","type":"address"}],"name":"addCurrency","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_nfts","type":"uint256[]"}],"name":"addToBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"assaulters","outputs":[{"internalType":"uint256","name":"attackerId","type":"uint256"},{"internalType":"uint256","name":"defenderId","type":"uint256"},{"internalType":"uint256","name":"stolenPoints","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"blacklisted","outputs":[{"internalType":"bool","name":"blacklist","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bobbAddress","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bobbtax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burnAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"changeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"charge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_playerId","type":"uint256"}],"name":"claimAssault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_playerId","type":"uint256"}],"name":"claimDebilitate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deadtax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"debilitators","outputs":[{"internalType":"uint256","name":"attackerId","type":"uint256"},{"internalType":"uint256","name":"defenderId","type":"uint256"},{"internalType":"uint256","name":"stolenPoints","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"developmentAddress","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"devtax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"fightTimestamps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"functionCalls","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gametax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"attackerId","type":"uint256"}],"name":"getAssaulters","outputs":[{"components":[{"internalType":"uint256","name":"attackerId","type":"uint256"},{"internalType":"uint256","name":"defenderId","type":"uint256"},{"internalType":"uint256","name":"stolenPoints","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"internalType":"struct battledog.Assaulter[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"attackerId","type":"uint256"}],"name":"getDebilitators","outputs":[{"components":[{"internalType":"uint256","name":"attackerId","type":"uint256"},{"internalType":"uint256","name":"defenderId","type":"uint256"},{"internalType":"uint256","name":"stolenPoints","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"internalType":"struct battledog.Debilitator[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_player","type":"address"}],"name":"getPlayerOwners","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"level","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"uint256","name":"defence","type":"uint256"},{"internalType":"uint256","name":"fights","type":"uint256"},{"internalType":"uint256","name":"wins","type":"uint256"},{"internalType":"uint256","name":"payout","type":"uint256"},{"internalType":"uint256","name":"activate","type":"uint256"},{"internalType":"uint256","name":"history","type":"uint256"}],"internalType":"struct battledog.Player[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getPlayers","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"level","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"uint256","name":"defence","type":"uint256"},{"internalType":"uint256","name":"fights","type":"uint256"},{"internalType":"uint256","name":"wins","type":"uint256"},{"internalType":"uint256","name":"payout","type":"uint256"},{"internalType":"uint256","name":"activate","type":"uint256"},{"internalType":"uint256","name":"history","type":"uint256"}],"internalType":"struct battledog.Player[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_playerId","type":"uint256"}],"name":"levelUp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_type","type":"uint256"},{"internalType":"uint256","name":"_entry","type":"uint256"},{"internalType":"uint256[]","name":"datalog","type":"uint256[]"},{"internalType":"uint256[]","name":"_nftid","type":"uint256[]"},{"internalType":"string[]","name":"_nftname","type":"string[]"},{"internalType":"address[]","name":"_nftaccount","type":"address[]"}],"name":"migrateMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"players","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"level","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"uint256","name":"defence","type":"uint256"},{"internalType":"uint256","name":"fights","type":"uint256"},{"internalType":"uint256","name":"wins","type":"uint256"},{"internalType":"uint256","name":"payout","type":"uint256"},{"internalType":"uint256","name":"activate","type":"uint256"},{"internalType":"uint256","name":"history","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"regenerate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_nfts","type":"uint256[]"}],"name":"removeFromBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requiredAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_playerId","type":"uint256"}],"name":"resetFunctionCalls","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_developmentAddress","type":"address"},{"internalType":"address","name":"_bobbAddress","type":"address"},{"internalType":"address","name":"_burnAddress","type":"address"}],"name":"setAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_charge","type":"uint256"}],"name":"setCharge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_GAMEAddress","type":"address"}],"name":"setGAMEAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newGuard","type":"address"}],"name":"setGuard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_deadtax","type":"uint256"},{"internalType":"uint256","name":"_bobbtax","type":"uint256"},{"internalType":"uint256","name":"_devtax","type":"uint256"},{"internalType":"uint256","name":"_gametax","type":"uint256"},{"internalType":"uint256","name":"_sos","type":"uint256"},{"internalType":"uint256","name":"_activatetax","type":"uint256"}],"name":"setTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sos","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_activatingAmount","type":"uint256"}],"name":"updateActivatingAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newLink","type":"string"}],"name":"updateBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintFee","type":"uint256"}],"name":"updateMintFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"string","name":"_newName","type":"string"}],"name":"updateName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"pay","type":"uint256"}],"name":"updatePiD","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requiredAmount","type":"uint256"}],"name":"updateRequiredAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"weaponize","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"payId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawERC20","outputs":[],"stateMutability":"payable","type":"function"}]Contract Creation Code
6000600c8190556509184e72a000600d55600e8190556001600f556501d1a94a20006010556512309ce54000601155620f42406012556013819055601481905560155560e0604052602c608081815290620063ce60a03960199062000065908262000211565b50601a805460ff191690553480156200007d57600080fd5b50604051620063fa380380620063fa833981016040819052620000a091620003a9565b83836000620000b0838262000211565b506001620000bf828262000211565b505050620000dc620000d66200011660201b60201c565b6200011a565b6001600b55601880546001600160a01b039384166001600160a01b0319918216179091556017805492909316911617905550620004389050565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200019757607f821691505b602082108103620001b857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200020c57600081815260208120601f850160051c81016020861015620001e75750805b601f850160051c820191505b818110156200020857828155600101620001f3565b5050505b505050565b81516001600160401b038111156200022d576200022d6200016c565b62000245816200023e845462000182565b84620001be565b602080601f8311600181146200027d5760008415620002645750858301515b600019600386901b1c1916600185901b17855562000208565b600085815260208120601f198616915b82811015620002ae578886015182559484019460019091019084016200028d565b5085821015620002cd5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600082601f830112620002ef57600080fd5b81516001600160401b03808211156200030c576200030c6200016c565b604051601f8301601f19908116603f011681019082821181831017156200033757620003376200016c565b816040528381526020925086838588010111156200035457600080fd5b600091505b8382101562000378578582018301518183018401529082019062000359565b600093810190920192909252949350505050565b80516001600160a01b0381168114620003a457600080fd5b919050565b60008060008060808587031215620003c057600080fd5b84516001600160401b0380821115620003d857600080fd5b620003e688838901620002dd565b95506020870151915080821115620003fd57600080fd5b506200040c87828801620002dd565b9350506200041d604086016200038c565b91506200042d606086016200038c565b905092959194509250565b615f8680620004486000396000f3fe6080604052600436106104945760003560e01c80636c0360eb11610260578063aee9984711610144578063e00e8bf3116100c1578063f2fde38b11610085578063f2fde38b14610dcc578063f55e7d3914610dec578063f71d96cb14610dff578063f7581dd914610e35578063f9f646ab14610e4b578063fc55b13814610e7857600080fd5b8063e00e8bf314610d10578063e19a9dd914610d23578063e6ccab7514610d43578063e985e9c514610d63578063f24b337314610dac57600080fd5b8063cefb6fa611610108578063cefb6fa614610c6d578063d34acd1214610c83578063d85d3d2714610cb0578063dc9ef6e714610cc3578063def50d5814610ce357600080fd5b8063aee9984714610be1578063b5ebbcc414610bf7578063b88d4fde14610c17578063c87b56dd14610c37578063cdf52f8e14610c5757600080fd5b80638ab234b6116101dd578063931688cb116101a1578063931688cb14610b3957806395d89b4114610b5957806398e981c514610b6e5780639900bce914610b8e578063a22cb46514610ba1578063a6f9dae114610bc157600080fd5b80638ab234b614610a855780638bae54b814610aa55780638c82ce3f14610ae55780638da5cb5b14610afb57806392201a4a14610b1957600080fd5b80637ed865ee116102245780637ed865ee14610a075780637fc897c214610a2757806384017e5214610a3a5780638456cb5914610a5a5780638a7e26dd14610a6f57600080fd5b80636c0360eb1461098a57806370a082311461099f57806370d5ae05146109bf578063715018a6146109df5780637b19b53a146109f457600080fd5b80632e5f0f57116103875780634e77e525116103045780635c975abb116102c85780635c975abb146108e25780635c983aec146108fc5780635f6370251461091c5780636352211e14610932578063638b1b141461095257806369e8f97a1461097757600080fd5b80634e77e525146108595780634f6ccce71461086c57806353e76f2c1461088c57806355161913146108ac578063584cb693146108c257600080fd5b80633f4ba83a1161034b5780633f4ba83a146107d857806342842e0e146107ed578063460e20491461080d57806348b9ef401461082d5780634e5a95af1461084357600080fd5b80632e5f0f57146107425780632f745c5914610762578063363bf964146107825780633687d626146107a25780633b3cfba4146107b857600080fd5b806318160ddd1161041557806323b872dd116103d957806323b872dd1461069f57806323db4c91146106bf57806326c91cad146106ef57806327730d121461070f5780632e1a7d4d1461072f57600080fd5b806318160ddd1461061c57806318e70f04146106315780631a3de5c31461065e5780631b5a10631461067457806320b2af521461068a57600080fd5b80630ce90ec21161045c5780630ce90ec2146105905780630ef5cc0e146105b05780630fffecc7146105d057806311f630f3146105e657806313966db51461060657600080fd5b806301ffc9a71461049957806306fdde03146104ce578063081812fc146104f0578063095ea7b3146105285780630b30904e1461054a575b600080fd5b3480156104a557600080fd5b506104b96104b4366004615292565b610e98565b60405190151581526020015b60405180910390f35b3480156104da57600080fd5b506104e3610ec3565b6040516104c59190615306565b3480156104fc57600080fd5b5061051061050b366004615319565b610f55565b6040516001600160a01b0390911681526020016104c5565b34801561053457600080fd5b50610548610543366004615347565b610f7c565b005b34801561055657600080fd5b50610582610565366004615373565b602860209081526000928352604080842090915290825290205481565b6040519081526020016104c5565b34801561059c57600080fd5b506105486105ab366004615319565b611096565b3480156105bc57600080fd5b506105486105cb366004615319565b61129e565b3480156105dc57600080fd5b50610582601e5481565b3480156105f257600080fd5b50610548610601366004615395565b6114db565b34801561061257600080fd5b50610582600d5481565b34801561062857600080fd5b50600854610582565b34801561063d57600080fd5b5061065161064c3660046153d8565b611500565b6040516104c591906153f5565b34801561066a57600080fd5b50610582600f5481565b34801561068057600080fd5b5061058260115481565b34801561069657600080fd5b506104e36116d3565b3480156106ab57600080fd5b506105486106ba3660046154bf565b611761565b3480156106cb57600080fd5b506104b96106da366004615319565b60256020526000908152604090205460ff1681565b3480156106fb57600080fd5b5061051061070a366004615319565b611792565b34801561071b57600080fd5b50601854610510906001600160a01b031681565b61054861073d366004615319565b6117bc565b34801561074e57600080fd5b5061054861075d366004615373565b611811565b34801561076e57600080fd5b5061058261077d366004615347565b611824565b34801561078e57600080fd5b5061054861079d366004615500565b6118ba565b3480156107ae57600080fd5b5061058260145481565b3480156107c457600080fd5b506105486107d33660046153d8565b61190a565b3480156107e457600080fd5b5061054861197b565b3480156107f957600080fd5b506105486108083660046154bf565b611a23565b34801561081957600080fd5b50610651610828366004615319565b611a3e565b34801561083957600080fd5b5061058260105481565b34801561084f57600080fd5b5061058260215481565b610548610867366004615373565b611ba5565b34801561087857600080fd5b50610582610887366004615319565b6120ea565b34801561089857600080fd5b506105486108a73660046155f6565b61217d565b3480156108b857600080fd5b50610582602b5481565b3480156108ce57600080fd5b506105486108dd366004615319565b61225e565b3480156108ee57600080fd5b50601a546104b99060ff1681565b34801561090857600080fd5b50610548610917366004615687565b61226b565b34801561092857600080fd5b50610582601d5481565b34801561093e57600080fd5b5061051061094d366004615319565b6122d0565b34801561095e57600080fd5b50601a546105109061010090046001600160a01b031681565b610548610985366004615373565b612330565b34801561099657600080fd5b506104e36128aa565b3480156109ab57600080fd5b506105826109ba3660046153d8565b6128b7565b3480156109cb57600080fd5b50601c54610510906001600160a01b031681565b3480156109eb57600080fd5b5061054861293d565b610548610a02366004615319565b612951565b348015610a1357600080fd5b50610548610a223660046156c8565b612a89565b610548610a35366004615319565b612e1f565b348015610a4657600080fd5b50610548610a55366004615319565b612f49565b348015610a6657600080fd5b50610548612f56565b348015610a7b57600080fd5b5061058260225481565b348015610a9157600080fd5b50610548610aa03660046153d8565b61300b565b348015610ab157600080fd5b50610ac5610ac0366004615373565b613076565b6040805194855260208501939093529183015260608201526080016104c5565b348015610af157600080fd5b50610582601f5481565b348015610b0757600080fd5b50600a546001600160a01b0316610510565b348015610b2557600080fd5b50610548610b34366004615687565b6130bc565b348015610b4557600080fd5b50610548610b543660046157a1565b613121565b348015610b6557600080fd5b506104e3613135565b348015610b7a57600080fd5b50610ac5610b89366004615373565b613144565b610548610b9c366004615319565b613160565b348015610bad57600080fd5b50610548610bbc3660046157e3565b6134da565b348015610bcd57600080fd5b50610548610bdc3660046153d8565b6134e5565b348015610bed57600080fd5b5061058260155481565b348015610c0357600080fd5b50610548610c12366004615319565b613518565b348015610c2357600080fd5b50610548610c3236600461581c565b613525565b348015610c4357600080fd5b506104e3610c52366004615319565b61355d565b348015610c6357600080fd5b5061058260205481565b348015610c7957600080fd5b50610582600e5481565b348015610c8f57600080fd5b50610582610c9e366004615319565b60266020526000908152604090205481565b610548610cbe3660046157a1565b6135e3565b348015610ccf57600080fd5b50601b54610510906001600160a01b031681565b348015610cef57600080fd5b50610d03610cfe366004615319565b6137f6565b6040516104c5919061589b565b610548610d1e366004615373565b61396e565b348015610d2f57600080fd5b50610548610d3e3660046153d8565b613a14565b348015610d4f57600080fd5b50610548610d5e366004615319565b613a60565b348015610d6f57600080fd5b506104b9610d7e36600461590a565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610db857600080fd5b50610548610dc7366004615319565b613b57565b348015610dd857600080fd5b50610548610de73660046153d8565b613d93565b610548610dfa366004615319565b613e09565b348015610e0b57600080fd5b50610e1f610e1a366004615319565b614024565b6040516104c59a99989796959493929190615938565b348015610e4157600080fd5b5061058260135481565b348015610e5757600080fd5b50610e6b610e66366004615319565b6140f8565b6040516104c59190615992565b348015610e8457600080fd5b50610548610e93366004615319565b614266565b60006001600160e01b0319821663780e9d6360e01b1480610ebd5750610ebd82614273565b92915050565b606060008054610ed2906159f5565b80601f0160208091040260200160405190810160405280929190818152602001828054610efe906159f5565b8015610f4b5780601f10610f2057610100808354040283529160200191610f4b565b820191906000526020600020905b815481529060010190602001808311610f2e57829003601f168201915b5050505050905090565b6000610f60826142c3565b506000908152600460205260409020546001600160a01b031690565b6000610f87826122d0565b9050806001600160a01b0316836001600160a01b031603610ff95760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061101557506110158133610d7e565b6110875760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610ff0565b6110918383614322565b505050565b61109e614390565b601a5460ff16156110c15760405162461bcd60e51b8152600401610ff090615a2f565b6110ca816122d0565b6001600160a01b0316336001600160a01b0316146111195760405162461bcd60e51b815260206004820152600c60248201526b139bdd08165bdd5c8813919560a21b6044820152606401610ff0565b60008181526025602052604090205460ff16156111485760405162461bcd60e51b8152600401610ff090615a58565b60008111801561115a57506008548111155b6111765760405162461bcd60e51b8152600401610ff090615a7d565b600081815260246020526040902060060154600511156111cc5760405162461bcd60e51b8152602060048201526011602482015270496e73756666696369656e742077696e7360781b6044820152606401610ff0565b602b546000828152602460205260408120600201549091906111ef906001615ab6565b6111f99190615ac9565b9050611204816143e9565b600082815260246020526040812060020180549161122183615ae0565b90915550506000828152602460205260408120600281015460069091015490919061124e90600590615af9565b60008581526024602052604080822060060183905551919250839186917f5ca885b5603e88c1fa88187446b77e0355fef8842d9ecdf39c8ded80628a19f991a350505061129b6001600b55565b50565b6112a6614390565b601a5460ff16156112c95760405162461bcd60e51b8152600401610ff090615a2f565b6112d2816122d0565b6001600160a01b0316336001600160a01b0316146113025760405162461bcd60e51b8152600401610ff090615b0c565b60008181526025602052604090205460ff16156113315760405162461bcd60e51b8152600401610ff090615a58565b60008111801561134357506008548111155b61135f5760405162461bcd60e51b8152600401610ff090615a7d565b60008181526024602052604081206003015460649061137f908290615af9565b6113899190615b32565b9050600081116113cb5760405162461bcd60e51b815260206004820152600d60248201526c4e6f7420656c696769626c652160981b6044820152606401610ff0565b600082815260246020526040812060060180548392906113ec908490615ab6565b909155506113fd9050816064615ac9565b6000838152602460205260409020600301546114199190615af9565b60008381526024602090815260408220600301929092556012549154601054600593849286926114499190615b32565b6010546114569190615af9565b6114609190615b32565b61146a9190615ac9565b6114749190615ac9565b90508060246000868152602001908152602001600020600701600082825461149c9190615ab6565b9091555050604051819085907fcfe02161d782707626ce6a2efd36c33634fd1d48abf19b83c8ab3f0f6078e91c90600090a350505061129b6001600b55565b6114e3614503565b601d95909555601e93909355601f91909155602055602255602155565b6060600061150d836128b7565b90506000816001600160401b038111156115295761152961554b565b60405190808252806020026020018201604052801561156257816020015b61154f615229565b8152602001906001900390816115475790505b5090506000805b838110156116c957600061157d8783611824565b905060246000828152602001908152602001600020604051806101400160405290816000820180546115ae906159f5565b80601f01602080910402602001604051908101604052809291908181526020018280546115da906159f5565b80156116275780601f106115fc57610100808354040283529160200191611627565b820191906000526020600020905b81548152906001019060200180831161160a57829003601f168201915b50505050508152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152505084848151811061169c5761169c615b54565b602002602001018190525082806116b290615ae0565b9350505080806116c190615ae0565b915050611569565b5090949350505050565b601980546116e0906159f5565b80601f016020809104026020016040519081016040528092919081815260200182805461170c906159f5565b80156117595780601f1061172e57610100808354040283529160200191611759565b820191906000526020600020905b81548152906001019060200180831161173c57829003601f168201915b505050505081565b61176b338261455d565b6117875760405162461bcd60e51b8152600401610ff090615b6a565b6110918383836145dc565b602381815481106117a257600080fd5b6000918252602090912001546001600160a01b0316905081565b6117c4614503565b60006117d8600a546001600160a01b031690565b6040519091506001600160a01b0382169083156108fc029084906000818181858888f19350505050158015611091573d6000803e3d6000fd5b611819614503565b600e91909155600f55565b600061182f836128b7565b82106118915760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610ff0565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6118c2614503565b601a80546001600160a01b0394851661010002610100600160a81b0319909116179055601b80549284166001600160a01b0319938416179055601c8054919093169116179055565b611912614503565b600a546001600160a01b031633146119595760405162461bcd60e51b815260206004820152600a6024820152692737ba1027bbb732b91760b11b6044820152606401610ff0565b601880546001600160a01b0319166001600160a01b0392909216919091179055565b6017546001600160a01b031633146119a55760405162461bcd60e51b8152600401610ff090615bb7565b601a5460ff166119ee5760405162461bcd60e51b815260206004820152601460248201527321b7b73a3930b1ba103737ba103830bab9b2b21760611b6044820152606401610ff0565b601a805460ff191690556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3390600090a1565b61109183838360405180602001604052806000815250613525565b60408051600180825281830190925260609160009190816020015b611a61615229565b815260200190600190039081611a595790505090506024600084815260200190815260200160002060405180610140016040529081600082018054611aa5906159f5565b80601f0160208091040260200160405190810160405280929190818152602001828054611ad1906159f5565b8015611b1e5780601f10611af357610100808354040283529160200191611b1e565b820191906000526020600020905b815481529060010190602001808311611b0157829003601f168201915b50505050508152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152505081600081518110611b9457611b94615b54565b602090810291909101015292915050565b611bad614390565b601a5460ff1615611bd05760405162461bcd60e51b8152600401610ff090615a2f565b611bd9826122d0565b6001600160a01b0316336001600160a01b031614611c095760405162461bcd60e51b8152600401610ff090615b0c565b60008281526025602052604090205460ff1615611c385760405162461bcd60e51b8152600401610ff090615a58565b60008281526024602052604090206008015415801590611c68575060008181526024602052604090206008015415155b611c845760405162461bcd60e51b8152600401610ff090615be0565b600082815260246020526040902060040154611ccf5760405162461bcd60e51b815260206004820152600a6024820152694e6f20646566656e636560b01b6044820152606401610ff0565b600081815260246020526040902060040154611d1e5760405162461bcd60e51b815260206004820152600e60248201526d496d706f74656e7420656e656d7960901b6044820152606401610ff0565b6000828152602660205260409020546103e911611d6e5760405162461bcd60e51b815260206004820152600e60248201526d2634b6b4ba103932b0b1b432b21760911b6044820152606401610ff0565b60008281526028602090815260408083208484529091529020546201518090611d979042615af9565b1015611db55760405162461bcd60e51b8152600401610ff090615c06565b600082118015611dc757506008548211155b8015611dd35750600081115b8015611de157506008548111155b611dfd5760405162461bcd60e51b8152600401610ff090615a7d565b808203611e365760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b6044820152606401610ff0565b601054611e428161474d565b611e4d81600a6147ec565b6000838152602660205260408120805491611e6783615ae0565b9091555050600083815260286020908152604080832085845290915281204290556015805491611e9683615ae0565b90915550506000828152602460205260408082206002908101548684529183200154118015611ed75750600083815260246020526040902060040154601411155b15611ee457506014611f45565b600083815260246020526040902060030154611f029061012c615ab6565b60008581526024602052604090206004015410801590611f345750600083815260246020526040902060040154601411155b15611f4157506014611f45565b50600a5b60008381526024602052604081206004018054839290611f66908490615af9565b909155505060008481526024602052604081206004018054839290611f8c908490615ab6565b925050819055504283857fff229b26956a17ed5d6c377286dfdad2e5bbfc48a4c8c1266b1b4a1bafa9d87984604051611fc791815260200190565b60405180910390a46000848152602460205260408120600501805491611fec83615ae0565b9091555050600084815260246020526040812060090180549161200e83615ae0565b91905055506012546020546010546120269190615b32565b6010546120339190615af9565b61203d9190615b32565b6000858152602460205260408120600701805490919061205e908490615ab6565b9091555050604080516080810182528581526020808201868152828401858152600089815260288452858120898252845285812054606086019081528a8252602a855295812080546001808201835591835294909120945160049094029094019283559051928201929092559051600282015590516003909101555b50506120e66001600b55565b5050565b60006120f560085490565b82106121585760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610ff0565b6008828154811061216b5761216b615b54565b90600052602060002001549050919050565b612185614390565b61218e826122d0565b6001600160a01b0316336001600160a01b0316146121de5760405162461bcd60e51b815260206004820152600d60248201526c2737ba102cb7bab91027232a1760991b6044820152606401610ff0565b60008151116122195760405162461bcd60e51b81526020600482015260076024820152664e6f204e616d6560c81b6044820152606401610ff0565b60085482111561223b5760405162461bcd60e51b8152600401610ff090615a7d565b60008281526024602052604090206122538282615c77565b506120e66001600b55565b612266614503565b601155565b612273614503565b60005b818110156110915760016025600085858581811061229657612296615b54565b60209081029290920135835250810191909152604001600020805460ff1916911515919091179055806122c881615ae0565b915050612276565b6000818152600260205260408120546001600160a01b031680610ebd5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610ff0565b612338614390565b601a5460ff161561235b5760405162461bcd60e51b8152600401610ff090615a2f565b612364826122d0565b6001600160a01b0316336001600160a01b0316146123b45760405162461bcd60e51b815260206004820152600d60248201526c4e6f7420796f7572204e46542160981b6044820152606401610ff0565b600082815260246020526040902060080154158015906123e4575060008181526024602052604090206008015415155b6124205760405162461bcd60e51b815260206004820152600d60248201526c20b1ba34bb30ba329027232a1760991b6044820152606401610ff0565b60008281526024602052604090206003015461246b5760405162461bcd60e51b815260206004820152600a60248201526927379030ba3a30b1b59760b11b6044820152606401610ff0565b6000818152602460205260409020600301546124bb5760405162461bcd60e51b815260206004820152600f60248201526e24b6b837ba32b73a1032b732b6bc9760891b6044820152606401610ff0565b6000828152602660205260409020546103e91161250b5760405162461bcd60e51b815260206004820152600e60248201526d2634b6b4ba103932b0b1b432b21760911b6044820152606401610ff0565b600082815260286020908152604080832084845290915290205462015180906125349042615af9565b10156125525760405162461bcd60e51b8152600401610ff090615c06565b60008211801561256457506008548211155b80156125705750600081115b801561257e57506008548111155b61259a5760405162461bcd60e51b8152600401610ff090615a7d565b8082036125d35760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b6044820152606401610ff0565b60008281526025602052604090205460ff16156126025760405162461bcd60e51b8152600401610ff090615a58565b60105461260e8161474d565b61261981600a6147ec565b600083815260266020526040812080549161263383615ae0565b909155505060008381526028602090815260408083208584529091528120429055601580549161266283615ae0565b909155505060008281526024602052604080822060029081015486845291832001541180156126a35750600083815260246020526040902060030154601411155b156126b057506014612711565b6000838152602460205260409020600401546126ce9061012c615ab6565b600085815260246020526040902060030154108015906127005750600083815260246020526040902060030154601411155b1561270d57506014612711565b50600a5b60008381526024602052604081206003018054839290612732908490615af9565b909155505060008481526024602052604081206003018054839290612758908490615ab6565b925050819055504283857f2a7e4271816fd9e2b2e21c4a4a7df63aa2c324c6ad1fc330161b6e7099206a788460405161279391815260200190565b60405180910390a460008481526024602052604081206005018054916127b883615ae0565b909155505060008481526024602052604081206009018054916127da83615ae0565b91905055506012546020546010546127f29190615b32565b6010546127ff9190615af9565b6128099190615b32565b6000858152602460205260408120600701805490919061282a908490615ab6565b9091555050604080516080810182528581526020808201868152828401858152600089815260288452858120898252845285812054606086019081528a82526029855295812080546001808201835591835294909120945160049094029094019283559051928201929092559051600282015590516003909101556120da565b601680546116e0906159f5565b60006001600160a01b0382166129215760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610ff0565b506001600160a01b031660009081526003602052604090205490565b612945614503565b61294f6000614a15565b565b612959614390565b601a5460ff161561297c5760405162461bcd60e51b8152600401610ff090615a2f565b6000818152602460205260409020600801546129aa5760405162461bcd60e51b8152600401610ff090615be0565b6129b3816122d0565b6001600160a01b0316336001600160a01b0316146129e35760405162461bcd60e51b8152600401610ff090615b0c565b6000811180156129f557506008548111155b612a115760405162461bcd60e51b8152600401610ff090615a7d565b60008181526025602052604090205460ff1615612a405760405162461bcd60e51b8152600401610ff090615a58565b601054612a4c8161474d565b612a578160326147ec565b60225460008381526024602052604081206003018054909190612a7b908490615ab6565b90915550506001600b555050565b612a91614503565b8460008b9003612c345760005b81811015612c2e576000612ab2828d615ab6565b9050604051806101400160405280888885818110612ad257612ad2615b54565b9050602002810190612ae49190615d36565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093855250505060208083018590526040808401839052606460608501819052608085015260a0840183905260c0840183905260e084018390526101008401839052610120909301829052848252602490522081518190612b749082615c77565b506020820151600182015560408201516002820155606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e08201516007820155610100820151600882015561012090910151600990910155612c05858584818110612be857612be8615b54565b9050602002016020810190612bfd91906153d8565b600c54614a67565b600c8054906000612c1583615ae0565b9190505550508080612c2690615ae0565b915050612a9e565b50612e12565b60005b88811015612e105760008a8a83818110612c5357612c53615b54565b90506020020135905088886000818110612c6f57612c6f615b54565b90506020020135602460008381526020019081526020016000206002018190555088886001818110612ca357612ca3615b54565b90506020020135602460008381526020019081526020016000206003018190555088886002818110612cd757612cd7615b54565b90506020020135602460008381526020019081526020016000206004018190555088886003818110612d0b57612d0b615b54565b90506020020135602460008381526020019081526020016000206005018190555088886004818110612d3f57612d3f615b54565b90506020020135602460008381526020019081526020016000206006018190555088886005818110612d7357612d73615b54565b90506020020135602460008381526020019081526020016000206007018190555088886006818110612da757612da7615b54565b90506020020135602460008381526020019081526020016000206008018190555088886007818110612ddb57612ddb615b54565b905060200201356024600083815260200190815260200160002060090181905550508080612e0890615ae0565b915050612c37565b505b5050505050505050505050565b612e27614390565b601a5460ff1615612e4a5760405162461bcd60e51b8152600401610ff090615a2f565b612e53816122d0565b6001600160a01b0316336001600160a01b031614612e835760405162461bcd60e51b8152600401610ff090615b0c565b600081118015612e9557506008548111155b612eb15760405162461bcd60e51b8152600401610ff090615a7d565b600081815260246020526040902060080154612edf5760405162461bcd60e51b8152600401610ff090615be0565b60008181526025602052604090205460ff1615612f0e5760405162461bcd60e51b8152600401610ff090615a58565b601054612f1a8161474d565b612f258160326147ec565b60225460008381526024602052604081206004018054909190612a7b908490615ab6565b612f51614503565b600d55565b6017546001600160a01b03163314612f805760405162461bcd60e51b8152600401610ff090615bb7565b601a5460ff1615612fd35760405162461bcd60e51b815260206004820152601860248201527f436f6e747261637420616c7265616479207061757365642e00000000000000006044820152606401610ff0565b601a805460ff191660011790556040517f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62590600090a1565b613013614503565b60408051602081019091526001600160a01b0391821681526023805460018101825560009190915290517fd57b2b5166478fd4318d2acc6cc2c704584312bdd8781b32d5d06abda57f423090910180546001600160a01b03191691909216179055565b602a602052816000526040600020818154811061309257600080fd5b60009182526020909120600490910201805460018201546002830154600390930154919450925084565b6130c4614503565b60005b81811015611091576000602560008585858181106130e7576130e7615b54565b60209081029290920135835250810191909152604001600020805460ff19169115159190911790558061311981615ae0565b9150506130c7565b613129614503565b60166120e68282615c77565b606060018054610ed2906159f5565b6029602052816000526040600020818154811061309257600080fd5b613168614390565b601a5460ff161561318b5760405162461bcd60e51b8152600401610ff090615a2f565b600081815260246020526040902060020154600111156131da5760405162461bcd60e51b815260206004820152600a6024820152694d696e204c6576656c3160b01b6044820152606401610ff0565b6000818152602460205260409020600701546132245760405162461bcd60e51b8152602060048201526009602482015268139bc81c185e5bdd5d60ba1b6044820152606401610ff0565b600081815260246020526040902060060154600511156132735760405162461bcd60e51b815260206004820152600a6024820152694669676874206d6f726560b01b6044820152606401610ff0565b61327c816122d0565b6001600160a01b0316336001600160a01b0316146132ac5760405162461bcd60e51b8152600401610ff090615b0c565b60008181526025602052604090205460ff16156132db5760405162461bcd60e51b8152600401610ff090615a58565b60125460008281526024602052604081206007015490916132fb91615ac9565b905060006023600e548154811061331457613314615b54565b600091825260209091200180546040516370a0823160e01b81523060048201529192506001600160a01b031690839082906370a0823190602401602060405180830381865afa15801561336b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061338f9190615d7c565b116133d25760405162461bcd60e51b81526020600482015260136024820152724e6f7420456e6f75676820526573657276657360681b6044820152606401610ff0565b60405163a9059cbb60e01b8152336004820152602481018490526001600160a01b0382169063a9059cbb906044016020604051808303816000875af115801561341f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134439190615d95565b6134815760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8811985a5b1959608a1b6044820152606401610ff0565b600084815260246020526040808220600781018390556006810183905560050182905551849133917f2148c22360ec869df90a6857cc7c0b2c254544deff5a5e2e88f91c6c3e27ee059190a350505061129b6001600b55565b6120e6338383614c00565b6017546001600160a01b0316331461350f5760405162461bcd60e51b8152600401610ff090615bb7565b61129b81613d93565b613520614503565b601055565b61352f338361455d565b61354b5760405162461bcd60e51b8152600401610ff090615b6a565b61355784848484614cce565b50505050565b606061356860085490565b8211156135875760405162461bcd60e51b8152600401610ff090615a7d565b600060168054613596906159f5565b9050116135b25760405180602001604052806000815250610ebd565b60166135bd83614d01565b6040516020016135ce929190615db2565b60405160208183030381529060405292915050565b6135eb614390565b601a5460ff161561360e5760405162461bcd60e51b8152600401610ff090615a2f565b600d5434146136525760405162461bcd60e51b815260206004820152601060248201526f496e73756666696369656e742066656560801b6044820152606401610ff0565b600081511161368d5760405162461bcd60e51b81526020600482015260076024820152664e6f204e616d6560c81b6044820152606401610ff0565b604051806101400160405280828152602001600c54815260200160008152602001606481526020016064815260200160008152602001600081526020016000815260200160008152602001600081525060246000600c54815260200190815260200160002060008201518160000190816137079190615c77565b506020820151600182015560408201516002820155606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e08201516007820155610100820151600882015561012090910151600990910155600c546137733382614a67565b60408051602080820183526000808352600c54815260259091528290209051815460ff19169015151790555181907f51413fa31ea07fada8e4b3a4719c2683c7288050bc37c83c4ad11ce93423087f906137ce908590615306565b60405180910390a2600c80549060006137e683615ae0565b91905055505061129b6001600b55565b6000818152602a60205260408120546060919081816001600160401b038111156138225761382261554b565b60405190808252806020026020018201604052801561387e57816020015b61386b6040518060800160405280600081526020016000815260200160008152602001600081525090565b8152602001906001900390816138405790505b50905060005b82811015613965576000868152602a602052604090208054879190839081106138af576138af615b54565b90600052602060002090600402016000015403613953576000868152602a602052604090208054829081106138e6576138e6615b54565b906000526020600020906004020160405180608001604052908160008201548152602001600182015481526020016002820154815260200160038201548152505082858151811061393957613939615b54565b6020026020010181905250838061394f90615ae0565b9450505b8061395d81615ae0565b915050613884565b50949350505050565b613976614503565b60006023838154811061398b5761398b615b54565b6000918252602090912001805460405163a9059cbb60e01b8152336004820152602481018590529192506001600160a01b031690819063a9059cbb906044016020604051808303816000875af11580156139e9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a0d9190615d95565b5050505050565b6017546001600160a01b03163314613a3e5760405162461bcd60e51b8152600401610ff090615bb7565b601780546001600160a01b0319166001600160a01b0392909216919091179055565b613a68614390565b601a5460ff1615613a8b5760405162461bcd60e51b8152600401610ff090615a2f565b613a94816122d0565b6001600160a01b0316336001600160a01b031614613ac45760405162461bcd60e51b8152600401610ff090615b0c565b60008181526025602052604090205460ff1615613af35760405162461bcd60e51b8152600401610ff090615a58565b6000818152602760205260409020546201518090613b119042615af9565b1015613b2f5760405162461bcd60e51b8152600401610ff090615c06565b60008181526026602090815260408083208390556027909152902042905561129b6001600b55565b613b5f614390565b601a5460ff1615613b825760405162461bcd60e51b8152600401610ff090615a2f565b613b8b816122d0565b6001600160a01b0316336001600160a01b031614613bbb5760405162461bcd60e51b8152600401610ff090615b0c565b60008181526025602052604090205460ff1615613bea5760405162461bcd60e51b8152600401610ff090615a58565b600081118015613bfc57506008548111155b613c185760405162461bcd60e51b8152600401610ff090615a7d565b600081815260246020526040812060040154606490613c38908290615af9565b613c429190615b32565b905060008111613c835760405162461bcd60e51b815260206004820152600c60248201526b4e6f7420456c696769626c6560a01b6044820152606401610ff0565b60008281526024602052604081206006018054839290613ca4908490615ab6565b90915550613cb59050816064615ac9565b600083815260246020526040902060040154613cd19190615af9565b6000838152602460209081526040822060040192909255601254915460105460059384928692613d019190615b32565b601054613d0e9190615af9565b613d189190615b32565b613d229190615ac9565b613d2c9190615ac9565b905080602460008681526020019081526020016000206007016000828254613d549190615ab6565b9091555050604051819085907f7f5659a067632eac859a934c471d405a845bf03086d0206bc77ca28c7b00b6c290600090a350505061129b6001600b55565b613d9b614503565b6001600160a01b038116613e005760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610ff0565b61129b81614a15565b613e11614390565b601a5460ff1615613e345760405162461bcd60e51b8152600401610ff090615a2f565b613e3d816122d0565b6001600160a01b0316336001600160a01b031614613e6d5760405162461bcd60e51b8152600401610ff090615b0c565b600081118015613e7f57506008548111155b613e9b5760405162461bcd60e51b8152600401610ff090615a7d565b60008181526025602052604090205460ff1615613eca5760405162461bcd60e51b8152600401610ff090615a58565b60008181526024602052604081206008015415613fef5760008281526024602052604090206006015460051115613f385760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742077696e732160701b6044820152606401610ff0565b6000601254602054601054613f4d9190615b32565b601054613f5a9190615af9565b613f649190615b32565b613f6f906005615ac9565b613f7a906005615ac9565b905080602460008581526020019081526020016000206007016000828254613fa29190615af9565b90915550506000838152602460205260408120600601805460059290613fc9908490615af9565b9091555050601254613fdb9082615ac9565b9150613fe9826021546147ec565b50614007565b50601154613ffc8161474d565b61400781600a6147ec565b60008281526024602052604081206008018054916137e683615ae0565b60246020526000908152604090208054819061403f906159f5565b80601f016020809104026020016040519081016040528092919081815260200182805461406b906159f5565b80156140b85780601f1061408d576101008083540402835291602001916140b8565b820191906000526020600020905b81548152906001019060200180831161409b57829003601f168201915b505050505090806001015490806002015490806003015490806004015490806005015490806006015490806007015490806008015490806009015490508a565b600081815260296020526040812054606091816001600160401b038111156141225761412261554b565b60405190808252806020026020018201604052801561417e57816020015b61416b6040518060800160405280600081526020016000815260200160008152602001600081525090565b8152602001906001900390816141405790505b5090506000805b838110156116c95760008681526029602052604090208054879190839081106141b0576141b0615b54565b906000526020600020906004020160000154036142545760008681526029602052604090208054829081106141e7576141e7615b54565b906000526020600020906004020160405180608001604052908160008201548152602001600182015481526020016002820154815260200160038201548152505083838151811061423a5761423a615b54565b6020026020010181905250818061425090615ae0565b9250505b8061425e81615ae0565b915050614185565b61426e614503565b602b55565b60006001600160e01b031982166380ac58cd60e01b14806142a457506001600160e01b03198216635b5e139f60e01b145b80610ebd57506301ffc9a760e01b6001600160e01b0319831614610ebd565b6000818152600260205260409020546001600160a01b031661129b5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610ff0565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190614357826122d0565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6002600b54036143e25760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ff0565b6002600b55565b60006023600f548154811061440057614400615b54565b600091825260209091200180546040516323b872dd60e01b8152336004820152306024820152604481018590529192506001600160a01b03169081906323b872dd906064016020604051808303816000875af1158015614464573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144889190615d95565b5060185460405163b90306ad60e01b8152600481018590526001600160a01b039091169063b90306ad90602401600060405180830381600087803b1580156144cf57600080fd5b505af11580156144e3573d6000803e3d6000fd5b5050505082601460008282546144f99190615ab6565b9091555050505050565b600a546001600160a01b0316331461294f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610ff0565b600080614569836122d0565b9050806001600160a01b0316846001600160a01b031614806145b057506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806145d45750836001600160a01b03166145c984610f55565b6001600160a01b0316145b949350505050565b826001600160a01b03166145ef826122d0565b6001600160a01b0316146146155760405162461bcd60e51b8152600401610ff090615e49565b6001600160a01b0382166146775760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610ff0565b6146848383836001614d93565b826001600160a01b0316614697826122d0565b6001600160a01b0316146146bd5760405162461bcd60e51b8152600401610ff090615e49565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60006023600e548154811061476457614764615b54565b600091825260209091200180546040516323b872dd60e01b8152336004820152306024820152604481018590529192506001600160a01b03169081906323b872dd906064016020604051808303816000875af11580156147c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135579190615d95565b600060646147fa8385615ac9565b6148049190615b32565b905060006064601d54836148189190615ac9565b6148229190615b32565b905060006064601e54846148369190615ac9565b6148409190615b32565b905060006064601f54856148549190615ac9565b61485e9190615b32565b905060006023600e548154811061487757614877615b54565b60009182526020909120018054601c5460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018890529293501690819063a9059cbb906044016020604051808303816000875af11580156148da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148fe9190615d95565b50601b5460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018690529082169063a9059cbb906044016020604051808303816000875af1158015614952573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149769190615d95565b50601a5460405163a9059cbb60e01b81526101009091046001600160a01b0390811660048301526024820185905282169063a9059cbb906044016020604051808303816000875af11580156149cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149f39190615d95565b508560136000828254614a069190615ab6565b90915550505050505050505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b038216614abd5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610ff0565b6000818152600260205260409020546001600160a01b031615614b225760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610ff0565b614b30600083836001614d93565b6000818152600260205260409020546001600160a01b031615614b955760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610ff0565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b816001600160a01b0316836001600160a01b031603614c615760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610ff0565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b614cd98484846145dc565b614ce584848484614ec0565b6135575760405162461bcd60e51b8152600401610ff090615e8e565b60606000614d0e83614fc1565b60010190506000816001600160401b03811115614d2d57614d2d61554b565b6040519080825280601f01601f191660200182016040528015614d57576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084614d6157509392505050565b6001811115614e025760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610ff0565b816001600160a01b038516614e5e57614e5981600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b614e81565b836001600160a01b0316856001600160a01b031614614e8157614e818582615099565b6001600160a01b038416614e9d57614e9881615136565b613a0d565b846001600160a01b0316846001600160a01b031614613a0d57613a0d84826151e5565b60006001600160a01b0384163b15614fb657604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614f04903390899088908890600401615ee0565b6020604051808303816000875af1925050508015614f3f575060408051601f3d908101601f19168201909252614f3c91810190615f1d565b60015b614f9c573d808015614f6d576040519150601f19603f3d011682016040523d82523d6000602084013e614f72565b606091505b508051600003614f945760405162461bcd60e51b8152600401610ff090615e8e565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506145d4565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106150005772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061502c576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061504a57662386f26fc10000830492506010015b6305f5e1008310615062576305f5e100830492506008015b612710831061507657612710830492506004015b60648310615088576064830492506002015b600a8310610ebd5760010192915050565b600060016150a6846128b7565b6150b09190615af9565b600083815260076020526040902054909150808214615103576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061514890600190615af9565b6000838152600960205260408120546008805493945090928490811061517057615170615b54565b90600052602060002001549050806008838154811061519157615191615b54565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806151c9576151c9615f3a565b6001900381819060005260206000200160009055905550505050565b60006151f0836128b7565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b604051806101400160405280606081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6001600160e01b03198116811461129b57600080fd5b6000602082840312156152a457600080fd5b81356152af8161527c565b9392505050565b60005b838110156152d15781810151838201526020016152b9565b50506000910152565b600081518084526152f28160208601602086016152b6565b601f01601f19169290920160200192915050565b6020815260006152af60208301846152da565b60006020828403121561532b57600080fd5b5035919050565b6001600160a01b038116811461129b57600080fd5b6000806040838503121561535a57600080fd5b823561536581615332565b946020939093013593505050565b6000806040838503121561538657600080fd5b50508035926020909101359150565b60008060008060008060c087890312156153ae57600080fd5b505084359660208601359650604086013595606081013595506080810135945060a0013592509050565b6000602082840312156153ea57600080fd5b81356152af81615332565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156154b157603f1989840301855281516101408151818652615443828701826152da565b838b0151878c0152898401518a880152606080850151908801526080808501519088015260a0808501519088015260c0808501519088015260e0808501519088015261010080850151908801526101209384015193909601929092525050938601939086019060010161541c565b509098975050505050505050565b6000806000606084860312156154d457600080fd5b83356154df81615332565b925060208401356154ef81615332565b929592945050506040919091013590565b60008060006060848603121561551557600080fd5b833561552081615332565b9250602084013561553081615332565b9150604084013561554081615332565b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b60006001600160401b038084111561557b5761557b61554b565b604051601f8501601f19908116603f011681019082821181831017156155a3576155a361554b565b816040528093508581528686860111156155bc57600080fd5b858560208301376000602087830101525050509392505050565b600082601f8301126155e757600080fd5b6152af83833560208501615561565b6000806040838503121561560957600080fd5b8235915060208301356001600160401b0381111561562657600080fd5b615632858286016155d6565b9150509250929050565b60008083601f84011261564e57600080fd5b5081356001600160401b0381111561566557600080fd5b6020830191508360208260051b850101111561568057600080fd5b9250929050565b6000806020838503121561569a57600080fd5b82356001600160401b038111156156b057600080fd5b6156bc8582860161563c565b90969095509350505050565b60008060008060008060008060008060c08b8d0312156156e757600080fd5b8a35995060208b0135985060408b01356001600160401b038082111561570c57600080fd5b6157188e838f0161563c565b909a50985060608d013591508082111561573157600080fd5b61573d8e838f0161563c565b909850965060808d013591508082111561575657600080fd5b6157628e838f0161563c565b909650945060a08d013591508082111561577b57600080fd5b506157888d828e0161563c565b915080935050809150509295989b9194979a5092959850565b6000602082840312156157b357600080fd5b81356001600160401b038111156157c957600080fd5b6145d4848285016155d6565b801515811461129b57600080fd5b600080604083850312156157f657600080fd5b823561580181615332565b91506020830135615811816157d5565b809150509250929050565b6000806000806080858703121561583257600080fd5b843561583d81615332565b9350602085013561584d81615332565b92506040850135915060608501356001600160401b0381111561586f57600080fd5b8501601f8101871361588057600080fd5b61588f87823560208401615561565b91505092959194509250565b6020808252825182820181905260009190848201906040850190845b818110156158fe576158eb838551805182526020810151602083015260408101516040830152606081015160608301525050565b92840192608092909201916001016158b7565b50909695505050505050565b6000806040838503121561591d57600080fd5b823561592881615332565b9150602083013561581181615332565b600061014080835261594c8184018e6152da565b602084019c909c52505060408101989098526060880196909652608087019490945260a086019290925260c085015260e084015261010083015261012090910152919050565b6020808252825182820181905260009190848201906040850190845b818110156158fe576159e2838551805182526020810151602083015260408101516040830152606081015160608301525050565b92840192608092909201916001016159ae565b600181811c90821680615a0957607f821691505b602082108103615a2957634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600f908201526e14185d5cd9590810dbdb9d1c9858dd608a1b604082015260600190565b6020808252600b908201526a109b1858dadb1a5cdd195960aa1b604082015260600190565b602080825260099082015268139bdd08119bdd5b9960ba1b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b80820180821115610ebd57610ebd615aa0565b8082028115828204841417610ebd57610ebd615aa0565b600060018201615af257615af2615aa0565b5060010190565b81810381811115610ebd57610ebd615aa0565b6020808252600c908201526b139bdd081e5bdd5c8813919560a21b604082015260600190565b600082615b4f57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b6020808252600f908201526e2737ba1030baba3437b934bd32b21760891b604082015260600190565b6020808252600c908201526b1058dd1a5d985d194813919560a21b604082015260600190565b6020808252600990820152682a37b79039b7b7b71760b91b604082015260600190565b601f82111561109157600081815260208120601f850160051c81016020861015615c505750805b601f850160051c820191505b81811015615c6f57828155600101615c5c565b505050505050565b81516001600160401b03811115615c9057615c9061554b565b615ca481615c9e84546159f5565b84615c29565b602080601f831160018114615cd95760008415615cc15750858301515b600019600386901b1c1916600185901b178555615c6f565b600085815260208120601f198616915b82811015615d0857888601518255948401946001909101908401615ce9565b5085821015615d265787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000808335601e19843603018112615d4d57600080fd5b8301803591506001600160401b03821115615d6757600080fd5b60200191503681900382131561568057600080fd5b600060208284031215615d8e57600080fd5b5051919050565b600060208284031215615da757600080fd5b81516152af816157d5565b6000808454615dc0816159f5565b60018281168015615dd85760018114615ded57615e1c565b60ff1984168752821515830287019450615e1c565b8860005260208060002060005b85811015615e135781548a820152908401908201615dfa565b50505082870194505b505050508351615e308183602088016152b6565b64173539b7b760d91b9101908152600501949350505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090615f13908301846152da565b9695505050505050565b600060208284031215615f2f57600080fd5b81516152af8161527c565b634e487b7160e01b600052603160045260246000fdfea26469706673582212203d5d2633d9c3ed7fbd9ffac38c4aea704791071eabe3e17ac4c3c60e0e031b7c64736f6c634300081200333078536f726365726572207c20426174746f75736169204e616b616d6f746f207c204461726b2d5669706572000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000deb4316defc86a53fe465207825d987cd2f636a4000000000000000000000000aba13099d371a483dbf6cfd5ca654c7a3547cc740000000000000000000000000000000000000000000000000000000000000009426174746c65646f67000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034244470000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106104945760003560e01c80636c0360eb11610260578063aee9984711610144578063e00e8bf3116100c1578063f2fde38b11610085578063f2fde38b14610dcc578063f55e7d3914610dec578063f71d96cb14610dff578063f7581dd914610e35578063f9f646ab14610e4b578063fc55b13814610e7857600080fd5b8063e00e8bf314610d10578063e19a9dd914610d23578063e6ccab7514610d43578063e985e9c514610d63578063f24b337314610dac57600080fd5b8063cefb6fa611610108578063cefb6fa614610c6d578063d34acd1214610c83578063d85d3d2714610cb0578063dc9ef6e714610cc3578063def50d5814610ce357600080fd5b8063aee9984714610be1578063b5ebbcc414610bf7578063b88d4fde14610c17578063c87b56dd14610c37578063cdf52f8e14610c5757600080fd5b80638ab234b6116101dd578063931688cb116101a1578063931688cb14610b3957806395d89b4114610b5957806398e981c514610b6e5780639900bce914610b8e578063a22cb46514610ba1578063a6f9dae114610bc157600080fd5b80638ab234b614610a855780638bae54b814610aa55780638c82ce3f14610ae55780638da5cb5b14610afb57806392201a4a14610b1957600080fd5b80637ed865ee116102245780637ed865ee14610a075780637fc897c214610a2757806384017e5214610a3a5780638456cb5914610a5a5780638a7e26dd14610a6f57600080fd5b80636c0360eb1461098a57806370a082311461099f57806370d5ae05146109bf578063715018a6146109df5780637b19b53a146109f457600080fd5b80632e5f0f57116103875780634e77e525116103045780635c975abb116102c85780635c975abb146108e25780635c983aec146108fc5780635f6370251461091c5780636352211e14610932578063638b1b141461095257806369e8f97a1461097757600080fd5b80634e77e525146108595780634f6ccce71461086c57806353e76f2c1461088c57806355161913146108ac578063584cb693146108c257600080fd5b80633f4ba83a1161034b5780633f4ba83a146107d857806342842e0e146107ed578063460e20491461080d57806348b9ef401461082d5780634e5a95af1461084357600080fd5b80632e5f0f57146107425780632f745c5914610762578063363bf964146107825780633687d626146107a25780633b3cfba4146107b857600080fd5b806318160ddd1161041557806323b872dd116103d957806323b872dd1461069f57806323db4c91146106bf57806326c91cad146106ef57806327730d121461070f5780632e1a7d4d1461072f57600080fd5b806318160ddd1461061c57806318e70f04146106315780631a3de5c31461065e5780631b5a10631461067457806320b2af521461068a57600080fd5b80630ce90ec21161045c5780630ce90ec2146105905780630ef5cc0e146105b05780630fffecc7146105d057806311f630f3146105e657806313966db51461060657600080fd5b806301ffc9a71461049957806306fdde03146104ce578063081812fc146104f0578063095ea7b3146105285780630b30904e1461054a575b600080fd5b3480156104a557600080fd5b506104b96104b4366004615292565b610e98565b60405190151581526020015b60405180910390f35b3480156104da57600080fd5b506104e3610ec3565b6040516104c59190615306565b3480156104fc57600080fd5b5061051061050b366004615319565b610f55565b6040516001600160a01b0390911681526020016104c5565b34801561053457600080fd5b50610548610543366004615347565b610f7c565b005b34801561055657600080fd5b50610582610565366004615373565b602860209081526000928352604080842090915290825290205481565b6040519081526020016104c5565b34801561059c57600080fd5b506105486105ab366004615319565b611096565b3480156105bc57600080fd5b506105486105cb366004615319565b61129e565b3480156105dc57600080fd5b50610582601e5481565b3480156105f257600080fd5b50610548610601366004615395565b6114db565b34801561061257600080fd5b50610582600d5481565b34801561062857600080fd5b50600854610582565b34801561063d57600080fd5b5061065161064c3660046153d8565b611500565b6040516104c591906153f5565b34801561066a57600080fd5b50610582600f5481565b34801561068057600080fd5b5061058260115481565b34801561069657600080fd5b506104e36116d3565b3480156106ab57600080fd5b506105486106ba3660046154bf565b611761565b3480156106cb57600080fd5b506104b96106da366004615319565b60256020526000908152604090205460ff1681565b3480156106fb57600080fd5b5061051061070a366004615319565b611792565b34801561071b57600080fd5b50601854610510906001600160a01b031681565b61054861073d366004615319565b6117bc565b34801561074e57600080fd5b5061054861075d366004615373565b611811565b34801561076e57600080fd5b5061058261077d366004615347565b611824565b34801561078e57600080fd5b5061054861079d366004615500565b6118ba565b3480156107ae57600080fd5b5061058260145481565b3480156107c457600080fd5b506105486107d33660046153d8565b61190a565b3480156107e457600080fd5b5061054861197b565b3480156107f957600080fd5b506105486108083660046154bf565b611a23565b34801561081957600080fd5b50610651610828366004615319565b611a3e565b34801561083957600080fd5b5061058260105481565b34801561084f57600080fd5b5061058260215481565b610548610867366004615373565b611ba5565b34801561087857600080fd5b50610582610887366004615319565b6120ea565b34801561089857600080fd5b506105486108a73660046155f6565b61217d565b3480156108b857600080fd5b50610582602b5481565b3480156108ce57600080fd5b506105486108dd366004615319565b61225e565b3480156108ee57600080fd5b50601a546104b99060ff1681565b34801561090857600080fd5b50610548610917366004615687565b61226b565b34801561092857600080fd5b50610582601d5481565b34801561093e57600080fd5b5061051061094d366004615319565b6122d0565b34801561095e57600080fd5b50601a546105109061010090046001600160a01b031681565b610548610985366004615373565b612330565b34801561099657600080fd5b506104e36128aa565b3480156109ab57600080fd5b506105826109ba3660046153d8565b6128b7565b3480156109cb57600080fd5b50601c54610510906001600160a01b031681565b3480156109eb57600080fd5b5061054861293d565b610548610a02366004615319565b612951565b348015610a1357600080fd5b50610548610a223660046156c8565b612a89565b610548610a35366004615319565b612e1f565b348015610a4657600080fd5b50610548610a55366004615319565b612f49565b348015610a6657600080fd5b50610548612f56565b348015610a7b57600080fd5b5061058260225481565b348015610a9157600080fd5b50610548610aa03660046153d8565b61300b565b348015610ab157600080fd5b50610ac5610ac0366004615373565b613076565b6040805194855260208501939093529183015260608201526080016104c5565b348015610af157600080fd5b50610582601f5481565b348015610b0757600080fd5b50600a546001600160a01b0316610510565b348015610b2557600080fd5b50610548610b34366004615687565b6130bc565b348015610b4557600080fd5b50610548610b543660046157a1565b613121565b348015610b6557600080fd5b506104e3613135565b348015610b7a57600080fd5b50610ac5610b89366004615373565b613144565b610548610b9c366004615319565b613160565b348015610bad57600080fd5b50610548610bbc3660046157e3565b6134da565b348015610bcd57600080fd5b50610548610bdc3660046153d8565b6134e5565b348015610bed57600080fd5b5061058260155481565b348015610c0357600080fd5b50610548610c12366004615319565b613518565b348015610c2357600080fd5b50610548610c3236600461581c565b613525565b348015610c4357600080fd5b506104e3610c52366004615319565b61355d565b348015610c6357600080fd5b5061058260205481565b348015610c7957600080fd5b50610582600e5481565b348015610c8f57600080fd5b50610582610c9e366004615319565b60266020526000908152604090205481565b610548610cbe3660046157a1565b6135e3565b348015610ccf57600080fd5b50601b54610510906001600160a01b031681565b348015610cef57600080fd5b50610d03610cfe366004615319565b6137f6565b6040516104c5919061589b565b610548610d1e366004615373565b61396e565b348015610d2f57600080fd5b50610548610d3e3660046153d8565b613a14565b348015610d4f57600080fd5b50610548610d5e366004615319565b613a60565b348015610d6f57600080fd5b506104b9610d7e36600461590a565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610db857600080fd5b50610548610dc7366004615319565b613b57565b348015610dd857600080fd5b50610548610de73660046153d8565b613d93565b610548610dfa366004615319565b613e09565b348015610e0b57600080fd5b50610e1f610e1a366004615319565b614024565b6040516104c59a99989796959493929190615938565b348015610e4157600080fd5b5061058260135481565b348015610e5757600080fd5b50610e6b610e66366004615319565b6140f8565b6040516104c59190615992565b348015610e8457600080fd5b50610548610e93366004615319565b614266565b60006001600160e01b0319821663780e9d6360e01b1480610ebd5750610ebd82614273565b92915050565b606060008054610ed2906159f5565b80601f0160208091040260200160405190810160405280929190818152602001828054610efe906159f5565b8015610f4b5780601f10610f2057610100808354040283529160200191610f4b565b820191906000526020600020905b815481529060010190602001808311610f2e57829003601f168201915b5050505050905090565b6000610f60826142c3565b506000908152600460205260409020546001600160a01b031690565b6000610f87826122d0565b9050806001600160a01b0316836001600160a01b031603610ff95760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061101557506110158133610d7e565b6110875760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610ff0565b6110918383614322565b505050565b61109e614390565b601a5460ff16156110c15760405162461bcd60e51b8152600401610ff090615a2f565b6110ca816122d0565b6001600160a01b0316336001600160a01b0316146111195760405162461bcd60e51b815260206004820152600c60248201526b139bdd08165bdd5c8813919560a21b6044820152606401610ff0565b60008181526025602052604090205460ff16156111485760405162461bcd60e51b8152600401610ff090615a58565b60008111801561115a57506008548111155b6111765760405162461bcd60e51b8152600401610ff090615a7d565b600081815260246020526040902060060154600511156111cc5760405162461bcd60e51b8152602060048201526011602482015270496e73756666696369656e742077696e7360781b6044820152606401610ff0565b602b546000828152602460205260408120600201549091906111ef906001615ab6565b6111f99190615ac9565b9050611204816143e9565b600082815260246020526040812060020180549161122183615ae0565b90915550506000828152602460205260408120600281015460069091015490919061124e90600590615af9565b60008581526024602052604080822060060183905551919250839186917f5ca885b5603e88c1fa88187446b77e0355fef8842d9ecdf39c8ded80628a19f991a350505061129b6001600b55565b50565b6112a6614390565b601a5460ff16156112c95760405162461bcd60e51b8152600401610ff090615a2f565b6112d2816122d0565b6001600160a01b0316336001600160a01b0316146113025760405162461bcd60e51b8152600401610ff090615b0c565b60008181526025602052604090205460ff16156113315760405162461bcd60e51b8152600401610ff090615a58565b60008111801561134357506008548111155b61135f5760405162461bcd60e51b8152600401610ff090615a7d565b60008181526024602052604081206003015460649061137f908290615af9565b6113899190615b32565b9050600081116113cb5760405162461bcd60e51b815260206004820152600d60248201526c4e6f7420656c696769626c652160981b6044820152606401610ff0565b600082815260246020526040812060060180548392906113ec908490615ab6565b909155506113fd9050816064615ac9565b6000838152602460205260409020600301546114199190615af9565b60008381526024602090815260408220600301929092556012549154601054600593849286926114499190615b32565b6010546114569190615af9565b6114609190615b32565b61146a9190615ac9565b6114749190615ac9565b90508060246000868152602001908152602001600020600701600082825461149c9190615ab6565b9091555050604051819085907fcfe02161d782707626ce6a2efd36c33634fd1d48abf19b83c8ab3f0f6078e91c90600090a350505061129b6001600b55565b6114e3614503565b601d95909555601e93909355601f91909155602055602255602155565b6060600061150d836128b7565b90506000816001600160401b038111156115295761152961554b565b60405190808252806020026020018201604052801561156257816020015b61154f615229565b8152602001906001900390816115475790505b5090506000805b838110156116c957600061157d8783611824565b905060246000828152602001908152602001600020604051806101400160405290816000820180546115ae906159f5565b80601f01602080910402602001604051908101604052809291908181526020018280546115da906159f5565b80156116275780601f106115fc57610100808354040283529160200191611627565b820191906000526020600020905b81548152906001019060200180831161160a57829003601f168201915b50505050508152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152505084848151811061169c5761169c615b54565b602002602001018190525082806116b290615ae0565b9350505080806116c190615ae0565b915050611569565b5090949350505050565b601980546116e0906159f5565b80601f016020809104026020016040519081016040528092919081815260200182805461170c906159f5565b80156117595780601f1061172e57610100808354040283529160200191611759565b820191906000526020600020905b81548152906001019060200180831161173c57829003601f168201915b505050505081565b61176b338261455d565b6117875760405162461bcd60e51b8152600401610ff090615b6a565b6110918383836145dc565b602381815481106117a257600080fd5b6000918252602090912001546001600160a01b0316905081565b6117c4614503565b60006117d8600a546001600160a01b031690565b6040519091506001600160a01b0382169083156108fc029084906000818181858888f19350505050158015611091573d6000803e3d6000fd5b611819614503565b600e91909155600f55565b600061182f836128b7565b82106118915760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610ff0565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6118c2614503565b601a80546001600160a01b0394851661010002610100600160a81b0319909116179055601b80549284166001600160a01b0319938416179055601c8054919093169116179055565b611912614503565b600a546001600160a01b031633146119595760405162461bcd60e51b815260206004820152600a6024820152692737ba1027bbb732b91760b11b6044820152606401610ff0565b601880546001600160a01b0319166001600160a01b0392909216919091179055565b6017546001600160a01b031633146119a55760405162461bcd60e51b8152600401610ff090615bb7565b601a5460ff166119ee5760405162461bcd60e51b815260206004820152601460248201527321b7b73a3930b1ba103737ba103830bab9b2b21760611b6044820152606401610ff0565b601a805460ff191690556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3390600090a1565b61109183838360405180602001604052806000815250613525565b60408051600180825281830190925260609160009190816020015b611a61615229565b815260200190600190039081611a595790505090506024600084815260200190815260200160002060405180610140016040529081600082018054611aa5906159f5565b80601f0160208091040260200160405190810160405280929190818152602001828054611ad1906159f5565b8015611b1e5780601f10611af357610100808354040283529160200191611b1e565b820191906000526020600020905b815481529060010190602001808311611b0157829003601f168201915b50505050508152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152505081600081518110611b9457611b94615b54565b602090810291909101015292915050565b611bad614390565b601a5460ff1615611bd05760405162461bcd60e51b8152600401610ff090615a2f565b611bd9826122d0565b6001600160a01b0316336001600160a01b031614611c095760405162461bcd60e51b8152600401610ff090615b0c565b60008281526025602052604090205460ff1615611c385760405162461bcd60e51b8152600401610ff090615a58565b60008281526024602052604090206008015415801590611c68575060008181526024602052604090206008015415155b611c845760405162461bcd60e51b8152600401610ff090615be0565b600082815260246020526040902060040154611ccf5760405162461bcd60e51b815260206004820152600a6024820152694e6f20646566656e636560b01b6044820152606401610ff0565b600081815260246020526040902060040154611d1e5760405162461bcd60e51b815260206004820152600e60248201526d496d706f74656e7420656e656d7960901b6044820152606401610ff0565b6000828152602660205260409020546103e911611d6e5760405162461bcd60e51b815260206004820152600e60248201526d2634b6b4ba103932b0b1b432b21760911b6044820152606401610ff0565b60008281526028602090815260408083208484529091529020546201518090611d979042615af9565b1015611db55760405162461bcd60e51b8152600401610ff090615c06565b600082118015611dc757506008548211155b8015611dd35750600081115b8015611de157506008548111155b611dfd5760405162461bcd60e51b8152600401610ff090615a7d565b808203611e365760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b6044820152606401610ff0565b601054611e428161474d565b611e4d81600a6147ec565b6000838152602660205260408120805491611e6783615ae0565b9091555050600083815260286020908152604080832085845290915281204290556015805491611e9683615ae0565b90915550506000828152602460205260408082206002908101548684529183200154118015611ed75750600083815260246020526040902060040154601411155b15611ee457506014611f45565b600083815260246020526040902060030154611f029061012c615ab6565b60008581526024602052604090206004015410801590611f345750600083815260246020526040902060040154601411155b15611f4157506014611f45565b50600a5b60008381526024602052604081206004018054839290611f66908490615af9565b909155505060008481526024602052604081206004018054839290611f8c908490615ab6565b925050819055504283857fff229b26956a17ed5d6c377286dfdad2e5bbfc48a4c8c1266b1b4a1bafa9d87984604051611fc791815260200190565b60405180910390a46000848152602460205260408120600501805491611fec83615ae0565b9091555050600084815260246020526040812060090180549161200e83615ae0565b91905055506012546020546010546120269190615b32565b6010546120339190615af9565b61203d9190615b32565b6000858152602460205260408120600701805490919061205e908490615ab6565b9091555050604080516080810182528581526020808201868152828401858152600089815260288452858120898252845285812054606086019081528a8252602a855295812080546001808201835591835294909120945160049094029094019283559051928201929092559051600282015590516003909101555b50506120e66001600b55565b5050565b60006120f560085490565b82106121585760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610ff0565b6008828154811061216b5761216b615b54565b90600052602060002001549050919050565b612185614390565b61218e826122d0565b6001600160a01b0316336001600160a01b0316146121de5760405162461bcd60e51b815260206004820152600d60248201526c2737ba102cb7bab91027232a1760991b6044820152606401610ff0565b60008151116122195760405162461bcd60e51b81526020600482015260076024820152664e6f204e616d6560c81b6044820152606401610ff0565b60085482111561223b5760405162461bcd60e51b8152600401610ff090615a7d565b60008281526024602052604090206122538282615c77565b506120e66001600b55565b612266614503565b601155565b612273614503565b60005b818110156110915760016025600085858581811061229657612296615b54565b60209081029290920135835250810191909152604001600020805460ff1916911515919091179055806122c881615ae0565b915050612276565b6000818152600260205260408120546001600160a01b031680610ebd5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610ff0565b612338614390565b601a5460ff161561235b5760405162461bcd60e51b8152600401610ff090615a2f565b612364826122d0565b6001600160a01b0316336001600160a01b0316146123b45760405162461bcd60e51b815260206004820152600d60248201526c4e6f7420796f7572204e46542160981b6044820152606401610ff0565b600082815260246020526040902060080154158015906123e4575060008181526024602052604090206008015415155b6124205760405162461bcd60e51b815260206004820152600d60248201526c20b1ba34bb30ba329027232a1760991b6044820152606401610ff0565b60008281526024602052604090206003015461246b5760405162461bcd60e51b815260206004820152600a60248201526927379030ba3a30b1b59760b11b6044820152606401610ff0565b6000818152602460205260409020600301546124bb5760405162461bcd60e51b815260206004820152600f60248201526e24b6b837ba32b73a1032b732b6bc9760891b6044820152606401610ff0565b6000828152602660205260409020546103e91161250b5760405162461bcd60e51b815260206004820152600e60248201526d2634b6b4ba103932b0b1b432b21760911b6044820152606401610ff0565b600082815260286020908152604080832084845290915290205462015180906125349042615af9565b10156125525760405162461bcd60e51b8152600401610ff090615c06565b60008211801561256457506008548211155b80156125705750600081115b801561257e57506008548111155b61259a5760405162461bcd60e51b8152600401610ff090615a7d565b8082036125d35760405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b6044820152606401610ff0565b60008281526025602052604090205460ff16156126025760405162461bcd60e51b8152600401610ff090615a58565b60105461260e8161474d565b61261981600a6147ec565b600083815260266020526040812080549161263383615ae0565b909155505060008381526028602090815260408083208584529091528120429055601580549161266283615ae0565b909155505060008281526024602052604080822060029081015486845291832001541180156126a35750600083815260246020526040902060030154601411155b156126b057506014612711565b6000838152602460205260409020600401546126ce9061012c615ab6565b600085815260246020526040902060030154108015906127005750600083815260246020526040902060030154601411155b1561270d57506014612711565b50600a5b60008381526024602052604081206003018054839290612732908490615af9565b909155505060008481526024602052604081206003018054839290612758908490615ab6565b925050819055504283857f2a7e4271816fd9e2b2e21c4a4a7df63aa2c324c6ad1fc330161b6e7099206a788460405161279391815260200190565b60405180910390a460008481526024602052604081206005018054916127b883615ae0565b909155505060008481526024602052604081206009018054916127da83615ae0565b91905055506012546020546010546127f29190615b32565b6010546127ff9190615af9565b6128099190615b32565b6000858152602460205260408120600701805490919061282a908490615ab6565b9091555050604080516080810182528581526020808201868152828401858152600089815260288452858120898252845285812054606086019081528a82526029855295812080546001808201835591835294909120945160049094029094019283559051928201929092559051600282015590516003909101556120da565b601680546116e0906159f5565b60006001600160a01b0382166129215760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610ff0565b506001600160a01b031660009081526003602052604090205490565b612945614503565b61294f6000614a15565b565b612959614390565b601a5460ff161561297c5760405162461bcd60e51b8152600401610ff090615a2f565b6000818152602460205260409020600801546129aa5760405162461bcd60e51b8152600401610ff090615be0565b6129b3816122d0565b6001600160a01b0316336001600160a01b0316146129e35760405162461bcd60e51b8152600401610ff090615b0c565b6000811180156129f557506008548111155b612a115760405162461bcd60e51b8152600401610ff090615a7d565b60008181526025602052604090205460ff1615612a405760405162461bcd60e51b8152600401610ff090615a58565b601054612a4c8161474d565b612a578160326147ec565b60225460008381526024602052604081206003018054909190612a7b908490615ab6565b90915550506001600b555050565b612a91614503565b8460008b9003612c345760005b81811015612c2e576000612ab2828d615ab6565b9050604051806101400160405280888885818110612ad257612ad2615b54565b9050602002810190612ae49190615d36565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093855250505060208083018590526040808401839052606460608501819052608085015260a0840183905260c0840183905260e084018390526101008401839052610120909301829052848252602490522081518190612b749082615c77565b506020820151600182015560408201516002820155606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e08201516007820155610100820151600882015561012090910151600990910155612c05858584818110612be857612be8615b54565b9050602002016020810190612bfd91906153d8565b600c54614a67565b600c8054906000612c1583615ae0565b9190505550508080612c2690615ae0565b915050612a9e565b50612e12565b60005b88811015612e105760008a8a83818110612c5357612c53615b54565b90506020020135905088886000818110612c6f57612c6f615b54565b90506020020135602460008381526020019081526020016000206002018190555088886001818110612ca357612ca3615b54565b90506020020135602460008381526020019081526020016000206003018190555088886002818110612cd757612cd7615b54565b90506020020135602460008381526020019081526020016000206004018190555088886003818110612d0b57612d0b615b54565b90506020020135602460008381526020019081526020016000206005018190555088886004818110612d3f57612d3f615b54565b90506020020135602460008381526020019081526020016000206006018190555088886005818110612d7357612d73615b54565b90506020020135602460008381526020019081526020016000206007018190555088886006818110612da757612da7615b54565b90506020020135602460008381526020019081526020016000206008018190555088886007818110612ddb57612ddb615b54565b905060200201356024600083815260200190815260200160002060090181905550508080612e0890615ae0565b915050612c37565b505b5050505050505050505050565b612e27614390565b601a5460ff1615612e4a5760405162461bcd60e51b8152600401610ff090615a2f565b612e53816122d0565b6001600160a01b0316336001600160a01b031614612e835760405162461bcd60e51b8152600401610ff090615b0c565b600081118015612e9557506008548111155b612eb15760405162461bcd60e51b8152600401610ff090615a7d565b600081815260246020526040902060080154612edf5760405162461bcd60e51b8152600401610ff090615be0565b60008181526025602052604090205460ff1615612f0e5760405162461bcd60e51b8152600401610ff090615a58565b601054612f1a8161474d565b612f258160326147ec565b60225460008381526024602052604081206004018054909190612a7b908490615ab6565b612f51614503565b600d55565b6017546001600160a01b03163314612f805760405162461bcd60e51b8152600401610ff090615bb7565b601a5460ff1615612fd35760405162461bcd60e51b815260206004820152601860248201527f436f6e747261637420616c7265616479207061757365642e00000000000000006044820152606401610ff0565b601a805460ff191660011790556040517f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62590600090a1565b613013614503565b60408051602081019091526001600160a01b0391821681526023805460018101825560009190915290517fd57b2b5166478fd4318d2acc6cc2c704584312bdd8781b32d5d06abda57f423090910180546001600160a01b03191691909216179055565b602a602052816000526040600020818154811061309257600080fd5b60009182526020909120600490910201805460018201546002830154600390930154919450925084565b6130c4614503565b60005b81811015611091576000602560008585858181106130e7576130e7615b54565b60209081029290920135835250810191909152604001600020805460ff19169115159190911790558061311981615ae0565b9150506130c7565b613129614503565b60166120e68282615c77565b606060018054610ed2906159f5565b6029602052816000526040600020818154811061309257600080fd5b613168614390565b601a5460ff161561318b5760405162461bcd60e51b8152600401610ff090615a2f565b600081815260246020526040902060020154600111156131da5760405162461bcd60e51b815260206004820152600a6024820152694d696e204c6576656c3160b01b6044820152606401610ff0565b6000818152602460205260409020600701546132245760405162461bcd60e51b8152602060048201526009602482015268139bc81c185e5bdd5d60ba1b6044820152606401610ff0565b600081815260246020526040902060060154600511156132735760405162461bcd60e51b815260206004820152600a6024820152694669676874206d6f726560b01b6044820152606401610ff0565b61327c816122d0565b6001600160a01b0316336001600160a01b0316146132ac5760405162461bcd60e51b8152600401610ff090615b0c565b60008181526025602052604090205460ff16156132db5760405162461bcd60e51b8152600401610ff090615a58565b60125460008281526024602052604081206007015490916132fb91615ac9565b905060006023600e548154811061331457613314615b54565b600091825260209091200180546040516370a0823160e01b81523060048201529192506001600160a01b031690839082906370a0823190602401602060405180830381865afa15801561336b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061338f9190615d7c565b116133d25760405162461bcd60e51b81526020600482015260136024820152724e6f7420456e6f75676820526573657276657360681b6044820152606401610ff0565b60405163a9059cbb60e01b8152336004820152602481018490526001600160a01b0382169063a9059cbb906044016020604051808303816000875af115801561341f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134439190615d95565b6134815760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8811985a5b1959608a1b6044820152606401610ff0565b600084815260246020526040808220600781018390556006810183905560050182905551849133917f2148c22360ec869df90a6857cc7c0b2c254544deff5a5e2e88f91c6c3e27ee059190a350505061129b6001600b55565b6120e6338383614c00565b6017546001600160a01b0316331461350f5760405162461bcd60e51b8152600401610ff090615bb7565b61129b81613d93565b613520614503565b601055565b61352f338361455d565b61354b5760405162461bcd60e51b8152600401610ff090615b6a565b61355784848484614cce565b50505050565b606061356860085490565b8211156135875760405162461bcd60e51b8152600401610ff090615a7d565b600060168054613596906159f5565b9050116135b25760405180602001604052806000815250610ebd565b60166135bd83614d01565b6040516020016135ce929190615db2565b60405160208183030381529060405292915050565b6135eb614390565b601a5460ff161561360e5760405162461bcd60e51b8152600401610ff090615a2f565b600d5434146136525760405162461bcd60e51b815260206004820152601060248201526f496e73756666696369656e742066656560801b6044820152606401610ff0565b600081511161368d5760405162461bcd60e51b81526020600482015260076024820152664e6f204e616d6560c81b6044820152606401610ff0565b604051806101400160405280828152602001600c54815260200160008152602001606481526020016064815260200160008152602001600081526020016000815260200160008152602001600081525060246000600c54815260200190815260200160002060008201518160000190816137079190615c77565b506020820151600182015560408201516002820155606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e08201516007820155610100820151600882015561012090910151600990910155600c546137733382614a67565b60408051602080820183526000808352600c54815260259091528290209051815460ff19169015151790555181907f51413fa31ea07fada8e4b3a4719c2683c7288050bc37c83c4ad11ce93423087f906137ce908590615306565b60405180910390a2600c80549060006137e683615ae0565b91905055505061129b6001600b55565b6000818152602a60205260408120546060919081816001600160401b038111156138225761382261554b565b60405190808252806020026020018201604052801561387e57816020015b61386b6040518060800160405280600081526020016000815260200160008152602001600081525090565b8152602001906001900390816138405790505b50905060005b82811015613965576000868152602a602052604090208054879190839081106138af576138af615b54565b90600052602060002090600402016000015403613953576000868152602a602052604090208054829081106138e6576138e6615b54565b906000526020600020906004020160405180608001604052908160008201548152602001600182015481526020016002820154815260200160038201548152505082858151811061393957613939615b54565b6020026020010181905250838061394f90615ae0565b9450505b8061395d81615ae0565b915050613884565b50949350505050565b613976614503565b60006023838154811061398b5761398b615b54565b6000918252602090912001805460405163a9059cbb60e01b8152336004820152602481018590529192506001600160a01b031690819063a9059cbb906044016020604051808303816000875af11580156139e9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a0d9190615d95565b5050505050565b6017546001600160a01b03163314613a3e5760405162461bcd60e51b8152600401610ff090615bb7565b601780546001600160a01b0319166001600160a01b0392909216919091179055565b613a68614390565b601a5460ff1615613a8b5760405162461bcd60e51b8152600401610ff090615a2f565b613a94816122d0565b6001600160a01b0316336001600160a01b031614613ac45760405162461bcd60e51b8152600401610ff090615b0c565b60008181526025602052604090205460ff1615613af35760405162461bcd60e51b8152600401610ff090615a58565b6000818152602760205260409020546201518090613b119042615af9565b1015613b2f5760405162461bcd60e51b8152600401610ff090615c06565b60008181526026602090815260408083208390556027909152902042905561129b6001600b55565b613b5f614390565b601a5460ff1615613b825760405162461bcd60e51b8152600401610ff090615a2f565b613b8b816122d0565b6001600160a01b0316336001600160a01b031614613bbb5760405162461bcd60e51b8152600401610ff090615b0c565b60008181526025602052604090205460ff1615613bea5760405162461bcd60e51b8152600401610ff090615a58565b600081118015613bfc57506008548111155b613c185760405162461bcd60e51b8152600401610ff090615a7d565b600081815260246020526040812060040154606490613c38908290615af9565b613c429190615b32565b905060008111613c835760405162461bcd60e51b815260206004820152600c60248201526b4e6f7420456c696769626c6560a01b6044820152606401610ff0565b60008281526024602052604081206006018054839290613ca4908490615ab6565b90915550613cb59050816064615ac9565b600083815260246020526040902060040154613cd19190615af9565b6000838152602460209081526040822060040192909255601254915460105460059384928692613d019190615b32565b601054613d0e9190615af9565b613d189190615b32565b613d229190615ac9565b613d2c9190615ac9565b905080602460008681526020019081526020016000206007016000828254613d549190615ab6565b9091555050604051819085907f7f5659a067632eac859a934c471d405a845bf03086d0206bc77ca28c7b00b6c290600090a350505061129b6001600b55565b613d9b614503565b6001600160a01b038116613e005760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610ff0565b61129b81614a15565b613e11614390565b601a5460ff1615613e345760405162461bcd60e51b8152600401610ff090615a2f565b613e3d816122d0565b6001600160a01b0316336001600160a01b031614613e6d5760405162461bcd60e51b8152600401610ff090615b0c565b600081118015613e7f57506008548111155b613e9b5760405162461bcd60e51b8152600401610ff090615a7d565b60008181526025602052604090205460ff1615613eca5760405162461bcd60e51b8152600401610ff090615a58565b60008181526024602052604081206008015415613fef5760008281526024602052604090206006015460051115613f385760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742077696e732160701b6044820152606401610ff0565b6000601254602054601054613f4d9190615b32565b601054613f5a9190615af9565b613f649190615b32565b613f6f906005615ac9565b613f7a906005615ac9565b905080602460008581526020019081526020016000206007016000828254613fa29190615af9565b90915550506000838152602460205260408120600601805460059290613fc9908490615af9565b9091555050601254613fdb9082615ac9565b9150613fe9826021546147ec565b50614007565b50601154613ffc8161474d565b61400781600a6147ec565b60008281526024602052604081206008018054916137e683615ae0565b60246020526000908152604090208054819061403f906159f5565b80601f016020809104026020016040519081016040528092919081815260200182805461406b906159f5565b80156140b85780601f1061408d576101008083540402835291602001916140b8565b820191906000526020600020905b81548152906001019060200180831161409b57829003601f168201915b505050505090806001015490806002015490806003015490806004015490806005015490806006015490806007015490806008015490806009015490508a565b600081815260296020526040812054606091816001600160401b038111156141225761412261554b565b60405190808252806020026020018201604052801561417e57816020015b61416b6040518060800160405280600081526020016000815260200160008152602001600081525090565b8152602001906001900390816141405790505b5090506000805b838110156116c95760008681526029602052604090208054879190839081106141b0576141b0615b54565b906000526020600020906004020160000154036142545760008681526029602052604090208054829081106141e7576141e7615b54565b906000526020600020906004020160405180608001604052908160008201548152602001600182015481526020016002820154815260200160038201548152505083838151811061423a5761423a615b54565b6020026020010181905250818061425090615ae0565b9250505b8061425e81615ae0565b915050614185565b61426e614503565b602b55565b60006001600160e01b031982166380ac58cd60e01b14806142a457506001600160e01b03198216635b5e139f60e01b145b80610ebd57506301ffc9a760e01b6001600160e01b0319831614610ebd565b6000818152600260205260409020546001600160a01b031661129b5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610ff0565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190614357826122d0565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6002600b54036143e25760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ff0565b6002600b55565b60006023600f548154811061440057614400615b54565b600091825260209091200180546040516323b872dd60e01b8152336004820152306024820152604481018590529192506001600160a01b03169081906323b872dd906064016020604051808303816000875af1158015614464573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144889190615d95565b5060185460405163b90306ad60e01b8152600481018590526001600160a01b039091169063b90306ad90602401600060405180830381600087803b1580156144cf57600080fd5b505af11580156144e3573d6000803e3d6000fd5b5050505082601460008282546144f99190615ab6565b9091555050505050565b600a546001600160a01b0316331461294f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610ff0565b600080614569836122d0565b9050806001600160a01b0316846001600160a01b031614806145b057506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806145d45750836001600160a01b03166145c984610f55565b6001600160a01b0316145b949350505050565b826001600160a01b03166145ef826122d0565b6001600160a01b0316146146155760405162461bcd60e51b8152600401610ff090615e49565b6001600160a01b0382166146775760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610ff0565b6146848383836001614d93565b826001600160a01b0316614697826122d0565b6001600160a01b0316146146bd5760405162461bcd60e51b8152600401610ff090615e49565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60006023600e548154811061476457614764615b54565b600091825260209091200180546040516323b872dd60e01b8152336004820152306024820152604481018590529192506001600160a01b03169081906323b872dd906064016020604051808303816000875af11580156147c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135579190615d95565b600060646147fa8385615ac9565b6148049190615b32565b905060006064601d54836148189190615ac9565b6148229190615b32565b905060006064601e54846148369190615ac9565b6148409190615b32565b905060006064601f54856148549190615ac9565b61485e9190615b32565b905060006023600e548154811061487757614877615b54565b60009182526020909120018054601c5460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018890529293501690819063a9059cbb906044016020604051808303816000875af11580156148da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148fe9190615d95565b50601b5460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018690529082169063a9059cbb906044016020604051808303816000875af1158015614952573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149769190615d95565b50601a5460405163a9059cbb60e01b81526101009091046001600160a01b0390811660048301526024820185905282169063a9059cbb906044016020604051808303816000875af11580156149cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149f39190615d95565b508560136000828254614a069190615ab6565b90915550505050505050505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b038216614abd5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610ff0565b6000818152600260205260409020546001600160a01b031615614b225760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610ff0565b614b30600083836001614d93565b6000818152600260205260409020546001600160a01b031615614b955760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610ff0565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b816001600160a01b0316836001600160a01b031603614c615760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610ff0565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b614cd98484846145dc565b614ce584848484614ec0565b6135575760405162461bcd60e51b8152600401610ff090615e8e565b60606000614d0e83614fc1565b60010190506000816001600160401b03811115614d2d57614d2d61554b565b6040519080825280601f01601f191660200182016040528015614d57576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084614d6157509392505050565b6001811115614e025760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610ff0565b816001600160a01b038516614e5e57614e5981600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b614e81565b836001600160a01b0316856001600160a01b031614614e8157614e818582615099565b6001600160a01b038416614e9d57614e9881615136565b613a0d565b846001600160a01b0316846001600160a01b031614613a0d57613a0d84826151e5565b60006001600160a01b0384163b15614fb657604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614f04903390899088908890600401615ee0565b6020604051808303816000875af1925050508015614f3f575060408051601f3d908101601f19168201909252614f3c91810190615f1d565b60015b614f9c573d808015614f6d576040519150601f19603f3d011682016040523d82523d6000602084013e614f72565b606091505b508051600003614f945760405162461bcd60e51b8152600401610ff090615e8e565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506145d4565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106150005772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061502c576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061504a57662386f26fc10000830492506010015b6305f5e1008310615062576305f5e100830492506008015b612710831061507657612710830492506004015b60648310615088576064830492506002015b600a8310610ebd5760010192915050565b600060016150a6846128b7565b6150b09190615af9565b600083815260076020526040902054909150808214615103576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061514890600190615af9565b6000838152600960205260408120546008805493945090928490811061517057615170615b54565b90600052602060002001549050806008838154811061519157615191615b54565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806151c9576151c9615f3a565b6001900381819060005260206000200160009055905550505050565b60006151f0836128b7565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b604051806101400160405280606081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6001600160e01b03198116811461129b57600080fd5b6000602082840312156152a457600080fd5b81356152af8161527c565b9392505050565b60005b838110156152d15781810151838201526020016152b9565b50506000910152565b600081518084526152f28160208601602086016152b6565b601f01601f19169290920160200192915050565b6020815260006152af60208301846152da565b60006020828403121561532b57600080fd5b5035919050565b6001600160a01b038116811461129b57600080fd5b6000806040838503121561535a57600080fd5b823561536581615332565b946020939093013593505050565b6000806040838503121561538657600080fd5b50508035926020909101359150565b60008060008060008060c087890312156153ae57600080fd5b505084359660208601359650604086013595606081013595506080810135945060a0013592509050565b6000602082840312156153ea57600080fd5b81356152af81615332565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156154b157603f1989840301855281516101408151818652615443828701826152da565b838b0151878c0152898401518a880152606080850151908801526080808501519088015260a0808501519088015260c0808501519088015260e0808501519088015261010080850151908801526101209384015193909601929092525050938601939086019060010161541c565b509098975050505050505050565b6000806000606084860312156154d457600080fd5b83356154df81615332565b925060208401356154ef81615332565b929592945050506040919091013590565b60008060006060848603121561551557600080fd5b833561552081615332565b9250602084013561553081615332565b9150604084013561554081615332565b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b60006001600160401b038084111561557b5761557b61554b565b604051601f8501601f19908116603f011681019082821181831017156155a3576155a361554b565b816040528093508581528686860111156155bc57600080fd5b858560208301376000602087830101525050509392505050565b600082601f8301126155e757600080fd5b6152af83833560208501615561565b6000806040838503121561560957600080fd5b8235915060208301356001600160401b0381111561562657600080fd5b615632858286016155d6565b9150509250929050565b60008083601f84011261564e57600080fd5b5081356001600160401b0381111561566557600080fd5b6020830191508360208260051b850101111561568057600080fd5b9250929050565b6000806020838503121561569a57600080fd5b82356001600160401b038111156156b057600080fd5b6156bc8582860161563c565b90969095509350505050565b60008060008060008060008060008060c08b8d0312156156e757600080fd5b8a35995060208b0135985060408b01356001600160401b038082111561570c57600080fd5b6157188e838f0161563c565b909a50985060608d013591508082111561573157600080fd5b61573d8e838f0161563c565b909850965060808d013591508082111561575657600080fd5b6157628e838f0161563c565b909650945060a08d013591508082111561577b57600080fd5b506157888d828e0161563c565b915080935050809150509295989b9194979a5092959850565b6000602082840312156157b357600080fd5b81356001600160401b038111156157c957600080fd5b6145d4848285016155d6565b801515811461129b57600080fd5b600080604083850312156157f657600080fd5b823561580181615332565b91506020830135615811816157d5565b809150509250929050565b6000806000806080858703121561583257600080fd5b843561583d81615332565b9350602085013561584d81615332565b92506040850135915060608501356001600160401b0381111561586f57600080fd5b8501601f8101871361588057600080fd5b61588f87823560208401615561565b91505092959194509250565b6020808252825182820181905260009190848201906040850190845b818110156158fe576158eb838551805182526020810151602083015260408101516040830152606081015160608301525050565b92840192608092909201916001016158b7565b50909695505050505050565b6000806040838503121561591d57600080fd5b823561592881615332565b9150602083013561581181615332565b600061014080835261594c8184018e6152da565b602084019c909c52505060408101989098526060880196909652608087019490945260a086019290925260c085015260e084015261010083015261012090910152919050565b6020808252825182820181905260009190848201906040850190845b818110156158fe576159e2838551805182526020810151602083015260408101516040830152606081015160608301525050565b92840192608092909201916001016159ae565b600181811c90821680615a0957607f821691505b602082108103615a2957634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600f908201526e14185d5cd9590810dbdb9d1c9858dd608a1b604082015260600190565b6020808252600b908201526a109b1858dadb1a5cdd195960aa1b604082015260600190565b602080825260099082015268139bdd08119bdd5b9960ba1b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b80820180821115610ebd57610ebd615aa0565b8082028115828204841417610ebd57610ebd615aa0565b600060018201615af257615af2615aa0565b5060010190565b81810381811115610ebd57610ebd615aa0565b6020808252600c908201526b139bdd081e5bdd5c8813919560a21b604082015260600190565b600082615b4f57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b6020808252600f908201526e2737ba1030baba3437b934bd32b21760891b604082015260600190565b6020808252600c908201526b1058dd1a5d985d194813919560a21b604082015260600190565b6020808252600990820152682a37b79039b7b7b71760b91b604082015260600190565b601f82111561109157600081815260208120601f850160051c81016020861015615c505750805b601f850160051c820191505b81811015615c6f57828155600101615c5c565b505050505050565b81516001600160401b03811115615c9057615c9061554b565b615ca481615c9e84546159f5565b84615c29565b602080601f831160018114615cd95760008415615cc15750858301515b600019600386901b1c1916600185901b178555615c6f565b600085815260208120601f198616915b82811015615d0857888601518255948401946001909101908401615ce9565b5085821015615d265787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000808335601e19843603018112615d4d57600080fd5b8301803591506001600160401b03821115615d6757600080fd5b60200191503681900382131561568057600080fd5b600060208284031215615d8e57600080fd5b5051919050565b600060208284031215615da757600080fd5b81516152af816157d5565b6000808454615dc0816159f5565b60018281168015615dd85760018114615ded57615e1c565b60ff1984168752821515830287019450615e1c565b8860005260208060002060005b85811015615e135781548a820152908401908201615dfa565b50505082870194505b505050508351615e308183602088016152b6565b64173539b7b760d91b9101908152600501949350505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090615f13908301846152da565b9695505050505050565b600060208284031215615f2f57600080fd5b81516152af8161527c565b634e487b7160e01b600052603160045260246000fdfea26469706673582212203d5d2633d9c3ed7fbd9ffac38c4aea704791071eabe3e17ac4c3c60e0e031b7c64736f6c63430008120033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000deb4316defc86a53fe465207825d987cd2f636a4000000000000000000000000aba13099d371a483dbf6cfd5ca654c7a3547cc740000000000000000000000000000000000000000000000000000000000000009426174746c65646f67000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034244470000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): Battledog
Arg [1] : _symbol (string): BDG
Arg [2] : GAMEAddress (address): 0xDeB4316DeFC86A53fE465207825D987CD2F636a4
Arg [3] : _newGuard (address): 0xabA13099d371a483DBF6cFD5cA654c7A3547cC74
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [2] : 000000000000000000000000deb4316defc86a53fe465207825d987cd2f636a4
Arg [3] : 000000000000000000000000aba13099d371a483dbf6cfd5ca654c7a3547cc74
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000009
Arg [5] : 426174746c65646f670000000000000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [7] : 4244470000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
113751:25833:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;107467:224;;;;;;;;;;-1:-1:-1;107467:224:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;107467:224:0;;;;;;;;91516:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;93028:171::-;;;;;;;;;;-1:-1:-1;93028:171:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1697:32:1;;;1679:51;;1667:2;1652:18;93028:171:0;1533:203:1;92546:416:0;;;;;;;;;;-1:-1:-1;92546:416:0;;;;;:::i;:::-;;:::i;:::-;;116341:72;;;;;;;;;;-1:-1:-1;116341:72:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;2596:25:1;;;2584:2;2569:18;116341:72:0;2450:177:1;131735:928:0;;;;;;;;;;-1:-1:-1;131735:928:0;;;;;:::i;:::-;;:::i;126974:1060::-;;;;;;;;;;-1:-1:-1;126974:1060:0;;;;;:::i;:::-;;:::i;114962:22::-;;;;;;;;;;;;;;;;120058:325;;;;;;;;;;-1:-1:-1;120058:325:0;;;;;:::i;:::-;;:::i;114194:38::-;;;;;;;;;;;;;;;;108107:113;;;;;;;;;;-1:-1:-1;108195:10:0;:17;108107:113;;136747:451;;;;;;;;;;-1:-1:-1;136747:451:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;114269:23::-;;;;;;;;;;;;;;;;114353:50;;;;;;;;;;;;;;;;114694:69;;;;;;;;;;;;;:::i;93728:301::-;;;;;;;;;;-1:-1:-1;93728:301:0;;;;;:::i;:::-;;:::i;116176:49::-;;;;;;;;;;-1:-1:-1;116176:49:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;116070:32;;;;;;;;;;-1:-1:-1;116070:32:0;;;;;:::i;:::-;;:::i;114668:19::-;;;;;;;;;;-1:-1:-1;114668:19:0;;;;-1:-1:-1;;;;;114668:19:0;;;133426:157;;;;;;:::i;:::-;;:::i;119933:117::-;;;;;;;;;;-1:-1:-1;119933:117:0;;;;;:::i;:::-;;:::i;107775:256::-;;;;;;;;;;-1:-1:-1;107775:256:0;;;;;:::i;:::-;;:::i;133859:265::-;;;;;;;;;;-1:-1:-1;133859:265:0;;;;;:::i;:::-;;:::i;114496:33::-;;;;;;;;;;;;;;;;119659:159;;;;;;;;;;-1:-1:-1;119659:159:0;;;;;:::i;:::-;;:::i;136356:144::-;;;;;;;;;;;;;:::i;94100:151::-;;;;;;;;;;-1:-1:-1;94100:151:0;;;;;:::i;:::-;;:::i;136525:214::-;;;;;;;;;;-1:-1:-1;136525:214:0;;;;;:::i;:::-;;:::i;114299:47::-;;;;;;;;;;;;;;;;115055:26;;;;;;;;;;;;;;;;128177:2273;;;;;;:::i;:::-;;:::i;108297:233::-;;;;;;;;;;-1:-1:-1;108297:233:0;;;;;:::i;:::-;;:::i;119161:390::-;;;;;;;;;;-1:-1:-1;119161:390:0;;;;;:::i;:::-;;:::i;131705:21::-;;;;;;;;;;;;;;;;120526:135;;;;;;;;;;-1:-1:-1;120526:135:0;;;;;:::i;:::-;;:::i;114770:26::-;;;;;;;;;;-1:-1:-1;114770:26:0;;;;;;;;139076:195;;;;;;;;;;-1:-1:-1;139076:195:0;;;;;:::i;:::-;;:::i;114933:22::-;;;;;;;;;;;;;;;;91226:223;;;;;;;;;;-1:-1:-1;91226:223:0;;;;;:::i;:::-;;:::i;114804:41::-;;;;;;;;;;-1:-1:-1;114804:41:0;;;;;;;-1:-1:-1;;;;;114804:41:0;;;124710:2166;;;;;;:::i;:::-;;:::i;114611:21::-;;;;;;;;;;;;;:::i;90957:207::-;;;;;;;;;;-1:-1:-1;90957:207:0;;;;;:::i;:::-;;:::i;114900:26::-;;;;;;;;;;-1:-1:-1;114900:26:0;;;;-1:-1:-1;;;;;114900:26:0;;;61829:103;;;;;;;;;;;;;:::i;123174:694::-;;;;;;:::i;:::-;;:::i;117502:1651::-;;;;;;;;;;-1:-1:-1;117502:1651:0;;;;;:::i;:::-;;:::i;123877:688::-;;;;;;:::i;:::-;;:::i;119826:99::-;;;;;;;;;;-1:-1:-1;119826:99:0;;;;;:::i;:::-;;:::i;136182:144::-;;;;;;;;;;;;;:::i;115088:18::-;;;;;;;;;;;;;;;;135458:185;;;;;;;;;;-1:-1:-1;135458:185:0;;;;;:::i;:::-;;:::i;116477:54::-;;;;;;;;;;-1:-1:-1;116477:54:0;;;;;:::i;:::-;;:::i;:::-;;;;10853:25:1;;;10909:2;10894:18;;10887:34;;;;10937:18;;;10930:34;10995:2;10980:18;;10973:34;10840:3;10825:19;116477:54:0;10622:391:1;114991:21:0;;;;;;;;;;;;;;;;61188:87;;;;;;;;;;-1:-1:-1;61261:6:0;;-1:-1:-1;;;;;61261:6:0;61188:87;;139279:201;;;;;;;;;;-1:-1:-1;139279:201:0;;;;;:::i;:::-;;:::i;135763:105::-;;;;;;;;;;-1:-1:-1;135763:105:0;;;;;:::i;:::-;;:::i;91685:104::-;;;;;;;;;;;;;:::i;116420:50::-;;;;;;;;;;-1:-1:-1;116420:50:0;;;;;:::i;:::-;;:::i;134212:1234::-;;;;;;:::i;:::-;;:::i;93271:155::-;;;;;;;;;;-1:-1:-1;93271:155:0;;;;;:::i;:::-;;:::i;133268:150::-;;;;;;;;;;-1:-1:-1;133268:150:0;;;;;:::i;:::-;;:::i;114540:31::-;;;;;;;;;;;;;;;;120391:127;;;;;;;;;;-1:-1:-1;120391:127:0;;;;;:::i;:::-;;:::i;94322:279::-;;;;;;;;;;-1:-1:-1;94322:279:0;;;;;:::i;:::-;;:::i;135876:278::-;;;;;;;;;;-1:-1:-1;135876:278:0;;;;;:::i;:::-;;:::i;115023:22::-;;;;;;;;;;;;;;;;114239:23;;;;;;;;;;;;;;;;116232:49;;;;;;;;;;-1:-1:-1;116232:49:0;;;;;:::i;:::-;;;;;;;;;;;;;;116605:889;;;;;;:::i;:::-;;:::i;114852:34::-;;;;;;;;;;-1:-1:-1;114852:34:0;;;;-1:-1:-1;;;;;114852:34:0;;;138542:526;;;;;;;;;;-1:-1:-1;138542:526:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;133591:260::-;;;;;;:::i;:::-;;:::i;139488:93::-;;;;;;;;;;-1:-1:-1;139488:93:0;;;;;:::i;:::-;;:::i;132675:581::-;;;;;;;;;;-1:-1:-1;132675:581:0;;;;;:::i;:::-;;:::i;93497:164::-;;;;;;;;;;-1:-1:-1;93497:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;93618:25:0;;;93594:4;93618:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;93497:164;130551:1068;;;;;;;;;;-1:-1:-1;130551:1068:0;;;;;:::i;:::-;;:::i;62087:201::-;;;;;;;;;;-1:-1:-1;62087:201:0;;;;;:::i;:::-;;:::i;121966:1200::-;;;;;;:::i;:::-;;:::i;116127:42::-;;;;;;;;;;-1:-1:-1;116127:42:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;;;:::i;114452:37::-;;;;;;;;;;;;;;;;137611:511;;;;;;;;;;-1:-1:-1;137611:511:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;119559:92::-;;;;;;;;;;-1:-1:-1;119559:92:0;;;;;:::i;:::-;;:::i;107467:224::-;107569:4;-1:-1:-1;;;;;;107593:50:0;;-1:-1:-1;;;107593:50:0;;:90;;;107647:36;107671:11;107647:23;:36::i;:::-;107586:97;107467:224;-1:-1:-1;;107467:224:0:o;91516:100::-;91570:13;91603:5;91596:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91516:100;:::o;93028:171::-;93104:7;93124:23;93139:7;93124:14;:23::i;:::-;-1:-1:-1;93167:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;93167:24:0;;93028:171::o;92546:416::-;92627:13;92643:23;92658:7;92643:14;:23::i;:::-;92627:39;;92691:5;-1:-1:-1;;;;;92685:11:0;:2;-1:-1:-1;;;;;92685:11:0;;92677:57;;;;-1:-1:-1;;;92677:57:0;;16232:2:1;92677:57:0;;;16214:21:1;16271:2;16251:18;;;16244:30;16310:34;16290:18;;;16283:62;-1:-1:-1;;;16361:18:1;;;16354:31;16402:19;;92677:57:0;;;;;;;;;59819:10;-1:-1:-1;;;;;92769:21:0;;;;:62;;-1:-1:-1;92794:37:0;92811:5;59819:10;93497:164;:::i;92794:37::-;92747:173;;;;-1:-1:-1;;;92747:173:0;;16634:2:1;92747:173:0;;;16616:21:1;16673:2;16653:18;;;16646:30;16712:34;16692:18;;;16685:62;16783:31;16763:18;;;16756:59;16832:19;;92747:173:0;16432:425:1;92747:173:0;92933:21;92942:2;92946:7;92933:8;:21::i;:::-;92616:346;92546:416;;:::o;131735:928::-;2387:21;:19;:21::i;:::-;131811:6:::1;::::0;::::1;;131810:7;131802:35;;;;-1:-1:-1::0;;;131802:35:0::1;;;;;;;:::i;:::-;131950:18;131958:9;131950:7;:18::i;:::-;-1:-1:-1::0;;;;;131936:32:0::1;:10;-1:-1:-1::0;;;;;131936:32:0::1;;131928:57;;;::::0;-1:-1:-1;;;131928:57:0;;17408:2:1;131928:57:0::1;::::0;::::1;17390:21:1::0;17447:2;17427:18;;;17420:30;-1:-1:-1;;;17466:18:1;;;17459:42;17518:18;;131928:57:0::1;17206:336:1::0;131928:57:0::1;132005:22;::::0;;;:11:::1;:22;::::0;;;;:32;::::1;;132004:33;131996:57;;;;-1:-1:-1::0;;;131996:57:0::1;;;;;;;:::i;:::-;132085:1;132073:9;:13;:43;;;;-1:-1:-1::0;108195:10:0;:17;132090:9:::1;:26;;132073:43;132065:65;;;;-1:-1:-1::0;;;132065:65:0::1;;;;;;;:::i;:::-;132149:18;::::0;;;:7:::1;:18;::::0;;;;:23:::1;;::::0;132176:1:::1;-1:-1:-1::0;132149:28:0::1;132141:58;;;::::0;-1:-1:-1;;;132141:58:0;;18426:2:1;132141:58:0::1;::::0;::::1;18408:21:1::0;18465:2;18445:18;;;18438:30;-1:-1:-1;;;18484:18:1;;;18477:47;18541:18;;132141:58:0::1;18224:341:1::0;132141:58:0::1;132289:6;::::0;132241:12:::1;132257:18:::0;;;:7:::1;:18;::::0;;;;:24:::1;;::::0;132241:12;;132289:6;132257:28:::1;::::0;132284:1:::1;132257:28;:::i;:::-;132256:39;;;;:::i;:::-;132241:54;;132306:14;132315:4;132306:8;:14::i;:::-;132378:18;::::0;;;:7:::1;:18;::::0;;;;:24:::1;;:26:::0;;;::::1;::::0;::::1;:::i;:::-;::::0;;;-1:-1:-1;;132415:20:0::1;132438:18:::0;;;:7:::1;:18;::::0;;;;:24:::1;::::0;::::1;::::0;132493:23:::1;::::0;;::::1;::::0;132438:24;;132415:20;132493:27:::1;::::0;132519:1:::1;::::0;132493:27:::1;:::i;:::-;132531:18;::::0;;;:7:::1;:18;::::0;;;;;:23:::1;;:35:::0;;;132618:37;132473:47;;-1:-1:-1;132642:12:0;;132539:9;;132618:37:::1;::::0;::::1;131791:872;;;2431:20:::0;1825:1;2951:7;:22;2768:213;2431:20;131735:928;:::o;126974:1060::-;2387:21;:19;:21::i;:::-;127055:6:::1;::::0;::::1;;127054:7;127046:35;;;;-1:-1:-1::0;;;127046:35:0::1;;;;;;;:::i;:::-;127197:18;127205:9;127197:7;:18::i;:::-;-1:-1:-1::0;;;;;127183:32:0::1;:10;-1:-1:-1::0;;;;;127183:32:0::1;;127175:57;;;;-1:-1:-1::0;;;127175:57:0::1;;;;;;;:::i;:::-;127252:22;::::0;;;:11:::1;:22;::::0;;;;:32;::::1;;127251:33;127243:57;;;;-1:-1:-1::0;;;127243:57:0::1;;;;;;;:::i;:::-;127332:1;127320:9;:13;:43;;;;-1:-1:-1::0;108195:10:0;:17;127337:9:::1;:26;;127320:43;127312:65;;;;-1:-1:-1::0;;;127312:65:0::1;;;;;;;:::i;:::-;127445:14;127463:18:::0;;;:7:::1;:18;::::0;;;;:25:::1;;::::0;127498:3:::1;::::0;127463:31:::1;::::0;127498:3;;127463:31:::1;:::i;:::-;127462:39;;;;:::i;:::-;127445:56;;127529:1;127520:6;:10;127512:36;;;::::0;-1:-1:-1;;;127512:36:0;;20175:2:1;127512:36:0::1;::::0;::::1;20157:21:1::0;20214:2;20194:18;;;20187:30;-1:-1:-1;;;20233:18:1;;;20226:43;20286:18;;127512:36:0::1;19973:337:1::0;127512:36:0::1;127589:18;::::0;;;:7:::1;:18;::::0;;;;:23:::1;;:33:::0;;127616:6;;127589:18;:33:::1;::::0;127616:6;;127589:33:::1;:::i;:::-;::::0;;;-1:-1:-1;127690:12:0::1;::::0;-1:-1:-1;127690:6:0;127699:3:::1;127690:12;:::i;:::-;127661:18;::::0;;;:7:::1;:18;::::0;;;;:25:::1;;::::0;:42:::1;::::0;;::::1;:::i;:::-;127633:18;::::0;;;:7:::1;:18;::::0;;;;;;:25:::1;;:70:::0;;;;127851:7:::1;::::0;127841;;127826:14:::1;::::0;127774:1:::1;::::0;;;127862:6;;127826:22:::1;::::0;127841:7;127826:22:::1;:::i;:::-;127808:14;;:41;;;;:::i;:::-;127807:51;;;;:::i;:::-;127806:62;;;;:::i;:::-;:78;;;;:::i;:::-;127786:98;;127924:9;127895:7;:18;127903:9;127895:18;;;;;;;;;;;:25;;;:38;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;127984:42:0::1;::::0;128016:9;;128005;;127984:42:::1;::::0;;;::::1;127035:999;;;2431:20:::0;1825:1;2951:7;:22;2768:213;120058:325;61074:13;:11;:13::i;:::-;120214:7:::1;:18:::0;;;;120243:7:::1;:18:::0;;;;120272:6:::1;:16:::0;;;;120299:7:::1;:18:::0;120328:3:::1;:10:::0;120349:11:::1;:26:::0;120058:325::o;136747:451::-;136810:15;136838:13;136854:18;136864:7;136854:9;:18::i;:::-;136838:34;;136883:22;136921:5;-1:-1:-1;;;;;136908:19:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;136883:44;;136938:15;136981:9;136976:191;137000:5;136996:1;:9;136976:191;;;137025:15;137043:31;137063:7;137072:1;137043:19;:31::i;:::-;137025:49;;137111:7;:16;137119:7;137111:16;;;;;;;;;;;137093:34;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:6;137100:7;137093:15;;;;;;;;:::i;:::-;;;;;;:34;;;;137146:9;;;;;:::i;:::-;;;;137012:155;137007:3;;;;;:::i;:::-;;;;136976:191;;;-1:-1:-1;137184:6:0;;136747:451;-1:-1:-1;;;;136747:451:0:o;114694:69::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;93728:301::-;93889:41;59819:10;93922:7;93889:18;:41::i;:::-;93881:99;;;;-1:-1:-1;;;93881:99:0;;;;;;;:::i;:::-;93993:28;94003:4;94009:2;94013:7;93993:9;:28::i;116070:32::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;116070:32:0;;-1:-1:-1;116070:32:0;:::o;133426:157::-;61074:13;:11;:13::i;:::-;133499:22:::1;133532:7;61261:6:::0;;-1:-1:-1;;;;;61261:6:0;;61188:87;133532:7:::1;133551:24;::::0;133499:41;;-1:-1:-1;;;;;;133551:15:0;::::1;::::0;:24;::::1;;;::::0;133567:7;;133551:24:::1;::::0;;;133567:7;133551:15;:24;::::1;;;;;;;;;;;;;::::0;::::1;;;;119933:117:::0;61074:13;:11;:13::i;:::-;120011:4:::1;:10:::0;;;;120032:4:::1;:10:::0;119933:117::o;107775:256::-;107872:7;107908:23;107925:5;107908:16;:23::i;:::-;107900:5;:31;107892:87;;;;-1:-1:-1;;;107892:87:0;;21063:2:1;107892:87:0;;;21045:21:1;21102:2;21082:18;;;21075:30;21141:34;21121:18;;;21114:62;-1:-1:-1;;;21192:18:1;;;21185:41;21243:19;;107892:87:0;20861:407:1;107892:87:0;-1:-1:-1;;;;;;107997:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;107775:256::o;133859:265::-;61074:13;:11;:13::i;:::-;133982:18:::1;:50:::0;;-1:-1:-1;;;;;133982:50:0;;::::1;;;-1:-1:-1::0;;;;;;133982:50:0;;::::1;;::::0;;134043:11:::1;:36:::0;;;;::::1;-1:-1:-1::0;;;;;;134043:36:0;;::::1;;::::0;;134090:11:::1;:26:::0;;;;;::::1;::::0;::::1;;::::0;;133859:265::o;119659:159::-;61074:13;:11;:13::i;:::-;61261:6;;-1:-1:-1;;;;;61261:6:0;119744:10:::1;:21;119736:44;;;::::0;-1:-1:-1;;;119736:44:0;;21475:2:1;119736:44:0::1;::::0;::::1;21457:21:1::0;21514:2;21494:18;;;21487:30;-1:-1:-1;;;21533:18:1;;;21526:40;21583:18;;119736:44:0::1;21273:334:1::0;119736:44:0::1;119791:4;:19:::0;;-1:-1:-1;;;;;;119791:19:0::1;-1:-1:-1::0;;;;;119791:19:0;;;::::1;::::0;;;::::1;::::0;;119659:159::o;136356:144::-;115171:5;;-1:-1:-1;;;;;115171:5:0;115157:10;:19;115149:47;;;;-1:-1:-1;;;115149:47:0;;;;;;;:::i;:::-;136411:6:::1;::::0;::::1;;136403:39;;;::::0;-1:-1:-1;;;136403:39:0;;22158:2:1;136403:39:0::1;::::0;::::1;22140:21:1::0;22197:2;22177:18;;;22170:30;-1:-1:-1;;;22216:18:1;;;22209:50;22276:18;;136403:39:0::1;21956:344:1::0;136403:39:0::1;136453:6;:14:::0;;-1:-1:-1;;136453:14:0::1;::::0;;136483:9:::1;::::0;::::1;::::0;136462:5:::1;::::0;136483:9:::1;136356:144::o:0;94100:151::-;94204:39;94221:4;94227:2;94231:7;94204:39;;;;;;;;;;;;:16;:39::i;136525:214::-;136642:15;;;136655:1;136642:15;;;;;;;;;136584;;136612:27;;136642:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;136612:45;;136685:7;:17;136693:8;136685:17;;;;;;;;;;;136668:34;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:11;136680:1;136668:14;;;;;;;;:::i;:::-;;;;;;;;;;:34;136720:11;136525:214;-1:-1:-1;;136525:214:0:o;128177:2273::-;2387:21;:19;:21::i;:::-;128285:6:::1;::::0;::::1;;128284:7;128276:35;;;;-1:-1:-1::0;;;128276:35:0::1;;;;;;;:::i;:::-;128344:19;128352:10;128344:7;:19::i;:::-;-1:-1:-1::0;;;;;128330:33:0::1;:10;-1:-1:-1::0;;;;;128330:33:0::1;;128322:58;;;;-1:-1:-1::0;;;128322:58:0::1;;;;;;;:::i;:::-;128401:23;::::0;;;:11:::1;:23;::::0;;;;:33;::::1;;128400:34;128392:58;;;;-1:-1:-1::0;;;128392:58:0::1;;;;;;;:::i;:::-;128501:1;128470:19:::0;;;:7:::1;:19;::::0;;;;:28:::1;;::::0;:32;;;;:68:::1;;-1:-1:-1::0;128537:1:0::1;128506:19:::0;;;:7:::1;:19;::::0;;;;:28:::1;;::::0;:32;;128470:68:::1;128462:93;;;;-1:-1:-1::0;;;128462:93:0::1;;;;;;;:::i;:::-;128611:1;128581:19:::0;;;:7:::1;:19;::::0;;;;:27:::1;;::::0;128573:54:::1;;;::::0;-1:-1:-1;;;128573:54:0;;22848:2:1;128573:54:0::1;::::0;::::1;22830:21:1::0;22887:2;22867:18;;;22860:30;-1:-1:-1;;;22906:18:1;;;22899:40;22956:18;;128573:54:0::1;22646:334:1::0;128573:54:0::1;128676:1;128646:19:::0;;;:7:::1;:19;::::0;;;;:27:::1;;::::0;128638:58:::1;;;::::0;-1:-1:-1;;;128638:58:0;;23187:2:1;128638:58:0::1;::::0;::::1;23169:21:1::0;23226:2;23206:18;;;23199:30;-1:-1:-1;;;23245:18:1;;;23238:44;23299:18;;128638:58:0::1;22985:338:1::0;128638:58:0::1;128715:25;::::0;;;:13:::1;:25;::::0;;;;;128743:4:::1;-1:-1:-1::0;128707:59:0::1;;;::::0;-1:-1:-1;;;128707:59:0;;23530:2:1;128707:59:0::1;::::0;::::1;23512:21:1::0;23569:2;23549:18;;;23542:30;-1:-1:-1;;;23588:18:1;;;23581:44;23642:18;;128707:59:0::1;23328:338:1::0;128707:59:0::1;128873:27;::::0;;;:15:::1;:27;::::0;;;;;;;:39;;;;;;;;;128916:8:::1;::::0;128855:57:::1;::::0;:15:::1;:57;:::i;:::-;:69;;128847:91;;;;-1:-1:-1::0;;;128847:91:0::1;;;;;;;:::i;:::-;128970:1;128957:10;:14;:45;;;;-1:-1:-1::0;108195:10:0;:17;128975:10:::1;:27;;128957:45;:63;;;;;129019:1;129006:10;:14;128957:63;:94;;;;-1:-1:-1::0;108195:10:0;:17;129024:10:::1;:27;;128957:94;128949:116;;;;-1:-1:-1::0;;;128949:116:0::1;;;;;;;:::i;:::-;129098:10;129084;:24:::0;129076:44:::1;;;::::0;-1:-1:-1;;;129076:44:0;;24210:2:1;129076:44:0::1;::::0;::::1;24192:21:1::0;24249:1;24229:18;;;24222:29;-1:-1:-1;;;24267:18:1;;;24260:37;24314:18;;129076:44:0::1;24008:330:1::0;129076:44:0::1;129161:14;::::0;129239:20:::1;129161:14:::0;129239::::1;:20::i;:::-;129318:14;129323:4;129329:2;129318:4;:14::i;:::-;129391:25;::::0;;;:13:::1;:25;::::0;;;;:27;;;::::1;::::0;::::1;:::i;:::-;::::0;;;-1:-1:-1;;129475:27:0::1;::::0;;;:15:::1;:27;::::0;;;;;;;:39;;;;;;;;129517:15:::1;129475:57:::0;;129551:12:::1;:14:::0;;;::::1;::::0;::::1;:::i;:::-;::::0;;;-1:-1:-1;;129605:20:0::1;129667:19:::0;;;:7:::1;:19;::::0;;;;;:25:::1;::::0;;::::1;::::0;129639:19;;;;;;:25:::1;::::0;:53:::1;:99:::0;::::1;;;-1:-1:-1::0;129705:19:0::1;::::0;;;:7:::1;:19;::::0;;;;:27:::1;;::::0;129736:2:::1;-1:-1:-1::0;129705:33:0::1;129639:99;129636:377;;;-1:-1:-1::0;129770:2:0::1;129636:377;;;129838:19;::::0;;;:7:::1;:19;::::0;;;;:26:::1;;::::0;:32:::1;::::0;129867:3:::1;129838:32;:::i;:::-;129806:19;::::0;;;:7:::1;:19;::::0;;;;:27:::1;;::::0;:65:::1;::::0;::::1;::::0;:111:::1;;-1:-1:-1::0;129884:19:0::1;::::0;;;:7:::1;:19;::::0;;;;:27:::1;;::::0;129915:2:::1;-1:-1:-1::0;129884:33:0::1;129806:111;129802:211;;;-1:-1:-1::0;129949:2:0::1;129802:211;;;-1:-1:-1::0;129999:2:0::1;129802:211;130023:19;::::0;;;:7:::1;:19;::::0;;;;:27:::1;;:43:::0;;130054:12;;130023:19;:43:::1;::::0;130054:12;;130023:43:::1;:::i;:::-;::::0;;;-1:-1:-1;;130077:19:0::1;::::0;;;:7:::1;:19;::::0;;;;:27:::1;;:43:::0;;130108:12;;130077:19;:43:::1;::::0;130108:12;;130077:43:::1;:::i;:::-;;;;;;;;130190:15;130164:10;130152;130136:70;130176:12;130136:70;;;;2596:25:1::0;;2584:2;2569:18;;2450:177;130136:70:0::1;;;;;;;;130217:19;::::0;;;:7:::1;:19;::::0;;;;:26:::1;;:28:::0;;;::::1;::::0;::::1;:::i;:::-;::::0;;;-1:-1:-1;;130256:19:0::1;::::0;;;:7:::1;:19;::::0;;;;:27:::1;;:29:::0;;;::::1;::::0;::::1;:::i;:::-;;;;;;130371:7;;130361;;130346:14;;:22;;;;:::i;:::-;130328:14;;:41;;;;:::i;:::-;130327:51;;;;:::i;:::-;130296:19;::::0;;;:7:::1;:19;::::0;;;;:26:::1;;:83:::0;;:26;;:19;:83:::1;::::0;;;::::1;:::i;:::-;::::0;;;-1:-1:-1;;138269:204:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;138422:27:0;;;:15;:27;;;;;:39;;;;;;;;;138269:204;;;;;;138484:24;;;:12;:24;;;;;:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;130390:52:::1;128265:2185;;2431:20:::0;1825:1;2951:7;:22;2768:213;2431:20;128177:2273;;:::o;108297:233::-;108372:7;108408:30;108195:10;:17;;108107:113;108408:30;108400:5;:38;108392:95;;;;-1:-1:-1;;;108392:95:0;;24545:2:1;108392:95:0;;;24527:21:1;24584:2;24564:18;;;24557:30;24623:34;24603:18;;;24596:62;-1:-1:-1;;;24674:18:1;;;24667:42;24726:19;;108392:95:0;24343:408:1;108392:95:0;108505:10;108516:5;108505:17;;;;;;;;:::i;:::-;;;;;;;;;108498:24;;108297:233;;;:::o;119161:390::-;2387:21;:19;:21::i;:::-;119275:17:::1;119283:8;119275:7;:17::i;:::-;-1:-1:-1::0;;;;;119261:31:0::1;:10;-1:-1:-1::0;;;;;119261:31:0::1;;119253:57;;;::::0;-1:-1:-1;;;119253:57:0;;24958:2:1;119253:57:0::1;::::0;::::1;24940:21:1::0;24997:2;24977:18;;;24970:30;-1:-1:-1;;;25016:18:1;;;25009:43;25069:18;;119253:57:0::1;24756:337:1::0;119253:57:0::1;119353:1;119334:8;119328:22;:26;119320:46;;;::::0;-1:-1:-1;;;119320:46:0;;25300:2:1;119320:46:0::1;::::0;::::1;25282:21:1::0;25339:1;25319:18;;;25312:29;-1:-1:-1;;;25357:18:1;;;25350:37;25404:18;;119320:46:0::1;25098:330:1::0;119320:46:0::1;108195:10:::0;:17;119401:8:::1;:25;;119376:64;;;;-1:-1:-1::0;;;119376:64:0::1;;;;;;;:::i;:::-;119502:17;::::0;;;:7:::1;:17;::::0;;;;:41:::1;119534:8:::0;119502:17;:41:::1;:::i;:::-;;2431:20:::0;1825:1;2951:7;:22;2768:213;120526:135;61074:13;:11;:13::i;:::-;120617:16:::1;:36:::0;120526:135::o;139076:195::-;61074:13;:11;:13::i;:::-;139161:9:::1;139156:108;139176:16:::0;;::::1;139156:108;;;139248:4;139214:11;:21;139226:5;;139232:1;139226:8;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;::::1;;139214:21:::0;;-1:-1:-1;139214:21:0;::::1;::::0;;;;;;-1:-1:-1;139214:21:0;:38;;-1:-1:-1;;139214:38:0::1;::::0;::::1;;::::0;;;::::1;::::0;;139194:3;::::1;::::0;::::1;:::i;:::-;;;;139156:108;;91226:223:::0;91298:7;95959:16;;;:7;:16;;;;;;-1:-1:-1;;;;;95959:16:0;;91362:56;;;;-1:-1:-1;;;91362:56:0;;27839:2:1;91362:56:0;;;27821:21:1;27878:2;27858:18;;;27851:30;-1:-1:-1;;;27897:18:1;;;27890:54;27961:18;;91362:56:0;27637:348:1;124710:2166:0;2387:21;:19;:21::i;:::-;124815:6:::1;::::0;::::1;;124814:7;124806:35;;;;-1:-1:-1::0;;;124806:35:0::1;;;;;;;:::i;:::-;124874:19;124882:10;124874:7;:19::i;:::-;-1:-1:-1::0;;;;;124860:33:0::1;:10;-1:-1:-1::0;;;;;124860:33:0::1;;124852:59;;;::::0;-1:-1:-1;;;124852:59:0;;28192:2:1;124852:59:0::1;::::0;::::1;28174:21:1::0;28231:2;28211:18;;;28204:30;-1:-1:-1;;;28250:18:1;;;28243:43;28303:18;;124852:59:0::1;27990:337:1::0;124852:59:0::1;124961:1;124930:19:::0;;;:7:::1;:19;::::0;;;;:28:::1;;::::0;:32;;;;:68:::1;;-1:-1:-1::0;124997:1:0::1;124966:19:::0;;;:7:::1;:19;::::0;;;;:28:::1;;::::0;:32;;124930:68:::1;124922:94;;;::::0;-1:-1:-1;;;124922:94:0;;28534:2:1;124922:94:0::1;::::0;::::1;28516:21:1::0;28573:2;28553:18;;;28546:30;-1:-1:-1;;;28592:18:1;;;28585:43;28645:18;;124922:94:0::1;28332:337:1::0;124922:94:0::1;125064:1;125035:19:::0;;;:7:::1;:19;::::0;;;;:26:::1;;::::0;125027:53:::1;;;::::0;-1:-1:-1;;;125027:53:0;;28876:2:1;125027:53:0::1;::::0;::::1;28858:21:1::0;28915:2;28895:18;;;28888:30;-1:-1:-1;;;28934:18:1;;;28927:40;28984:18;;125027:53:0::1;28674:334:1::0;125027:53:0::1;125128:1;125099:19:::0;;;:7:::1;:19;::::0;;;;:26:::1;;::::0;125091:58:::1;;;::::0;-1:-1:-1;;;125091:58:0;;29215:2:1;125091:58:0::1;::::0;::::1;29197:21:1::0;29254:2;29234:18;;;29227:30;-1:-1:-1;;;29273:18:1;;;29266:45;29328:18;;125091:58:0::1;29013:339:1::0;125091:58:0::1;125168:25;::::0;;;:13:::1;:25;::::0;;;;;125196:4:::1;-1:-1:-1::0;125160:59:0::1;;;::::0;-1:-1:-1;;;125160:59:0;;23530:2:1;125160:59:0::1;::::0;::::1;23512:21:1::0;23569:2;23549:18;;;23542:30;-1:-1:-1;;;23588:18:1;;;23581:44;23642:18;;125160:59:0::1;23328:338:1::0;125160:59:0::1;125256:27;::::0;;;:15:::1;:27;::::0;;;;;;;:39;;;;;;;;;125299:8:::1;::::0;125238:57:::1;::::0;:15:::1;:57;:::i;:::-;:69;;125230:91;;;;-1:-1:-1::0;;;125230:91:0::1;;;;;;;:::i;:::-;125353:1;125340:10;:14;:45;;;;-1:-1:-1::0;108195:10:0;:17;125358:10:::1;:27;;125340:45;:63;;;;;125402:1;125389:10;:14;125340:63;:94;;;;-1:-1:-1::0;108195:10:0;:17;125407:10:::1;:27;;125340:94;125332:116;;;;-1:-1:-1::0;;;125332:116:0::1;;;;;;;:::i;:::-;125481:10;125467;:24:::0;125459:44:::1;;;::::0;-1:-1:-1;;;125459:44:0;;24210:2:1;125459:44:0::1;::::0;::::1;24192:21:1::0;24249:1;24229:18;;;24222:29;-1:-1:-1;;;24267:18:1;;;24260:37;24314:18;;125459:44:0::1;24008:330:1::0;125459:44:0::1;125523:23;::::0;;;:11:::1;:23;::::0;;;;:33;::::1;;125522:34;125514:58;;;;-1:-1:-1::0;;;125514:58:0::1;;;;;;;:::i;:::-;125614:14;::::0;125692:20:::1;125614:14:::0;125692::::1;:20::i;:::-;125774:14;125779:4;125785:2;125774:4;:14::i;:::-;125847:25;::::0;;;:13:::1;:25;::::0;;;;:27;;;::::1;::::0;::::1;:::i;:::-;::::0;;;-1:-1:-1;;125931:27:0::1;::::0;;;:15:::1;:27;::::0;;;;;;;:39;;;;;;;;125973:15:::1;125931:57:::0;;125999:12:::1;:14:::0;;;::::1;::::0;::::1;:::i;:::-;::::0;;;-1:-1:-1;;126052:20:0::1;126114:19:::0;;;:7:::1;:19;::::0;;;;;:25:::1;::::0;;::::1;::::0;126086:19;;;;;;:25:::1;::::0;:53:::1;:98:::0;::::1;;;-1:-1:-1::0;126152:19:0::1;::::0;;;:7:::1;:19;::::0;;;;:26:::1;;::::0;126182:2:::1;-1:-1:-1::0;126152:32:0::1;126086:98;126083:363;;;-1:-1:-1::0;126216:2:0::1;126083:363;;;126271:19;::::0;;;:7:::1;:19;::::0;;;;:27:::1;;::::0;:33:::1;::::0;126301:3:::1;126271:33;:::i;:::-;126240:19;::::0;;;:7:::1;:19;::::0;;;;:26:::1;;::::0;:65:::1;::::0;::::1;::::0;:110:::1;;-1:-1:-1::0;126318:19:0::1;::::0;;;:7:::1;:19;::::0;;;;:26:::1;;::::0;126348:2:::1;-1:-1:-1::0;126318:32:0::1;126240:110;126236:210;;;-1:-1:-1::0;126382:2:0::1;126236:210;;;-1:-1:-1::0;126432:2:0::1;126236:210;126456:19;::::0;;;:7:::1;:19;::::0;;;;:26:::1;;:42:::0;;126486:12;;126456:19;:42:::1;::::0;126486:12;;126456:42:::1;:::i;:::-;::::0;;;-1:-1:-1;;126509:19:0::1;::::0;;;:7:::1;:19;::::0;;;;:26:::1;;:42:::0;;126539:12;;126509:19;:42:::1;::::0;126539:12;;126509:42:::1;:::i;:::-;;;;;;;;126618:15;126592:10;126580;126567:67;126604:12;126567:67;;;;2596:25:1::0;;2584:2;2569:18;;2450:177;126567:67:0::1;;;;;;;;126645:19;::::0;;;:7:::1;:19;::::0;;;;:26:::1;;:28:::0;;;::::1;::::0;::::1;:::i;:::-;::::0;;;-1:-1:-1;;126684:19:0::1;::::0;;;:7:::1;:19;::::0;;;;:27:::1;;:29:::0;;;::::1;::::0;::::1;:::i;:::-;;;;;;126799:7;;126789;;126774:14;;:22;;;;:::i;:::-;126756:14;;:41;;;;:::i;:::-;126755:51;;;;:::i;:::-;126724:19;::::0;;;:7:::1;:19;::::0;;;;:26:::1;;:83:::0;;:26;;:19;:83:::1;::::0;;;::::1;:::i;:::-;::::0;;;-1:-1:-1;;137344:202:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;137495:27:0;;;:15;:27;;;;;:39;;;;;;;;;137344:202;;;;;;137557:22;;;:10;:22;;;;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;126818:50:::1;137211:392:::0;114611:21;;;;;;;:::i;90957:207::-;91029:7;-1:-1:-1;;;;;91057:19:0;;91049:73;;;;-1:-1:-1;;;91049:73:0;;29559:2:1;91049:73:0;;;29541:21:1;29598:2;29578:18;;;29571:30;29637:34;29617:18;;;29610:62;-1:-1:-1;;;29688:18:1;;;29681:39;29737:19;;91049:73:0;29357:405:1;91049:73:0;-1:-1:-1;;;;;;91140:16:0;;;;;:9;:16;;;;;;;90957:207::o;61829:103::-;61074:13;:11;:13::i;:::-;61894:30:::1;61921:1;61894:18;:30::i;:::-;61829:103::o:0;123174:694::-;2387:21;:19;:21::i;:::-;123268:6:::1;::::0;::::1;;123267:7;123259:35;;;;-1:-1:-1::0;;;123259:35:0::1;;;;;;;:::i;:::-;123342:1;123313:17:::0;;;:7:::1;:17;::::0;;;;:26:::1;;::::0;123305:55:::1;;;;-1:-1:-1::0;;;123305:55:0::1;;;;;;;:::i;:::-;123393:17;123401:8;123393:7;:17::i;:::-;-1:-1:-1::0;;;;;123379:31:0::1;:10;-1:-1:-1::0;;;;;123379:31:0::1;;123371:56;;;;-1:-1:-1::0;;;123371:56:0::1;;;;;;;:::i;:::-;123457:1;123446:8;:12;:41;;;;-1:-1:-1::0;108195:10:0;:17;123462:8:::1;:25;;123446:41;123438:63;;;;-1:-1:-1::0;;;123438:63:0::1;;;;;;;:::i;:::-;123521:21;::::0;;;:11:::1;:21;::::0;;;;:31;::::1;;123520:32;123512:56;;;;-1:-1:-1::0;;;123512:56:0::1;;;;;;;:::i;:::-;123610:14;::::0;123696:20:::1;123610:14:::0;123696::::1;:20::i;:::-;123778:14;123783:4;123789:2;123778:4;:14::i;:::-;123857:3;::::0;123829:17:::1;::::0;;;:7:::1;:17;::::0;;;;:24:::1;;:31:::0;;:24;;:17;:31:::1;::::0;123857:3;;123829:31:::1;:::i;:::-;::::0;;;-1:-1:-1;;1825:1:0;2951:7;:22;-1:-1:-1;131735:928:0;:::o;117502:1651::-;61074:13;:11;:13::i;:::-;117721:6;117704:14:::1;117751:10:::0;;;117747:1399:::1;;117789:9;117784:690;117808:6;117804:1;:10;117784:690;;;117840:13;117856:10;117865:1:::0;117856:6;:10:::1;:::i;:::-;117840:26;;117958:342;;;;;;;;117994:8;;118003:1;117994:11;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;117958:342;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;-1:-1:-1;117958:342:0;;;-1:-1:-1;;;117958:342:0::1;::::0;;::::1;::::0;;;;;;;;;;118099:3:::1;117958:342:::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;117941:14;;;:7:::1;:14:::0;;;:359;;:14;;:359:::1;::::0;:14;:359:::1;:::i;:::-;-1:-1:-1::0;117941:359:0::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;118378:30:::1;118384:11:::0;;118396:1;118384:14;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;118400:7;;118378:5;:30::i;:::-;118445:7;:9:::0;;;:7:::1;:9;::::0;::::1;:::i;:::-;;;;;;117821:653;117816:3;;;;;:::i;:::-;;;;117784:690;;;;117747:1399;;;118539:9;118534:597;118554:18:::0;;::::1;118534:597;;;118602:11;118616:7;;118624:1;118616:10;;;;;;;:::i;:::-;;;;;;;118602:24;;118722:6;;118729:1;118722:9;;;;;;;:::i;:::-;;;;;;;118701:7;:12;118709:3;118701:12;;;;;;;;;;;:18;;:30;;;;118776:6;;118783:1;118776:9;;;;;;;:::i;:::-;;;;;;;118754:7;:12;118762:3;118754:12;;;;;;;;;;;:19;;:31;;;;118831:6;;118838:1;118831:9;;;;;;;:::i;:::-;;;;;;;118808:7;:12;118816:3;118808:12;;;;;;;;;;;:20;;:32;;;;118885:6;;118892:1;118885:9;;;;;;;:::i;:::-;;;;;;;118863:7;:12;118871:3;118863:12;;;;;;;;;;;:19;;:31;;;;118937:6;;118944:1;118937:9;;;;;;;:::i;:::-;;;;;;;118917:7;:12;118925:3;118917:12;;;;;;;;;;;:17;;:29;;;;118991:6;;118998:1;118991:9;;;;;;;:::i;:::-;;;;;;;118969:7;:12;118977:3;118969:12;;;;;;;;;;;:19;;:31;;;;119047:6;;119054:1;119047:9;;;;;;;:::i;:::-;;;;;;;119023:7;:12;119031:3;119023:12;;;;;;;;;;;:21;;:33;;;;119102:6;;119109:1;119102:9;;;;;;;:::i;:::-;;;;;;;119079:7;:12;119087:3;119079:12;;;;;;;;;;;:20;;:32;;;;118579:552;118574:3;;;;;:::i;:::-;;;;118534:597;;;;117747:1399;117695:1458;117502:1651:::0;;;;;;;;;;:::o;123877:688::-;2387:21;:19;:21::i;:::-;123964:6:::1;::::0;::::1;;123963:7;123955:35;;;;-1:-1:-1::0;;;123955:35:0::1;;;;;;;:::i;:::-;124023:17;124031:8;124023:7;:17::i;:::-;-1:-1:-1::0;;;;;124009:31:0::1;:10;-1:-1:-1::0;;;;;124009:31:0::1;;124001:56;;;;-1:-1:-1::0;;;124001:56:0::1;;;;;;;:::i;:::-;124087:1;124076:8;:12;:41;;;;-1:-1:-1::0;108195:10:0;:17;124092:8:::1;:25;;124076:41;124068:63;;;;-1:-1:-1::0;;;124068:63:0::1;;;;;;;:::i;:::-;124179:1;124150:17:::0;;;:7:::1;:17;::::0;;;;:26:::1;;::::0;124142:55:::1;;;;-1:-1:-1::0;;;124142:55:0::1;;;;;;;:::i;:::-;124223:21;::::0;;;:11:::1;:21;::::0;;;;:31;::::1;;124222:32;124214:56;;;;-1:-1:-1::0;;;124214:56:0::1;;;;;;;:::i;:::-;124314:14;::::0;124392:20:::1;124314:14:::0;124392::::1;:20::i;:::-;124473:14;124478:4;124484:2;124473:4;:14::i;:::-;124554:3;::::0;124525:17:::1;::::0;;;:7:::1;:17;::::0;;;;:25:::1;;:32:::0;;:25;;:17;:32:::1;::::0;124554:3;;124525:32:::1;:::i;119826:99::-:0;61074:13;:11;:13::i;:::-;119899:7:::1;:18:::0;119826:99::o;136182:144::-;115171:5;;-1:-1:-1;;;;;115171:5:0;115157:10;:19;115149:47;;;;-1:-1:-1;;;115149:47:0;;;;;;;:::i;:::-;136236:6:::1;::::0;::::1;;136235:7;136227:44;;;::::0;-1:-1:-1;;;136227:44:0;;30496:2:1;136227:44:0::1;::::0;::::1;30478:21:1::0;30535:2;30515:18;;;30508:30;30574:26;30554:18;;;30547:54;30618:18;;136227:44:0::1;30294:348:1::0;136227:44:0::1;136282:6;:13:::0;;-1:-1:-1;;136282:13:0::1;136291:4;136282:13;::::0;;136311:7:::1;::::0;::::1;::::0;136282:6:::1;::::0;136311:7:::1;136182:144::o:0;135458:185::-;61074:13;:11;:13::i;:::-;135560:64:::1;::::0;;::::1;::::0;::::1;::::0;;;-1:-1:-1;;;;;135560:64:0;;::::1;::::0;;135527:13:::1;:108:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;135527:108:0;;;;;;;;;::::1;::::0;;-1:-1:-1;;;;;;135527:108:0::1;::::0;;;::::1;;::::0;;135458:185::o;116477:54::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;116477:54:0;-1:-1:-1;116477:54:0;:::o;139279:201::-;61074:13;:11;:13::i;:::-;139369:9:::1;139364:109;139384:16:::0;;::::1;139364:109;;;139456:5;139422:11;:21;139434:5;;139440:1;139434:8;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;::::1;;139422:21:::0;;-1:-1:-1;139422:21:0;::::1;::::0;;;;;;-1:-1:-1;139422:21:0;:39;;-1:-1:-1;;139422:39:0::1;::::0;::::1;;::::0;;;::::1;::::0;;139402:3;::::1;::::0;::::1;:::i;:::-;;;;139364:109;;135763:105:::0;61074:13;:11;:13::i;:::-;135842:7:::1;:18;135852:8:::0;135842:7;:18:::1;:::i;91685:104::-:0;91741:13;91774:7;91767:14;;;;;:::i;116420:50::-;;;;;;;;;;;;;;;;;;;;134212:1234;2387:21;:19;:21::i;:::-;134297:6:::1;::::0;::::1;;134296:7;134288:35;;;;-1:-1:-1::0;;;134288:35:0::1;;;;;;;:::i;:::-;134342:18;::::0;;;:7:::1;:18;::::0;;;;:24:::1;;::::0;134370:1:::1;-1:-1:-1::0;134342:29:0::1;134334:52;;;::::0;-1:-1:-1;;;134334:52:0;;30849:2:1;134334:52:0::1;::::0;::::1;30831:21:1::0;30888:2;30868:18;;;30861:30;-1:-1:-1;;;30907:18:1;;;30900:40;30957:18;;134334:52:0::1;30647:334:1::0;134334:52:0::1;134433:1;134405:18:::0;;;:7:::1;:18;::::0;;;;:25:::1;;::::0;134397:51:::1;;;::::0;-1:-1:-1;;;134397:51:0;;31188:2:1;134397:51:0::1;::::0;::::1;31170:21:1::0;31227:1;31207:18;;;31200:29;-1:-1:-1;;;31245:18:1;;;31238:39;31294:18;;134397:51:0::1;30986:332:1::0;134397:51:0::1;134467:18;::::0;;;:7:::1;:18;::::0;;;;:23:::1;;::::0;134494:1:::1;-1:-1:-1::0;134467:28:0::1;134459:51;;;::::0;-1:-1:-1;;;134459:51:0;;31525:2:1;134459:51:0::1;::::0;::::1;31507:21:1::0;31564:2;31544:18;;;31537:30;-1:-1:-1;;;31583:18:1;;;31576:40;31633:18;;134459:51:0::1;31323:334:1::0;134459:51:0::1;134543:18;134551:9;134543:7;:18::i;:::-;-1:-1:-1::0;;;;;134529:32:0::1;:10;-1:-1:-1::0;;;;;134529:32:0::1;;134521:57;;;;-1:-1:-1::0;;;134521:57:0::1;;;;;;;:::i;:::-;134598:22;::::0;;;:11:::1;:22;::::0;;;;:32;::::1;;134597:33;134589:57;;;;-1:-1:-1::0;;;134589:57:0::1;;;;;;;:::i;:::-;134750:7;::::0;134698:20:::1;134722:18:::0;;;:7:::1;:18;::::0;;;;:25:::1;;::::0;134698:20;;134722:35:::1;::::0;::::1;:::i;:::-;134698:60;;134769:24;134796:13;134810:4;;134796:19;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;134863:15:::0;;134960:33:::1;::::0;-1:-1:-1;;;134960:33:0;;134987:4:::1;134960:33;::::0;::::1;1679:51:1::0;134796:19:0;;-1:-1:-1;;;;;;134863:15:0::1;::::0;134996:12;;134863:15;;134960:18:::1;::::0;1652::1;;134960:33:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:48;134952:80;;;::::0;-1:-1:-1;;;134952:80:0;;32053:2:1;134952:80:0::1;::::0;::::1;32035:21:1::0;32092:2;32072:18;;;32065:30;-1:-1:-1;;;32111:18:1;;;32104:49;32170:18;;134952:80:0::1;31851:343:1::0;134952:80:0::1;135110:43;::::0;-1:-1:-1;;;135110:43:0;;135128:10:::1;135110:43;::::0;::::1;32373:51:1::0;32440:18;;;32433:34;;;-1:-1:-1;;;;;135110:17:0;::::1;::::0;::::1;::::0;32346:18:1;;135110:43:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;135102:71;;;::::0;-1:-1:-1;;;135102:71:0;;32930:2:1;135102:71:0::1;::::0;::::1;32912:21:1::0;32969:2;32949:18;;;32942:30;-1:-1:-1;;;32988:18:1;;;32981:45;33043:18;;135102:71:0::1;32728:339:1::0;135102:71:0::1;135264:1;135236:18:::0;;;:7:::1;:18;::::0;;;;;:25:::1;::::0;::::1;:29:::0;;;135276:23:::1;::::0;::::1;:27:::0;;;135314:25:::1;;:28:::0;;;135398:40;135425:12;;135413:10:::1;::::0;135398:40:::1;::::0;135264:1;135398:40:::1;134277:1169;;;2431:20:::0;1825:1;2951:7;:22;2768:213;93271:155;93366:52;59819:10;93399:8;93409;93366:18;:52::i;133268:150::-;115171:5;;-1:-1:-1;;;;;115171:5:0;115157:10;:19;115149:47;;;;-1:-1:-1;;;115149:47:0;;;;;;;:::i;:::-;133383:27:::1;133401:8;133383:17;:27::i;120391:127::-:0;61074:13;:11;:13::i;:::-;120478:14:::1;:32:::0;120391:127::o;94322:279::-;94453:41;59819:10;94486:7;94453:18;:41::i;:::-;94445:99;;;;-1:-1:-1;;;94445:99:0;;;;;;;:::i;:::-;94555:38;94569:4;94575:2;94579:7;94588:4;94555:13;:38::i;:::-;94322:279;;;;:::o;135876:278::-;135942:13;135984;108195:10;:17;;108107:113;135984:13;135972:8;:25;;135964:47;;;;-1:-1:-1;;;135964:47:0;;;;;;;:::i;:::-;136056:1;136038:7;136032:21;;;;;:::i;:::-;;;:25;:114;;;;;;;;;;;;;;;;;136093:7;136102:19;:8;:17;:19::i;:::-;136076:55;;;;;;;;;:::i;:::-;;;;;;;;;;;;;136018:128;135876:278;-1:-1:-1;;135876:278:0:o;116605:889::-;2387:21;:19;:21::i;:::-;116688:6:::1;::::0;::::1;;116687:7;116679:35;;;;-1:-1:-1::0;;;116679:35:0::1;;;;;;;:::i;:::-;116746:7;;116733:9;:20;116725:49;;;::::0;-1:-1:-1;;;116725:49:0;;34466:2:1;116725:49:0::1;::::0;::::1;34448:21:1::0;34505:2;34485:18;;;34478:30;-1:-1:-1;;;34524:18:1;;;34517:46;34580:18;;116725:49:0::1;34264:340:1::0;116725:49:0::1;116815:1;116799:5;116793:19;:23;116785:43;;;::::0;-1:-1:-1;;;116785:43:0;;25300:2:1;116785:43:0::1;::::0;::::1;25282:21:1::0;25339:1;25319:18;;;25312:29;-1:-1:-1;;;25357:18:1;;;25350:37;25404:18;;116785:43:0::1;25098:330:1::0;116785:43:0::1;116901:258;;;;;;;;116929:5;116901:258;;;;116953:7;;116901:258;;;;116982:1;116901:258;;;;117006:3;116901:258;;;;117033:3;116901:258;;;;117059:1;116901:258;;;;117081:1;116901:258;;;;117105:1;116901:258;;;;117131:1;116901:258;;;;117156:1;116901:258;;::::0;116882:7:::1;:16;116890:7;;116882:16;;;;;;;;;;;:277;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;116882:277:0::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;117239:7:::1;::::0;117257:26:::1;117263:10;117239:7:::0;117257:5:::1;:26::i;:::-;117358:55;::::0;;::::1;::::0;;::::1;::::0;;-1:-1:-1;117358:55:0;;;117347:7:::1;::::0;117335:20;;:11:::1;:20:::0;;;;;;:78;;;;-1:-1:-1;;117335:78:0::1;::::0;::::1;;;::::0;;117439:27;117458:7;;117439:27:::1;::::0;::::1;::::0;117451:5;;117439:27:::1;:::i;:::-;;;;;;;;117477:7;:9:::0;;;:7:::1;:9;::::0;::::1;:::i;:::-;;;;;;116668:826;2431:20:::0;1825:1;2951:7;:22;2768:213;138542:526;138641:15;138687:24;;;:12;:24;;;;;:31;138608:20;;138641:15;;138687:31;-1:-1:-1;;;;;138759:24:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;138759:24:0;;;;;;;;;;;;;;;;;138729:54;;138809:9;138804:233;138828:5;138824:1;:9;138804:233;;;138860:24;;;;:12;:24;;;;;:27;;138902:10;;138860:24;138885:1;;138860:27;;;;;;:::i;:::-;;;;;;;;;;;:38;;;:52;138856:170;;138952:24;;;;:12;:24;;;;;:27;;138977:1;;138952:27;;;;;;:::i;:::-;;;;;;;;;;;138934:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:6;138941:7;138934:15;;;;;;;;:::i;:::-;;;;;;:45;;;;139000:9;;;;;:::i;:::-;;;;138856:170;138835:3;;;;:::i;:::-;;;;138804:233;;;-1:-1:-1;139054:6:0;138542:526;-1:-1:-1;;;;138542:526:0:o;133591:260::-;61074:13;:11;:13::i;:::-;133684:24:::1;133711:13;133725:5;133711:20;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;133779:15:::0;;133805:38:::1;::::0;-1:-1:-1;;;133805:38:0;;133823:10:::1;133805:38;::::0;::::1;32373:51:1::0;32440:18;;;32433:34;;;133711:20:0;;-1:-1:-1;;;;;;133779:15:0::1;::::0;;;133805:17:::1;::::0;32346:18:1;;133805:38:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;133673:178;;133591:260:::0;;:::o;139488:93::-;115171:5;;-1:-1:-1;;;;;115171:5:0;115157:10;:19;115149:47;;;;-1:-1:-1;;;115149:47:0;;;;;;;:::i;:::-;139556:5:::1;:17:::0;;-1:-1:-1;;;;;;139556:17:0::1;-1:-1:-1::0;;;;;139556:17:0;;;::::1;::::0;;;::::1;::::0;;139488:93::o;132675:581::-;2387:21;:19;:21::i;:::-;132762:6:::1;::::0;::::1;;132761:7;132753:35;;;;-1:-1:-1::0;;;132753:35:0::1;;;;;;;:::i;:::-;132821:18;132829:9;132821:7;:18::i;:::-;-1:-1:-1::0;;;;;132807:32:0::1;:10;-1:-1:-1::0;;;;;132807:32:0::1;;132799:57;;;;-1:-1:-1::0;;;132799:57:0::1;;;;;;;:::i;:::-;132876:22;::::0;;;:11:::1;:22;::::0;;;;:32;::::1;;132875:33;132867:57;;;;-1:-1:-1::0;;;132867:57:0::1;;;;;;;:::i;:::-;133025:20;::::0;;;:9:::1;:20;::::0;;;;;133049:8:::1;::::0;133007:38:::1;::::0;:15:::1;:38;:::i;:::-;:50;;132999:72;;;;-1:-1:-1::0;;;132999:72:0::1;;;;;;;:::i;:::-;133154:1;133127:24:::0;;;:13:::1;:24;::::0;;;;;;;:28;;;133210:9:::1;:20:::0;;;;;133233:15:::1;133210:38:::0;;2431:20;1825:1;2951:7;:22;2768:213;130551:1068;2387:21;:19;:21::i;:::-;130635:6:::1;::::0;::::1;;130634:7;130626:35;;;;-1:-1:-1::0;;;130626:35:0::1;;;;;;;:::i;:::-;130777:18;130785:9;130777:7;:18::i;:::-;-1:-1:-1::0;;;;;130763:32:0::1;:10;-1:-1:-1::0;;;;;130763:32:0::1;;130755:57;;;;-1:-1:-1::0;;;130755:57:0::1;;;;;;;:::i;:::-;130832:22;::::0;;;:11:::1;:22;::::0;;;;:32;::::1;;130831:33;130823:57;;;;-1:-1:-1::0;;;130823:57:0::1;;;;;;;:::i;:::-;130912:1;130900:9;:13;:43;;;;-1:-1:-1::0;108195:10:0;:17;130917:9:::1;:26;;130900:43;130892:65;;;;-1:-1:-1::0;;;130892:65:0::1;;;;;;;:::i;:::-;131025:14;131043:18:::0;;;:7:::1;:18;::::0;;;;:26:::1;;::::0;131079:3:::1;::::0;131043:32:::1;::::0;131079:3;;131043:32:::1;:::i;:::-;131042:40;;;;:::i;:::-;131025:57;;131110:1;131101:6;:10;131093:35;;;::::0;-1:-1:-1;;;131093:35:0;;34811:2:1;131093:35:0::1;::::0;::::1;34793:21:1::0;34850:2;34830:18;;;34823:30;-1:-1:-1;;;34869:18:1;;;34862:42;34921:18;;131093:35:0::1;34609:336:1::0;131093:35:0::1;131169:18;::::0;;;:7:::1;:18;::::0;;;;:23:::1;;:33:::0;;131196:6;;131169:18;:33:::1;::::0;131196:6;;131169:33:::1;:::i;:::-;::::0;;;-1:-1:-1;131272:12:0::1;::::0;-1:-1:-1;131272:6:0;131281:3:::1;131272:12;:::i;:::-;131242:18;::::0;;;:7:::1;:18;::::0;;;;:26:::1;;::::0;:43:::1;::::0;;::::1;:::i;:::-;131213:18;::::0;;;:7:::1;:18;::::0;;;;;;:26:::1;;:72:::0;;;;131433:7:::1;::::0;131423;;131408:14:::1;::::0;131356:1:::1;::::0;;;131444:6;;131408:22:::1;::::0;131423:7;131408:22:::1;:::i;:::-;131390:14;;:41;;;;:::i;:::-;131389:51;;;;:::i;:::-;131388:62;;;;:::i;:::-;:78;;;;:::i;:::-;131368:98;;131506:9;131477:7;:18;131485:9;131477:18;;;;;;;;;;;:25;;;:38;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;131566:45:0::1;::::0;131601:9;;131590;;131566:45:::1;::::0;;;::::1;130615:1004;;;2431:20:::0;1825:1;2951:7;:22;2768:213;62087:201;61074:13;:11;:13::i;:::-;-1:-1:-1;;;;;62176:22:0;::::1;62168:73;;;::::0;-1:-1:-1;;;62168:73:0;;35152:2:1;62168:73:0::1;::::0;::::1;35134:21:1::0;35191:2;35171:18;;;35164:30;35230:34;35210:18;;;35203:62;-1:-1:-1;;;35281:18:1;;;35274:36;35327:19;;62168:73:0::1;34950:402:1::0;62168:73:0::1;62252:28;62271:8;62252:18;:28::i;121966:1200::-:0;2387:21;:19;:21::i;:::-;122054:6:::1;::::0;::::1;;122053:7;122045:35;;;;-1:-1:-1::0;;;122045:35:0::1;;;;;;;:::i;:::-;122113:17;122121:8;122113:7;:17::i;:::-;-1:-1:-1::0;;;;;122099:31:0::1;:10;-1:-1:-1::0;;;;;122099:31:0::1;;122091:56;;;;-1:-1:-1::0;;;122091:56:0::1;;;;;;;:::i;:::-;122177:1;122166:8;:12;:41;;;;-1:-1:-1::0;108195:10:0;:17;122182:8:::1;:25;;122166:41;122158:63;;;;-1:-1:-1::0;;;122158:63:0::1;;;;;;;:::i;:::-;122241:21;::::0;;;:11:::1;:21;::::0;;;;:31;::::1;;122240:32;122232:56;;;;-1:-1:-1::0;;;122232:56:0::1;;;;;;;:::i;:::-;122300:12;122326:17:::0;;;:7:::1;:17;::::0;;;;:26:::1;;::::0;:30;122323:767:::1;;122381:17;::::0;;;:7:::1;:17;::::0;;;;:22:::1;;::::0;122407:1:::1;-1:-1:-1::0;122381:27:0::1;122373:58;;;::::0;-1:-1:-1;;;122373:58:0;;35559:2:1;122373:58:0::1;::::0;::::1;35541:21:1::0;35598:2;35578:18;;;35571:30;-1:-1:-1;;;35617:18:1;;;35610:48;35675:18;;122373:58:0::1;35357:342:1::0;122373:58:0::1;122493:17;122558:7;;122548;;122533:14;;:22;;;;:::i;:::-;122515:14;;:41;;;;:::i;:::-;122514:51;;;;:::i;:::-;122513:57;::::0;122569:1:::1;122513:57;:::i;:::-;:61;::::0;122573:1:::1;122513:61;:::i;:::-;122493:81;;122618:9;122590:7;:17;122598:8;122590:17;;;;;;;;;;;:24;;;:37;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;122642:17:0::1;::::0;;;:7:::1;:17;::::0;;;;:22:::1;;:27:::0;;122668:1:::1;::::0;122642:17;:27:::1;::::0;122668:1;;122642:27:::1;:::i;:::-;::::0;;;-1:-1:-1;;122703:7:0::1;::::0;122691:19:::1;::::0;:9;:19:::1;:::i;:::-;122684:26;;122788:23;122793:4;122799:11;;122788:4;:23::i;:::-;122358:468;122323:767;;;-1:-1:-1::0;122869:16:0::1;::::0;122967:20:::1;122869:16:::0;122967:14:::1;:20::i;:::-;123063:14;123068:4;123074:2;123063:4;:14::i;:::-;123130:17;::::0;;;:7:::1;:17;::::0;;;;:26:::1;;:28:::0;;;::::1;::::0;::::1;:::i;116127:42::-:0;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;137611:511::-;137706:13;137722:22;;;:10;:22;;;;;:29;137675:18;;137722:29;-1:-1:-1;;;;;137790:22:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;137790:22:0;;;;;;;;;;;;;;;;;137762:50;;137833:15;137868:9;137863:228;137887:5;137883:1;:9;137863:228;;;137919:22;;;;:10;:22;;;;;:25;;137959:10;;137919:22;137942:1;;137919:25;;;;;;:::i;:::-;;;;;;;;;;;:36;;;:50;137915:165;;138009:22;;;;:10;:22;;;;;:25;;138032:1;;138009:25;;;;;;:::i;:::-;;;;;;;;;;;137991:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:6;137998:7;137991:15;;;;;;;;:::i;:::-;;;;;;:43;;;;138053:9;;;;;:::i;:::-;;;;137915:165;137894:3;;;;:::i;:::-;;;;137863:228;;119559:92;61074:13;:11;:13::i;:::-;119627:6:::1;:16:::0;119559:92::o;90588:305::-;90690:4;-1:-1:-1;;;;;;90727:40:0;;-1:-1:-1;;;90727:40:0;;:105;;-1:-1:-1;;;;;;;90784:48:0;;-1:-1:-1;;;90784:48:0;90727:105;:158;;;-1:-1:-1;;;;;;;;;;82241:40:0;;;90849:36;82132:157;102591:135;96361:4;95959:16;;;:7;:16;;;;;;-1:-1:-1;;;;;95959:16:0;102665:53;;;;-1:-1:-1;;;102665:53:0;;27839:2:1;102665:53:0;;;27821:21:1;27878:2;27858:18;;;27851:30;-1:-1:-1;;;27897:18:1;;;27890:54;27961:18;;102665:53:0;27637:348:1;101904:174:0;101979:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;101979:29:0;-1:-1:-1;;;;;101979:29:0;;;;;;;;:24;;102033:23;101979:24;102033:14;:23::i;:::-;-1:-1:-1;;;;;102024:46:0;;;;;;;;;;;101904:174;;:::o;2467:293::-;1869:1;2601:7;;:19;2593:63;;;;-1:-1:-1;;;2593:63:0;;35906:2:1;2593:63:0;;;35888:21:1;35945:2;35925:18;;;35918:30;35984:33;35964:18;;;35957:61;36035:18;;2593:63:0;35704:355:1;2593:63:0;1869:1;2734:7;:18;2467:293::o;121312:393::-;121371:24;121398:13;121412:4;;121398:19;;;;;;;;:::i;:::-;;;;;;;;;;121465:15;;121491:61;;-1:-1:-1;;;121491:61:0;;121513:10;121491:61;;;36304:34:1;121533:4:0;36354:18:1;;;36347:43;36406:18;;;36399:34;;;121398:19:0;;-1:-1:-1;;;;;;121465:15:0;;;;121491:21;;36239:18:1;;121491:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;121627:4:0;;121621:29;;-1:-1:-1;;;121621:29:0;;;;;2596:25:1;;;-1:-1:-1;;;;;121627:4:0;;;;121621:16;;2569:18:1;;121621:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;121679:11;121661:14;;:29;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;121312:393:0:o;61353:132::-;61261:6;;-1:-1:-1;;;;;61261:6:0;59819:10;61417:23;61409:68;;;;-1:-1:-1;;;61409:68:0;;36646:2:1;61409:68:0;;;36628:21:1;;;36665:18;;;36658:30;36724:34;36704:18;;;36697:62;36776:18;;61409:68:0;36444:356:1;96591:264:0;96684:4;96701:13;96717:23;96732:7;96717:14;:23::i;:::-;96701:39;;96770:5;-1:-1:-1;;;;;96759:16:0;:7;-1:-1:-1;;;;;96759:16:0;;:52;;;-1:-1:-1;;;;;;93618:25:0;;;93594:4;93618:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;96779:32;96759:87;;;;96839:7;-1:-1:-1;;;;;96815:31:0;:20;96827:7;96815:11;:20::i;:::-;-1:-1:-1;;;;;96815:31:0;;96759:87;96751:96;96591:264;-1:-1:-1;;;;96591:264:0:o;100556:1229::-;100681:4;-1:-1:-1;;;;;100654:31:0;:23;100669:7;100654:14;:23::i;:::-;-1:-1:-1;;;;;100654:31:0;;100646:81;;;;-1:-1:-1;;;100646:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;100746:16:0;;100738:65;;;;-1:-1:-1;;;100738:65:0;;37413:2:1;100738:65:0;;;37395:21:1;37452:2;37432:18;;;37425:30;37491:34;37471:18;;;37464:62;-1:-1:-1;;;37542:18:1;;;37535:34;37586:19;;100738:65:0;37211:400:1;100738:65:0;100816:42;100837:4;100843:2;100847:7;100856:1;100816:20;:42::i;:::-;100988:4;-1:-1:-1;;;;;100961:31:0;:23;100976:7;100961:14;:23::i;:::-;-1:-1:-1;;;;;100961:31:0;;100953:81;;;;-1:-1:-1;;;100953:81:0;;;;;;;:::i;:::-;101106:24;;;;:15;:24;;;;;;;;101099:31;;-1:-1:-1;;;;;;101099:31:0;;;;;;-1:-1:-1;;;;;101582:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;101582:20:0;;;101617:13;;;;;;;;;:18;;101099:31;101617:18;;;101657:16;;;:7;:16;;;;;;:21;;;;;;;;;;101696:27;;101122:7;;101696:27;;;92616:346;92546:416;;:::o;121717:241::-;121776:24;121803:13;121817:4;;121803:19;;;;;;;;:::i;:::-;;;;;;;;;;121870:15;;121896:54;;-1:-1:-1;;;121896:54:0;;121918:10;121896:54;;;36304:34:1;121937:4:0;36354:18:1;;;36347:43;36406:18;;;36399:34;;;121803:19:0;;-1:-1:-1;;;;;;121870:15:0;;;;121896:21;;36239:18:1;;121896:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;120669:635::-;120738:18;120780:3;120760:18;120774:4;120760:11;:18;:::i;:::-;120759:24;;;;:::i;:::-;120738:45;;120797:12;120836:3;120827:7;;120814:10;:20;;;;:::i;:::-;120813:26;;;;:::i;:::-;120797:42;;120850:12;120889:3;120880:7;;120867:10;:20;;;;:::i;:::-;120866:26;;;;:::i;:::-;120850:42;;120903:12;120941:3;120933:6;;120920:10;:19;;;;:::i;:::-;120919:25;;;;:::i;:::-;120903:41;;120957:24;120984:13;120998:4;;120984:19;;;;;;;;:::i;:::-;;;;;;;;;;121051:15;;121110:11;;121092:36;;-1:-1:-1;;;121092:36:0;;-1:-1:-1;;;;;121110:11:0;;;121092:36;;;32373:51:1;32440:18;;;32433:34;;;120984:19:0;;-1:-1:-1;121051:15:0;;;;121092:17;;32346:18:1;;121092:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;121172:11:0;;121154:36;;-1:-1:-1;;;121154:36:0;;-1:-1:-1;;;;;121172:11:0;;;121154:36;;;32373:51:1;32440:18;;;32433:34;;;121154:17:0;;;;;;32346:18:1;;121154:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;121220:18:0;;121202:43;;-1:-1:-1;;;121202:43:0;;121220:18;;;;-1:-1:-1;;;;;121220:18:0;;;121202:43;;;32373:51:1;32440:18;;;32433:34;;;121202:17:0;;;;;32346:18:1;;121202:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;121279:10;121257:18;;:32;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;;;;120669:635:0:o;62448:191::-;62541:6;;;-1:-1:-1;;;;;62558:17:0;;;-1:-1:-1;;;;;;62558:17:0;;;;;;;62591:40;;62541:6;;;62558:17;62541:6;;62591:40;;62522:16;;62591:40;62511:128;62448:191;:::o;98155:942::-;-1:-1:-1;;;;;98235:16:0;;98227:61;;;;-1:-1:-1;;;98227:61:0;;38105:2:1;98227:61:0;;;38087:21:1;;;38124:18;;;38117:30;38183:34;38163:18;;;38156:62;38235:18;;98227:61:0;37903:356:1;98227:61:0;96361:4;95959:16;;;:7;:16;;;;;;-1:-1:-1;;;;;95959:16:0;96385:31;98299:58;;;;-1:-1:-1;;;98299:58:0;;38466:2:1;98299:58:0;;;38448:21:1;38505:2;38485:18;;;38478:30;38544;38524:18;;;38517:58;38592:18;;98299:58:0;38264:352:1;98299:58:0;98370:48;98399:1;98403:2;98407:7;98416:1;98370:20;:48::i;:::-;96361:4;95959:16;;;:7;:16;;;;;;-1:-1:-1;;;;;95959:16:0;96385:31;98508:58;;;;-1:-1:-1;;;98508:58:0;;38466:2:1;98508:58:0;;;38448:21:1;38505:2;38485:18;;;38478:30;38544;38524:18;;;38517:58;38592:18;;98508:58:0;38264:352:1;98508:58:0;-1:-1:-1;;;;;98915:13:0;;;;;;:9;:13;;;;;;;;:18;;98932:1;98915:18;;;98957:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;98957:21:0;;;;;98996:33;98965:7;;98915:13;;98996:33;;98915:13;;98996:33;128177:2273;;:::o;102221:281::-;102342:8;-1:-1:-1;;;;;102333:17:0;:5;-1:-1:-1;;;;;102333:17:0;;102325:55;;;;-1:-1:-1;;;102325:55:0;;38823:2:1;102325:55:0;;;38805:21:1;38862:2;38842:18;;;38835:30;38901:27;38881:18;;;38874:55;38946:18;;102325:55:0;38621:349:1;102325:55:0;-1:-1:-1;;;;;102391:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;102391:46:0;;;;;;;;;;102453:41;;540::1;;;102453::0;;513:18:1;102453:41:0;;;;;;;102221:281;;;:::o;95482:270::-;95595:28;95605:4;95611:2;95615:7;95595:9;:28::i;:::-;95642:47;95665:4;95671:2;95675:7;95684:4;95642:22;:47::i;:::-;95634:110;;;;-1:-1:-1;;;95634:110:0;;;;;;;:::i;56658:716::-;56714:13;56765:14;56782:17;56793:5;56782:10;:17::i;:::-;56802:1;56782:21;56765:38;;56818:20;56852:6;-1:-1:-1;;;;;56841:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56841:18:0;-1:-1:-1;56818:41:0;-1:-1:-1;56983:28:0;;;56999:2;56983:28;57040:288;-1:-1:-1;;57072:5:0;-1:-1:-1;;;57209:2:0;57198:14;;57193:30;57072:5;57180:44;57270:2;57261:11;;;-1:-1:-1;57291:21:0;57040:288;57291:21;-1:-1:-1;57349:6:0;56658:716;-1:-1:-1;;;56658:716:0:o;108604:915::-;108871:1;108859:9;:13;108855:222;;;109002:63;;-1:-1:-1;;;109002:63:0;;39596:2:1;109002:63:0;;;39578:21:1;39635:2;39615:18;;;39608:30;39674:34;39654:18;;;39647:62;-1:-1:-1;;;39725:18:1;;;39718:51;39786:19;;109002:63:0;39394:417:1;108855:222:0;109107:12;-1:-1:-1;;;;;109136:18:0;;109132:187;;109171:40;109203:7;110346:10;:17;;110319:24;;;;:15;:24;;;;;:44;;;110374:24;;;;;;;;;;;;110242:164;109171:40;109132:187;;;109241:2;-1:-1:-1;;;;;109233:10:0;:4;-1:-1:-1;;;;;109233:10:0;;109229:90;;109260:47;109293:4;109299:7;109260:32;:47::i;:::-;-1:-1:-1;;;;;109333:16:0;;109329:183;;109366:45;109403:7;109366:36;:45::i;:::-;109329:183;;;109439:4;-1:-1:-1;;;;;109433:10:0;:2;-1:-1:-1;;;;;109433:10:0;;109429:83;;109460:40;109488:2;109492:7;109460:27;:40::i;103290:853::-;103444:4;-1:-1:-1;;;;;103465:13:0;;64415:19;:23;103461:675;;103501:71;;-1:-1:-1;;;103501:71:0;;-1:-1:-1;;;;;103501:36:0;;;;;:71;;59819:10;;103552:4;;103558:7;;103567:4;;103501:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;103501:71:0;;;;;;;;-1:-1:-1;;103501:71:0;;;;;;;;;;;;:::i;:::-;;;103497:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;103742:6;:13;103759:1;103742:18;103738:328;;103785:60;;-1:-1:-1;;;103785:60:0;;;;;;;:::i;103738:328::-;104016:6;104010:13;104001:6;103997:2;103993:15;103986:38;103497:584;-1:-1:-1;;;;;;103623:51:0;-1:-1:-1;;;103623:51:0;;-1:-1:-1;103616:58:0;;103461:675;-1:-1:-1;104120:4:0;103290:853;;;;;;:::o;53492:948::-;53545:7;;-1:-1:-1;;;53623:17:0;;53619:106;;-1:-1:-1;;;53661:17:0;;;-1:-1:-1;53707:2:0;53697:12;53619:106;53752:8;53743:5;:17;53739:106;;53790:8;53781:17;;;-1:-1:-1;53827:2:0;53817:12;53739:106;53872:8;53863:5;:17;53859:106;;53910:8;53901:17;;;-1:-1:-1;53947:2:0;53937:12;53859:106;53992:7;53983:5;:16;53979:103;;54029:7;54020:16;;;-1:-1:-1;54065:1:0;54055:11;53979:103;54109:7;54100:5;:16;54096:103;;54146:7;54137:16;;;-1:-1:-1;54182:1:0;54172:11;54096:103;54226:7;54217:5;:16;54213:103;;54263:7;54254:16;;;-1:-1:-1;54299:1:0;54289:11;54213:103;54343:7;54334:5;:16;54330:68;;54381:1;54371:11;54426:6;53492:948;-1:-1:-1;;53492:948:0:o;111033:988::-;111299:22;111349:1;111324:22;111341:4;111324:16;:22::i;:::-;:26;;;;:::i;:::-;111361:18;111382:26;;;:17;:26;;;;;;111299:51;;-1:-1:-1;111515:28:0;;;111511:328;;-1:-1:-1;;;;;111582:18:0;;111560:19;111582:18;;;:12;:18;;;;;;;;:34;;;;;;;;;111633:30;;;;;;:44;;;111750:30;;:17;:30;;;;;:43;;;111511:328;-1:-1:-1;111935:26:0;;;;:17;:26;;;;;;;;111928:33;;;-1:-1:-1;;;;;111979:18:0;;;;;:12;:18;;;;;:34;;;;;;;111972:41;111033:988::o;112316:1079::-;112594:10;:17;112569:22;;112594:21;;112614:1;;112594:21;:::i;:::-;112626:18;112647:24;;;:15;:24;;;;;;113020:10;:26;;112569:46;;-1:-1:-1;112647:24:0;;112569:46;;113020:26;;;;;;:::i;:::-;;;;;;;;;112998:48;;113084:11;113059:10;113070;113059:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;113164:28;;;:15;:28;;;;;;;:41;;;113336:24;;;;;113329:31;113371:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;112387:1008;;;112316:1079;:::o;109820:221::-;109905:14;109922:20;109939:2;109922:16;:20::i;:::-;-1:-1:-1;;;;;109953:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;109998:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;109820:221:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;:::-;384:5;150:245;-1:-1:-1;;;150:245:1:o;592:250::-;677:1;687:113;701:6;698:1;695:13;687:113;;;777:11;;;771:18;758:11;;;751:39;723:2;716:10;687:113;;;-1:-1:-1;;834:1:1;816:16;;809:27;592:250::o;847:271::-;889:3;927:5;921:12;954:6;949:3;942:19;970:76;1039:6;1032:4;1027:3;1023:14;1016:4;1009:5;1005:16;970:76;:::i;:::-;1100:2;1079:15;-1:-1:-1;;1075:29:1;1066:39;;;;1107:4;1062:50;;847:271;-1:-1:-1;;847:271:1:o;1123:220::-;1272:2;1261:9;1254:21;1235:4;1292:45;1333:2;1322:9;1318:18;1310:6;1292:45;:::i;1348:180::-;1407:6;1460:2;1448:9;1439:7;1435:23;1431:32;1428:52;;;1476:1;1473;1466:12;1428:52;-1:-1:-1;1499:23:1;;1348:180;-1:-1:-1;1348:180:1:o;1741:131::-;-1:-1:-1;;;;;1816:31:1;;1806:42;;1796:70;;1862:1;1859;1852:12;1877:315;1945:6;1953;2006:2;1994:9;1985:7;1981:23;1977:32;1974:52;;;2022:1;2019;2012:12;1974:52;2061:9;2048:23;2080:31;2105:5;2080:31;:::i;:::-;2130:5;2182:2;2167:18;;;;2154:32;;-1:-1:-1;;;1877:315:1:o;2197:248::-;2265:6;2273;2326:2;2314:9;2305:7;2301:23;2297:32;2294:52;;;2342:1;2339;2332:12;2294:52;-1:-1:-1;;2365:23:1;;;2435:2;2420:18;;;2407:32;;-1:-1:-1;2197:248:1:o;2632:523::-;2736:6;2744;2752;2760;2768;2776;2829:3;2817:9;2808:7;2804:23;2800:33;2797:53;;;2846:1;2843;2836:12;2797:53;-1:-1:-1;;2869:23:1;;;2939:2;2924:18;;2911:32;;-1:-1:-1;2990:2:1;2975:18;;2962:32;;3041:2;3026:18;;3013:32;;-1:-1:-1;3092:3:1;3077:19;;3064:33;;-1:-1:-1;3144:3:1;3129:19;3116:33;;-1:-1:-1;2632:523:1;-1:-1:-1;2632:523:1:o;3160:247::-;3219:6;3272:2;3260:9;3251:7;3247:23;3243:32;3240:52;;;3288:1;3285;3278:12;3240:52;3327:9;3314:23;3346:31;3371:5;3346:31;:::i;3412:1734::-;3602:4;3631:2;3671;3660:9;3656:18;3701:2;3690:9;3683:21;3724:6;3759;3753:13;3790:6;3782;3775:22;3816:2;3806:12;;3849:2;3838:9;3834:18;3827:25;;3911:2;3901:6;3898:1;3894:14;3883:9;3879:30;3875:39;3949:2;3941:6;3937:15;3970:1;3980:1137;3994:6;3991:1;3988:13;3980:1137;;;4087:2;4083:7;4071:9;4063:6;4059:22;4055:36;4050:3;4043:49;4121:6;4115:13;4151:6;4196:2;4190:9;4227:2;4219:6;4212:18;4257:48;4301:2;4293:6;4289:15;4275:12;4257:48;:::i;:::-;4348:11;;;4342:18;4325:15;;;4318:43;4404:11;;;4398:18;4381:15;;;4374:43;4440:4;4487:11;;;4481:18;4464:15;;;4457:43;4523:4;4570:11;;;4564:18;4547:15;;;4540:43;4606:4;4653:11;;;4647:18;4630:15;;;4623:43;4689:4;4736:11;;;4730:18;4713:15;;;4706:43;4772:4;4819:11;;;4813:18;4796:15;;;4789:43;4856:6;4906:12;;;4900:19;4882:16;;;4875:45;4944:6;4994:12;;;4988:19;4970:16;;;;4963:45;;;;-1:-1:-1;;5095:12:1;;;;5060:15;;;;4016:1;4009:9;3980:1137;;;-1:-1:-1;5134:6:1;;3412:1734;-1:-1:-1;;;;;;;;3412:1734:1:o;5151:456::-;5228:6;5236;5244;5297:2;5285:9;5276:7;5272:23;5268:32;5265:52;;;5313:1;5310;5303:12;5265:52;5352:9;5339:23;5371:31;5396:5;5371:31;:::i;:::-;5421:5;-1:-1:-1;5478:2:1;5463:18;;5450:32;5491:33;5450:32;5491:33;:::i;:::-;5151:456;;5543:7;;-1:-1:-1;;;5597:2:1;5582:18;;;;5569:32;;5151:456::o;5834:529::-;5911:6;5919;5927;5980:2;5968:9;5959:7;5955:23;5951:32;5948:52;;;5996:1;5993;5986:12;5948:52;6035:9;6022:23;6054:31;6079:5;6054:31;:::i;:::-;6104:5;-1:-1:-1;6161:2:1;6146:18;;6133:32;6174:33;6133:32;6174:33;:::i;:::-;6226:7;-1:-1:-1;6285:2:1;6270:18;;6257:32;6298:33;6257:32;6298:33;:::i;:::-;6350:7;6340:17;;;5834:529;;;;;:::o;6368:127::-;6429:10;6424:3;6420:20;6417:1;6410:31;6460:4;6457:1;6450:15;6484:4;6481:1;6474:15;6500:632;6565:5;-1:-1:-1;;;;;6636:2:1;6628:6;6625:14;6622:40;;;6642:18;;:::i;:::-;6717:2;6711:9;6685:2;6771:15;;-1:-1:-1;;6767:24:1;;;6793:2;6763:33;6759:42;6747:55;;;6817:18;;;6837:22;;;6814:46;6811:72;;;6863:18;;:::i;:::-;6903:10;6899:2;6892:22;6932:6;6923:15;;6962:6;6954;6947:22;7002:3;6993:6;6988:3;6984:16;6981:25;6978:45;;;7019:1;7016;7009:12;6978:45;7069:6;7064:3;7057:4;7049:6;7045:17;7032:44;7124:1;7117:4;7108:6;7100;7096:19;7092:30;7085:41;;;;6500:632;;;;;:::o;7137:222::-;7180:5;7233:3;7226:4;7218:6;7214:17;7210:27;7200:55;;7251:1;7248;7241:12;7200:55;7273:80;7349:3;7340:6;7327:20;7320:4;7312:6;7308:17;7273:80;:::i;7364:390::-;7442:6;7450;7503:2;7491:9;7482:7;7478:23;7474:32;7471:52;;;7519:1;7516;7509:12;7471:52;7555:9;7542:23;7532:33;;7616:2;7605:9;7601:18;7588:32;-1:-1:-1;;;;;7635:6:1;7632:30;7629:50;;;7675:1;7672;7665:12;7629:50;7698;7740:7;7731:6;7720:9;7716:22;7698:50;:::i;:::-;7688:60;;;7364:390;;;;;:::o;7759:367::-;7822:8;7832:6;7886:3;7879:4;7871:6;7867:17;7863:27;7853:55;;7904:1;7901;7894:12;7853:55;-1:-1:-1;7927:20:1;;-1:-1:-1;;;;;7959:30:1;;7956:50;;;8002:1;7999;7992:12;7956:50;8039:4;8031:6;8027:17;8015:29;;8099:3;8092:4;8082:6;8079:1;8075:14;8067:6;8063:27;8059:38;8056:47;8053:67;;;8116:1;8113;8106:12;8053:67;7759:367;;;;;:::o;8131:437::-;8217:6;8225;8278:2;8266:9;8257:7;8253:23;8249:32;8246:52;;;8294:1;8291;8284:12;8246:52;8334:9;8321:23;-1:-1:-1;;;;;8359:6:1;8356:30;8353:50;;;8399:1;8396;8389:12;8353:50;8438:70;8500:7;8491:6;8480:9;8476:22;8438:70;:::i;:::-;8527:8;;8412:96;;-1:-1:-1;8131:437:1;-1:-1:-1;;;;8131:437:1:o;8797:1554::-;9021:6;9029;9037;9045;9053;9061;9069;9077;9085;9093;9146:3;9134:9;9125:7;9121:23;9117:33;9114:53;;;9163:1;9160;9153:12;9114:53;9199:9;9186:23;9176:33;;9256:2;9245:9;9241:18;9228:32;9218:42;;9311:2;9300:9;9296:18;9283:32;-1:-1:-1;;;;;9375:2:1;9367:6;9364:14;9361:34;;;9391:1;9388;9381:12;9361:34;9430:70;9492:7;9483:6;9472:9;9468:22;9430:70;:::i;:::-;9519:8;;-1:-1:-1;9404:96:1;-1:-1:-1;9607:2:1;9592:18;;9579:32;;-1:-1:-1;9623:16:1;;;9620:36;;;9652:1;9649;9642:12;9620:36;9691:72;9755:7;9744:8;9733:9;9729:24;9691:72;:::i;:::-;9782:8;;-1:-1:-1;9665:98:1;-1:-1:-1;9870:3:1;9855:19;;9842:33;;-1:-1:-1;9887:16:1;;;9884:36;;;9916:1;9913;9906:12;9884:36;9955:72;10019:7;10008:8;9997:9;9993:24;9955:72;:::i;:::-;10046:8;;-1:-1:-1;9929:98:1;-1:-1:-1;10134:3:1;10119:19;;10106:33;;-1:-1:-1;10151:16:1;;;10148:36;;;10180:1;10177;10170:12;10148:36;;10219:72;10283:7;10272:8;10261:9;10257:24;10219:72;:::i;:::-;10193:98;;10310:8;10300:18;;;10337:8;10327:18;;;8797:1554;;;;;;;;;;;;;:::o;11018:322::-;11087:6;11140:2;11128:9;11119:7;11115:23;11111:32;11108:52;;;11156:1;11153;11146:12;11108:52;11196:9;11183:23;-1:-1:-1;;;;;11221:6:1;11218:30;11215:50;;;11261:1;11258;11251:12;11215:50;11284;11326:7;11317:6;11306:9;11302:22;11284:50;:::i;11345:118::-;11431:5;11424:13;11417:21;11410:5;11407:32;11397:60;;11453:1;11450;11443:12;11468:382;11533:6;11541;11594:2;11582:9;11573:7;11569:23;11565:32;11562:52;;;11610:1;11607;11600:12;11562:52;11649:9;11636:23;11668:31;11693:5;11668:31;:::i;:::-;11718:5;-1:-1:-1;11775:2:1;11760:18;;11747:32;11788:30;11747:32;11788:30;:::i;:::-;11837:7;11827:17;;;11468:382;;;;;:::o;11855:795::-;11950:6;11958;11966;11974;12027:3;12015:9;12006:7;12002:23;11998:33;11995:53;;;12044:1;12041;12034:12;11995:53;12083:9;12070:23;12102:31;12127:5;12102:31;:::i;:::-;12152:5;-1:-1:-1;12209:2:1;12194:18;;12181:32;12222:33;12181:32;12222:33;:::i;:::-;12274:7;-1:-1:-1;12328:2:1;12313:18;;12300:32;;-1:-1:-1;12383:2:1;12368:18;;12355:32;-1:-1:-1;;;;;12399:30:1;;12396:50;;;12442:1;12439;12432:12;12396:50;12465:22;;12518:4;12510:13;;12506:27;-1:-1:-1;12496:55:1;;12547:1;12544;12537:12;12496:55;12570:74;12636:7;12631:2;12618:16;12613:2;12609;12605:11;12570:74;:::i;:::-;12560:84;;;11855:795;;;;;;;:::o;12924:715::-;13153:2;13205:21;;;13275:13;;13178:18;;;13297:22;;;13124:4;;13153:2;13376:15;;;;13350:2;13335:18;;;13124:4;13419:194;13433:6;13430:1;13427:13;13419:194;;;13482:49;13527:3;13518:6;13512:13;12738:5;12732:12;12727:3;12720:25;12794:4;12787:5;12783:16;12777:23;12770:4;12765:3;12761:14;12754:47;12850:4;12843:5;12839:16;12833:23;12826:4;12821:3;12817:14;12810:47;12906:4;12899:5;12895:16;12889:23;12882:4;12877:3;12873:14;12866:47;;;12655:264;13482:49;13588:15;;;;13560:4;13551:14;;;;;13455:1;13448:9;13419:194;;;-1:-1:-1;13630:3:1;;12924:715;-1:-1:-1;;;;;;12924:715:1:o;13644:388::-;13712:6;13720;13773:2;13761:9;13752:7;13748:23;13744:32;13741:52;;;13789:1;13786;13779:12;13741:52;13828:9;13815:23;13847:31;13872:5;13847:31;:::i;:::-;13897:5;-1:-1:-1;13954:2:1;13939:18;;13926:32;13967:33;13926:32;13967:33;:::i;14037:887::-;14401:4;14430:3;14460:2;14449:9;14442:21;14480:45;14521:2;14510:9;14506:18;14498:6;14480:45;:::i;:::-;14556:2;14541:18;;14534:34;;;;-1:-1:-1;;14599:2:1;14584:18;;14577:34;;;;14642:2;14627:18;;14620:34;;;;14685:3;14670:19;;14663:35;;;;14729:3;14714:19;;14707:35;;;;14773:3;14758:19;;14751:35;14817:3;14802:19;;14795:35;14861:3;14846:19;;14839:35;14905:3;14890:19;;;14883:35;14472:53;14037:887;-1:-1:-1;14037:887:1:o;14929:711::-;15154:2;15206:21;;;15276:13;;15179:18;;;15298:22;;;15125:4;;15154:2;15377:15;;;;15351:2;15336:18;;;15125:4;15420:194;15434:6;15431:1;15428:13;15420:194;;;15483:49;15528:3;15519:6;15513:13;12738:5;12732:12;12727:3;12720:25;12794:4;12787:5;12783:16;12777:23;12770:4;12765:3;12761:14;12754:47;12850:4;12843:5;12839:16;12833:23;12826:4;12821:3;12817:14;12810:47;12906:4;12899:5;12895:16;12889:23;12882:4;12877:3;12873:14;12866:47;;;12655:264;15483:49;15589:15;;;;15561:4;15552:14;;;;;15456:1;15449:9;15420:194;;15645:380;15724:1;15720:12;;;;15767;;;15788:61;;15842:4;15834:6;15830:17;15820:27;;15788:61;15895:2;15887:6;15884:14;15864:18;15861:38;15858:161;;15941:10;15936:3;15932:20;15929:1;15922:31;15976:4;15973:1;15966:15;16004:4;16001:1;15994:15;15858:161;;15645:380;;;:::o;16862:339::-;17064:2;17046:21;;;17103:2;17083:18;;;17076:30;-1:-1:-1;;;17137:2:1;17122:18;;17115:45;17192:2;17177:18;;16862:339::o;17547:335::-;17749:2;17731:21;;;17788:2;17768:18;;;17761:30;-1:-1:-1;;;17822:2:1;17807:18;;17800:41;17873:2;17858:18;;17547:335::o;17887:332::-;18089:2;18071:21;;;18128:1;18108:18;;;18101:29;-1:-1:-1;;;18161:2:1;18146:18;;18139:39;18210:2;18195:18;;17887:332::o;18570:127::-;18631:10;18626:3;18622:20;18619:1;18612:31;18662:4;18659:1;18652:15;18686:4;18683:1;18676:15;18702:125;18767:9;;;18788:10;;;18785:36;;;18801:18;;:::i;18832:168::-;18905:9;;;18936;;18953:15;;;18947:22;;18933:37;18923:71;;18974:18;;:::i;19005:135::-;19044:3;19065:17;;;19062:43;;19085:18;;:::i;:::-;-1:-1:-1;19132:1:1;19121:13;;19005:135::o;19145:128::-;19212:9;;;19233:11;;;19230:37;;;19247:18;;:::i;19278:336::-;19480:2;19462:21;;;19519:2;19499:18;;;19492:30;-1:-1:-1;;;19553:2:1;19538:18;;19531:42;19605:2;19590:18;;19278:336::o;19751:217::-;19791:1;19817;19807:132;;19861:10;19856:3;19852:20;19849:1;19842:31;19896:4;19893:1;19886:15;19924:4;19921:1;19914:15;19807:132;-1:-1:-1;19953:9:1;;19751:217::o;20315:127::-;20376:10;20371:3;20367:20;20364:1;20357:31;20407:4;20404:1;20397:15;20431:4;20428:1;20421:15;20447:409;20649:2;20631:21;;;20688:2;20668:18;;;20661:30;20727:34;20722:2;20707:18;;20700:62;-1:-1:-1;;;20793:2:1;20778:18;;20771:43;20846:3;20831:19;;20447:409::o;21612:339::-;21814:2;21796:21;;;21853:2;21833:18;;;21826:30;-1:-1:-1;;;21887:2:1;21872:18;;21865:45;21942:2;21927:18;;21612:339::o;22305:336::-;22507:2;22489:21;;;22546:2;22526:18;;;22519:30;-1:-1:-1;;;22580:2:1;22565:18;;22558:42;22632:2;22617:18;;22305:336::o;23671:332::-;23873:2;23855:21;;;23912:1;23892:18;;;23885:29;-1:-1:-1;;;23945:2:1;23930:18;;23923:39;23994:2;23979:18;;23671:332::o;25559:545::-;25661:2;25656:3;25653:11;25650:448;;;25697:1;25722:5;25718:2;25711:17;25767:4;25763:2;25753:19;25837:2;25825:10;25821:19;25818:1;25814:27;25808:4;25804:38;25873:4;25861:10;25858:20;25855:47;;;-1:-1:-1;25896:4:1;25855:47;25951:2;25946:3;25942:12;25939:1;25935:20;25929:4;25925:31;25915:41;;26006:82;26024:2;26017:5;26014:13;26006:82;;;26069:17;;;26050:1;26039:13;26006:82;;;26010:3;;;25559:545;;;:::o;26280:1352::-;26406:3;26400:10;-1:-1:-1;;;;;26425:6:1;26422:30;26419:56;;;26455:18;;:::i;:::-;26484:97;26574:6;26534:38;26566:4;26560:11;26534:38;:::i;:::-;26528:4;26484:97;:::i;:::-;26636:4;;26700:2;26689:14;;26717:1;26712:663;;;;27419:1;27436:6;27433:89;;;-1:-1:-1;27488:19:1;;;27482:26;27433:89;-1:-1:-1;;26237:1:1;26233:11;;;26229:24;26225:29;26215:40;26261:1;26257:11;;;26212:57;27535:81;;26682:944;;26712:663;25506:1;25499:14;;;25543:4;25530:18;;-1:-1:-1;;26748:20:1;;;26866:236;26880:7;26877:1;26874:14;26866:236;;;26969:19;;;26963:26;26948:42;;27061:27;;;;27029:1;27017:14;;;;26896:19;;26866:236;;;26870:3;27130:6;27121:7;27118:19;27115:201;;;27191:19;;;27185:26;-1:-1:-1;;27274:1:1;27270:14;;;27286:3;27266:24;27262:37;27258:42;27243:58;27228:74;;27115:201;-1:-1:-1;;;;;27362:1:1;27346:14;;;27342:22;27329:36;;-1:-1:-1;26280:1352:1:o;29767:522::-;29845:4;29851:6;29911:11;29898:25;30005:2;30001:7;29990:8;29974:14;29970:29;29966:43;29946:18;29942:68;29932:96;;30024:1;30021;30014:12;29932:96;30051:33;;30103:20;;;-1:-1:-1;;;;;;30135:30:1;;30132:50;;;30178:1;30175;30168:12;30132:50;30211:4;30199:17;;-1:-1:-1;30242:14:1;30238:27;;;30228:38;;30225:58;;;30279:1;30276;30269:12;31662:184;31732:6;31785:2;31773:9;31764:7;31760:23;31756:32;31753:52;;;31801:1;31798;31791:12;31753:52;-1:-1:-1;31824:16:1;;31662:184;-1:-1:-1;31662:184:1:o;32478:245::-;32545:6;32598:2;32586:9;32577:7;32573:23;32569:32;32566:52;;;32614:1;32611;32604:12;32566:52;32646:9;32640:16;32665:28;32687:5;32665:28;:::i;33072:1187::-;33349:3;33378:1;33411:6;33405:13;33441:36;33467:9;33441:36;:::i;:::-;33496:1;33513:18;;;33540:133;;;;33687:1;33682:356;;;;33506:532;;33540:133;-1:-1:-1;;33573:24:1;;33561:37;;33646:14;;33639:22;33627:35;;33618:45;;;-1:-1:-1;33540:133:1;;33682:356;33713:6;33710:1;33703:17;33743:4;33788:2;33785:1;33775:16;33813:1;33827:165;33841:6;33838:1;33835:13;33827:165;;;33919:14;;33906:11;;;33899:35;33962:16;;;;33856:10;;33827:165;;;33831:3;;;34021:6;34016:3;34012:16;34005:23;;33506:532;;;;;34069:6;34063:13;34085:68;34144:8;34139:3;34132:4;34124:6;34120:17;34085:68;:::i;:::-;-1:-1:-1;;;34175:18:1;;34202:22;;;34251:1;34240:13;;33072:1187;-1:-1:-1;;;;33072:1187:1:o;36805:401::-;37007:2;36989:21;;;37046:2;37026:18;;;37019:30;37085:34;37080:2;37065:18;;37058:62;-1:-1:-1;;;37151:2:1;37136:18;;37129:35;37196:3;37181:19;;36805:401::o;38975:414::-;39177:2;39159:21;;;39216:2;39196:18;;;39189:30;39255:34;39250:2;39235:18;;39228:62;-1:-1:-1;;;39321:2:1;39306:18;;39299:48;39379:3;39364:19;;38975:414::o;39816:489::-;-1:-1:-1;;;;;40085:15:1;;;40067:34;;40137:15;;40132:2;40117:18;;40110:43;40184:2;40169:18;;40162:34;;;40232:3;40227:2;40212:18;;40205:31;;;40010:4;;40253:46;;40279:19;;40271:6;40253:46;:::i;:::-;40245:54;39816:489;-1:-1:-1;;;;;;39816:489:1:o;40310:249::-;40379:6;40432:2;40420:9;40411:7;40407:23;40403:32;40400:52;;;40448:1;40445;40438:12;40400:52;40480:9;40474:16;40499:30;40523:5;40499:30;:::i;40564:127::-;40625:10;40620:3;40616:20;40613:1;40606:31;40656:4;40653:1;40646:15;40680:4;40677:1;40670:15
Swarm Source
ipfs://3d5d2633d9c3ed7fbd9ffac38c4aea704791071eabe3e17ac4c3c60e0e031b7c
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in MNT
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
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.