Source Code
Overview
HYPE Balance
HYPE Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
HypesinoV2
Compiler Version
v0.8.28+commit.7893614a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;
import {Initializable} from "npm/@openzeppelin/[email protected]/proxy/utils/Initializable.sol";
import {UUPSUpgradeable} from "npm/@openzeppelin/[email protected]/proxy/utils/UUPSUpgradeable.sol";
import {OwnableUpgradeable} from "npm/@openzeppelin/[email protected]/access/OwnableUpgradeable.sol";
import {ReentrancyGuardUpgradeable} from "npm/@openzeppelin/[email protected]/security/ReentrancyGuardUpgradeable.sol";
/// @notice Minimal interface the slot uses to request randomness.
/// Your deployed DRAND adapter implements this and calls back fulfillRandomness().
interface IVRF {
function requestRandomness() external returns (uint256 requestId);
}
contract HypesinoV2 is Initializable, UUPSUpgradeable, OwnableUpgradeable, ReentrancyGuardUpgradeable {
// ----------- Config (existing storage) -----------
IVRF public vrf;
uint256 public FIXED_BET = 0.05 ether;
uint256 public feeBps = 200; // 2% default
uint256 public accumulatedFees;
uint256 public maxActiveRequests = 500; // explicit cap to bound activeIds growth
// Exposure reserve for active spins (max payout depends on tier; see _maxMultForTier)
uint256 public pendingExposure;
// Cancel windows
uint256 public constant CANCEL_DELAY = 60; // owner can cancel after 60s
uint256 public constant PLAYER_CANCEL_DELAY = 300; // player can cancel after 5m
// RTP tuning (no sub-1x):
// - No payout for sequential/straight.
// - One-pair pays 1x only if the pair digit != 0 (pairs of 0 are no-hit).
// - Two-pairs pays ~1.95x (BPS below).
uint256 public constant TWO_PAIRS_PAYOUT_BPS = 19_500; // ~1.95x
// ----------- State -----------
struct Request {
address player; // 20 bytes
uint128 netBet; // 16 bytes (net = gross - fee)
uint64 timestamp; // 8 bytes
bool usedCredit; // 1 byte
bool active; // 1 byte
// NEW FIELD appended at end of struct — safe for upgrade:
uint8 tier; // 0 => 0.05, 1 => 0.25, 2 => 0.5
}
// requestId => request state
mapping(uint256 => Request) public requests;
// compact active set for O(1) add/remove
uint256[] private activeIds;
// 1-based index in activeIds (0 means "not present")
mapping(uint256 => uint256) private activeIndex;
// DEPRECATED: old fixed-bet credits (retained for storage)
mapping(address => uint256) public credits;
// deferred payouts when player transfer fails (existing position — do not move)
mapping(address => uint256) public pendingOwed;
// ----------- NEW storage (APPEND ONLY BELOW THIS LINE) -----------
// NEW: per-tier credits (tier: 0=0.05, 1=0.25, 2=0.5)
mapping(address => mapping(uint8 => uint256)) public creditsByTier;
// ----------- Tier configuration (constants: no storage) -----------
// Bet tiers (gross bet amounts)
uint256 public constant BET_TIER0 = 0.05 ether;
uint256 public constant BET_TIER1 = 0.25 ether;
uint256 public constant BET_TIER2 = 0.50 ether;
// RTP multipliers per tier (apply to raw payout) in basis points (NET multipliers).
// Calibrated to target ~97.8%, ~94%, ~90% gross RTP with feeBps = 400 (4%).
uint256 public constant RTP_BPS_T0 = 10_550; // tuned for ~97.8% gross
uint256 public constant RTP_BPS_T1 = 10_120; // tuned for ~94% gross
uint256 public constant RTP_BPS_T2 = 9_700; // tuned for ~90% gross
// Max jackpot multipliers per tier
// NOTE: Tier2 (0.5) capped at 25x instead of 50x.
uint256 public constant MAX_MULT_T0 = 50;
uint256 public constant MAX_MULT_T1 = 50;
uint256 public constant MAX_MULT_T2 = 25;
// ----------- Events -----------
event SpinRequested(
address indexed player,
uint256 indexed requestId,
uint8 tier,
uint256 grossBet,
uint256 netBet
);
event SpinResult(
uint256 indexed requestId,
address indexed player,
uint256 bet,
uint256[5] reels,
uint256 payout,
uint256 randomnessRound,
uint8 tier
);
event SpinCancelled(
uint256 indexed requestId,
address indexed player,
uint256 netBet
);
event CreditsPurchased(address indexed player, uint8 tier, uint256 credits, uint256 amount);
event OwnerUpdated(address indexed newOwner);
event VrfUpdated(address indexed newVrf);
event FixedBetUpdated(uint256 newFixedBet);
event FeeBpsUpdated(uint256 newFeeBps);
event PayoutDeferred(address indexed player, uint256 amount);
event MaxActiveRequestsUpdated(uint256 newMaxActiveRequests);
// ----------- Errors -----------
error NotOwner();
error OnlyVRF();
error BadBet();
error BankrollTooLow();
error DuplicateRequest();
error NoSuchRequest();
error TooEarly();
error NotAuthorized();
error WithdrawExceedsFreeBalance();
error TransferFailed();
error TooManyActiveRequests();
error InvalidTier();
error DeprecatedEndpoint();
modifier onlyVRF() {
if (msg.sender != address(vrf)) revert OnlyVRF();
_;
}
// ----------- Initializer -----------
function initialize(address vrfAddr) public initializer {
__UUPSUpgradeable_init();
__Ownable_init();
__ReentrancyGuard_init();
vrf = IVRF(vrfAddr);
// set default config values for upgradeable storage
FIXED_BET = 0.05 ether;
feeBps = 400; // 4%
maxActiveRequests = 500;
}
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
// ----------- Admin -----------
function setOwner(address newOwner) external onlyOwner {
_transferOwnership(newOwner);
emit OwnerUpdated(newOwner);
}
function setVrf(address newVrf) external onlyOwner {
vrf = IVRF(newVrf);
emit VrfUpdated(newVrf);
}
function setFixedBet(uint256 newFixedBet) external onlyOwner {
FIXED_BET = newFixedBet;
emit FixedBetUpdated(newFixedBet);
}
function setFeeBps(uint256 newFeeBps) external onlyOwner {
require(newFeeBps <= 1000, "fee too high"); // cap 10% for safety
feeBps = newFeeBps;
emit FeeBpsUpdated(newFeeBps);
}
function setMaxActiveRequests(uint256 newMax) external onlyOwner {
require(newMax > 0, "max=0");
maxActiveRequests = newMax;
emit MaxActiveRequestsUpdated(newMax);
}
// ----------- User actions (NEW tiered entrypoints) -----------
/// @notice Place a spin using one of the three bet tiers.
/// @param tier 0 => 0.05, 1 => 0.25, 2 => 0.5
function spin(uint8 tier) external payable nonReentrant {
uint256 grossBet = _betAmount(tier);
if (msg.value != grossBet) revert BadBet();
uint256 netBet = _netBet(grossBet);
// Reserve worst-case exposure for this tier (ceil(maxMult * RTP) * net)
uint256 newExposure = pendingExposure + (netBet * _effectiveMaxMult(tier));
if (address(this).balance < newExposure) revert BankrollTooLow();
if (activeIds.length >= maxActiveRequests) revert TooManyActiveRequests();
uint256 id = vrf.requestRandomness();
if (requests[id].player != address(0)) revert DuplicateRequest();
requests[id] = Request({
player: msg.sender,
netBet: uint128(netBet),
timestamp: uint64(block.timestamp),
usedCredit: false,
active: true,
tier: tier
});
_addActive(id);
pendingExposure = newExposure;
accumulatedFees += (grossBet - netBet);
emit SpinRequested(msg.sender, id, tier, grossBet, netBet);
}
/// @notice Spin using previously purchased credits for the given tier.
/// For tier 0, legacy credits are consumed as a fallback if present.
function spinWithCredit(uint8 tier) external nonReentrant {
uint256 grossBet = _betAmount(tier);
// Prefer new per-tier credits; fallback to legacy for tier 0.
uint256 c = creditsByTier[msg.sender][tier];
if (c >= 1) {
unchecked { creditsByTier[msg.sender][tier] = c - 1; }
} else if (tier == 0 && credits[msg.sender] >= 1) {
unchecked { credits[msg.sender] = credits[msg.sender] - 1; }
} else {
revert("no credit");
}
uint256 netBet = _netBet(grossBet);
uint256 newExposure = pendingExposure + (netBet * _effectiveMaxMult(tier));
if (address(this).balance < newExposure) revert BankrollTooLow();
if (activeIds.length >= maxActiveRequests) revert TooManyActiveRequests();
uint256 id = vrf.requestRandomness();
if (requests[id].player != address(0)) revert DuplicateRequest();
requests[id] = Request({
player: msg.sender,
netBet: uint128(netBet),
timestamp: uint64(block.timestamp),
usedCredit: true,
active: true,
tier: tier
});
_addActive(id);
pendingExposure = newExposure;
accumulatedFees += (grossBet - netBet);
emit SpinRequested(msg.sender, id, tier, grossBet, netBet);
}
// ----------- User actions (DEPRECATED fixed-bet entrypoints) -----------
function spin() external payable nonReentrant {
revert DeprecatedEndpoint();
}
function spinWithCredit() external nonReentrant {
revert DeprecatedEndpoint();
}
// Permissionless VRF adapter calls back here with randomness
function fulfillRandomness(uint256 requestId, uint256 rand, uint256 randomnessRound) external onlyVRF nonReentrant {
Request memory r = requests[requestId];
if (!r.active || r.player == address(0)) revert NoSuchRequest();
// Effects
requests[requestId].active = false;
_removeActive(requestId);
pendingExposure -= (uint256(r.netBet) * _effectiveMaxMult(r.tier));
// Derive reels deterministically from VRF output
uint256[5] memory reels;
reels[0] = uint256(keccak256(abi.encodePacked(rand, uint256(0)))) % 10;
reels[1] = uint256(keccak256(abi.encodePacked(rand, uint256(1)))) % 10;
reels[2] = uint256(keccak256(abi.encodePacked(rand, uint256(2)))) % 10;
reels[3] = uint256(keccak256(abi.encodePacked(rand, uint256(3)))) % 10;
reels[4] = uint256(keccak256(abi.encodePacked(rand, uint256(4)))) % 10;
uint256 payout = _calculatePayout(r.tier, reels, uint256(r.netBet));
// Interactions
if (payout > 0) {
(bool ok, ) = payable(r.player).call{value: payout}("");
if (!ok) {
pendingOwed[r.player] += payout;
emit PayoutDeferred(r.player, payout);
}
}
emit SpinResult(requestId, r.player, uint256(r.netBet), reels, payout, randomnessRound, r.tier);
}
// Owner or player cancels after delay; refunds net bet or restores a credit
function cancelRequest(uint256 requestId) external nonReentrant {
Request memory r = requests[requestId];
if (!r.active || r.player == address(0)) revert NoSuchRequest();
// Authorization + timing
if (msg.sender == owner()) {
if (block.timestamp < uint256(r.timestamp) + CANCEL_DELAY) revert TooEarly();
} else if (msg.sender == r.player) {
if (block.timestamp < uint256(r.timestamp) + PLAYER_CANCEL_DELAY) revert TooEarly();
} else {
revert NotAuthorized();
}
// Effects
requests[requestId].active = false;
_removeActive(requestId);
pendingExposure -= (uint256(r.netBet) * _effectiveMaxMult(r.tier));
// Interactions
if (r.usedCredit) {
// Refund credit to the same tier as stored on the request
creditsByTier[r.player][r.tier] += 1;
} else {
(bool ok, ) = payable(r.player).call{value: uint256(r.netBet)}("");
if (!ok) revert TransferFailed();
}
emit SpinCancelled(requestId, r.player, uint256(r.netBet));
}
// ----------- Credits / Bankroll -----------
/// @notice Buy credits for a specific tier (0=>0.05, 1=>0.25, 2=>0.5).
function buyCredits(uint8 tier, uint256 creditsCount) external payable nonReentrant {
require(creditsCount > 0, "credits=0");
uint256 grossBet = _betAmount(tier);
require(msg.value == grossBet * creditsCount, "bad eth");
creditsByTier[msg.sender][tier] += creditsCount;
emit CreditsPurchased(msg.sender, tier, creditsCount, msg.value);
}
/// @notice Deprecated fixed-bet credit buyer.
function buyCredits(uint256 /*creditsCount*/ ) external payable nonReentrant {
revert DeprecatedEndpoint();
}
function fund() external payable {}
function withdraw(uint256 amount) external onlyOwner nonReentrant {
if (amount > address(this).balance - pendingExposure) revert WithdrawExceedsFreeBalance();
(bool ok, ) = payable(owner()).call{value: amount}("");
if (!ok) revert TransferFailed();
}
// ----------- UUPS Auth -----------
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
function withdrawOwed() external nonReentrant {
uint256 amt = pendingOwed[msg.sender];
require(amt > 0, "nothing owed");
pendingOwed[msg.sender] = 0;
(bool ok, ) = payable(msg.sender).call{value: amt}("");
require(ok, "withdraw failed");
}
// ----------- Views -----------
function isRequestActive(uint256 requestId) external view returns (bool) {
return requests[requestId].active;
}
function getRequestInfo(uint256 requestId)
external
view
returns (address player, uint256 netBet, uint64 createdAt, bool active, bool usedCredit, uint8 tier)
{
Request memory r = requests[requestId];
return (r.player, uint256(r.netBet), r.timestamp, r.active, r.usedCredit, r.tier);
}
function getActiveCount() external view returns (uint256) {
return activeIds.length;
}
function getActiveSlice(uint256 offset, uint256 size) external view returns (uint256[] memory ids) {
uint256 n = activeIds.length;
if (offset >= n) return new uint256[](0);
uint256 end = offset + size;
if (end > n) end = n;
uint256 outLen = end - offset;
ids = new uint256[](outLen);
for (uint256 i = 0; i < outLen; i++) {
ids[i] = activeIds[offset + i];
}
return ids;
}
// ----------- Internals -----------
function _addActive(uint256 id) internal {
activeIds.push(id);
activeIndex[id] = activeIds.length; // 1-based
}
function _removeActive(uint256 id) internal {
uint256 idx1 = activeIndex[id];
if (idx1 == 0) return; // already removed
uint256 i = idx1 - 1;
uint256 last = activeIds[activeIds.length - 1];
activeIds[i] = last;
activeIndex[last] = i + 1;
activeIds.pop();
delete activeIndex[id];
}
function _payMul(uint256 bet, uint256 bps) internal pure returns (uint256) {
return (bet * bps) / 10_000;
}
function _netBet(uint256 grossBet) internal view returns (uint256) {
uint256 fee = (grossBet * feeBps) / 10_000;
return grossBet - fee;
}
function _betAmount(uint8 tier) internal pure returns (uint256) {
if (tier == 0) return BET_TIER0;
if (tier == 1) return BET_TIER1;
if (tier == 2) return BET_TIER2;
revert InvalidTier();
}
function _maxMultForTier(uint8 tier) internal pure returns (uint256) {
if (tier == 0) return MAX_MULT_T0;
if (tier == 1) return MAX_MULT_T1;
if (tier == 2) return MAX_MULT_T2;
revert InvalidTier();
}
// Payouts with RTP scaling and hard cap at base tier max
function _calculatePayout(uint8 tier, uint256[5] memory reels, uint256 bet) internal pure returns (uint256) {
uint256 raw = _basePayoutLogic(tier, reels, bet);
uint256 adjBps = (tier == 0) ? RTP_BPS_T0 : (tier == 1) ? RTP_BPS_T1 : RTP_BPS_T2;
uint256 scaled = (raw * adjBps) / 10_000;
uint256 cap = bet * _maxMultForTier(tier);
if (scaled > cap) scaled = cap;
return scaled;
}
// ceil(maxMult * adjBps / 10_000) used for reserve accounting
function _effectiveMaxMult(uint8 tier) internal pure returns (uint256) {
uint256 base = _maxMultForTier(tier);
uint256 adjBps = (tier == 0) ? RTP_BPS_T0 : (tier == 1) ? RTP_BPS_T1 : RTP_BPS_T2;
return (base * adjBps + 9_999) / 10_000; // ceil division
}
function _basePayoutLogic(uint8 tier, uint256[5] memory reels, uint256 bet) internal pure returns (uint256) {
uint256 maxMult = (tier == 0) ? MAX_MULT_T0 : (tier == 1) ? MAX_MULT_T1 : MAX_MULT_T2;
// Five 7s -> jackpot capped by tier
if (reels[0] == 7 && reels[1] == 7 && reels[2] == 7 && reels[3] == 7 && reels[4] == 7) {
return bet * maxMult;
}
// Five of a kind (not 7s) -> half of jackpot cap
if (_isFiveOfAKind(reels) && reels[0] != 7) {
return (bet * maxMult) / 2;
}
// 10x: Four of a kind (includes four 7s)
if (_isFourOfAKind(reels)) {
return bet * 10;
}
// 5x: Full house
if (_isFullHouse(reels)) {
return bet * 5;
}
// 3x: Three of a kind (or three 7s)
if (_isThreeOfAKind(reels)) {
return bet * 3;
}
// ~1.95x: Two pairs
if (_isTwoPairs(reels)) {
return _payMul(bet, TWO_PAIRS_PAYOUT_BPS);
}
// 1x: One pair only if pair digit != 0
(bool hasPair, uint256 pairDigit) = _onePairDigit(reels);
if (hasPair && pairDigit != 0) {
return bet;
}
// 0x: No pay for sequential/straight or no hand
return 0;
}
function _isFiveOfAKind(uint256[5] memory reels) internal pure returns (bool) {
return reels[0] == reels[1] && reels[1] == reels[2] && reels[2] == reels[3] && reels[3] == reels[4];
}
function _isFourOfAKind(uint256[5] memory reels) internal pure returns (bool) {
uint256[10] memory counts;
for (uint256 i = 0; i < 5; i++) counts[reels[i]]++;
for (uint256 i = 0; i < 10; i++) if (counts[i] == 4) return true;
return false;
}
function _isFullHouse(uint256[5] memory reels) internal pure returns (bool) {
uint256[10] memory counts;
for (uint256 i = 0; i < 5; i++) counts[reels[i]]++;
bool hasThree = false;
bool hasTwo = false;
for (uint256 i = 0; i < 10; i++) {
if (counts[i] == 3) hasThree = true;
if (counts[i] == 2) hasTwo = true;
}
return hasThree && hasTwo;
}
function _isThreeOfAKind(uint256[5] memory reels) internal pure returns (bool) {
uint256[10] memory counts;
for (uint256 i = 0; i < 5; i++) counts[reels[i]]++;
for (uint256 i = 0; i < 10; i++) if (counts[i] == 3) return true;
return false;
}
function _isTwoPairs(uint256[5] memory reels) internal pure returns (bool) {
uint256[10] memory counts;
for (uint256 i = 0; i < 5; i++) counts[reels[i]]++;
uint256 pairs = 0;
for (uint256 i = 0; i < 10; i++) if (counts[i] == 2) pairs++;
return pairs == 2;
}
function _onePairDigit(uint256[5] memory reels) internal pure returns (bool hasPair, uint256 pairDigit) {
uint256[10] memory counts;
for (uint256 i = 0; i < 5; i++) counts[reels[i]]++;
uint256 pairs = 0;
uint256 digit = 0;
for (uint256 i = 0; i < 10; i++) {
if (counts[i] == 2) {
pairs++;
digit = i;
if (pairs > 1) break;
} else if (counts[i] > 2) {
// not a one-pair hand if we have trips, quads, or five-kind
return (false, 0);
}
}
if (pairs == 1) {
return (true, digit);
}
return (false, 0);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* 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 OwnableUpgradeable is Initializable, ContextUpgradeable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal onlyInitializing {
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal onlyInitializing {
_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);
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)
pragma solidity ^0.8.0;
/**
* @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
* proxy whose upgrades are fully controlled by the current implementation.
*/
interface IERC1822ProxiableUpgradeable {
/**
* @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
* address.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy.
*/
function proxiableUUID() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)
pragma solidity ^0.8.0;
/**
* @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.
*
* _Available since v4.8.3._
*/
interface IERC1967Upgradeable {
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Emitted when the beacon is changed.
*/
event BeaconUpgraded(address indexed beacon);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)
pragma solidity ^0.8.0;
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeaconUpgradeable {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {BeaconProxy} will check that this address is a contract.
*/
function implementation() external view returns (address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)
pragma solidity ^0.8.2;
import "../beacon/IBeaconUpgradeable.sol";
import "../../interfaces/IERC1967Upgradeable.sol";
import "../../interfaces/draft-IERC1822Upgradeable.sol";
import "../../utils/AddressUpgradeable.sol";
import "../../utils/StorageSlotUpgradeable.sol";
import {Initializable} from "../utils/Initializable.sol";
/**
* @dev This abstract contract provides getters and event emitting update functions for
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
*
* _Available since v4.1._
*/
abstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {
// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
function __ERC1967Upgrade_init() internal onlyInitializing {
}
function __ERC1967Upgrade_init_unchained() internal onlyInitializing {
}
/**
* @dev Returns the current implementation address.
*/
function _getImplementation() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract");
StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
}
/**
* @dev Perform implementation upgrade
*
* Emits an {Upgraded} event.
*/
function _upgradeTo(address newImplementation) internal {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
/**
* @dev Perform implementation upgrade with additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {
_upgradeTo(newImplementation);
if (data.length > 0 || forceCall) {
AddressUpgradeable.functionDelegateCall(newImplementation, data);
}
}
/**
* @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {
// Upgrades from old implementations will perform a rollback test. This test requires the new
// implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing
// this special case will break upgrade paths from old UUPS implementation to new ones.
if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {
_setImplementation(newImplementation);
} else {
try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {
require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID");
} catch {
revert("ERC1967Upgrade: new implementation is not UUPS");
}
_upgradeToAndCall(newImplementation, data, forceCall);
}
}
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Returns the current admin.
*/
function _getAdmin() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
require(newAdmin != address(0), "ERC1967: new admin is the zero address");
StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {AdminChanged} event.
*/
function _changeAdmin(address newAdmin) internal {
emit AdminChanged(_getAdmin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
* This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
*/
bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
/**
* @dev Returns the current beacon.
*/
function _getBeacon() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;
}
/**
* @dev Stores a new beacon in the EIP1967 beacon slot.
*/
function _setBeacon(address newBeacon) private {
require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract");
require(
AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),
"ERC1967: beacon implementation is not a contract"
);
StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;
}
/**
* @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
* not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
*
* Emits a {BeaconUpgraded} event.
*/
function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {
_setBeacon(newBeacon);
emit BeaconUpgraded(newBeacon);
if (data.length > 0 || forceCall) {
AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);
}
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.2;
import "../../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: setting the version to 255 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized != type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)
pragma solidity ^0.8.0;
import "../../interfaces/draft-IERC1822Upgradeable.sol";
import "../ERC1967/ERC1967UpgradeUpgradeable.sol";
import {Initializable} from "./Initializable.sol";
/**
* @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
* {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
*
* A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
* reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
* `UUPSUpgradeable` with a custom implementation of upgrades.
*
* The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
*
* _Available since v4.1._
*/
abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
address private immutable __self = address(this);
/**
* @dev Check that the execution is being performed through a delegatecall call and that the execution context is
* a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
* for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
* function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
* fail.
*/
modifier onlyProxy() {
require(address(this) != __self, "Function must be called through delegatecall");
require(_getImplementation() == __self, "Function must be called through active proxy");
_;
}
/**
* @dev Check that the execution is not being performed through a delegate call. This allows a function to be
* callable on the implementing contract but not through proxies.
*/
modifier notDelegated() {
require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall");
_;
}
function __UUPSUpgradeable_init() internal onlyInitializing {
}
function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
}
/**
* @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
* implementation. It is used to validate the implementation's compatibility when performing an upgrade.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
*/
function proxiableUUID() external view virtual override notDelegated returns (bytes32) {
return _IMPLEMENTATION_SLOT;
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*
* @custom:oz-upgrades-unsafe-allow-reachable delegatecall
*/
function upgradeTo(address newImplementation) public virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, new bytes(0), false);
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
* encoded in `data`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*
* @custom:oz-upgrades-unsafe-allow-reachable delegatecall
*/
function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, data, true);
}
/**
* @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
* {upgradeTo} and {upgradeToAndCall}.
*
* Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
*
* ```solidity
* function _authorizeUpgrade(address) internal override onlyOwner {}
* ```
*/
function _authorizeUpgrade(address newImplementation) internal virtual;
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuardUpgradeable is Initializable {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
function __ReentrancyGuard_init() internal onlyInitializing {
__ReentrancyGuard_init_unchained();
}
function __ReentrancyGuard_init_unchained() internal onlyInitializing {
_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;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
// 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 AddressUpgradeable {
/**
* @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);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
pragma solidity ^0.8.0;
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
pragma solidity ^0.8.0;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC1967 implementation slot:
* ```solidity
* contract ERC1967 {
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*
* _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._
* _Available since v4.9 for `string`, `bytes`._
*/
library StorageSlotUpgradeable {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
struct StringSlot {
string value;
}
struct BytesSlot {
bytes value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` with member `value` located at `slot`.
*/
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` representation of the string storage pointer `store`.
*/
function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
/**
* @dev Returns an `BytesSlot` with member `value` located at `slot`.
*/
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
*/
function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1967.sol)
pragma solidity >=0.4.11;
/**
* @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.
*/
interface IERC1967 {
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Emitted when the beacon is changed.
*/
event BeaconUpgraded(address indexed beacon);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (proxy/beacon/IBeacon.sol)
pragma solidity >=0.4.16;
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeacon {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {UpgradeableBeacon} will check that this address is a contract.
*/
function implementation() external view returns (address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.2.0) (proxy/ERC1967/ERC1967Proxy.sol)
pragma solidity ^0.8.22;
import {Proxy} from "../Proxy.sol";
import {ERC1967Utils} from "./ERC1967Utils.sol";
/**
* @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
* implementation address that can be changed. This address is stored in storage in the location specified by
* https://eips.ethereum.org/EIPS/eip-1967[ERC-1967], so that it doesn't conflict with the storage layout of the
* implementation behind the proxy.
*/
contract ERC1967Proxy is Proxy {
/**
* @dev Initializes the upgradeable proxy with an initial implementation specified by `implementation`.
*
* If `_data` is nonempty, it's used as data in a delegate call to `implementation`. This will typically be an
* encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.
*
* Requirements:
*
* - If `data` is empty, `msg.value` must be zero.
*/
constructor(address implementation, bytes memory _data) payable {
ERC1967Utils.upgradeToAndCall(implementation, _data);
}
/**
* @dev Returns the current implementation address.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using
* the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`
*/
function _implementation() internal view virtual override returns (address) {
return ERC1967Utils.getImplementation();
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (proxy/ERC1967/ERC1967Utils.sol)
pragma solidity ^0.8.21;
import {IBeacon} from "../beacon/IBeacon.sol";
import {IERC1967} from "../../interfaces/IERC1967.sol";
import {Address} from "../../utils/Address.sol";
import {StorageSlot} from "../../utils/StorageSlot.sol";
/**
* @dev This library provides getters and event emitting update functions for
* https://eips.ethereum.org/EIPS/eip-1967[ERC-1967] slots.
*/
library ERC1967Utils {
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1.
*/
// solhint-disable-next-line private-vars-leading-underscore
bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev The `implementation` of the proxy is invalid.
*/
error ERC1967InvalidImplementation(address implementation);
/**
* @dev The `admin` of the proxy is invalid.
*/
error ERC1967InvalidAdmin(address admin);
/**
* @dev The `beacon` of the proxy is invalid.
*/
error ERC1967InvalidBeacon(address beacon);
/**
* @dev An upgrade function sees `msg.value > 0` that may be lost.
*/
error ERC1967NonPayable();
/**
* @dev Returns the current implementation address.
*/
function getImplementation() internal view returns (address) {
return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;
}
/**
* @dev Stores a new address in the ERC-1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
if (newImplementation.code.length == 0) {
revert ERC1967InvalidImplementation(newImplementation);
}
StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;
}
/**
* @dev Performs implementation upgrade with additional setup call if data is nonempty.
* This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
* to avoid stuck value in the contract.
*
* Emits an {IERC1967-Upgraded} event.
*/
function upgradeToAndCall(address newImplementation, bytes memory data) internal {
_setImplementation(newImplementation);
emit IERC1967.Upgraded(newImplementation);
if (data.length > 0) {
Address.functionDelegateCall(newImplementation, data);
} else {
_checkNonPayable();
}
}
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1.
*/
// solhint-disable-next-line private-vars-leading-underscore
bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Returns the current admin.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using
* the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
*/
function getAdmin() internal view returns (address) {
return StorageSlot.getAddressSlot(ADMIN_SLOT).value;
}
/**
* @dev Stores a new address in the ERC-1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
if (newAdmin == address(0)) {
revert ERC1967InvalidAdmin(address(0));
}
StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {IERC1967-AdminChanged} event.
*/
function changeAdmin(address newAdmin) internal {
emit IERC1967.AdminChanged(getAdmin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
* This is the keccak-256 hash of "eip1967.proxy.beacon" subtracted by 1.
*/
// solhint-disable-next-line private-vars-leading-underscore
bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
/**
* @dev Returns the current beacon.
*/
function getBeacon() internal view returns (address) {
return StorageSlot.getAddressSlot(BEACON_SLOT).value;
}
/**
* @dev Stores a new beacon in the ERC-1967 beacon slot.
*/
function _setBeacon(address newBeacon) private {
if (newBeacon.code.length == 0) {
revert ERC1967InvalidBeacon(newBeacon);
}
StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;
address beaconImplementation = IBeacon(newBeacon).implementation();
if (beaconImplementation.code.length == 0) {
revert ERC1967InvalidImplementation(beaconImplementation);
}
}
/**
* @dev Change the beacon and trigger a setup call if data is nonempty.
* This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
* to avoid stuck value in the contract.
*
* Emits an {IERC1967-BeaconUpgraded} event.
*
* CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since
* it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for
* efficiency.
*/
function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {
_setBeacon(newBeacon);
emit IERC1967.BeaconUpgraded(newBeacon);
if (data.length > 0) {
Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
} else {
_checkNonPayable();
}
}
/**
* @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract
* if an upgrade doesn't perform an initialization call.
*/
function _checkNonPayable() private {
if (msg.value > 0) {
revert ERC1967NonPayable();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/Proxy.sol)
pragma solidity ^0.8.20;
/**
* @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
* instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
* be specified by overriding the virtual {_implementation} function.
*
* Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
* different contract through the {_delegate} function.
*
* The success and return data of the delegated call will be returned back to the caller of the proxy.
*/
abstract contract Proxy {
/**
* @dev Delegates the current call to `implementation`.
*
* This function does not return to its internal call site, it will return directly to the external caller.
*/
function _delegate(address implementation) internal virtual {
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize())
// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
// Copy the returned data.
returndatacopy(0, 0, returndatasize())
switch result
// delegatecall returns 0 on error.
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
/**
* @dev This is a virtual function that should be overridden so it returns the address to which the fallback
* function and {_fallback} should delegate.
*/
function _implementation() internal view virtual returns (address);
/**
* @dev Delegates the current call to the address returned by `_implementation()`.
*
* This function does not return to its internal call site, it will return directly to the external caller.
*/
function _fallback() internal virtual {
_delegate(_implementation());
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
* function in the contract matches the call data.
*/
fallback() external payable virtual {
_fallback();
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/Address.sol)
pragma solidity ^0.8.20;
import {Errors} from "./Errors.sol";
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert Errors.InsufficientBalance(address(this).balance, amount);
}
(bool success, bytes memory returndata) = recipient.call{value: amount}("");
if (!success) {
_revert(returndata);
}
}
/**
* @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 or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {Errors.FailedCall} error.
*
* 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.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @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`.
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert Errors.InsufficientBalance(address(this).balance, value);
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case
* of an unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {Errors.FailedCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}.
*/
function _revert(bytes memory returndata) 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
assembly ("memory-safe") {
revert(add(returndata, 0x20), mload(returndata))
}
} else {
revert Errors.FailedCall();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of common custom errors used in multiple contracts
*
* IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.
* It is recommended to avoid relying on the error API for critical functionality.
*
* _Available since v5.1._
*/
library Errors {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error InsufficientBalance(uint256 balance, uint256 needed);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedCall();
/**
* @dev The deployment failed.
*/
error FailedDeployment();
/**
* @dev A necessary precompile is missing.
*/
error MissingPrecompile(address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
pragma solidity ^0.8.20;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC-1967 implementation slot:
* ```solidity
* contract ERC1967 {
* // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(newImplementation.code.length > 0);
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*
* TIP: Consider using this library along with {SlotDerivation}.
*/
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
struct Int256Slot {
int256 value;
}
struct StringSlot {
string value;
}
struct BytesSlot {
bytes value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `Int256Slot` with member `value` located at `slot`.
*/
function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `StringSlot` with member `value` located at `slot`.
*/
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` representation of the string storage pointer `store`.
*/
function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
assembly ("memory-safe") {
r.slot := store.slot
}
}
/**
* @dev Returns a `BytesSlot` with member `value` located at `slot`.
*/
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
*/
function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
assembly ("memory-safe") {
r.slot := store.slot
}
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.28;
contract Counter {
uint public x;
event Increment(uint by);
function inc() public {
x++;
emit Increment(1);
}
function incBy(uint by) public {
require(by > 0, "incBy: increment should be positive");
x += by;
emit Increment(by);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title IBLS
* @notice Interface for the BLSVerifier contract
*/
interface IBLS {
function isValidSignature(
uint256[2] calldata sig
) external view returns (bool);
function verifySingle(
uint256[2] calldata sig,
uint256[4] calldata pk,
uint256[2] calldata message
) external view returns (bool ok, bool callSuccess);
function hashToPoint(
bytes calldata dst,
bytes calldata msgBytes
) external view returns (uint256[2] memory);
}
abstract contract VRFConsumerBase {
function rawFulfillRandomness(
uint256 requestId,
bytes32 randomness
) external virtual;
}
/**
* @title DrandVRF_Split
* @notice Lightweight VRF contract that delegates BLS operations to BLSVerifier
* @dev This split architecture allows deployment within HyperEVM's small block limits
* while keeping round calculation on-chain (no client-side round computation)
*/
contract DrandVRF_Split {
event RandomnessRequested(
uint256 indexed id,
address indexed requester,
uint64 round,
uint256 deadline,
bytes32 salt
);
event RandomnessFulfilled(
uint256 indexed id,
uint64 round,
bytes32 randomness
);
event BeaconUpdated(uint256[4] pubkey, uint256 genesisTime, uint256 period);
// ----- Errors -----
error InvalidPublicKey(uint256[4] pubkey);
error InvalidSignature(
uint256[4] pubkey,
uint256[2] message,
uint256[2] sig
);
error TooEarly(uint64 round, uint256 notBefore);
error AlreadyFulfilled(uint256 id);
error BadRound(uint64 provided, uint64 expectedMin);
error RequestNotFound(uint256 id);
// ----- BLS Verifier (immutable to avoid SLOAD) -----
IBLS public immutable bls;
// ----- Beacon config (all immutable to avoid SLOADs) -----
// Store G2 pubkey as 4 immutables; reconstruct the array on demand.
uint256 public immutable P0;
uint256 public immutable P1;
uint256 public immutable P2;
uint256 public immutable P3;
function DRAND_PUBKEY() public view returns (uint256[4] memory k) {
k[0] = P0;
k[1] = P1;
k[2] = P2;
k[3] = P3;
}
uint64 public immutable GENESIS_TIME;
uint64 public immutable PERIOD;
bytes public constant DST =
bytes("BLS_SIG_BN254G1_XMD:KECCAK-256_SVDW_RO_NUL_");
struct Request {
// pack small fields first to reduce slots
uint64 deadline; // unix ts
uint64 minRound; // from deadline
bool fulfilled; // 1 byte
address requester; // 20 bytes
address callback; // 20 bytes
bytes32 salt; // 32 bytes
bytes32 randomness; // 32 bytes
}
uint256 public lastId;
mapping(uint256 => Request) public requests;
/**
* @notice Constructor
* @param blsVerifier Address of the BLSVerifier contract
* @param pubkey The drand beacon's G2 public key
* @param genesisTime Unix timestamp of the beacon's genesis
* @param period Seconds between beacon rounds
*/
constructor(
address blsVerifier,
uint256[4] memory pubkey,
uint256 genesisTime,
uint256 period
) {
// Store BLS verifier address
bls = IBLS(blsVerifier);
// SKIP BLS validation to save ~800k gas
// Pubkey pre-validated off-chain: isValidPublicKey returns true
// if (!bls.isValidPublicKey(pubkey)) revert InvalidPublicKey(pubkey);
P0 = pubkey[0];
P1 = pubkey[1];
P2 = pubkey[2];
P3 = pubkey[3];
GENESIS_TIME = uint64(genesisTime);
PERIOD = uint64(period);
emit BeaconUpdated(pubkey, genesisTime, period);
}
// ----- Public: request -----
function requestRandomness(
uint256 deadline,
bytes32 salt,
address consumer
) external returns (uint256 id) {
uint64 round = _roundFromDeadline(deadline);
unchecked {
id = ++lastId;
}
Request storage r = requests[id];
r.deadline = uint64(deadline);
r.minRound = round;
r.fulfilled = false;
r.requester = msg.sender;
r.callback = consumer;
r.salt = salt;
r.randomness = bytes32(0);
emit RandomnessRequested(id, msg.sender, round, deadline, salt);
}
// ----- Public: fulfill -----
function fulfillRandomness(
uint256 id,
uint64 round,
uint256[2] calldata signature
) external {
Request storage r = requests[id];
if (r.requester == address(0)) revert RequestNotFound(id);
if (r.fulfilled) revert AlreadyFulfilled(id);
if (round < r.minRound) revert BadRound(round, r.minRound);
uint256 notBefore = uint256(GENESIS_TIME) +
uint256(round - 1) *
uint256(PERIOD);
// small +1s jitter retained as in your version
if (block.timestamp + 1 < notBefore) revert TooEarly(round, notBefore);
// message = hashToPoint(DST, keccak(last 8 bytes of round))
uint256[2] memory message = _hashRoundToPoint(round);
// G1 sanity then pairing verify (delegated to BLSVerifier)
if (!bls.isValidSignature(signature)) {
revert InvalidSignature(DRAND_PUBKEY(), message, signature);
}
(bool ok, bool callSuccess) = bls.verifySingle(
signature,
DRAND_PUBKEY(),
message
);
if (!callSuccess || !ok) {
revert InvalidSignature(DRAND_PUBKEY(), message, signature);
}
bytes32 randomness = keccak256(
abi.encode(
signature,
id,
r.requester,
block.chainid,
address(this),
r.salt
)
);
r.fulfilled = true;
r.randomness = randomness;
if (r.callback != address(0)) {
VRFConsumerBase(r.callback).rawFulfillRandomness(id, randomness);
}
emit RandomnessFulfilled(id, round, randomness);
}
// ----- Views & helpers -----
function getRequest(uint256 id) external view returns (Request memory) {
return requests[id];
}
function minRoundFromDeadline(
uint256 deadline
) external view returns (uint64) {
return _roundFromDeadline(deadline);
}
function _hashRoundToPoint(
uint64 round
) internal view returns (uint256[2] memory message) {
bytes memory hashed = new bytes(32);
assembly {
mstore(0x00, round)
let digest := keccak256(0x18, 0x08) // last 8 bytes
mstore(add(0x20, hashed), digest)
}
// Delegate to BLSVerifier for hash-to-point operation
message = bls.hashToPoint(DST, hashed);
}
function _roundFromDeadline(
uint256 deadline
) internal view returns (uint64) {
uint64 g = GENESIS_TIME;
if (deadline <= g) return 1;
uint256 delta = deadline - g;
uint64 whole = uint64(delta / PERIOD);
return whole + (delta % PERIOD > 0 ? 1 : 0);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "./DRandVRF_Split.sol"; // for VRFConsumerBase type
interface IVRFMinimal {
function requestRandomness() external returns (uint256 requestId);
}
interface ISlotMachine5Like {
function fulfillRandomness(
uint256 requestId,
uint256 rand,
uint256 randomnessRound
) external;
}
interface IDrandVRFSplitLike {
function requestRandomness(
uint256 deadline,
bytes32 salt,
address consumer
) external returns (uint256 id);
function minRoundFromDeadline(uint256 deadline) external view returns (uint64);
}
/**
* @title DrandVRFAdapter
* @notice Bridges DRandVRF_Split to SlotMachine5's IVRF interface.
* @dev Acts as the VRF for SlotMachine5: forwards requests to DRandVRF_Split and
* receives the callback, then calls SlotMachine5.fulfillRandomness.
*/
contract DrandVRFAdapter is VRFConsumerBase, IVRFMinimal {
IDrandVRFSplitLike public immutable drand;
address public immutable slot; // SlotMachine5 instance expecting IVRF
// Optional: store a round hint derived from the request's deadline
mapping(uint256 => uint64) public requestIdToMinRound;
constructor(address drandAddress, address slotAddress) {
require(drandAddress != address(0), "drand=0");
require(slotAddress != address(0), "slot=0");
drand = IDrandVRFSplitLike(drandAddress);
slot = slotAddress;
}
/**
* @notice Called by SlotMachine5 to request randomness.
* @dev Enforces only slot can request; returns DRand request id.
*/
function requestRandomness() external returns (uint256 requestId) {
require(msg.sender == slot, "only slot");
// Use current timestamp as deadline; fulfiller must wait until valid round
uint256 deadline = block.timestamp;
bytes32 salt = keccak256(
abi.encodePacked(blockhash(block.number - 1), msg.sender, address(this))
);
// Compute a round hint to surface in SlotMachine5 events later
uint64 minRound = drand.minRoundFromDeadline(deadline);
requestId = drand.requestRandomness(deadline, salt, address(this));
requestIdToMinRound[requestId] = minRound;
}
/**
* @notice DRandVRF_Split callback entrypoint.
* @dev Restrict to drand; forward to SlotMachine5 with uint256(rand) and stored round hint.
*/
function rawFulfillRandomness(
uint256 requestId,
bytes32 randomness
) external override {
require(msg.sender == address(drand), "only drand");
uint256 rand = uint256(randomness);
uint256 roundHint = uint256(requestIdToMinRound[requestId]);
// cleanup
if (requestIdToMinRound[requestId] != 0) {
delete requestIdToMinRound[requestId];
}
ISlotMachine5Like(slot).fulfillRandomness(requestId, rand, roundHint);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import { ERC1967Proxy } from "npm/@openzeppelin/[email protected]/proxy/ERC1967/ERC1967Proxy.sol";
/// @notice Minimal ERC1967 proxy for UUPS implementations.
/// Uses constructor (implementation, initData) as expected by tests.
contract HypesinoV2Proxy is ERC1967Proxy {
constructor(address implementation, bytes memory initData)
ERC1967Proxy(implementation, initData)
{}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IVRFMinimal {
function requestRandomness() external returns (uint256 requestId);
}
interface IHypesinoV2CallbackTarget {
function fulfillRandomness(uint256 requestId, uint256 rand, uint256 randomnessRound) external;
}
// Simple mock VRF that returns incremental request ids and can call back into a target.
contract MockVRF is IVRFMinimal {
uint256 public nextId = 1;
uint256 public forcedId; // if non-zero, will be used as the next id once
function setForcedId(uint256 id) external {
forcedId = id;
}
function requestRandomness() external returns (uint256 requestId) {
if (forcedId != 0) {
requestId = forcedId;
forcedId = 0;
} else {
requestId = nextId;
unchecked {
nextId = nextId + 1;
}
}
}
function fulfill(address target, uint256 requestId, uint256 rand, uint256 randomnessRound) external {
// This external call makes msg.sender == address(this) in the target,
// which allows testing onlyVRF gating in the Hypesino contract.
IHypesinoV2CallbackTarget(target).fulfillRandomness(requestId, rand, randomnessRound);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract RevertingReceiver {
error AlwaysRevert();
receive() external payable {
revert AlwaysRevert();
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface ISpinTarget {
function spin(uint8 tier) external payable;
}
contract SpinCallerRevertOnReceive {
error PayoutRejected();
function playSpin(address target) external payable {
ISpinTarget(target).spin{value: msg.value}(0);
}
receive() external payable {
revert PayoutRejected();
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import { HypesinoV2 } from "../HypesinoV2.sol";
contract TestHypesinoV2 is HypesinoV2 {
function testCalculatePayout(uint8 tier, uint256[5] calldata reels, uint256 bet) external pure returns (uint256) {
return _calculatePayout(tier, reels, bet);
}
}{
"evmVersion": "cancun",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BadBet","type":"error"},{"inputs":[],"name":"BankrollTooLow","type":"error"},{"inputs":[],"name":"DeprecatedEndpoint","type":"error"},{"inputs":[],"name":"DuplicateRequest","type":"error"},{"inputs":[],"name":"InvalidTier","type":"error"},{"inputs":[],"name":"NoSuchRequest","type":"error"},{"inputs":[],"name":"NotAuthorized","type":"error"},{"inputs":[],"name":"NotOwner","type":"error"},{"inputs":[],"name":"OnlyVRF","type":"error"},{"inputs":[],"name":"TooEarly","type":"error"},{"inputs":[],"name":"TooManyActiveRequests","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"WithdrawExceedsFreeBalance","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"credits","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"CreditsPurchased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFeeBps","type":"uint256"}],"name":"FeeBpsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFixedBet","type":"uint256"}],"name":"FixedBetUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMaxActiveRequests","type":"uint256"}],"name":"MaxActiveRequestsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdated","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":[{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PayoutDeferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"uint256","name":"netBet","type":"uint256"}],"name":"SpinCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"grossBet","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"netBet","type":"uint256"}],"name":"SpinRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"uint256","name":"bet","type":"uint256"},{"indexed":false,"internalType":"uint256[5]","name":"reels","type":"uint256[5]"},{"indexed":false,"internalType":"uint256","name":"payout","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"randomnessRound","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"tier","type":"uint8"}],"name":"SpinResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newVrf","type":"address"}],"name":"VrfUpdated","type":"event"},{"inputs":[],"name":"BET_TIER0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BET_TIER1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BET_TIER2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CANCEL_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FIXED_BET","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_MULT_T0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_MULT_T1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_MULT_T2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PLAYER_CANCEL_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RTP_BPS_T0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RTP_BPS_T1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RTP_BPS_T2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TWO_PAIRS_PAYOUT_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accumulatedFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"buyCredits","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"uint256","name":"creditsCount","type":"uint256"}],"name":"buyCredits","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"cancelRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"credits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint8","name":"","type":"uint8"}],"name":"creditsByTier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeBps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"uint256","name":"rand","type":"uint256"},{"internalType":"uint256","name":"randomnessRound","type":"uint256"}],"name":"fulfillRandomness","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fund","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"getActiveCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"offset","type":"uint256"},{"internalType":"uint256","name":"size","type":"uint256"}],"name":"getActiveSlice","outputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"getRequestInfo","outputs":[{"internalType":"address","name":"player","type":"address"},{"internalType":"uint256","name":"netBet","type":"uint256"},{"internalType":"uint64","name":"createdAt","type":"uint64"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"bool","name":"usedCredit","type":"bool"},{"internalType":"uint8","name":"tier","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"vrfAddr","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"isRequestActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxActiveRequests","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingExposure","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pendingOwed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"requests","outputs":[{"internalType":"address","name":"player","type":"address"},{"internalType":"uint128","name":"netBet","type":"uint128"},{"internalType":"uint64","name":"timestamp","type":"uint64"},{"internalType":"bool","name":"usedCredit","type":"bool"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"tier","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFeeBps","type":"uint256"}],"name":"setFeeBps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFixedBet","type":"uint256"}],"name":"setFixedBet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMax","type":"uint256"}],"name":"setMaxActiveRequests","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newVrf","type":"address"}],"name":"setVrf","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"tier","type":"uint8"}],"name":"spin","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"spin","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"spinWithCredit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"tier","type":"uint8"}],"name":"spinWithCredit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"vrf","outputs":[{"internalType":"contract IVRF","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawOwed","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60a06040523073ffffffffffffffffffffffffffffffffffffffff1660809073ffffffffffffffffffffffffffffffffffffffff1681525066b1a2bc2ec5000060fc5560c860fd556101f460ff55348015610058575f5ffd5b5061006761006c60201b60201c565b6101fc565b5f60019054906101000a900460ff16156100bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100b2906101aa565b60405180910390fd5b60ff80165f5f9054906101000a900460ff1660ff16146101285760ff5f5f6101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff60405161011f91906101e3565b60405180910390a15b565b5f82825260208201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e6974695f8201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b5f61019460278361012a565b915061019f8261013a565b604082019050919050565b5f6020820190508181035f8301526101c181610188565b9050919050565b5f60ff82169050919050565b6101dd816101c8565b82525050565b5f6020820190506101f65f8301846101d4565b92915050565b608051615a286102305f395f81816117a70152818161183501528181611ab601528181611b440152611bf30152615a285ff3fe6080604052600436106102ad575f3560e01c806363338b1711610174578063b5deb024116100db578063e388048611610094578063ee0e1bb81161006e578063ee0e1bb8146109e1578063f0acd7d514610a09578063f2fde38b14610a13578063fe5ff46814610a3b576102ad565b8063e388048614610965578063e87284831461098f578063e8c18027146109b7576102ad565b8063b5deb0241461089f578063b60d4288146108c9578063c1302185146108d3578063c4d66de8146108e9578063c7e34a8614610911578063dc136f2e1461093b576102ad565b806388dc1cd11161012d57806388dc1cd1146107a35780638da5cb5b146107df5780639213f67c146108095780639750e3d8146108315780639dbc517b1461084d578063a8ae22b414610877576102ad565b806363338b17146106a857806364c54d60146106d2578063715018a6146106fa57806372c27b62146107105780637496c5a61461073857806381d12c5814610762576102ad565b80632dd85345116102185780634f1ef286116101d15780634f1ef2861461059657806352d1902d146105b257806354ebd9ba146105dc578063587f5ed7146106185780635a1c3833146106425780635c1b17621461067e576102ad565b80632dd85345146104b45780632e1a7d4d146104de5780633015394c146105065780633659cfe61461052e57806339a72c5c146105565780634724eddd1461056c576102ad565b8063186385701161026a57806318638570146103c6578063191fe9a0146103e2578063199e998a1461040c5780632147d5091461043657806324a9d85314610460578063291dda291461048a576102ad565b80630359a8a3146102b15780630b816045146102ed5780630c4dfe3f1461032e5780630c9490431461034a57806313af4035146103745780631574ac441461039c575b5f5ffd5b3480156102bc575f5ffd5b506102d760048036038101906102d291906144a9565b610a77565b6040516102e491906144ee565b60405180910390f35b3480156102f8575f5ffd5b50610313600480360381019061030e91906144a9565b610aa2565b60405161032596959493929190614592565b60405180910390f35b610348600480360381019061034391906144a9565b610c2f565b005b348015610355575f5ffd5b5061035e610c69565b60405161036b919061464c565b60405180910390f35b34801561037f575f5ffd5b5061039a6004803603810190610395919061468f565b610c8e565b005b3480156103a7575f5ffd5b506103b0610ce5565b6040516103bd91906146ba565b60405180910390f35b6103e060048036038101906103db91906146fd565b610ceb565b005b3480156103ed575f5ffd5b506103f6611132565b60405161040391906146ba565b60405180910390f35b348015610417575f5ffd5b50610420611138565b60405161042d91906146ba565b60405180910390f35b348015610441575f5ffd5b5061044a61113d565b60405161045791906146ba565b60405180910390f35b34801561046b575f5ffd5b50610474611143565b60405161048191906146ba565b60405180910390f35b348015610495575f5ffd5b5061049e611149565b6040516104ab91906146ba565b60405180910390f35b3480156104bf575f5ffd5b506104c8611155565b6040516104d591906146ba565b60405180910390f35b3480156104e9575f5ffd5b5061050460048036038101906104ff91906144a9565b61115b565b005b348015610511575f5ffd5b5061052c600480360381019061052791906144a9565b611265565b005b348015610539575f5ffd5b50610554600480360381019061054f919061468f565b6117a5565b005b348015610561575f5ffd5b5061056a61192b565b005b348015610577575f5ffd5b50610580611aae565b60405161058d91906146ba565b60405180910390f35b6105b060048036038101906105ab9190614864565b611ab4565b005b3480156105bd575f5ffd5b506105c6611bf0565b6040516105d391906148d6565b60405180910390f35b3480156105e7575f5ffd5b5061060260048036038101906105fd91906148ef565b611ca7565b60405161060f91906146ba565b60405180910390f35b348015610623575f5ffd5b5061062c611cc8565b60405161063991906146ba565b60405180910390f35b34801561064d575f5ffd5b506106686004803603810190610663919061492d565b611cce565b6040516106759190614a22565b60405180910390f35b348015610689575f5ffd5b50610692611e14565b60405161069f91906146ba565b60405180910390f35b3480156106b3575f5ffd5b506106bc611e19565b6040516106c991906146ba565b60405180910390f35b3480156106dd575f5ffd5b506106f860048036038101906106f3919061468f565b611e26565b005b348015610705575f5ffd5b5061070e611eb4565b005b34801561071b575f5ffd5b50610736600480360381019061073191906144a9565b611ec7565b005b348015610743575f5ffd5b5061074c611f55565b60405161075991906146ba565b60405180910390f35b34801561076d575f5ffd5b50610788600480360381019061078391906144a9565b611f5a565b60405161079a96959493929190614a6c565b60405180910390f35b3480156107ae575f5ffd5b506107c960048036038101906107c4919061468f565b612008565b6040516107d691906146ba565b60405180910390f35b3480156107ea575f5ffd5b506107f361201e565b6040516108009190614acb565b60405180910390f35b348015610814575f5ffd5b5061082f600480360381019061082a9190614ae4565b612046565b005b61084b60048036038101906108469190614b34565b612686565b005b348015610858575f5ffd5b506108616127f1565b60405161086e91906146ba565b60405180910390f35b348015610882575f5ffd5b5061089d600480360381019061089891906144a9565b6127f8565b005b3480156108aa575f5ffd5b506108b3612841565b6040516108c091906146ba565b60405180910390f35b6108d1612847565b005b3480156108de575f5ffd5b506108e7612849565b005b3480156108f4575f5ffd5b5061090f600480360381019061090a919061468f565b612883565b005b34801561091c575f5ffd5b50610925612a2e565b60405161093291906146ba565b60405180910390f35b348015610946575f5ffd5b5061094f612a3a565b60405161095c91906146ba565b60405180910390f35b348015610970575f5ffd5b50610979612a40565b60405161098691906146ba565b60405180910390f35b34801561099a575f5ffd5b506109b560048036038101906109b091906146fd565b612a4b565b005b3480156109c2575f5ffd5b506109cb613035565b6040516109d891906146ba565b60405180910390f35b3480156109ec575f5ffd5b50610a076004803603810190610a0291906144a9565b61303a565b005b610a116130c5565b005b348015610a1e575f5ffd5b50610a396004803603810190610a34919061468f565b6130ff565b005b348015610a46575f5ffd5b50610a616004803603810190610a5c919061468f565b613181565b604051610a6e91906146ba565b60405180910390f35b5f6101015f8381526020019081526020015f2060010160199054906101000a900460ff169050919050565b5f5f5f5f5f5f5f6101015f8981526020019081526020015f206040518060c00160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015f9054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016001820160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020016001820160189054906101000a900460ff161515151581526020016001820160199054906101000a900460ff1615151515815260200160018201601a9054906101000a900460ff1660ff1660ff16815250509050805f015181602001516fffffffffffffffffffffffffffffffff168260400151836080015184606001518560a001519650965096509650965096505091939550919395565b610c37613197565b6040517ff7d1257c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60fb5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610c966131f0565b610c9f8161326e565b8073ffffffffffffffffffffffffffffffffffffffff167f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b60405160405180910390a250565b60fc5481565b610cf3613197565b5f610cfd82613331565b9050803414610d38576040517f5509ca7300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f610d42826133b8565b90505f610d4e846133eb565b82610d599190614b9f565b61010054610d679190614be0565b905080471015610da3576040517fec5ec7ce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ff546101028054905010610de4576040517f53c034cf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60fb5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f8413b076040518163ffffffff1660e01b81526004016020604051808303815f875af1158015610e50573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e749190614c27565b90505f73ffffffffffffffffffffffffffffffffffffffff166101015f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610f0e576040517fe27d026d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040518060c001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff1681526020014267ffffffffffffffff1681526020015f151581526020016001151581526020018660ff168152506101015f8381526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015f6101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060408201518160010160106101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060608201518160010160186101000a81548160ff02191690831515021790555060808201518160010160196101000a81548160ff02191690831515021790555060a082015181600101601a6101000a81548160ff021916908360ff1602179055509050506110a581613454565b816101008190555082846110b99190614c52565b60fe5f8282546110c99190614be0565b92505081905550803373ffffffffffffffffffffffffffffffffffffffff167fcf3f5c404e572eb9b23fc829e0c3721aeb9c020a64e27d15fabbc091de3ad92787878760405161111b93929190614c85565b60405180910390a35050505061112f6131e6565b50565b61293681565b603281565b614c2c81565b60fd5481565b6706f05b59d3b2000081565b61012c81565b6111636131f0565b61116b613197565b610100544761117a9190614c52565b8111156111b3576040517f6df2b55c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6111bc61201e565b73ffffffffffffffffffffffffffffffffffffffff16826040516111df90614ce7565b5f6040518083038185875af1925050503d805f8114611219576040519150601f19603f3d011682016040523d82523d5f602084013e61121e565b606091505b5050905080611259576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506112626131e6565b50565b61126d613197565b5f6101015f8381526020019081526020015f206040518060c00160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015f9054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016001820160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020016001820160189054906101000a900460ff161515151581526020016001820160199054906101000a900460ff1615151515815260200160018201601a9054906101000a900460ff1660ff1660ff16815250509050806080015115806113ee57505f73ffffffffffffffffffffffffffffffffffffffff16815f015173ffffffffffffffffffffffffffffffffffffffff16145b15611425576040517fc423735200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61142d61201e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036114b857603c816040015167ffffffffffffffff1661147a9190614be0565b4210156114b3576040517f085de62500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61157b565b805f015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036115485761012c816040015167ffffffffffffffff1661150a9190614be0565b421015611543576040517f085de62500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61157a565b6040517fea8e4eb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5f6101015f8481526020019081526020015f2060010160196101000a81548160ff0219169083151502179055506115b18261349b565b6115be8160a001516133eb565b81602001516fffffffffffffffffffffffffffffffff166115df9190614b9f565b6101005f8282546115f09190614c52565b925050819055508060600151156116775760016101065f835f015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8360a0015160ff1660ff1681526020019081526020015f205f82825461166b9190614be0565b92505081905550611731565b5f815f015173ffffffffffffffffffffffffffffffffffffffff1682602001516fffffffffffffffffffffffffffffffff166040516116b590614ce7565b5f6040518083038185875af1925050503d805f81146116ef576040519150601f19603f3d011682016040523d82523d5f602084013e6116f4565b606091505b505090508061172f576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b805f015173ffffffffffffffffffffffffffffffffffffffff16827ff5b74e631bc000f4c9329ba0231ef5e4d23fb8db17bc3c43b1e893b17b42ddd683602001516fffffffffffffffffffffffffffffffff1660405161179191906146ba565b60405180910390a3506117a26131e6565b50565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1603611833576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182a90614d7b565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16611872613588565b73ffffffffffffffffffffffffffffffffffffffff16146118c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118bf90614e09565b60405180910390fd5b6118d1816135db565b611928815f67ffffffffffffffff8111156118ef576118ee614740565b5b6040519080825280601f01601f1916602001820160405280156119215781602001600182028036833780820191505090505b505f6135e6565b50565b611933613197565b5f6101055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490505f81116119b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119ae90614e71565b60405180910390fd5b5f6101055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055505f3373ffffffffffffffffffffffffffffffffffffffff1682604051611a1f90614ce7565b5f6040518083038185875af1925050503d805f8114611a59576040519150601f19603f3d011682016040523d82523d5f602084013e611a5e565b606091505b5050905080611aa2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9990614ed9565b60405180910390fd5b5050611aac6131e6565b565b60ff5481565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1603611b42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3990614d7b565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16611b81613588565b73ffffffffffffffffffffffffffffffffffffffff1614611bd7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bce90614e09565b60405180910390fd5b611be0826135db565b611bec828260016135e6565b5050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614611c7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7690614f67565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b905090565b610106602052815f5260405f20602052805f5260405f205f91509150505481565b60fe5481565b60605f610102805490509050808410611d32575f67ffffffffffffffff811115611cfb57611cfa614740565b5b604051908082528060200260200182016040528015611d295781602001602082028036833780820191505090505b50915050611e0e565b5f8385611d3f9190614be0565b905081811115611d4d578190505b5f8582611d5a9190614c52565b90508067ffffffffffffffff811115611d7657611d75614740565b5b604051908082528060200260200182016040528015611da45781602001602082028036833780820191505090505b5093505f5f90505b81811015611e09576101028188611dc39190614be0565b81548110611dd457611dd3614f85565b5b905f5260205f200154858281518110611df057611def614f85565b5b6020026020010181815250508080600101915050611dac565b505050505b92915050565b601981565b5f61010280549050905090565b611e2e6131f0565b8060fb5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f48909173584eb61f90468a9f46407141ac6d3ba091d2b9b487ac911bfd83b22d60405160405180910390a250565b611ebc6131f0565b611ec55f61326e565b565b611ecf6131f0565b6103e8811115611f14576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f0b90614ffc565b60405180910390fd5b8060fd819055507f0399aa81c69e33acc2ff42d0f7a0809e6bf4c10ff3c3a7e040b12fedc14602f281604051611f4a91906146ba565b60405180910390a150565b603c81565b610101602052805f5260405f205f91509050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001015f9054906101000a90046fffffffffffffffffffffffffffffffff16908060010160109054906101000a900467ffffffffffffffff16908060010160189054906101000a900460ff16908060010160199054906101000a900460ff169080600101601a9054906101000a900460ff16905086565b610105602052805f5260405f205f915090505481565b5f60975f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60fb5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146120cc576040517f60f6d5a800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120d4613197565b5f6101015f8581526020019081526020015f206040518060c00160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015f9054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016001820160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020016001820160189054906101000a900460ff161515151581526020016001820160199054906101000a900460ff1615151515815260200160018201601a9054906101000a900460ff1660ff1660ff168152505090508060800151158061225557505f73ffffffffffffffffffffffffffffffffffffffff16815f015173ffffffffffffffffffffffffffffffffffffffff16145b1561228c576040517fc423735200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6101015f8681526020019081526020015f2060010160196101000a81548160ff0219169083151502179055506122c28461349b565b6122cf8160a001516133eb565b81602001516fffffffffffffffffffffffffffffffff166122f09190614b9f565b6101005f8282546123019190614c52565b92505081905550612310614420565b600a845f60405160200161232592919061503a565b604051602081830303815290604052805190602001205f1c6123479190615092565b815f6005811061235a57612359614f85565b5b602002018181525050600a84600160405160200161237992919061503a565b604051602081830303815290604052805190602001205f1c61239b9190615092565b816001600581106123af576123ae614f85565b5b602002018181525050600a8460026040516020016123ce92919061503a565b604051602081830303815290604052805190602001205f1c6123f09190615092565b8160026005811061240457612403614f85565b5b602002018181525050600a84600360405160200161242392919061503a565b604051602081830303815290604052805190602001205f1c6124459190615092565b8160036005811061245957612458614f85565b5b602002018181525050600a84600460405160200161247892919061503a565b604051602081830303815290604052805190602001205f1c61249a9190615092565b816004600581106124ae576124ad614f85565b5b6020020181815250505f6124dd8360a001518385602001516fffffffffffffffffffffffffffffffff16613750565b90505f811115612602575f835f015173ffffffffffffffffffffffffffffffffffffffff168260405161250f90614ce7565b5f6040518083038185875af1925050503d805f8114612549576040519150601f19603f3d011682016040523d82523d5f602084013e61254e565b606091505b505090508061260057816101055f865f015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546125a79190614be0565b92505081905550835f015173ffffffffffffffffffffffffffffffffffffffff167f0e54be18cea4b7c02dcb455aa29944656f9f30fbb0ba328fe8a75d10e52511dd836040516125f791906146ba565b60405180910390a25b505b825f015173ffffffffffffffffffffffffffffffffffffffff16867fa43436eeaedcc7dcc28ba81074692578b4a610cd09431297dbae2d05903ca0d885602001516fffffffffffffffffffffffffffffffff168585898960a0015160405161266e959493929190615141565b60405180910390a35050506126816131e6565b505050565b61268e613197565b5f81116126d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c7906151de565b60405180910390fd5b5f6126da83613331565b905081816126e89190614b9f565b3414612729576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161272090615246565b60405180910390fd5b816101065f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8560ff1660ff1681526020019081526020015f205f82825461278b9190614be0565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167f8a84f062b33e96a9f60da7234d3e72c40f3f0cf776a9f4d349367c56f647dc5b8484346040516127dc93929190614c85565b60405180910390a2506127ed6131e6565b5050565b6101005481565b6128006131f0565b8060fc819055507f6384a9a54dfe83048a6f688c87e7999d2a354b437d8b10c60ac88af7d8cbf70b8160405161283691906146ba565b60405180910390a150565b61278881565b565b612851613197565b6040517ff7d1257c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f60019054906101000a900460ff161590508080156128b3575060015f5f9054906101000a900460ff1660ff16105b806128e057506128c2306137d9565b1580156128df575060015f5f9054906101000a900460ff1660ff16145b5b61291f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612916906152d4565b60405180910390fd5b60015f5f6101000a81548160ff021916908360ff160217905550801561295a5760015f60016101000a81548160ff0219169083151502179055505b6129626137fb565b61296a61384b565b6129726138a3565b8160fb5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555066b1a2bc2ec5000060fc8190555061019060fd819055506101f460ff819055508015612a2a575f5f60016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986001604051612a21919061532b565b60405180910390a15b5050565b6703782dace9d9000081565b6125e481565b66b1a2bc2ec5000081565b612a53613197565b5f612a5d82613331565b90505f6101065f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8460ff1660ff1681526020019081526020015f2054905060018110612b1e57600181036101065f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8560ff1660ff1681526020019081526020015f2081905550612c39565b5f8360ff16148015612b6f575060016101045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410155b15612bfd5760016101045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054036101045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550612c38565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c2f9061538e565b60405180910390fd5b5b5f612c43836133b8565b90505f612c4f856133eb565b82612c5a9190614b9f565b61010054612c689190614be0565b905080471015612ca4576040517fec5ec7ce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ff546101028054905010612ce5576040517f53c034cf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60fb5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f8413b076040518163ffffffff1660e01b81526004016020604051808303815f875af1158015612d51573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d759190614c27565b90505f73ffffffffffffffffffffffffffffffffffffffff166101015f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612e0f576040517fe27d026d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040518060c001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff1681526020014267ffffffffffffffff1681526020016001151581526020016001151581526020018760ff168152506101015f8381526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015f6101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060408201518160010160106101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060608201518160010160186101000a81548160ff02191690831515021790555060808201518160010160196101000a81548160ff02191690831515021790555060a082015181600101601a6101000a81548160ff021916908360ff160217905550905050612fa781613454565b81610100819055508285612fbb9190614c52565b60fe5f828254612fcb9190614be0565b92505081905550803373ffffffffffffffffffffffffffffffffffffffff167fcf3f5c404e572eb9b23fc829e0c3721aeb9c020a64e27d15fabbc091de3ad92788888760405161301d93929190614c85565b60405180910390a350505050506130326131e6565b50565b603281565b6130426131f0565b5f8111613084576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161307b906153f6565b60405180910390fd5b8060ff819055507f85bd1c44665a79780edfd48f00e6e14d8f56196e1dc8bc24aedfc1e9ce6f30fd816040516130ba91906146ba565b60405180910390a150565b6130cd613197565b6040517ff7d1257c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6131076131f0565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613175576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161316c90615484565b60405180910390fd5b61317e8161326e565b50565b610104602052805f5260405f205f915090505481565b600260c954036131dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131d3906154ec565b60405180910390fd5b600260c981905550565b600160c981905550565b6131f86138fb565b73ffffffffffffffffffffffffffffffffffffffff1661321661201e565b73ffffffffffffffffffffffffffffffffffffffff161461326c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161326390615554565b60405180910390fd5b565b5f60975f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160975f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f5f8260ff160361334b5766b1a2bc2ec5000090506133b3565b60018260ff1603613366576703782dace9d9000090506133b3565b60028260ff1603613381576706f05b59d3b2000090506133b3565b6040517fe142361700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b5f5f61271060fd54846133cb9190614b9f565b6133d59190615572565b905080836133e39190614c52565b915050919050565b5f5f6133f683613902565b90505f5f8460ff161461341f5760018460ff1614613416576125e461341a565b6127885b613423565b6129365b905061271061270f82846134379190614b9f565b6134419190614be0565b61344b9190615572565b92505050919050565b61010281908060018154018082558091505060019003905f5260205f20015f9091909190915055610102805490506101035f8381526020019081526020015f208190555050565b5f6101035f8381526020019081526020015f205490505f81036134be5750613585565b5f6001826134cc9190614c52565b90505f6101026001610102805490506134e59190614c52565b815481106134f6576134f5614f85565b5b905f5260205f200154905080610102838154811061351757613516614f85565b5b905f5260205f2001819055506001826135309190614be0565b6101035f8381526020019081526020015f2081905550610102805480613559576135586155a2565b5b600190038181905f5260205f20015f905590556101035f8581526020019081526020015f205f90555050505b50565b5f6135b47f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b613975565b5f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6135e36131f0565b50565b6136117f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435f1b61397e565b5f015f9054906101000a900460ff16156136335761362e83613987565b61374b565b8273ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561369b57506040513d601f19601f8201168201806040525081019061369891906155f9565b60015b6136da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136d190615694565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b811461373e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161373590615722565b60405180910390fd5b5061374a838383613a3d565b5b505050565b5f5f61375d858585613a68565b90505f5f8660ff16146137865760018660ff161461377d576125e4613781565b6127885b61378a565b6129365b90505f612710828461379c9190614b9f565b6137a69190615572565b90505f6137b288613902565b866137bd9190614b9f565b9050808211156137cb578091505b819450505050509392505050565b5f5f8273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b5f60019054906101000a900460ff16613849576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613840906157b0565b60405180910390fd5b565b5f60019054906101000a900460ff16613899576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613890906157b0565b60405180910390fd5b6138a1613c6e565b565b5f60019054906101000a900460ff166138f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138e8906157b0565b60405180910390fd5b6138f9613cce565b565b5f33905090565b5f5f8260ff16036139165760329050613970565b60018260ff160361392a5760329050613970565b60028260ff160361393e5760199050613970565b6040517fe142361700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b5f819050919050565b5f819050919050565b613990816137d9565b6139cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139c69061583e565b60405180910390fd5b806139fb7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b613975565b5f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b613a4683613d26565b5f82511180613a525750805b15613a6357613a618383613d75565b505b505050565b5f5f5f8560ff1614613a8e5760018560ff1614613a86576019613a89565b60325b613a91565b60325b90506007845f60058110613aa857613aa7614f85565b5b6020020151148015613ad25750600784600160058110613acb57613aca614f85565b5b6020020151145b8015613af65750600784600260058110613aef57613aee614f85565b5b6020020151145b8015613b1a5750600784600360058110613b1357613b12614f85565b5b6020020151145b8015613b3e5750600784600460058110613b3757613b36614f85565b5b6020020151145b15613b57578083613b4f9190614b9f565b915050613c67565b613b6084613da2565b8015613b8457506007845f60058110613b7c57613b7b614f85565b5b602002015114155b15613ba95760028184613b979190614b9f565b613ba19190615572565b915050613c67565b613bb284613e8d565b15613bcc57600a83613bc49190614b9f565b915050613c67565b613bd584613f42565b15613bef57600583613be79190614b9f565b915050613c67565b613bf884614027565b15613c1257600383613c0a9190614b9f565b915050613c67565b613c1b846140dc565b15613c3457613c2c83614c2c61419c565b915050613c67565b5f5f613c3f866141be565b91509150818015613c5057505f8114155b15613c6057849350505050613c67565b5f93505050505b9392505050565b5f60019054906101000a900460ff16613cbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613cb3906157b0565b60405180910390fd5b613ccc613cc76138fb565b61326e565b565b5f60019054906101000a900460ff16613d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613d13906157b0565b60405180910390fd5b600160c981905550565b613d2f81613987565b8073ffffffffffffffffffffffffffffffffffffffff167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b60405160405180910390a250565b6060613d9a83836040518060600160405280602781526020016159cc602791396142db565b905092915050565b5f81600160058110613db757613db6614f85565b5b6020020151825f60058110613dcf57613dce614f85565b5b6020020151148015613e10575081600260058110613df057613def614f85565b5b602002015182600160058110613e0957613e08614f85565b5b6020020151145b8015613e4b575081600360058110613e2b57613e2a614f85565b5b602002015182600260058110613e4457613e43614f85565b5b6020020151145b8015613e86575081600460058110613e6657613e65614f85565b5b602002015182600360058110613e7f57613e7e614f85565b5b6020020151145b9050919050565b5f613e96614442565b5f5f90505b6005811015613ef15781848260058110613eb857613eb7614f85565b5b6020020151600a8110613ece57613ecd614f85565b5b602002018051809190613ee09061585c565b815250508080600101915050613e9b565b505f5f90505b600a811015613f375760048282600a8110613f1557613f14614f85565b5b602002015103613f2a57600192505050613f3d565b8080600101915050613ef7565b505f9150505b919050565b5f613f4b614442565b5f5f90505b6005811015613fa65781848260058110613f6d57613f6c614f85565b5b6020020151600a8110613f8357613f82614f85565b5b602002018051809190613f959061585c565b815250508080600101915050613f50565b505f5f90505f5f90505f5f90505b600a8110156140125760038482600a8110613fd257613fd1614f85565b5b602002015103613fe157600192505b60028482600a8110613ff657613ff5614f85565b5b60200201510361400557600191505b8080600101915050613fb4565b5081801561401d5750805b9350505050919050565b5f614030614442565b5f5f90505b600581101561408b578184826005811061405257614051614f85565b5b6020020151600a811061406857614067614f85565b5b60200201805180919061407a9061585c565b815250508080600101915050614035565b505f5f90505b600a8110156140d15760038282600a81106140af576140ae614f85565b5b6020020151036140c4576001925050506140d7565b8080600101915050614091565b505f9150505b919050565b5f6140e5614442565b5f5f90505b6005811015614140578184826005811061410757614106614f85565b5b6020020151600a811061411d5761411c614f85565b5b60200201805180919061412f9061585c565b8152505080806001019150506140ea565b505f5f90505f5f90505b600a81101561418e5760028382600a811061416857614167614f85565b5b60200201510361418157818061417d9061585c565b9250505b808060010191505061414a565b506002811492505050919050565b5f61271082846141ac9190614b9f565b6141b69190615572565b905092915050565b5f5f6141c8614442565b5f5f90505b600581101561422357818582600581106141ea576141e9614f85565b5b6020020151600a8110614200576141ff614f85565b5b6020020180518091906142129061585c565b8152505080806001019150506141cd565b505f5f90505f5f90505f5f90505b600a8110156142b45760028482600a811061424f5761424e614f85565b5b6020020151036142775782806142649061585c565b935050809150600183116142b4576142a7565b60028482600a811061428c5761428b614f85565b5b602002015111156142a6575f5f95509550505050506142d6565b5b8080600101915050614231565b50600182036142cc57600181945094505050506142d6565b5f5f945094505050505b915091565b60605f5f8573ffffffffffffffffffffffffffffffffffffffff168560405161430491906158eb565b5f60405180830381855af49150503d805f811461433c576040519150601f19603f3d011682016040523d82523d5f602084013e614341565b606091505b50915091506143528683838761435d565b925050509392505050565b606083156143be575f8351036143b657614376856137d9565b6143b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016143ac9061594b565b60405180910390fd5b5b8290506143c9565b6143c883836143d1565b5b949350505050565b5f825111156143e35781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161441791906159ab565b60405180910390fd5b6040518060a00160405280600590602082028036833780820191505090505090565b604051806101400160405280600a90602082028036833780820191505090505090565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b61448881614476565b8114614492575f5ffd5b50565b5f813590506144a38161447f565b92915050565b5f602082840312156144be576144bd61446e565b5b5f6144cb84828501614495565b91505092915050565b5f8115159050919050565b6144e8816144d4565b82525050565b5f6020820190506145015f8301846144df565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61453082614507565b9050919050565b61454081614526565b82525050565b61454f81614476565b82525050565b5f67ffffffffffffffff82169050919050565b61457181614555565b82525050565b5f60ff82169050919050565b61458c81614577565b82525050565b5f60c0820190506145a55f830189614537565b6145b26020830188614546565b6145bf6040830187614568565b6145cc60608301866144df565b6145d960808301856144df565b6145e660a0830184614583565b979650505050505050565b5f819050919050565b5f61461461460f61460a84614507565b6145f1565b614507565b9050919050565b5f614625826145fa565b9050919050565b5f6146368261461b565b9050919050565b6146468161462c565b82525050565b5f60208201905061465f5f83018461463d565b92915050565b61466e81614526565b8114614678575f5ffd5b50565b5f8135905061468981614665565b92915050565b5f602082840312156146a4576146a361446e565b5b5f6146b18482850161467b565b91505092915050565b5f6020820190506146cd5f830184614546565b92915050565b6146dc81614577565b81146146e6575f5ffd5b50565b5f813590506146f7816146d3565b92915050565b5f602082840312156147125761471161446e565b5b5f61471f848285016146e9565b91505092915050565b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61477682614730565b810181811067ffffffffffffffff8211171561479557614794614740565b5b80604052505050565b5f6147a7614465565b90506147b3828261476d565b919050565b5f67ffffffffffffffff8211156147d2576147d1614740565b5b6147db82614730565b9050602081019050919050565b828183375f83830152505050565b5f614808614803846147b8565b61479e565b9050828152602081018484840111156148245761482361472c565b5b61482f8482856147e8565b509392505050565b5f82601f83011261484b5761484a614728565b5b813561485b8482602086016147f6565b91505092915050565b5f5f6040838503121561487a5761487961446e565b5b5f6148878582860161467b565b925050602083013567ffffffffffffffff8111156148a8576148a7614472565b5b6148b485828601614837565b9150509250929050565b5f819050919050565b6148d0816148be565b82525050565b5f6020820190506148e95f8301846148c7565b92915050565b5f5f604083850312156149055761490461446e565b5b5f6149128582860161467b565b9250506020614923858286016146e9565b9150509250929050565b5f5f604083850312156149435761494261446e565b5b5f61495085828601614495565b925050602061496185828601614495565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61499d81614476565b82525050565b5f6149ae8383614994565b60208301905092915050565b5f602082019050919050565b5f6149d08261496b565b6149da8185614975565b93506149e583614985565b805f5b83811015614a155781516149fc88826149a3565b9750614a07836149ba565b9250506001810190506149e8565b5085935050505092915050565b5f6020820190508181035f830152614a3a81846149c6565b905092915050565b5f6fffffffffffffffffffffffffffffffff82169050919050565b614a6681614a42565b82525050565b5f60c082019050614a7f5f830189614537565b614a8c6020830188614a5d565b614a996040830187614568565b614aa660608301866144df565b614ab360808301856144df565b614ac060a0830184614583565b979650505050505050565b5f602082019050614ade5f830184614537565b92915050565b5f5f5f60608486031215614afb57614afa61446e565b5b5f614b0886828701614495565b9350506020614b1986828701614495565b9250506040614b2a86828701614495565b9150509250925092565b5f5f60408385031215614b4a57614b4961446e565b5b5f614b57858286016146e9565b9250506020614b6885828601614495565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f614ba982614476565b9150614bb483614476565b9250828202614bc281614476565b91508282048414831517614bd957614bd8614b72565b5b5092915050565b5f614bea82614476565b9150614bf583614476565b9250828201905080821115614c0d57614c0c614b72565b5b92915050565b5f81519050614c218161447f565b92915050565b5f60208284031215614c3c57614c3b61446e565b5b5f614c4984828501614c13565b91505092915050565b5f614c5c82614476565b9150614c6783614476565b9250828203905081811115614c7f57614c7e614b72565b5b92915050565b5f606082019050614c985f830186614583565b614ca56020830185614546565b614cb26040830184614546565b949350505050565b5f81905092915050565b50565b5f614cd25f83614cba565b9150614cdd82614cc4565b5f82019050919050565b5f614cf182614cc7565b9150819050919050565b5f82825260208201905092915050565b7f46756e6374696f6e206d7573742062652063616c6c6564207468726f756768205f8201527f64656c656761746563616c6c0000000000000000000000000000000000000000602082015250565b5f614d65602c83614cfb565b9150614d7082614d0b565b604082019050919050565b5f6020820190508181035f830152614d9281614d59565b9050919050565b7f46756e6374696f6e206d7573742062652063616c6c6564207468726f756768205f8201527f6163746976652070726f78790000000000000000000000000000000000000000602082015250565b5f614df3602c83614cfb565b9150614dfe82614d99565b604082019050919050565b5f6020820190508181035f830152614e2081614de7565b9050919050565b7f6e6f7468696e67206f77656400000000000000000000000000000000000000005f82015250565b5f614e5b600c83614cfb565b9150614e6682614e27565b602082019050919050565b5f6020820190508181035f830152614e8881614e4f565b9050919050565b7f7769746864726177206661696c656400000000000000000000000000000000005f82015250565b5f614ec3600f83614cfb565b9150614ece82614e8f565b602082019050919050565b5f6020820190508181035f830152614ef081614eb7565b9050919050565b7f555550535570677261646561626c653a206d757374206e6f742062652063616c5f8201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000602082015250565b5f614f51603883614cfb565b9150614f5c82614ef7565b604082019050919050565b5f6020820190508181035f830152614f7e81614f45565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f66656520746f6f206869676800000000000000000000000000000000000000005f82015250565b5f614fe6600c83614cfb565b9150614ff182614fb2565b602082019050919050565b5f6020820190508181035f83015261501381614fda565b9050919050565b5f819050919050565b61503461502f82614476565b61501a565b82525050565b5f6150458285615023565b6020820191506150558284615023565b6020820191508190509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61509c82614476565b91506150a783614476565b9250826150b7576150b6615065565b5b828206905092915050565b5f60059050919050565b5f81905092915050565b5f819050919050565b5f602082019050919050565b6150f4816150c2565b6150fe81846150cc565b9250615109826150d6565b805f5b8381101561513957815161512087826149a3565b965061512b836150df565b92505060018101905061510c565b505050505050565b5f610120820190506151555f830188614546565b61516260208301876150eb565b61516f60c0830186614546565b61517c60e0830185614546565b61518a610100830184614583565b9695505050505050565b7f637265646974733d3000000000000000000000000000000000000000000000005f82015250565b5f6151c8600983614cfb565b91506151d382615194565b602082019050919050565b5f6020820190508181035f8301526151f5816151bc565b9050919050565b7f62616420657468000000000000000000000000000000000000000000000000005f82015250565b5f615230600783614cfb565b915061523b826151fc565b602082019050919050565b5f6020820190508181035f83015261525d81615224565b9050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c7265615f8201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b5f6152be602e83614cfb565b91506152c982615264565b604082019050919050565b5f6020820190508181035f8301526152eb816152b2565b9050919050565b5f819050919050565b5f61531561531061530b846152f2565b6145f1565b614577565b9050919050565b615325816152fb565b82525050565b5f60208201905061533e5f83018461531c565b92915050565b7f6e6f2063726564697400000000000000000000000000000000000000000000005f82015250565b5f615378600983614cfb565b915061538382615344565b602082019050919050565b5f6020820190508181035f8301526153a58161536c565b9050919050565b7f6d61783d300000000000000000000000000000000000000000000000000000005f82015250565b5f6153e0600583614cfb565b91506153eb826153ac565b602082019050919050565b5f6020820190508181035f83015261540d816153d4565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f61546e602683614cfb565b915061547982615414565b604082019050919050565b5f6020820190508181035f83015261549b81615462565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c005f82015250565b5f6154d6601f83614cfb565b91506154e1826154a2565b602082019050919050565b5f6020820190508181035f830152615503816154ca565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f61553e602083614cfb565b91506155498261550a565b602082019050919050565b5f6020820190508181035f83015261556b81615532565b9050919050565b5f61557c82614476565b915061558783614476565b92508261559757615596615065565b5b828204905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffd5b6155d8816148be565b81146155e2575f5ffd5b50565b5f815190506155f3816155cf565b92915050565b5f6020828403121561560e5761560d61446e565b5b5f61561b848285016155e5565b91505092915050565b7f45524331393637557067726164653a206e657720696d706c656d656e746174695f8201527f6f6e206973206e6f742055555053000000000000000000000000000000000000602082015250565b5f61567e602e83614cfb565b915061568982615624565b604082019050919050565b5f6020820190508181035f8301526156ab81615672565b9050919050565b7f45524331393637557067726164653a20756e737570706f727465642070726f785f8201527f6961626c65555549440000000000000000000000000000000000000000000000602082015250565b5f61570c602983614cfb565b9150615717826156b2565b604082019050919050565b5f6020820190508181035f83015261573981615700565b9050919050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420695f8201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b5f61579a602b83614cfb565b91506157a582615740565b604082019050919050565b5f6020820190508181035f8301526157c78161578e565b9050919050565b7f455243313936373a206e657720696d706c656d656e746174696f6e206973206e5f8201527f6f74206120636f6e747261637400000000000000000000000000000000000000602082015250565b5f615828602d83614cfb565b9150615833826157ce565b604082019050919050565b5f6020820190508181035f8301526158558161581c565b9050919050565b5f61586682614476565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361589857615897614b72565b5b600182019050919050565b5f81519050919050565b8281835e5f83830152505050565b5f6158c5826158a3565b6158cf8185614cba565b93506158df8185602086016158ad565b80840191505092915050565b5f6158f682846158bb565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000005f82015250565b5f615935601d83614cfb565b915061594082615901565b602082019050919050565b5f6020820190508181035f83015261596281615929565b9050919050565b5f81519050919050565b5f61597d82615969565b6159878185614cfb565b93506159978185602086016158ad565b6159a081614730565b840191505092915050565b5f6020820190508181035f8301526159c38184615973565b90509291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220c957ec2dfc01665de153430d4756410aa1eb970acaaff982c232dd4572b8e26c64736f6c634300081c0033
Deployed Bytecode
0x6080604052600436106102ad575f3560e01c806363338b1711610174578063b5deb024116100db578063e388048611610094578063ee0e1bb81161006e578063ee0e1bb8146109e1578063f0acd7d514610a09578063f2fde38b14610a13578063fe5ff46814610a3b576102ad565b8063e388048614610965578063e87284831461098f578063e8c18027146109b7576102ad565b8063b5deb0241461089f578063b60d4288146108c9578063c1302185146108d3578063c4d66de8146108e9578063c7e34a8614610911578063dc136f2e1461093b576102ad565b806388dc1cd11161012d57806388dc1cd1146107a35780638da5cb5b146107df5780639213f67c146108095780639750e3d8146108315780639dbc517b1461084d578063a8ae22b414610877576102ad565b806363338b17146106a857806364c54d60146106d2578063715018a6146106fa57806372c27b62146107105780637496c5a61461073857806381d12c5814610762576102ad565b80632dd85345116102185780634f1ef286116101d15780634f1ef2861461059657806352d1902d146105b257806354ebd9ba146105dc578063587f5ed7146106185780635a1c3833146106425780635c1b17621461067e576102ad565b80632dd85345146104b45780632e1a7d4d146104de5780633015394c146105065780633659cfe61461052e57806339a72c5c146105565780634724eddd1461056c576102ad565b8063186385701161026a57806318638570146103c6578063191fe9a0146103e2578063199e998a1461040c5780632147d5091461043657806324a9d85314610460578063291dda291461048a576102ad565b80630359a8a3146102b15780630b816045146102ed5780630c4dfe3f1461032e5780630c9490431461034a57806313af4035146103745780631574ac441461039c575b5f5ffd5b3480156102bc575f5ffd5b506102d760048036038101906102d291906144a9565b610a77565b6040516102e491906144ee565b60405180910390f35b3480156102f8575f5ffd5b50610313600480360381019061030e91906144a9565b610aa2565b60405161032596959493929190614592565b60405180910390f35b610348600480360381019061034391906144a9565b610c2f565b005b348015610355575f5ffd5b5061035e610c69565b60405161036b919061464c565b60405180910390f35b34801561037f575f5ffd5b5061039a6004803603810190610395919061468f565b610c8e565b005b3480156103a7575f5ffd5b506103b0610ce5565b6040516103bd91906146ba565b60405180910390f35b6103e060048036038101906103db91906146fd565b610ceb565b005b3480156103ed575f5ffd5b506103f6611132565b60405161040391906146ba565b60405180910390f35b348015610417575f5ffd5b50610420611138565b60405161042d91906146ba565b60405180910390f35b348015610441575f5ffd5b5061044a61113d565b60405161045791906146ba565b60405180910390f35b34801561046b575f5ffd5b50610474611143565b60405161048191906146ba565b60405180910390f35b348015610495575f5ffd5b5061049e611149565b6040516104ab91906146ba565b60405180910390f35b3480156104bf575f5ffd5b506104c8611155565b6040516104d591906146ba565b60405180910390f35b3480156104e9575f5ffd5b5061050460048036038101906104ff91906144a9565b61115b565b005b348015610511575f5ffd5b5061052c600480360381019061052791906144a9565b611265565b005b348015610539575f5ffd5b50610554600480360381019061054f919061468f565b6117a5565b005b348015610561575f5ffd5b5061056a61192b565b005b348015610577575f5ffd5b50610580611aae565b60405161058d91906146ba565b60405180910390f35b6105b060048036038101906105ab9190614864565b611ab4565b005b3480156105bd575f5ffd5b506105c6611bf0565b6040516105d391906148d6565b60405180910390f35b3480156105e7575f5ffd5b5061060260048036038101906105fd91906148ef565b611ca7565b60405161060f91906146ba565b60405180910390f35b348015610623575f5ffd5b5061062c611cc8565b60405161063991906146ba565b60405180910390f35b34801561064d575f5ffd5b506106686004803603810190610663919061492d565b611cce565b6040516106759190614a22565b60405180910390f35b348015610689575f5ffd5b50610692611e14565b60405161069f91906146ba565b60405180910390f35b3480156106b3575f5ffd5b506106bc611e19565b6040516106c991906146ba565b60405180910390f35b3480156106dd575f5ffd5b506106f860048036038101906106f3919061468f565b611e26565b005b348015610705575f5ffd5b5061070e611eb4565b005b34801561071b575f5ffd5b50610736600480360381019061073191906144a9565b611ec7565b005b348015610743575f5ffd5b5061074c611f55565b60405161075991906146ba565b60405180910390f35b34801561076d575f5ffd5b50610788600480360381019061078391906144a9565b611f5a565b60405161079a96959493929190614a6c565b60405180910390f35b3480156107ae575f5ffd5b506107c960048036038101906107c4919061468f565b612008565b6040516107d691906146ba565b60405180910390f35b3480156107ea575f5ffd5b506107f361201e565b6040516108009190614acb565b60405180910390f35b348015610814575f5ffd5b5061082f600480360381019061082a9190614ae4565b612046565b005b61084b60048036038101906108469190614b34565b612686565b005b348015610858575f5ffd5b506108616127f1565b60405161086e91906146ba565b60405180910390f35b348015610882575f5ffd5b5061089d600480360381019061089891906144a9565b6127f8565b005b3480156108aa575f5ffd5b506108b3612841565b6040516108c091906146ba565b60405180910390f35b6108d1612847565b005b3480156108de575f5ffd5b506108e7612849565b005b3480156108f4575f5ffd5b5061090f600480360381019061090a919061468f565b612883565b005b34801561091c575f5ffd5b50610925612a2e565b60405161093291906146ba565b60405180910390f35b348015610946575f5ffd5b5061094f612a3a565b60405161095c91906146ba565b60405180910390f35b348015610970575f5ffd5b50610979612a40565b60405161098691906146ba565b60405180910390f35b34801561099a575f5ffd5b506109b560048036038101906109b091906146fd565b612a4b565b005b3480156109c2575f5ffd5b506109cb613035565b6040516109d891906146ba565b60405180910390f35b3480156109ec575f5ffd5b50610a076004803603810190610a0291906144a9565b61303a565b005b610a116130c5565b005b348015610a1e575f5ffd5b50610a396004803603810190610a34919061468f565b6130ff565b005b348015610a46575f5ffd5b50610a616004803603810190610a5c919061468f565b613181565b604051610a6e91906146ba565b60405180910390f35b5f6101015f8381526020019081526020015f2060010160199054906101000a900460ff169050919050565b5f5f5f5f5f5f5f6101015f8981526020019081526020015f206040518060c00160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015f9054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016001820160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020016001820160189054906101000a900460ff161515151581526020016001820160199054906101000a900460ff1615151515815260200160018201601a9054906101000a900460ff1660ff1660ff16815250509050805f015181602001516fffffffffffffffffffffffffffffffff168260400151836080015184606001518560a001519650965096509650965096505091939550919395565b610c37613197565b6040517ff7d1257c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60fb5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610c966131f0565b610c9f8161326e565b8073ffffffffffffffffffffffffffffffffffffffff167f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b60405160405180910390a250565b60fc5481565b610cf3613197565b5f610cfd82613331565b9050803414610d38576040517f5509ca7300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f610d42826133b8565b90505f610d4e846133eb565b82610d599190614b9f565b61010054610d679190614be0565b905080471015610da3576040517fec5ec7ce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ff546101028054905010610de4576040517f53c034cf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60fb5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f8413b076040518163ffffffff1660e01b81526004016020604051808303815f875af1158015610e50573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e749190614c27565b90505f73ffffffffffffffffffffffffffffffffffffffff166101015f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610f0e576040517fe27d026d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040518060c001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff1681526020014267ffffffffffffffff1681526020015f151581526020016001151581526020018660ff168152506101015f8381526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015f6101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060408201518160010160106101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060608201518160010160186101000a81548160ff02191690831515021790555060808201518160010160196101000a81548160ff02191690831515021790555060a082015181600101601a6101000a81548160ff021916908360ff1602179055509050506110a581613454565b816101008190555082846110b99190614c52565b60fe5f8282546110c99190614be0565b92505081905550803373ffffffffffffffffffffffffffffffffffffffff167fcf3f5c404e572eb9b23fc829e0c3721aeb9c020a64e27d15fabbc091de3ad92787878760405161111b93929190614c85565b60405180910390a35050505061112f6131e6565b50565b61293681565b603281565b614c2c81565b60fd5481565b6706f05b59d3b2000081565b61012c81565b6111636131f0565b61116b613197565b610100544761117a9190614c52565b8111156111b3576040517f6df2b55c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6111bc61201e565b73ffffffffffffffffffffffffffffffffffffffff16826040516111df90614ce7565b5f6040518083038185875af1925050503d805f8114611219576040519150601f19603f3d011682016040523d82523d5f602084013e61121e565b606091505b5050905080611259576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506112626131e6565b50565b61126d613197565b5f6101015f8381526020019081526020015f206040518060c00160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015f9054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016001820160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020016001820160189054906101000a900460ff161515151581526020016001820160199054906101000a900460ff1615151515815260200160018201601a9054906101000a900460ff1660ff1660ff16815250509050806080015115806113ee57505f73ffffffffffffffffffffffffffffffffffffffff16815f015173ffffffffffffffffffffffffffffffffffffffff16145b15611425576040517fc423735200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61142d61201e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036114b857603c816040015167ffffffffffffffff1661147a9190614be0565b4210156114b3576040517f085de62500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61157b565b805f015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036115485761012c816040015167ffffffffffffffff1661150a9190614be0565b421015611543576040517f085de62500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61157a565b6040517fea8e4eb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5f6101015f8481526020019081526020015f2060010160196101000a81548160ff0219169083151502179055506115b18261349b565b6115be8160a001516133eb565b81602001516fffffffffffffffffffffffffffffffff166115df9190614b9f565b6101005f8282546115f09190614c52565b925050819055508060600151156116775760016101065f835f015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8360a0015160ff1660ff1681526020019081526020015f205f82825461166b9190614be0565b92505081905550611731565b5f815f015173ffffffffffffffffffffffffffffffffffffffff1682602001516fffffffffffffffffffffffffffffffff166040516116b590614ce7565b5f6040518083038185875af1925050503d805f81146116ef576040519150601f19603f3d011682016040523d82523d5f602084013e6116f4565b606091505b505090508061172f576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b805f015173ffffffffffffffffffffffffffffffffffffffff16827ff5b74e631bc000f4c9329ba0231ef5e4d23fb8db17bc3c43b1e893b17b42ddd683602001516fffffffffffffffffffffffffffffffff1660405161179191906146ba565b60405180910390a3506117a26131e6565b50565b7f000000000000000000000000e3b99f65c0292690519b7029934197e70c29686873ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1603611833576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182a90614d7b565b60405180910390fd5b7f000000000000000000000000e3b99f65c0292690519b7029934197e70c29686873ffffffffffffffffffffffffffffffffffffffff16611872613588565b73ffffffffffffffffffffffffffffffffffffffff16146118c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118bf90614e09565b60405180910390fd5b6118d1816135db565b611928815f67ffffffffffffffff8111156118ef576118ee614740565b5b6040519080825280601f01601f1916602001820160405280156119215781602001600182028036833780820191505090505b505f6135e6565b50565b611933613197565b5f6101055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490505f81116119b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119ae90614e71565b60405180910390fd5b5f6101055f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055505f3373ffffffffffffffffffffffffffffffffffffffff1682604051611a1f90614ce7565b5f6040518083038185875af1925050503d805f8114611a59576040519150601f19603f3d011682016040523d82523d5f602084013e611a5e565b606091505b5050905080611aa2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9990614ed9565b60405180910390fd5b5050611aac6131e6565b565b60ff5481565b7f000000000000000000000000e3b99f65c0292690519b7029934197e70c29686873ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1603611b42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3990614d7b565b60405180910390fd5b7f000000000000000000000000e3b99f65c0292690519b7029934197e70c29686873ffffffffffffffffffffffffffffffffffffffff16611b81613588565b73ffffffffffffffffffffffffffffffffffffffff1614611bd7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bce90614e09565b60405180910390fd5b611be0826135db565b611bec828260016135e6565b5050565b5f7f000000000000000000000000e3b99f65c0292690519b7029934197e70c29686873ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614611c7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7690614f67565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b905090565b610106602052815f5260405f20602052805f5260405f205f91509150505481565b60fe5481565b60605f610102805490509050808410611d32575f67ffffffffffffffff811115611cfb57611cfa614740565b5b604051908082528060200260200182016040528015611d295781602001602082028036833780820191505090505b50915050611e0e565b5f8385611d3f9190614be0565b905081811115611d4d578190505b5f8582611d5a9190614c52565b90508067ffffffffffffffff811115611d7657611d75614740565b5b604051908082528060200260200182016040528015611da45781602001602082028036833780820191505090505b5093505f5f90505b81811015611e09576101028188611dc39190614be0565b81548110611dd457611dd3614f85565b5b905f5260205f200154858281518110611df057611def614f85565b5b6020026020010181815250508080600101915050611dac565b505050505b92915050565b601981565b5f61010280549050905090565b611e2e6131f0565b8060fb5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f48909173584eb61f90468a9f46407141ac6d3ba091d2b9b487ac911bfd83b22d60405160405180910390a250565b611ebc6131f0565b611ec55f61326e565b565b611ecf6131f0565b6103e8811115611f14576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f0b90614ffc565b60405180910390fd5b8060fd819055507f0399aa81c69e33acc2ff42d0f7a0809e6bf4c10ff3c3a7e040b12fedc14602f281604051611f4a91906146ba565b60405180910390a150565b603c81565b610101602052805f5260405f205f91509050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001015f9054906101000a90046fffffffffffffffffffffffffffffffff16908060010160109054906101000a900467ffffffffffffffff16908060010160189054906101000a900460ff16908060010160199054906101000a900460ff169080600101601a9054906101000a900460ff16905086565b610105602052805f5260405f205f915090505481565b5f60975f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60fb5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146120cc576040517f60f6d5a800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120d4613197565b5f6101015f8581526020019081526020015f206040518060c00160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015f9054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016001820160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020016001820160189054906101000a900460ff161515151581526020016001820160199054906101000a900460ff1615151515815260200160018201601a9054906101000a900460ff1660ff1660ff168152505090508060800151158061225557505f73ffffffffffffffffffffffffffffffffffffffff16815f015173ffffffffffffffffffffffffffffffffffffffff16145b1561228c576040517fc423735200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6101015f8681526020019081526020015f2060010160196101000a81548160ff0219169083151502179055506122c28461349b565b6122cf8160a001516133eb565b81602001516fffffffffffffffffffffffffffffffff166122f09190614b9f565b6101005f8282546123019190614c52565b92505081905550612310614420565b600a845f60405160200161232592919061503a565b604051602081830303815290604052805190602001205f1c6123479190615092565b815f6005811061235a57612359614f85565b5b602002018181525050600a84600160405160200161237992919061503a565b604051602081830303815290604052805190602001205f1c61239b9190615092565b816001600581106123af576123ae614f85565b5b602002018181525050600a8460026040516020016123ce92919061503a565b604051602081830303815290604052805190602001205f1c6123f09190615092565b8160026005811061240457612403614f85565b5b602002018181525050600a84600360405160200161242392919061503a565b604051602081830303815290604052805190602001205f1c6124459190615092565b8160036005811061245957612458614f85565b5b602002018181525050600a84600460405160200161247892919061503a565b604051602081830303815290604052805190602001205f1c61249a9190615092565b816004600581106124ae576124ad614f85565b5b6020020181815250505f6124dd8360a001518385602001516fffffffffffffffffffffffffffffffff16613750565b90505f811115612602575f835f015173ffffffffffffffffffffffffffffffffffffffff168260405161250f90614ce7565b5f6040518083038185875af1925050503d805f8114612549576040519150601f19603f3d011682016040523d82523d5f602084013e61254e565b606091505b505090508061260057816101055f865f015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546125a79190614be0565b92505081905550835f015173ffffffffffffffffffffffffffffffffffffffff167f0e54be18cea4b7c02dcb455aa29944656f9f30fbb0ba328fe8a75d10e52511dd836040516125f791906146ba565b60405180910390a25b505b825f015173ffffffffffffffffffffffffffffffffffffffff16867fa43436eeaedcc7dcc28ba81074692578b4a610cd09431297dbae2d05903ca0d885602001516fffffffffffffffffffffffffffffffff168585898960a0015160405161266e959493929190615141565b60405180910390a35050506126816131e6565b505050565b61268e613197565b5f81116126d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c7906151de565b60405180910390fd5b5f6126da83613331565b905081816126e89190614b9f565b3414612729576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161272090615246565b60405180910390fd5b816101065f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8560ff1660ff1681526020019081526020015f205f82825461278b9190614be0565b925050819055503373ffffffffffffffffffffffffffffffffffffffff167f8a84f062b33e96a9f60da7234d3e72c40f3f0cf776a9f4d349367c56f647dc5b8484346040516127dc93929190614c85565b60405180910390a2506127ed6131e6565b5050565b6101005481565b6128006131f0565b8060fc819055507f6384a9a54dfe83048a6f688c87e7999d2a354b437d8b10c60ac88af7d8cbf70b8160405161283691906146ba565b60405180910390a150565b61278881565b565b612851613197565b6040517ff7d1257c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f60019054906101000a900460ff161590508080156128b3575060015f5f9054906101000a900460ff1660ff16105b806128e057506128c2306137d9565b1580156128df575060015f5f9054906101000a900460ff1660ff16145b5b61291f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612916906152d4565b60405180910390fd5b60015f5f6101000a81548160ff021916908360ff160217905550801561295a5760015f60016101000a81548160ff0219169083151502179055505b6129626137fb565b61296a61384b565b6129726138a3565b8160fb5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555066b1a2bc2ec5000060fc8190555061019060fd819055506101f460ff819055508015612a2a575f5f60016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986001604051612a21919061532b565b60405180910390a15b5050565b6703782dace9d9000081565b6125e481565b66b1a2bc2ec5000081565b612a53613197565b5f612a5d82613331565b90505f6101065f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8460ff1660ff1681526020019081526020015f2054905060018110612b1e57600181036101065f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8560ff1660ff1681526020019081526020015f2081905550612c39565b5f8360ff16148015612b6f575060016101045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205410155b15612bfd5760016101045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054036101045f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550612c38565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c2f9061538e565b60405180910390fd5b5b5f612c43836133b8565b90505f612c4f856133eb565b82612c5a9190614b9f565b61010054612c689190614be0565b905080471015612ca4576040517fec5ec7ce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ff546101028054905010612ce5576040517f53c034cf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60fb5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f8413b076040518163ffffffff1660e01b81526004016020604051808303815f875af1158015612d51573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d759190614c27565b90505f73ffffffffffffffffffffffffffffffffffffffff166101015f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612e0f576040517fe27d026d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040518060c001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff1681526020014267ffffffffffffffff1681526020016001151581526020016001151581526020018760ff168152506101015f8381526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015f6101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060408201518160010160106101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060608201518160010160186101000a81548160ff02191690831515021790555060808201518160010160196101000a81548160ff02191690831515021790555060a082015181600101601a6101000a81548160ff021916908360ff160217905550905050612fa781613454565b81610100819055508285612fbb9190614c52565b60fe5f828254612fcb9190614be0565b92505081905550803373ffffffffffffffffffffffffffffffffffffffff167fcf3f5c404e572eb9b23fc829e0c3721aeb9c020a64e27d15fabbc091de3ad92788888760405161301d93929190614c85565b60405180910390a350505050506130326131e6565b50565b603281565b6130426131f0565b5f8111613084576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161307b906153f6565b60405180910390fd5b8060ff819055507f85bd1c44665a79780edfd48f00e6e14d8f56196e1dc8bc24aedfc1e9ce6f30fd816040516130ba91906146ba565b60405180910390a150565b6130cd613197565b6040517ff7d1257c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6131076131f0565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613175576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161316c90615484565b60405180910390fd5b61317e8161326e565b50565b610104602052805f5260405f205f915090505481565b600260c954036131dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131d3906154ec565b60405180910390fd5b600260c981905550565b600160c981905550565b6131f86138fb565b73ffffffffffffffffffffffffffffffffffffffff1661321661201e565b73ffffffffffffffffffffffffffffffffffffffff161461326c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161326390615554565b60405180910390fd5b565b5f60975f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160975f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f5f8260ff160361334b5766b1a2bc2ec5000090506133b3565b60018260ff1603613366576703782dace9d9000090506133b3565b60028260ff1603613381576706f05b59d3b2000090506133b3565b6040517fe142361700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b5f5f61271060fd54846133cb9190614b9f565b6133d59190615572565b905080836133e39190614c52565b915050919050565b5f5f6133f683613902565b90505f5f8460ff161461341f5760018460ff1614613416576125e461341a565b6127885b613423565b6129365b905061271061270f82846134379190614b9f565b6134419190614be0565b61344b9190615572565b92505050919050565b61010281908060018154018082558091505060019003905f5260205f20015f9091909190915055610102805490506101035f8381526020019081526020015f208190555050565b5f6101035f8381526020019081526020015f205490505f81036134be5750613585565b5f6001826134cc9190614c52565b90505f6101026001610102805490506134e59190614c52565b815481106134f6576134f5614f85565b5b905f5260205f200154905080610102838154811061351757613516614f85565b5b905f5260205f2001819055506001826135309190614be0565b6101035f8381526020019081526020015f2081905550610102805480613559576135586155a2565b5b600190038181905f5260205f20015f905590556101035f8581526020019081526020015f205f90555050505b50565b5f6135b47f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b613975565b5f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6135e36131f0565b50565b6136117f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435f1b61397e565b5f015f9054906101000a900460ff16156136335761362e83613987565b61374b565b8273ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561369b57506040513d601f19601f8201168201806040525081019061369891906155f9565b60015b6136da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136d190615694565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b811461373e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161373590615722565b60405180910390fd5b5061374a838383613a3d565b5b505050565b5f5f61375d858585613a68565b90505f5f8660ff16146137865760018660ff161461377d576125e4613781565b6127885b61378a565b6129365b90505f612710828461379c9190614b9f565b6137a69190615572565b90505f6137b288613902565b866137bd9190614b9f565b9050808211156137cb578091505b819450505050509392505050565b5f5f8273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b5f60019054906101000a900460ff16613849576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613840906157b0565b60405180910390fd5b565b5f60019054906101000a900460ff16613899576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613890906157b0565b60405180910390fd5b6138a1613c6e565b565b5f60019054906101000a900460ff166138f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138e8906157b0565b60405180910390fd5b6138f9613cce565b565b5f33905090565b5f5f8260ff16036139165760329050613970565b60018260ff160361392a5760329050613970565b60028260ff160361393e5760199050613970565b6040517fe142361700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b5f819050919050565b5f819050919050565b613990816137d9565b6139cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139c69061583e565b60405180910390fd5b806139fb7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b613975565b5f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b613a4683613d26565b5f82511180613a525750805b15613a6357613a618383613d75565b505b505050565b5f5f5f8560ff1614613a8e5760018560ff1614613a86576019613a89565b60325b613a91565b60325b90506007845f60058110613aa857613aa7614f85565b5b6020020151148015613ad25750600784600160058110613acb57613aca614f85565b5b6020020151145b8015613af65750600784600260058110613aef57613aee614f85565b5b6020020151145b8015613b1a5750600784600360058110613b1357613b12614f85565b5b6020020151145b8015613b3e5750600784600460058110613b3757613b36614f85565b5b6020020151145b15613b57578083613b4f9190614b9f565b915050613c67565b613b6084613da2565b8015613b8457506007845f60058110613b7c57613b7b614f85565b5b602002015114155b15613ba95760028184613b979190614b9f565b613ba19190615572565b915050613c67565b613bb284613e8d565b15613bcc57600a83613bc49190614b9f565b915050613c67565b613bd584613f42565b15613bef57600583613be79190614b9f565b915050613c67565b613bf884614027565b15613c1257600383613c0a9190614b9f565b915050613c67565b613c1b846140dc565b15613c3457613c2c83614c2c61419c565b915050613c67565b5f5f613c3f866141be565b91509150818015613c5057505f8114155b15613c6057849350505050613c67565b5f93505050505b9392505050565b5f60019054906101000a900460ff16613cbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613cb3906157b0565b60405180910390fd5b613ccc613cc76138fb565b61326e565b565b5f60019054906101000a900460ff16613d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613d13906157b0565b60405180910390fd5b600160c981905550565b613d2f81613987565b8073ffffffffffffffffffffffffffffffffffffffff167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b60405160405180910390a250565b6060613d9a83836040518060600160405280602781526020016159cc602791396142db565b905092915050565b5f81600160058110613db757613db6614f85565b5b6020020151825f60058110613dcf57613dce614f85565b5b6020020151148015613e10575081600260058110613df057613def614f85565b5b602002015182600160058110613e0957613e08614f85565b5b6020020151145b8015613e4b575081600360058110613e2b57613e2a614f85565b5b602002015182600260058110613e4457613e43614f85565b5b6020020151145b8015613e86575081600460058110613e6657613e65614f85565b5b602002015182600360058110613e7f57613e7e614f85565b5b6020020151145b9050919050565b5f613e96614442565b5f5f90505b6005811015613ef15781848260058110613eb857613eb7614f85565b5b6020020151600a8110613ece57613ecd614f85565b5b602002018051809190613ee09061585c565b815250508080600101915050613e9b565b505f5f90505b600a811015613f375760048282600a8110613f1557613f14614f85565b5b602002015103613f2a57600192505050613f3d565b8080600101915050613ef7565b505f9150505b919050565b5f613f4b614442565b5f5f90505b6005811015613fa65781848260058110613f6d57613f6c614f85565b5b6020020151600a8110613f8357613f82614f85565b5b602002018051809190613f959061585c565b815250508080600101915050613f50565b505f5f90505f5f90505f5f90505b600a8110156140125760038482600a8110613fd257613fd1614f85565b5b602002015103613fe157600192505b60028482600a8110613ff657613ff5614f85565b5b60200201510361400557600191505b8080600101915050613fb4565b5081801561401d5750805b9350505050919050565b5f614030614442565b5f5f90505b600581101561408b578184826005811061405257614051614f85565b5b6020020151600a811061406857614067614f85565b5b60200201805180919061407a9061585c565b815250508080600101915050614035565b505f5f90505b600a8110156140d15760038282600a81106140af576140ae614f85565b5b6020020151036140c4576001925050506140d7565b8080600101915050614091565b505f9150505b919050565b5f6140e5614442565b5f5f90505b6005811015614140578184826005811061410757614106614f85565b5b6020020151600a811061411d5761411c614f85565b5b60200201805180919061412f9061585c565b8152505080806001019150506140ea565b505f5f90505f5f90505b600a81101561418e5760028382600a811061416857614167614f85565b5b60200201510361418157818061417d9061585c565b9250505b808060010191505061414a565b506002811492505050919050565b5f61271082846141ac9190614b9f565b6141b69190615572565b905092915050565b5f5f6141c8614442565b5f5f90505b600581101561422357818582600581106141ea576141e9614f85565b5b6020020151600a8110614200576141ff614f85565b5b6020020180518091906142129061585c565b8152505080806001019150506141cd565b505f5f90505f5f90505f5f90505b600a8110156142b45760028482600a811061424f5761424e614f85565b5b6020020151036142775782806142649061585c565b935050809150600183116142b4576142a7565b60028482600a811061428c5761428b614f85565b5b602002015111156142a6575f5f95509550505050506142d6565b5b8080600101915050614231565b50600182036142cc57600181945094505050506142d6565b5f5f945094505050505b915091565b60605f5f8573ffffffffffffffffffffffffffffffffffffffff168560405161430491906158eb565b5f60405180830381855af49150503d805f811461433c576040519150601f19603f3d011682016040523d82523d5f602084013e614341565b606091505b50915091506143528683838761435d565b925050509392505050565b606083156143be575f8351036143b657614376856137d9565b6143b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016143ac9061594b565b60405180910390fd5b5b8290506143c9565b6143c883836143d1565b5b949350505050565b5f825111156143e35781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161441791906159ab565b60405180910390fd5b6040518060a00160405280600590602082028036833780820191505090505090565b604051806101400160405280600a90602082028036833780820191505090505090565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b61448881614476565b8114614492575f5ffd5b50565b5f813590506144a38161447f565b92915050565b5f602082840312156144be576144bd61446e565b5b5f6144cb84828501614495565b91505092915050565b5f8115159050919050565b6144e8816144d4565b82525050565b5f6020820190506145015f8301846144df565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61453082614507565b9050919050565b61454081614526565b82525050565b61454f81614476565b82525050565b5f67ffffffffffffffff82169050919050565b61457181614555565b82525050565b5f60ff82169050919050565b61458c81614577565b82525050565b5f60c0820190506145a55f830189614537565b6145b26020830188614546565b6145bf6040830187614568565b6145cc60608301866144df565b6145d960808301856144df565b6145e660a0830184614583565b979650505050505050565b5f819050919050565b5f61461461460f61460a84614507565b6145f1565b614507565b9050919050565b5f614625826145fa565b9050919050565b5f6146368261461b565b9050919050565b6146468161462c565b82525050565b5f60208201905061465f5f83018461463d565b92915050565b61466e81614526565b8114614678575f5ffd5b50565b5f8135905061468981614665565b92915050565b5f602082840312156146a4576146a361446e565b5b5f6146b18482850161467b565b91505092915050565b5f6020820190506146cd5f830184614546565b92915050565b6146dc81614577565b81146146e6575f5ffd5b50565b5f813590506146f7816146d3565b92915050565b5f602082840312156147125761471161446e565b5b5f61471f848285016146e9565b91505092915050565b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61477682614730565b810181811067ffffffffffffffff8211171561479557614794614740565b5b80604052505050565b5f6147a7614465565b90506147b3828261476d565b919050565b5f67ffffffffffffffff8211156147d2576147d1614740565b5b6147db82614730565b9050602081019050919050565b828183375f83830152505050565b5f614808614803846147b8565b61479e565b9050828152602081018484840111156148245761482361472c565b5b61482f8482856147e8565b509392505050565b5f82601f83011261484b5761484a614728565b5b813561485b8482602086016147f6565b91505092915050565b5f5f6040838503121561487a5761487961446e565b5b5f6148878582860161467b565b925050602083013567ffffffffffffffff8111156148a8576148a7614472565b5b6148b485828601614837565b9150509250929050565b5f819050919050565b6148d0816148be565b82525050565b5f6020820190506148e95f8301846148c7565b92915050565b5f5f604083850312156149055761490461446e565b5b5f6149128582860161467b565b9250506020614923858286016146e9565b9150509250929050565b5f5f604083850312156149435761494261446e565b5b5f61495085828601614495565b925050602061496185828601614495565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61499d81614476565b82525050565b5f6149ae8383614994565b60208301905092915050565b5f602082019050919050565b5f6149d08261496b565b6149da8185614975565b93506149e583614985565b805f5b83811015614a155781516149fc88826149a3565b9750614a07836149ba565b9250506001810190506149e8565b5085935050505092915050565b5f6020820190508181035f830152614a3a81846149c6565b905092915050565b5f6fffffffffffffffffffffffffffffffff82169050919050565b614a6681614a42565b82525050565b5f60c082019050614a7f5f830189614537565b614a8c6020830188614a5d565b614a996040830187614568565b614aa660608301866144df565b614ab360808301856144df565b614ac060a0830184614583565b979650505050505050565b5f602082019050614ade5f830184614537565b92915050565b5f5f5f60608486031215614afb57614afa61446e565b5b5f614b0886828701614495565b9350506020614b1986828701614495565b9250506040614b2a86828701614495565b9150509250925092565b5f5f60408385031215614b4a57614b4961446e565b5b5f614b57858286016146e9565b9250506020614b6885828601614495565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f614ba982614476565b9150614bb483614476565b9250828202614bc281614476565b91508282048414831517614bd957614bd8614b72565b5b5092915050565b5f614bea82614476565b9150614bf583614476565b9250828201905080821115614c0d57614c0c614b72565b5b92915050565b5f81519050614c218161447f565b92915050565b5f60208284031215614c3c57614c3b61446e565b5b5f614c4984828501614c13565b91505092915050565b5f614c5c82614476565b9150614c6783614476565b9250828203905081811115614c7f57614c7e614b72565b5b92915050565b5f606082019050614c985f830186614583565b614ca56020830185614546565b614cb26040830184614546565b949350505050565b5f81905092915050565b50565b5f614cd25f83614cba565b9150614cdd82614cc4565b5f82019050919050565b5f614cf182614cc7565b9150819050919050565b5f82825260208201905092915050565b7f46756e6374696f6e206d7573742062652063616c6c6564207468726f756768205f8201527f64656c656761746563616c6c0000000000000000000000000000000000000000602082015250565b5f614d65602c83614cfb565b9150614d7082614d0b565b604082019050919050565b5f6020820190508181035f830152614d9281614d59565b9050919050565b7f46756e6374696f6e206d7573742062652063616c6c6564207468726f756768205f8201527f6163746976652070726f78790000000000000000000000000000000000000000602082015250565b5f614df3602c83614cfb565b9150614dfe82614d99565b604082019050919050565b5f6020820190508181035f830152614e2081614de7565b9050919050565b7f6e6f7468696e67206f77656400000000000000000000000000000000000000005f82015250565b5f614e5b600c83614cfb565b9150614e6682614e27565b602082019050919050565b5f6020820190508181035f830152614e8881614e4f565b9050919050565b7f7769746864726177206661696c656400000000000000000000000000000000005f82015250565b5f614ec3600f83614cfb565b9150614ece82614e8f565b602082019050919050565b5f6020820190508181035f830152614ef081614eb7565b9050919050565b7f555550535570677261646561626c653a206d757374206e6f742062652063616c5f8201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000602082015250565b5f614f51603883614cfb565b9150614f5c82614ef7565b604082019050919050565b5f6020820190508181035f830152614f7e81614f45565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f66656520746f6f206869676800000000000000000000000000000000000000005f82015250565b5f614fe6600c83614cfb565b9150614ff182614fb2565b602082019050919050565b5f6020820190508181035f83015261501381614fda565b9050919050565b5f819050919050565b61503461502f82614476565b61501a565b82525050565b5f6150458285615023565b6020820191506150558284615023565b6020820191508190509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61509c82614476565b91506150a783614476565b9250826150b7576150b6615065565b5b828206905092915050565b5f60059050919050565b5f81905092915050565b5f819050919050565b5f602082019050919050565b6150f4816150c2565b6150fe81846150cc565b9250615109826150d6565b805f5b8381101561513957815161512087826149a3565b965061512b836150df565b92505060018101905061510c565b505050505050565b5f610120820190506151555f830188614546565b61516260208301876150eb565b61516f60c0830186614546565b61517c60e0830185614546565b61518a610100830184614583565b9695505050505050565b7f637265646974733d3000000000000000000000000000000000000000000000005f82015250565b5f6151c8600983614cfb565b91506151d382615194565b602082019050919050565b5f6020820190508181035f8301526151f5816151bc565b9050919050565b7f62616420657468000000000000000000000000000000000000000000000000005f82015250565b5f615230600783614cfb565b915061523b826151fc565b602082019050919050565b5f6020820190508181035f83015261525d81615224565b9050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c7265615f8201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b5f6152be602e83614cfb565b91506152c982615264565b604082019050919050565b5f6020820190508181035f8301526152eb816152b2565b9050919050565b5f819050919050565b5f61531561531061530b846152f2565b6145f1565b614577565b9050919050565b615325816152fb565b82525050565b5f60208201905061533e5f83018461531c565b92915050565b7f6e6f2063726564697400000000000000000000000000000000000000000000005f82015250565b5f615378600983614cfb565b915061538382615344565b602082019050919050565b5f6020820190508181035f8301526153a58161536c565b9050919050565b7f6d61783d300000000000000000000000000000000000000000000000000000005f82015250565b5f6153e0600583614cfb565b91506153eb826153ac565b602082019050919050565b5f6020820190508181035f83015261540d816153d4565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f61546e602683614cfb565b915061547982615414565b604082019050919050565b5f6020820190508181035f83015261549b81615462565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c005f82015250565b5f6154d6601f83614cfb565b91506154e1826154a2565b602082019050919050565b5f6020820190508181035f830152615503816154ca565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f61553e602083614cfb565b91506155498261550a565b602082019050919050565b5f6020820190508181035f83015261556b81615532565b9050919050565b5f61557c82614476565b915061558783614476565b92508261559757615596615065565b5b828204905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffd5b6155d8816148be565b81146155e2575f5ffd5b50565b5f815190506155f3816155cf565b92915050565b5f6020828403121561560e5761560d61446e565b5b5f61561b848285016155e5565b91505092915050565b7f45524331393637557067726164653a206e657720696d706c656d656e746174695f8201527f6f6e206973206e6f742055555053000000000000000000000000000000000000602082015250565b5f61567e602e83614cfb565b915061568982615624565b604082019050919050565b5f6020820190508181035f8301526156ab81615672565b9050919050565b7f45524331393637557067726164653a20756e737570706f727465642070726f785f8201527f6961626c65555549440000000000000000000000000000000000000000000000602082015250565b5f61570c602983614cfb565b9150615717826156b2565b604082019050919050565b5f6020820190508181035f83015261573981615700565b9050919050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420695f8201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b5f61579a602b83614cfb565b91506157a582615740565b604082019050919050565b5f6020820190508181035f8301526157c78161578e565b9050919050565b7f455243313936373a206e657720696d706c656d656e746174696f6e206973206e5f8201527f6f74206120636f6e747261637400000000000000000000000000000000000000602082015250565b5f615828602d83614cfb565b9150615833826157ce565b604082019050919050565b5f6020820190508181035f8301526158558161581c565b9050919050565b5f61586682614476565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361589857615897614b72565b5b600182019050919050565b5f81519050919050565b8281835e5f83830152505050565b5f6158c5826158a3565b6158cf8185614cba565b93506158df8185602086016158ad565b80840191505092915050565b5f6158f682846158bb565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000005f82015250565b5f615935601d83614cfb565b915061594082615901565b602082019050919050565b5f6020820190508181035f83015261596281615929565b9050919050565b5f81519050919050565b5f61597d82615969565b6159878185614cfb565b93506159978185602086016158ad565b6159a081614730565b840191505092915050565b5f6020820190508181035f8301526159c38184615973565b90509291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220c957ec2dfc01665de153430d4756410aa1eb970acaaff982c232dd4572b8e26c64736f6c634300081c0033
Deployed Bytecode Sourcemap
776:19722:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13810:123;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;13939:332;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;:::i;:::-;;;;;;;;12901:121;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;941:15;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5812:137;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;963:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6823:1072;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3353:43;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3715:40;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1695:53;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1006:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3130:46;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1411:49;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;13069:278;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;11202:1129;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3408:195:9;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;13484:283:0;;;;;;;;;;;;;:::i;:::-;;1089:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3922:220:9;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3027:131;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2842:66:0;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1053:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;14381:458;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3761:40;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;14277:98;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5955:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2085:101:3;;;;;;;;;;;;;:::i;:::-;;6230:205:0;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1326:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2216:43;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;:::i;:::-;;;;;;;;2657:46;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1462:85:3;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;9751:1364:0;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;12463:381;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1267:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6080:144;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3428:43;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;13028:35;;;:::i;:::-;;9587:92;;;;;;;;;;;;;:::i;:::-;;5316:341;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3078:46;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3501:42;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3026:46;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8059:1347;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3669:40;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6441:193;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;9491:90;;;:::i;:::-;;2335:198:3;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2521:42:0;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;13810:123;13877:4;13900:8;:19;13909:9;13900:19;;;;;;;;;;;:26;;;;;;;;;;;;13893:33;;13810:123;;;:::o;13939:332::-;14029:14;14045;14061:16;14079:11;14092:15;14109:10;14135:16;14154:8;:19;14163:9;14154:19;;;;;;;;;;;14135:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14191:1;:8;;;14209:1;:8;;;14201:17;;14220:1;:11;;;14233:1;:8;;;14243:1;:12;;;14257:1;:6;;;14183:81;;;;;;;;;;;;;13939:332;;;;;;;:::o;12901:121::-;2526:21:10;:19;:21::i;:::-;12995:20:0::1;;;;;;;;;;;;;;941:15:::0;;;;;;;;;;;;;:::o;5812:137::-;1355:13:3;:11;:13::i;:::-;5877:28:0::1;5896:8;5877:18;:28::i;:::-;5933:8;5920:22;;;;;;;;;;;;5812:137:::0;:::o;963:37::-;;;;:::o;6823:1072::-;2526:21:10;:19;:21::i;:::-;6889:16:0::1;6908;6919:4;6908:10;:16::i;:::-;6889:35;;6951:8;6938:9;:21;6934:42;;6968:8;;;;;;;;;;;;;;6934:42;6987:14;7004:17;7012:8;7004:7;:17::i;:::-;6987:34;;7112:19;7162:23;7180:4;7162:17;:23::i;:::-;7153:6;:32;;;;:::i;:::-;7134:15;;:52;;;;:::i;:::-;7112:74;;7224:11;7200:21;:35;7196:64;;;7244:16;;;;;;;;;;;;;;7196:64;7294:17;;7274:9;:16;;;;:37;7270:73;;7320:23;;;;;;;;;;;;;;7270:73;7354:10;7367:3;;;;;;;;;;;:21;;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7354:36;;7435:1;7404:33;;:8;:12;7413:2;7404:12;;;;;;;;;;;:19;;;;;;;;;;;;:33;;;7400:64;;7446:18;;;;;;;;;;;;;;7400:64;7490:217;;;;;;;;7520:10;7490:217;;;;;;7560:6;7490:217;;;;;;7599:15;7490:217;;;;;;7641:5;7490:217;;;;;;7668:4;7490:217;;;;;;7692:4;7490:217;;;;::::0;7475:8:::1;:12;7484:2;7475:12;;;;;;;;;;;:232;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7718:14;7729:2;7718:10;:14::i;:::-;7760:11;7742:15;:29;;;;7812:6;7801:8;:17;;;;:::i;:::-;7781:15;;:38;;;;;;;:::i;:::-;;;;;;;;7861:2;7849:10;7835:53;;;7865:4;7871:8;7881:6;7835:53;;;;;;;;:::i;:::-;;;;;;;;6879:1016;;;;2568:20:10::0;:18;:20::i;:::-;6823:1072:0;:::o;3353:43::-;3390:6;3353:43;:::o;3715:40::-;3753:2;3715:40;:::o;1695:53::-;1742:6;1695:53;:::o;1006:27::-;;;;:::o;3130:46::-;3166:10;3130:46;:::o;1411:49::-;1457:3;1411:49;:::o;13069:278::-;1355:13:3;:11;:13::i;:::-;2526:21:10::1;:19;:21::i;:::-;13182:15:0::2;;13158:21;:39;;;;:::i;:::-;13149:6;:48;13145:89;;;13206:28;;;;;;;;;;;;;;13145:89;13245:7;13266;:5;:7::i;:::-;13258:21;;13287:6;13258:40;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13244:54;;;13313:2;13308:32;;13324:16;;;;;;;;;;;;;;13308:32;13135:212;2568:20:10::1;:18;:20::i;:::-;13069:278:0::0;:::o;11202:1129::-;2526:21:10;:19;:21::i;:::-;11276:16:0::1;11295:8;:19;11304:9;11295:19;;;;;;;;;;;11276:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;11329:1;:8;;;11328:9;:35;;;;11361:1;11341:22;;:1;:8;;;:22;;;11328:35;11324:63;;;11372:15;;;;;;;;;;;;;;11324:63;11450:7;:5;:7::i;:::-;11436:21;;:10;:21;;::::0;11432:323:::1;;1365:2;11503:1;:11;;;11495:20;;:35;;;;:::i;:::-;11477:15;:53;11473:76;;;11539:10;;;;;;;;;;;;;;11473:76;11432:323;;;11584:1;:8;;;11570:22;;:10;:22;;::::0;11566:189:::1;;1457:3;11638:1;:11;;;11630:20;;:42;;;;:::i;:::-;11612:15;:60;11608:83;;;11681:10;;;;;;;;;;;;;;11608:83;11566:189;;;11729:15;;;;;;;;;;;;;;11566:189;11432:323;11813:5;11784:8;:19;11793:9;11784:19;;;;;;;;;;;:26;;;:34;;;;;;;;;;;;;;;;;;11828:24;11842:9;11828:13;:24::i;:::-;11902:25;11920:1;:6;;;11902:17;:25::i;:::-;11890:1;:8;;;11882:17;;:45;;;;:::i;:::-;11862:15;;:66;;;;;;;:::i;:::-;;;;;;;;11967:1;:12;;;11963:293;;;12101:1;12066:13;:23;12080:1;:8;;;12066:23;;;;;;;;;;;;;;;:31;12090:1;:6;;;12066:31;;;;;;;;;;;;;;;;:36;;;;;;;:::i;:::-;;;;;;;;11963:293;;;12134:7;12155:1;:8;;;12147:22;;12185:1;:8;;;12177:17;;12147:52;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12133:66;;;12218:2;12213:32;;12229:16;;;;;;;;;;;;;;12213:32;12119:137;11963:293;12296:1;:8;;;12271:53;;12285:9;12271:53;12314:1;:8;;;12306:17;;12271:53;;;;;;:::i;:::-;;;;;;;;11266:1065;2568:20:10::0;:18;:20::i;:::-;11202:1129:0;:::o;3408:195:9:-;1764:6;1747:23;;1755:4;1747:23;;;1739:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;1861:6;1837:30;;:20;:18;:20::i;:::-;:30;;;1829:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;3489:36:::1;3507:17;3489;:36::i;:::-;3535:61;3557:17;3586:1;3576:12;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3590:5;3535:21;:61::i;:::-;3408:195:::0;:::o;13484:283:0:-;2526:21:10;:19;:21::i;:::-;13540:11:0::1;13554;:23;13566:10;13554:23;;;;;;;;;;;;;;;;13540:37;;13601:1;13595:3;:7;13587:32;;;;;;;;;;;;:::i;:::-;;;;;;;;;13655:1;13629:11;:23;13641:10;13629:23;;;;;;;;;;;;;;;:27;;;;13667:7;13688:10;13680:24;;13712:3;13680:40;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13666:54;;;13738:2;13730:30;;;;;;;;;;;;:::i;:::-;;;;;;;;;13530:237;;2568:20:10::0;:18;:20::i;:::-;13484:283:0:o;1089:38::-;;;;:::o;3922:220:9:-;1764:6;1747:23;;1755:4;1747:23;;;1739:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;1861:6;1837:30;;:20;:18;:20::i;:::-;:30;;;1829:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;4037:36:::1;4055:17;4037;:36::i;:::-;4083:52;4105:17;4124:4;4130;4083:21;:52::i;:::-;3922:220:::0;;:::o;3027:131::-;3105:7;2199:6;2182:23;;2190:4;2182:23;;;2174:92;;;;;;;;;;;;:::i;:::-;;;;;;;;;1180:66:6::1;3131:20:9;;3124:27;;3027:131:::0;:::o;2842:66:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1053:30::-;;;;:::o;14381:458::-;14458:20;14490:9;14502;:16;;;;14490:28;;14542:1;14532:6;:11;14528:40;;14566:1;14552:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14545:23;;;;;14528:40;14578:11;14601:4;14592:6;:13;;;;:::i;:::-;14578:27;;14625:1;14619:3;:7;14615:20;;;14634:1;14628:7;;14615:20;14645:14;14668:6;14662:3;:12;;;;:::i;:::-;14645:29;;14704:6;14690:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14684:27;;14726:9;14738:1;14726:13;;14721:92;14745:6;14741:1;:10;14721:92;;;14781:9;14800:1;14791:6;:10;;;;:::i;:::-;14781:21;;;;;;;;:::i;:::-;;;;;;;;;;14772:3;14776:1;14772:6;;;;;;;;:::i;:::-;;;;;;;:30;;;;;14753:3;;;;;;;14721:92;;;;14822:10;;;14381:458;;;;;:::o;3761:40::-;3799:2;3761:40;:::o;14277:98::-;14326:7;14352:9;:16;;;;14345:23;;14277:98;:::o;5955:119::-;1355:13:3;:11;:13::i;:::-;6027:6:0::1;6016:3;;:18;;;;;;;;;;;;;;;;;;6060:6;6049:18;;;;;;;;;;;;5955:119:::0;:::o;2085:101:3:-;1355:13;:11;:13::i;:::-;2149:30:::1;2176:1;2149:18;:30::i;:::-;2085:101::o:0;6230:205:0:-;1355:13:3;:11;:13::i;:::-;6318:4:0::1;6305:9;:17;;6297:42;;;;;;;;;;;;:::i;:::-;;;;;;;;;6380:9;6371:6;:18;;;;6404:24;6418:9;6404:24;;;;;;:::i;:::-;;;;;;;;6230:205:::0;:::o;1326:41::-;1365:2;1326:41;:::o;2216:43::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2657:46::-;;;;;;;;;;;;;;;;;:::o;1462:85:3:-;1508:7;1534:6;;;;;;;;;;;1527:13;;1462:85;:::o;9751:1364:0:-;5227:3;;;;;;;;;;;5205:26;;:10;:26;;;5201:48;;5240:9;;;;;;;;;;;;;;5201:48;2526:21:10::1;:19;:21::i;:::-;9876:16:0::2;9895:8;:19;9904:9;9895:19;;;;;;;;;;;9876:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;9929:1;:8;;;9928:9;:35;;;;9961:1;9941:22;;:1;:8;;;:22;;;9928:35;9924:63;;;9972:15;;;;;;;;;;;;;;9924:63;10046:5;10017:8;:19;10026:9;10017:19;;;;;;;;;;;:26;;;:34;;;;;;;;;;;;;;;;;;10061:24;10075:9;10061:13;:24::i;:::-;10135:25;10153:1;:6;;;10135:17;:25::i;:::-;10123:1;:8;;;10115:17;;:45;;;;:::i;:::-;10095:15;;:66;;;;;;;:::i;:::-;;;;;;;;10230:23;;:::i;:::-;10331:2;10309:4;10323:1;10292:34;;;;;;;;;:::i;:::-;;;;;;;;;;;;;10282:45;;;;;;10274:54;;:59;;;;:::i;:::-;10263:5;10269:1;10263:8;;;;;;;:::i;:::-;;;;;:70;;;::::0;::::2;10411:2;10389:4;10403:1;10372:34;;;;;;;;;:::i;:::-;;;;;;;;;;;;;10362:45;;;;;;10354:54;;:59;;;;:::i;:::-;10343:5;10349:1;10343:8;;;;;;;:::i;:::-;;;;;:70;;;::::0;::::2;10491:2;10469:4;10483:1;10452:34;;;;;;;;;:::i;:::-;;;;;;;;;;;;;10442:45;;;;;;10434:54;;:59;;;;:::i;:::-;10423:5;10429:1;10423:8;;;;;;;:::i;:::-;;;;;:70;;;::::0;::::2;10571:2;10549:4;10563:1;10532:34;;;;;;;;;:::i;:::-;;;;;;;;;;;;;10522:45;;;;;;10514:54;;:59;;;;:::i;:::-;10503:5;10509:1;10503:8;;;;;;;:::i;:::-;;;;;:70;;;::::0;::::2;10651:2;10629:4;10643:1;10612:34;;;;;;;;;:::i;:::-;;;;;;;;;;;;;10602:45;;;;;;10594:54;;:59;;;;:::i;:::-;10583:5;10589:1;10583:8;;;;;;;:::i;:::-;;;;;:70;;;::::0;::::2;10664:14;10681:50;10698:1;:6;;;10706:5;10721:1;:8;;;10713:17;;10681:16;:50::i;:::-;10664:67;;10779:1;10770:6;:10;10766:237;;;10797:7;10818:1;:8;;;10810:22;;10840:6;10810:41;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10796:55;;;10870:2;10865:128;;10917:6;10892:11;:21;10904:1;:8;;;10892:21;;;;;;;;;;;;;;;;:31;;;;;;;:::i;:::-;;;;;;;;10961:1;:8;;;10946:32;;;10971:6;10946:32;;;;;;:::i;:::-;;;;;;;;10865:128;10782:221;10766:237;11040:1;:8;;;11018:90;;11029:9;11018:90;11058:1;:8;;;11050:17;;11069:5;11076:6;11084:15;11101:1;:6;;;11018:90;;;;;;;;;;:::i;:::-;;;;;;;;9866:1249;;;2568:20:10::1;:18;:20::i;:::-;9751:1364:0::0;;;:::o;12463:381::-;2526:21:10;:19;:21::i;:::-;12580:1:0::1;12565:12;:16;12557:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;12605:16;12624;12635:4;12624:10;:16::i;:::-;12605:35;;12682:12;12671:8;:23;;;;:::i;:::-;12658:9;:36;12650:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;12751:12;12716:13;:25;12730:10;12716:25;;;;;;;;;;;;;;;:31;12742:4;12716:31;;;;;;;;;;;;;;;;:47;;;;;;;:::i;:::-;;;;;;;;12795:10;12778:59;;;12807:4;12813:12;12827:9;12778:59;;;;;;;;:::i;:::-;;;;;;;;12547:297;2568:20:10::0;:18;:20::i;:::-;12463:381:0;;:::o;1267:30::-;;;;:::o;6080:144::-;1355:13:3;:11;:13::i;:::-;6163:11:0::1;6151:9;:23;;;;6189:28;6205:11;6189:28;;;;;;:::i;:::-;;;;;;;;6080:144:::0;:::o;3428:43::-;3465:6;3428:43;:::o;13028:35::-;:::o;9587:92::-;2526:21:10;:19;:21::i;:::-;9652:20:0::1;;;;;;;;;;;;;;5316:341:::0;3279:19:8;3302:13;;;;;;;;;;;3301:14;3279:36;;3347:14;:34;;;;;3380:1;3365:12;;;;;;;;;;;:16;;;3347:34;3346:108;;;;3388:44;3426:4;3388:29;:44::i;:::-;3387:45;:66;;;;;3452:1;3436:12;;;;;;;;;;;:17;;;3387:66;3346:108;3325:201;;;;;;;;;;;;:::i;:::-;;;;;;;;;3551:1;3536:12;;:16;;;;;;;;;;;;;;;;;;3566:14;3562:65;;;3612:4;3596:13;;:20;;;;;;;;;;;;;;;;;;3562:65;5382:24:0::1;:22;:24::i;:::-;5416:16;:14;:16::i;:::-;5442:24;:22;:24::i;:::-;5488:7;5477:3;;:19;;;;;;;;;;;;;;;;;;5579:10;5567:9;:22;;;;5608:3;5599:6;:12;;;;5647:3;5627:17;:23;;;;3651:14:8::0;3647:99;;;3697:5;3681:13;;:21;;;;;;;;;;;;;;;;;;3721:14;3733:1;3721:14;;;;;;:::i;:::-;;;;;;;;3647:99;3269:483;5316:341:0;:::o;3078:46::-;3114:10;3078:46;:::o;3501:42::-;3538:5;3501:42;:::o;3026:46::-;3062:10;3026:46;:::o;8059:1347::-;2526:21:10;:19;:21::i;:::-;8127:16:0::1;8146;8157:4;8146:10;:16::i;:::-;8127:35;;8244:9;8256:13;:25;8270:10;8256:25;;;;;;;;;;;;;;;:31;8282:4;8256:31;;;;;;;;;;;;;;;;8244:43;;8306:1;8301;:6;8297:273;;8373:1;8369;:5;8335:13;:25;8349:10;8335:25;;;;;;;;;;;;;;;:31;8361:4;8335:31;;;;;;;;;;;;;;;:39;;;;8297:273;;;8405:1;8397:4;:9;;;:37;;;;;8433:1;8410:7;:19;8418:10;8410:19;;;;;;;;;;;;;;;;:24;;8397:37;8393:177;;;8506:1;8484:7;:19;8492:10;8484:19;;;;;;;;;;;;;;;;:23;8462:7;:19;8470:10;8462:19;;;;;;;;;;;;;;;:45;;;;8393:177;;;8540:19;;;;;;;;;;:::i;:::-;;;;;;;;8393:177;8297:273;8580:14;8597:17;8605:8;8597:7;:17::i;:::-;8580:34;;8624:19;8674:23;8692:4;8674:17;:23::i;:::-;8665:6;:32;;;;:::i;:::-;8646:15;;:52;;;;:::i;:::-;8624:74;;8736:11;8712:21;:35;8708:64;;;8756:16;;;;;;;;;;;;;;8708:64;8806:17;;8786:9;:16;;;;:37;8782:73;;8832:23;;;;;;;;;;;;;;8782:73;8866:10;8879:3;;;;;;;;;;;:21;;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8866:36;;8947:1;8916:33;;:8;:12;8925:2;8916:12;;;;;;;;;;;:19;;;;;;;;;;;;:33;;;8912:64;;8958:18;;;;;;;;;;;;;;8912:64;9002:216;;;;;;;;9032:10;9002:216;;;;;;9072:6;9002:216;;;;;;9111:15;9002:216;;;;;;9153:4;9002:216;;;;;;9179:4;9002:216;;;;;;9203:4;9002:216;;;;::::0;8987:8:::1;:12;8996:2;8987:12;;;;;;;;;;;:231;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9229:14;9240:2;9229:10;:14::i;:::-;9271:11;9253:15;:29;;;;9323:6;9312:8;:17;;;;:::i;:::-;9292:15;;:38;;;;;;;:::i;:::-;;;;;;;;9372:2;9360:10;9346:53;;;9376:4;9382:8;9392:6;9346:53;;;;;;;;:::i;:::-;;;;;;;;8117:1289;;;;;2568:20:10::0;:18;:20::i;:::-;8059:1347:0;:::o;3669:40::-;3707:2;3669:40;:::o;6441:193::-;1355:13:3;:11;:13::i;:::-;6533:1:0::1;6524:6;:10;6516:28;;;;;;;;;;;;:::i;:::-;;;;;;;;;6574:6;6554:17;:26;;;;6595:32;6620:6;6595:32;;;;;;:::i;:::-;;;;;;;;6441:193:::0;:::o;9491:90::-;2526:21:10;:19;:21::i;:::-;9554:20:0::1;;;;;;;;;;;;;;2335:198:3::0;1355:13;:11;:13::i;:::-;2443:1:::1;2423:22;;:8;:22;;::::0;2415:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;2498:28;2517:8;2498:18;:28::i;:::-;2335:198:::0;:::o;2521:42:0:-;;;;;;;;;;;;;;;;;:::o;2601:287:10:-;1851:1;2733:7;;:19;2725:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;1851:1;2863:7;:18;;;;2601:287::o;2894:209::-;1808:1;3074:7;:22;;;;2894:209::o;1620:130:3:-;1694:12;:10;:12::i;:::-;1683:23;;:7;:5;:7::i;:::-;:23;;;1675:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;1620:130::o;2687:187::-;2760:16;2779:6;;;;;;;;;;;2760:25;;2804:8;2795:6;;:17;;;;;;;;;;;;;;;;;;2858:8;2827:40;;2848:8;2827:40;;;;;;;;;;;;2750:124;2687:187;:::o;15665:224:0:-;15720:7;15751:1;15743:4;:9;;;15739:31;;3062:10;15754:16;;;;15739:31;15792:1;15784:4;:9;;;15780:31;;3114:10;15795:16;;;;15780:31;15833:1;15825:4;:9;;;15821:31;;3166:10;15836:16;;;;15821:31;15869:13;;;;;;;;;;;;;;15665:224;;;;:::o;15502:157::-;15560:7;15579:11;15615:6;15605;;15594:8;:17;;;;:::i;:::-;15593:28;;;;:::i;:::-;15579:42;;15649:3;15638:8;:14;;;;:::i;:::-;15631:21;;;15502:157;;;:::o;16699:281::-;16761:7;16780:12;16795:21;16811:4;16795:15;:21::i;:::-;16780:36;;16826:14;16852:1;16844:4;:9;;;16843:64;;16879:1;16871:4;:9;;;16870:37;;3538:5;16870:37;;;3465:6;16870:37;16843:64;;;3390:6;16843:64;16826:81;;16950:6;16941:5;16932:6;16925:4;:13;;;;:::i;:::-;:21;;;;:::i;:::-;16924:32;;;;:::i;:::-;16917:39;;;;16699:281;;;:::o;14886:131::-;14937:9;14952:2;14937:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14983:9;:16;;;;14965:11;:15;14977:2;14965:15;;;;;;;;;;;:34;;;;14886:131;:::o;15023:348::-;15077:12;15092:11;:15;15104:2;15092:15;;;;;;;;;;;;15077:30;;15129:1;15121:4;:9;15117:22;;15132:7;;;15117:22;15167:9;15186:1;15179:4;:8;;;;:::i;:::-;15167:20;;15197:12;15212:9;15241:1;15222:9;:16;;;;:20;;;;:::i;:::-;15212:31;;;;;;;;:::i;:::-;;;;;;;;;;15197:46;;15268:4;15253:9;15263:1;15253:12;;;;;;;;:::i;:::-;;;;;;;;;:19;;;;15306:1;15302;:5;;;;:::i;:::-;15282:11;:17;15294:4;15282:17;;;;;;;;;;;:25;;;;15317:9;:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;15349:11;:15;15361:2;15349:15;;;;;;;;;;;15342:22;;;15067:304;;;15023:348;;:::o;1478:151:6:-;1531:7;1557:59;1180:66;1595:20;;1557:37;:59::i;:::-;:65;;;;;;;;;;;;1550:72;;1478:151;:::o;13394:84:0:-;1355:13:3;:11;:13::i;:::-;13394:84:0;:::o;2841:944:6:-;3257:53;839:66;3295:14;;3257:37;:53::i;:::-;:59;;;;;;;;;;;;3253:526;;;3332:37;3351:17;3332:18;:37::i;:::-;3253:526;;;3433:17;3404:61;;;:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;3400:302;;3631:56;;;;;;;;;;:::i;:::-;;;;;;;;3400:302;1180:66;3525:20;;3517:4;:28;3509:82;;;;;;;;;;;;:::i;:::-;;;;;;;;;3468:138;3715:53;3733:17;3752:4;3758:9;3715:17;:53::i;:::-;3253:526;2841:944;;;:::o;16198:428:0:-;16297:7;16316:11;16330:34;16347:4;16353:5;16360:3;16330:16;:34::i;:::-;16316:48;;16374:14;16400:1;16392:4;:9;;;16391:64;;16427:1;16419:4;:9;;;16418:37;;3538:5;16418:37;;;3465:6;16418:37;16391:64;;;3390:6;16391:64;16374:81;;16465:14;16499:6;16489;16483:3;:12;;;;:::i;:::-;16482:23;;;;:::i;:::-;16465:40;;16515:11;16535:21;16551:4;16535:15;:21::i;:::-;16529:3;:27;;;;:::i;:::-;16515:41;;16579:3;16570:6;:12;16566:30;;;16593:3;16584:12;;16566:30;16613:6;16606:13;;;;;;16198:428;;;;;:::o;1423:320:11:-;1483:4;1735:1;1713:7;:19;;;:23;1706:30;;1423:320;;;:::o;2290:67:9:-;5374:13:8;;;;;;;;;;;5366:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;2290:67:9:o;1024:95:3:-;5374:13:8;;;;;;;;;;;5366:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;1086:26:3::1;:24;:26::i;:::-;1024:95::o:0;1889:111:10:-;5374:13:8;;;;;;;;;;;5366:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;1959:34:10::1;:32;:34::i;:::-;1889:111::o:0;886:96:12:-;939:7;965:10;958:17;;886:96;:::o;15895:235:0:-;15955:7;15986:1;15978:4;:9;;;15974:33;;3707:2;15989:18;;;;15974:33;16029:1;16021:4;:9;;;16017:33;;3753:2;16032:18;;;;16017:33;16072:1;16064:4;:9;;;16060:33;;3799:2;16075:18;;;;16060:33;16110:13;;;;;;;;;;;;;;15895:235;;;;:::o;1870:190:13:-;1931:21;2040:4;2030:14;;1870:190;;;:::o;2158:::-;2219:21;2328:4;2318:14;;2158:190;;;:::o;1720:281:6:-;1801:48;1831:17;1801:29;:48::i;:::-;1793:106;;;;;;;;;;;;:::i;:::-;;;;;;;;;1977:17;1909:59;1180:66;1947:20;;1909:37;:59::i;:::-;:65;;;:85;;;;;;;;;;;;;;;;;;1720:281;:::o;2393:276::-;2501:29;2512:17;2501:10;:29::i;:::-;2558:1;2544:4;:11;:15;:28;;;;2563:9;2544:28;2540:123;;;2588:64;2628:17;2647:4;2588:39;:64::i;:::-;;2540:123;2393:276;;;:::o;16986:1304:0:-;17085:7;17104:15;17131:1;17123:4;:9;;;17122:67;;17159:1;17151:4;:9;;;17150:39;;3799:2;17150:39;;;3753:2;17150:39;17122:67;;;3707:2;17122:67;17104:85;;17261:1;17249:5;17255:1;17249:8;;;;;;;:::i;:::-;;;;;;:13;:30;;;;;17278:1;17266:5;17272:1;17266:8;;;;;;;:::i;:::-;;;;;;:13;17249:30;:47;;;;;17295:1;17283:5;17289:1;17283:8;;;;;;;:::i;:::-;;;;;;:13;17249:47;:64;;;;;17312:1;17300:5;17306:1;17300:8;;;;;;;:::i;:::-;;;;;;:13;17249:64;:81;;;;;17329:1;17317:5;17323:1;17317:8;;;;;;;:::i;:::-;;;;;;:13;17249:81;17245:132;;;17359:7;17353:3;:13;;;;:::i;:::-;17346:20;;;;;17245:132;17449:21;17464:5;17449:14;:21::i;:::-;:38;;;;;17486:1;17474:5;17480:1;17474:8;;;;;;;:::i;:::-;;;;;;:13;;17449:38;17445:95;;;17528:1;17517:7;17511:3;:13;;;;:::i;:::-;17510:19;;;;:::i;:::-;17503:26;;;;;17445:95;17604:21;17619:5;17604:14;:21::i;:::-;17600:67;;;17654:2;17648:3;:8;;;;:::i;:::-;17641:15;;;;;17600:67;17707:19;17720:5;17707:12;:19::i;:::-;17703:64;;;17755:1;17749:3;:7;;;;:::i;:::-;17742:14;;;;;17703:64;17826:22;17842:5;17826:15;:22::i;:::-;17822:67;;;17877:1;17871:3;:7;;;;:::i;:::-;17864:14;;;;;17822:67;17932:18;17944:5;17932:11;:18::i;:::-;17928:90;;;17973:34;17981:3;1742:6;17973:7;:34::i;:::-;17966:41;;;;;17928:90;18077:12;18091:17;18112:20;18126:5;18112:13;:20::i;:::-;18076:56;;;;18146:7;:25;;;;;18170:1;18157:9;:14;;18146:25;18142:66;;;18194:3;18187:10;;;;;;;18142:66;18282:1;18275:8;;;;;16986:1304;;;;;;:::o;1125:111:3:-;5374:13:8;;;;;;;;;;;5366:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;1197:32:3::1;1216:12;:10;:12::i;:::-;1197:18;:32::i;:::-;1125:111::o:0;2006:109:10:-;5374:13:8;;;;;;;;;;;5366:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;1808:1:10::1;2086:7;:22;;;;2006:109::o:0;2107:152:6:-;2173:37;2192:17;2173:18;:37::i;:::-;2234:17;2225:27;;;;;;;;;;;;2107:152;:::o;6685:198:11:-;6768:12;6799:77;6820:6;6828:4;6799:77;;;;;;;;;;;;;;;;;:20;:77::i;:::-;6792:84;;6685:198;;;;:::o;18296:194:0:-;18368:4;18403:5;18409:1;18403:8;;;;;;;:::i;:::-;;;;;;18391:5;18397:1;18391:8;;;;;;;:::i;:::-;;;;;;:20;:44;;;;;18427:5;18433:1;18427:8;;;;;;;:::i;:::-;;;;;;18415:5;18421:1;18415:8;;;;;;;:::i;:::-;;;;;;:20;18391:44;:68;;;;;18451:5;18457:1;18451:8;;;;;;;:::i;:::-;;;;;;18439:5;18445:1;18439:8;;;;;;;:::i;:::-;;;;;;:20;18391:68;:92;;;;;18475:5;18481:1;18475:8;;;;;;;:::i;:::-;;;;;;18463:5;18469:1;18463:8;;;;;;;:::i;:::-;;;;;;:20;18391:92;18384:99;;18296:194;;;:::o;18496:276::-;18568:4;18584:25;;:::i;:::-;18624:9;18636:1;18624:13;;18619:50;18643:1;18639;:5;18619:50;;;18651:6;18658:5;18664:1;18658:8;;;;;;;:::i;:::-;;;;;;18651:16;;;;;;;:::i;:::-;;;;;:18;;;;;;;;:::i;:::-;;;;;18646:3;;;;;;;18619:50;;;;18684:9;18696:1;18684:13;;18679:64;18703:2;18699:1;:6;18679:64;;;18729:1;18716:6;18723:1;18716:9;;;;;;;:::i;:::-;;;;;;:14;18712:31;;18739:4;18732:11;;;;;;18712:31;18707:3;;;;;;;18679:64;;;;18760:5;18753:12;;;18496:276;;;;:::o;18778:422::-;18848:4;18864:25;;:::i;:::-;18904:9;18916:1;18904:13;;18899:50;18923:1;18919;:5;18899:50;;;18931:6;18938:5;18944:1;18938:8;;;;;;;:::i;:::-;;;;;;18931:16;;;;;;;:::i;:::-;;;;;:18;;;;;;;;:::i;:::-;;;;;18926:3;;;;;;;18899:50;;;;18959:13;18975:5;18959:21;;18990:11;19004:5;18990:19;;19024:9;19036:1;19024:13;;19019:140;19043:2;19039:1;:6;19019:140;;;19083:1;19070:6;19077:1;19070:9;;;;;;;:::i;:::-;;;;;;:14;19066:35;;19097:4;19086:15;;19066:35;19132:1;19119:6;19126:1;19119:9;;;;;;;:::i;:::-;;;;;;:14;19115:33;;19144:4;19135:13;;19115:33;19047:3;;;;;;;19019:140;;;;19175:8;:18;;;;;19187:6;19175:18;19168:25;;;;;18778:422;;;:::o;19206:277::-;19279:4;19295:25;;:::i;:::-;19335:9;19347:1;19335:13;;19330:50;19354:1;19350;:5;19330:50;;;19362:6;19369:5;19375:1;19369:8;;;;;;;:::i;:::-;;;;;;19362:16;;;;;;;:::i;:::-;;;;;:18;;;;;;;;:::i;:::-;;;;;19357:3;;;;;;;19330:50;;;;19395:9;19407:1;19395:13;;19390:64;19414:2;19410:1;:6;19390:64;;;19440:1;19427:6;19434:1;19427:9;;;;;;;:::i;:::-;;;;;;:14;19423:31;;19450:4;19443:11;;;;;;19423:31;19418:3;;;;;;;19390:64;;;;19471:5;19464:12;;;19206:277;;;;:::o;19489:301::-;19558:4;19574:25;;:::i;:::-;19614:9;19626:1;19614:13;;19609:50;19633:1;19629;:5;19609:50;;;19641:6;19648:5;19654:1;19648:8;;;;;;;:::i;:::-;;;;;;19641:16;;;;;;;:::i;:::-;;;;;:18;;;;;;;;:::i;:::-;;;;;19636:3;;;;;;;19609:50;;;;19669:13;19685:1;19669:17;;19701:9;19713:1;19701:13;;19696:60;19720:2;19716:1;:6;19696:60;;;19746:1;19733:6;19740:1;19733:9;;;;;;;:::i;:::-;;;;;;:14;19729:27;;19749:7;;;;;:::i;:::-;;;;19729:27;19724:3;;;;;;;19696:60;;;;19782:1;19773:5;:10;19766:17;;;;19489:301;;;:::o;15377:119::-;15443:7;15483:6;15476:3;15470;:9;;;;:::i;:::-;15469:20;;;;:::i;:::-;15462:27;;15377:119;;;;:::o;19796:700::-;19867:12;19881:17;19910:25;;:::i;:::-;19950:9;19962:1;19950:13;;19945:50;19969:1;19965;:5;19945:50;;;19977:6;19984:5;19990:1;19984:8;;;;;;;:::i;:::-;;;;;;19977:16;;;;;;;:::i;:::-;;;;;:18;;;;;;;;:::i;:::-;;;;;19972:3;;;;;;;19945:50;;;;20005:13;20021:1;20005:17;;20032:13;20048:1;20032:17;;20064:9;20076:1;20064:13;;20059:334;20083:2;20079:1;:6;20059:334;;;20123:1;20110:6;20117:1;20110:9;;;;;;;:::i;:::-;;;;;;:14;20106:277;;20144:7;;;;;:::i;:::-;;;;20177:1;20169:9;;20208:1;20200:5;:9;20211:5;20196:20;20106:277;;;20253:1;20241:6;20248:1;20241:9;;;;;;;:::i;:::-;;;;;;:13;20237:146;;;20359:5;20366:1;20351:17;;;;;;;;;;20237:146;20106:277;20087:3;;;;;;;20059:334;;;;20415:1;20406:5;:10;20402:61;;20440:4;20446:5;20432:20;;;;;;;;;20402:61;20480:5;20487:1;20472:17;;;;;;;19796:700;;;;:::o;7069:325:11:-;7210:12;7235;7249:23;7276:6;:19;;7296:4;7276:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7234:67;;;;7318:69;7345:6;7353:7;7362:10;7374:12;7318:26;:69::i;:::-;7311:76;;;;7069:325;;;;;:::o;7682:628::-;7862:12;7890:7;7886:418;;;7938:1;7917:10;:17;:22;7913:286;;8132:18;8143:6;8132:10;:18::i;:::-;8124:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;7913:286;8219:10;8212:17;;;;7886:418;8260:33;8268:10;8280:12;8260:7;:33::i;:::-;7682:628;;;;;;;:::o;8832:540::-;9011:1;8991:10;:17;:21;8987:379;;;9219:10;9213:17;9275:15;9262:10;9258:2;9254:19;9247:44;8987:379;9342:12;9335:20;;;;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:28:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:139::-;591:5;629:6;616:20;607:29;;645:33;672:5;645:33;:::i;:::-;545:139;;;;:::o;690:329::-;749:6;798:2;786:9;777:7;773:23;769:32;766:119;;;804:79;;:::i;:::-;766:119;924:1;949:53;994:7;985:6;974:9;970:22;949:53;:::i;:::-;939:63;;895:117;690:329;;;;:::o;1025:90::-;1059:7;1102:5;1095:13;1088:21;1077:32;;1025:90;;;:::o;1121:109::-;1202:21;1217:5;1202:21;:::i;:::-;1197:3;1190:34;1121:109;;:::o;1236:210::-;1323:4;1361:2;1350:9;1346:18;1338:26;;1374:65;1436:1;1425:9;1421:17;1412:6;1374:65;:::i;:::-;1236:210;;;;:::o;1452:126::-;1489:7;1529:42;1522:5;1518:54;1507:65;;1452:126;;;:::o;1584:96::-;1621:7;1650:24;1668:5;1650:24;:::i;:::-;1639:35;;1584:96;;;:::o;1686:118::-;1773:24;1791:5;1773:24;:::i;:::-;1768:3;1761:37;1686:118;;:::o;1810:::-;1897:24;1915:5;1897:24;:::i;:::-;1892:3;1885:37;1810:118;;:::o;1934:101::-;1970:7;2010:18;2003:5;1999:30;1988:41;;1934:101;;;:::o;2041:115::-;2126:23;2143:5;2126:23;:::i;:::-;2121:3;2114:36;2041:115;;:::o;2162:86::-;2197:7;2237:4;2230:5;2226:16;2215:27;;2162:86;;;:::o;2254:112::-;2337:22;2353:5;2337:22;:::i;:::-;2332:3;2325:35;2254:112;;:::o;2372:739::-;2587:4;2625:3;2614:9;2610:19;2602:27;;2639:71;2707:1;2696:9;2692:17;2683:6;2639:71;:::i;:::-;2720:72;2788:2;2777:9;2773:18;2764:6;2720:72;:::i;:::-;2802:70;2868:2;2857:9;2853:18;2844:6;2802:70;:::i;:::-;2882:66;2944:2;2933:9;2929:18;2920:6;2882:66;:::i;:::-;2958:67;3020:3;3009:9;3005:19;2996:6;2958:67;:::i;:::-;3035:69;3099:3;3088:9;3084:19;3075:6;3035:69;:::i;:::-;2372:739;;;;;;;;;:::o;3117:60::-;3145:3;3166:5;3159:12;;3117:60;;;:::o;3183:142::-;3233:9;3266:53;3284:34;3293:24;3311:5;3293:24;:::i;:::-;3284:34;:::i;:::-;3266:53;:::i;:::-;3253:66;;3183:142;;;:::o;3331:126::-;3381:9;3414:37;3445:5;3414:37;:::i;:::-;3401:50;;3331:126;;;:::o;3463:137::-;3524:9;3557:37;3588:5;3557:37;:::i;:::-;3544:50;;3463:137;;;:::o;3606:153::-;3704:48;3746:5;3704:48;:::i;:::-;3699:3;3692:61;3606:153;;:::o;3765:244::-;3869:4;3907:2;3896:9;3892:18;3884:26;;3920:82;3999:1;3988:9;3984:17;3975:6;3920:82;:::i;:::-;3765:244;;;;:::o;4015:122::-;4088:24;4106:5;4088:24;:::i;:::-;4081:5;4078:35;4068:63;;4127:1;4124;4117:12;4068:63;4015:122;:::o;4143:139::-;4189:5;4227:6;4214:20;4205:29;;4243:33;4270:5;4243:33;:::i;:::-;4143:139;;;;:::o;4288:329::-;4347:6;4396:2;4384:9;4375:7;4371:23;4367:32;4364:119;;;4402:79;;:::i;:::-;4364:119;4522:1;4547:53;4592:7;4583:6;4572:9;4568:22;4547:53;:::i;:::-;4537:63;;4493:117;4288:329;;;;:::o;4623:222::-;4716:4;4754:2;4743:9;4739:18;4731:26;;4767:71;4835:1;4824:9;4820:17;4811:6;4767:71;:::i;:::-;4623:222;;;;:::o;4851:118::-;4922:22;4938:5;4922:22;:::i;:::-;4915:5;4912:33;4902:61;;4959:1;4956;4949:12;4902:61;4851:118;:::o;4975:135::-;5019:5;5057:6;5044:20;5035:29;;5073:31;5098:5;5073:31;:::i;:::-;4975:135;;;;:::o;5116:325::-;5173:6;5222:2;5210:9;5201:7;5197:23;5193:32;5190:119;;;5228:79;;:::i;:::-;5190:119;5348:1;5373:51;5416:7;5407:6;5396:9;5392:22;5373:51;:::i;:::-;5363:61;;5319:115;5116:325;;;;:::o;5447:117::-;5556:1;5553;5546:12;5570:117;5679:1;5676;5669:12;5693:102;5734:6;5785:2;5781:7;5776:2;5769:5;5765:14;5761:28;5751:38;;5693:102;;;:::o;5801:180::-;5849:77;5846:1;5839:88;5946:4;5943:1;5936:15;5970:4;5967:1;5960:15;5987:281;6070:27;6092:4;6070:27;:::i;:::-;6062:6;6058:40;6200:6;6188:10;6185:22;6164:18;6152:10;6149:34;6146:62;6143:88;;;6211:18;;:::i;:::-;6143:88;6251:10;6247:2;6240:22;6030:238;5987:281;;:::o;6274:129::-;6308:6;6335:20;;:::i;:::-;6325:30;;6364:33;6392:4;6384:6;6364:33;:::i;:::-;6274:129;;;:::o;6409:307::-;6470:4;6560:18;6552:6;6549:30;6546:56;;;6582:18;;:::i;:::-;6546:56;6620:29;6642:6;6620:29;:::i;:::-;6612:37;;6704:4;6698;6694:15;6686:23;;6409:307;;;:::o;6722:148::-;6820:6;6815:3;6810;6797:30;6861:1;6852:6;6847:3;6843:16;6836:27;6722:148;;;:::o;6876:423::-;6953:5;6978:65;6994:48;7035:6;6994:48;:::i;:::-;6978:65;:::i;:::-;6969:74;;7066:6;7059:5;7052:21;7104:4;7097:5;7093:16;7142:3;7133:6;7128:3;7124:16;7121:25;7118:112;;;7149:79;;:::i;:::-;7118:112;7239:54;7286:6;7281:3;7276;7239:54;:::i;:::-;6959:340;6876:423;;;;;:::o;7318:338::-;7373:5;7422:3;7415:4;7407:6;7403:17;7399:27;7389:122;;7430:79;;:::i;:::-;7389:122;7547:6;7534:20;7572:78;7646:3;7638:6;7631:4;7623:6;7619:17;7572:78;:::i;:::-;7563:87;;7379:277;7318:338;;;;:::o;7662:652::-;7739:6;7747;7796:2;7784:9;7775:7;7771:23;7767:32;7764:119;;;7802:79;;:::i;:::-;7764:119;7922:1;7947:53;7992:7;7983:6;7972:9;7968:22;7947:53;:::i;:::-;7937:63;;7893:117;8077:2;8066:9;8062:18;8049:32;8108:18;8100:6;8097:30;8094:117;;;8130:79;;:::i;:::-;8094:117;8235:62;8289:7;8280:6;8269:9;8265:22;8235:62;:::i;:::-;8225:72;;8020:287;7662:652;;;;;:::o;8320:77::-;8357:7;8386:5;8375:16;;8320:77;;;:::o;8403:118::-;8490:24;8508:5;8490:24;:::i;:::-;8485:3;8478:37;8403:118;;:::o;8527:222::-;8620:4;8658:2;8647:9;8643:18;8635:26;;8671:71;8739:1;8728:9;8724:17;8715:6;8671:71;:::i;:::-;8527:222;;;;:::o;8755:470::-;8821:6;8829;8878:2;8866:9;8857:7;8853:23;8849:32;8846:119;;;8884:79;;:::i;:::-;8846:119;9004:1;9029:53;9074:7;9065:6;9054:9;9050:22;9029:53;:::i;:::-;9019:63;;8975:117;9131:2;9157:51;9200:7;9191:6;9180:9;9176:22;9157:51;:::i;:::-;9147:61;;9102:116;8755:470;;;;;:::o;9231:474::-;9299:6;9307;9356:2;9344:9;9335:7;9331:23;9327:32;9324:119;;;9362:79;;:::i;:::-;9324:119;9482:1;9507:53;9552:7;9543:6;9532:9;9528:22;9507:53;:::i;:::-;9497:63;;9453:117;9609:2;9635:53;9680:7;9671:6;9660:9;9656:22;9635:53;:::i;:::-;9625:63;;9580:118;9231:474;;;;;:::o;9711:114::-;9778:6;9812:5;9806:12;9796:22;;9711:114;;;:::o;9831:184::-;9930:11;9964:6;9959:3;9952:19;10004:4;9999:3;9995:14;9980:29;;9831:184;;;;:::o;10021:132::-;10088:4;10111:3;10103:11;;10141:4;10136:3;10132:14;10124:22;;10021:132;;;:::o;10159:108::-;10236:24;10254:5;10236:24;:::i;:::-;10231:3;10224:37;10159:108;;:::o;10273:179::-;10342:10;10363:46;10405:3;10397:6;10363:46;:::i;:::-;10441:4;10436:3;10432:14;10418:28;;10273:179;;;;:::o;10458:113::-;10528:4;10560;10555:3;10551:14;10543:22;;10458:113;;;:::o;10607:732::-;10726:3;10755:54;10803:5;10755:54;:::i;:::-;10825:86;10904:6;10899:3;10825:86;:::i;:::-;10818:93;;10935:56;10985:5;10935:56;:::i;:::-;11014:7;11045:1;11030:284;11055:6;11052:1;11049:13;11030:284;;;11131:6;11125:13;11158:63;11217:3;11202:13;11158:63;:::i;:::-;11151:70;;11244:60;11297:6;11244:60;:::i;:::-;11234:70;;11090:224;11077:1;11074;11070:9;11065:14;;11030:284;;;11034:14;11330:3;11323:10;;10731:608;;;10607:732;;;;:::o;11345:373::-;11488:4;11526:2;11515:9;11511:18;11503:26;;11575:9;11569:4;11565:20;11561:1;11550:9;11546:17;11539:47;11603:108;11706:4;11697:6;11603:108;:::i;:::-;11595:116;;11345:373;;;;:::o;11724:118::-;11761:7;11801:34;11794:5;11790:46;11779:57;;11724:118;;;:::o;11848:::-;11935:24;11953:5;11935:24;:::i;:::-;11930:3;11923:37;11848:118;;:::o;11972:739::-;12187:4;12225:3;12214:9;12210:19;12202:27;;12239:71;12307:1;12296:9;12292:17;12283:6;12239:71;:::i;:::-;12320:72;12388:2;12377:9;12373:18;12364:6;12320:72;:::i;:::-;12402:70;12468:2;12457:9;12453:18;12444:6;12402:70;:::i;:::-;12482:66;12544:2;12533:9;12529:18;12520:6;12482:66;:::i;:::-;12558:67;12620:3;12609:9;12605:19;12596:6;12558:67;:::i;:::-;12635:69;12699:3;12688:9;12684:19;12675:6;12635:69;:::i;:::-;11972:739;;;;;;;;;:::o;12717:222::-;12810:4;12848:2;12837:9;12833:18;12825:26;;12861:71;12929:1;12918:9;12914:17;12905:6;12861:71;:::i;:::-;12717:222;;;;:::o;12945:619::-;13022:6;13030;13038;13087:2;13075:9;13066:7;13062:23;13058:32;13055:119;;;13093:79;;:::i;:::-;13055:119;13213:1;13238:53;13283:7;13274:6;13263:9;13259:22;13238:53;:::i;:::-;13228:63;;13184:117;13340:2;13366:53;13411:7;13402:6;13391:9;13387:22;13366:53;:::i;:::-;13356:63;;13311:118;13468:2;13494:53;13539:7;13530:6;13519:9;13515:22;13494:53;:::i;:::-;13484:63;;13439:118;12945:619;;;;;:::o;13570:470::-;13636:6;13644;13693:2;13681:9;13672:7;13668:23;13664:32;13661:119;;;13699:79;;:::i;:::-;13661:119;13819:1;13844:51;13887:7;13878:6;13867:9;13863:22;13844:51;:::i;:::-;13834:61;;13790:115;13944:2;13970:53;14015:7;14006:6;13995:9;13991:22;13970:53;:::i;:::-;13960:63;;13915:118;13570:470;;;;;:::o;14046:180::-;14094:77;14091:1;14084:88;14191:4;14188:1;14181:15;14215:4;14212:1;14205:15;14232:410;14272:7;14295:20;14313:1;14295:20;:::i;:::-;14290:25;;14329:20;14347:1;14329:20;:::i;:::-;14324:25;;14384:1;14381;14377:9;14406:30;14424:11;14406:30;:::i;:::-;14395:41;;14585:1;14576:7;14572:15;14569:1;14566:22;14546:1;14539:9;14519:83;14496:139;;14615:18;;:::i;:::-;14496:139;14280:362;14232:410;;;;:::o;14648:191::-;14688:3;14707:20;14725:1;14707:20;:::i;:::-;14702:25;;14741:20;14759:1;14741:20;:::i;:::-;14736:25;;14784:1;14781;14777:9;14770:16;;14805:3;14802:1;14799:10;14796:36;;;14812:18;;:::i;:::-;14796:36;14648:191;;;;:::o;14845:143::-;14902:5;14933:6;14927:13;14918:22;;14949:33;14976:5;14949:33;:::i;:::-;14845:143;;;;:::o;14994:351::-;15064:6;15113:2;15101:9;15092:7;15088:23;15084:32;15081:119;;;15119:79;;:::i;:::-;15081:119;15239:1;15264:64;15320:7;15311:6;15300:9;15296:22;15264:64;:::i;:::-;15254:74;;15210:128;14994:351;;;;:::o;15351:194::-;15391:4;15411:20;15429:1;15411:20;:::i;:::-;15406:25;;15445:20;15463:1;15445:20;:::i;:::-;15440:25;;15489:1;15486;15482:9;15474:17;;15513:1;15507:4;15504:11;15501:37;;;15518:18;;:::i;:::-;15501:37;15351:194;;;;:::o;15551:434::-;15696:4;15734:2;15723:9;15719:18;15711:26;;15747:67;15811:1;15800:9;15796:17;15787:6;15747:67;:::i;:::-;15824:72;15892:2;15881:9;15877:18;15868:6;15824:72;:::i;:::-;15906;15974:2;15963:9;15959:18;15950:6;15906:72;:::i;:::-;15551:434;;;;;;:::o;15991:147::-;16092:11;16129:3;16114:18;;15991:147;;;;:::o;16144:114::-;;:::o;16264:398::-;16423:3;16444:83;16525:1;16520:3;16444:83;:::i;:::-;16437:90;;16536:93;16625:3;16536:93;:::i;:::-;16654:1;16649:3;16645:11;16638:18;;16264:398;;;:::o;16668:379::-;16852:3;16874:147;17017:3;16874:147;:::i;:::-;16867:154;;17038:3;17031:10;;16668:379;;;:::o;17053:169::-;17137:11;17171:6;17166:3;17159:19;17211:4;17206:3;17202:14;17187:29;;17053:169;;;;:::o;17228:231::-;17368:34;17364:1;17356:6;17352:14;17345:58;17437:14;17432:2;17424:6;17420:15;17413:39;17228:231;:::o;17465:366::-;17607:3;17628:67;17692:2;17687:3;17628:67;:::i;:::-;17621:74;;17704:93;17793:3;17704:93;:::i;:::-;17822:2;17817:3;17813:12;17806:19;;17465:366;;;:::o;17837:419::-;18003:4;18041:2;18030:9;18026:18;18018:26;;18090:9;18084:4;18080:20;18076:1;18065:9;18061:17;18054:47;18118:131;18244:4;18118:131;:::i;:::-;18110:139;;17837:419;;;:::o;18262:231::-;18402:34;18398:1;18390:6;18386:14;18379:58;18471:14;18466:2;18458:6;18454:15;18447:39;18262:231;:::o;18499:366::-;18641:3;18662:67;18726:2;18721:3;18662:67;:::i;:::-;18655:74;;18738:93;18827:3;18738:93;:::i;:::-;18856:2;18851:3;18847:12;18840:19;;18499:366;;;:::o;18871:419::-;19037:4;19075:2;19064:9;19060:18;19052:26;;19124:9;19118:4;19114:20;19110:1;19099:9;19095:17;19088:47;19152:131;19278:4;19152:131;:::i;:::-;19144:139;;18871:419;;;:::o;19296:162::-;19436:14;19432:1;19424:6;19420:14;19413:38;19296:162;:::o;19464:366::-;19606:3;19627:67;19691:2;19686:3;19627:67;:::i;:::-;19620:74;;19703:93;19792:3;19703:93;:::i;:::-;19821:2;19816:3;19812:12;19805:19;;19464:366;;;:::o;19836:419::-;20002:4;20040:2;20029:9;20025:18;20017:26;;20089:9;20083:4;20079:20;20075:1;20064:9;20060:17;20053:47;20117:131;20243:4;20117:131;:::i;:::-;20109:139;;19836:419;;;:::o;20261:165::-;20401:17;20397:1;20389:6;20385:14;20378:41;20261:165;:::o;20432:366::-;20574:3;20595:67;20659:2;20654:3;20595:67;:::i;:::-;20588:74;;20671:93;20760:3;20671:93;:::i;:::-;20789:2;20784:3;20780:12;20773:19;;20432:366;;;:::o;20804:419::-;20970:4;21008:2;20997:9;20993:18;20985:26;;21057:9;21051:4;21047:20;21043:1;21032:9;21028:17;21021:47;21085:131;21211:4;21085:131;:::i;:::-;21077:139;;20804:419;;;:::o;21229:243::-;21369:34;21365:1;21357:6;21353:14;21346:58;21438:26;21433:2;21425:6;21421:15;21414:51;21229:243;:::o;21478:366::-;21620:3;21641:67;21705:2;21700:3;21641:67;:::i;:::-;21634:74;;21717:93;21806:3;21717:93;:::i;:::-;21835:2;21830:3;21826:12;21819:19;;21478:366;;;:::o;21850:419::-;22016:4;22054:2;22043:9;22039:18;22031:26;;22103:9;22097:4;22093:20;22089:1;22078:9;22074:17;22067:47;22131:131;22257:4;22131:131;:::i;:::-;22123:139;;21850:419;;;:::o;22275:180::-;22323:77;22320:1;22313:88;22420:4;22417:1;22410:15;22444:4;22441:1;22434:15;22461:162;22601:14;22597:1;22589:6;22585:14;22578:38;22461:162;:::o;22629:366::-;22771:3;22792:67;22856:2;22851:3;22792:67;:::i;:::-;22785:74;;22868:93;22957:3;22868:93;:::i;:::-;22986:2;22981:3;22977:12;22970:19;;22629:366;;;:::o;23001:419::-;23167:4;23205:2;23194:9;23190:18;23182:26;;23254:9;23248:4;23244:20;23240:1;23229:9;23225:17;23218:47;23282:131;23408:4;23282:131;:::i;:::-;23274:139;;23001:419;;;:::o;23426:79::-;23465:7;23494:5;23483:16;;23426:79;;;:::o;23511:157::-;23616:45;23636:24;23654:5;23636:24;:::i;:::-;23616:45;:::i;:::-;23611:3;23604:58;23511:157;;:::o;23674:397::-;23814:3;23829:75;23900:3;23891:6;23829:75;:::i;:::-;23929:2;23924:3;23920:12;23913:19;;23942:75;24013:3;24004:6;23942:75;:::i;:::-;24042:2;24037:3;24033:12;24026:19;;24062:3;24055:10;;23674:397;;;;;:::o;24077:180::-;24125:77;24122:1;24115:88;24222:4;24219:1;24212:15;24246:4;24243:1;24236:15;24263:176;24295:1;24312:20;24330:1;24312:20;:::i;:::-;24307:25;;24346:20;24364:1;24346:20;:::i;:::-;24341:25;;24385:1;24375:35;;24390:18;;:::i;:::-;24375:35;24431:1;24428;24424:9;24419:14;;24263:176;;;;:::o;24445:104::-;24510:6;24538:4;24528:14;;24445:104;;;:::o;24555:143::-;24652:11;24689:3;24674:18;;24555:143;;;;:::o;24704:98::-;24769:4;24792:3;24784:11;;24704:98;;;:::o;24808:111::-;24876:4;24908;24903:3;24899:14;24891:22;;24808:111;;;:::o;24957:694::-;25093:52;25139:5;25093:52;:::i;:::-;25161:84;25238:6;25233:3;25161:84;:::i;:::-;25154:91;;25269:54;25317:5;25269:54;:::i;:::-;25346:7;25377:1;25362:282;25387:6;25384:1;25381:13;25362:282;;;25463:6;25457:13;25490:63;25549:3;25534:13;25490:63;:::i;:::-;25483:70;;25576:58;25627:6;25576:58;:::i;:::-;25566:68;;25422:222;25409:1;25406;25402:9;25397:14;;25362:282;;;25366:14;25069:582;;;24957:694;;:::o;25657:750::-;25904:4;25942:3;25931:9;25927:19;25919:27;;25956:71;26024:1;26013:9;26009:17;26000:6;25956:71;:::i;:::-;26037:118;26151:2;26140:9;26136:18;26127:6;26037:118;:::i;:::-;26165:73;26233:3;26222:9;26218:19;26209:6;26165:73;:::i;:::-;26248;26316:3;26305:9;26301:19;26292:6;26248:73;:::i;:::-;26331:69;26395:3;26384:9;26380:19;26371:6;26331:69;:::i;:::-;25657:750;;;;;;;;:::o;26413:159::-;26553:11;26549:1;26541:6;26537:14;26530:35;26413:159;:::o;26578:365::-;26720:3;26741:66;26805:1;26800:3;26741:66;:::i;:::-;26734:73;;26816:93;26905:3;26816:93;:::i;:::-;26934:2;26929:3;26925:12;26918:19;;26578:365;;;:::o;26949:419::-;27115:4;27153:2;27142:9;27138:18;27130:26;;27202:9;27196:4;27192:20;27188:1;27177:9;27173:17;27166:47;27230:131;27356:4;27230:131;:::i;:::-;27222:139;;26949:419;;;:::o;27374:157::-;27514:9;27510:1;27502:6;27498:14;27491:33;27374:157;:::o;27537:365::-;27679:3;27700:66;27764:1;27759:3;27700:66;:::i;:::-;27693:73;;27775:93;27864:3;27775:93;:::i;:::-;27893:2;27888:3;27884:12;27877:19;;27537:365;;;:::o;27908:419::-;28074:4;28112:2;28101:9;28097:18;28089:26;;28161:9;28155:4;28151:20;28147:1;28136:9;28132:17;28125:47;28189:131;28315:4;28189:131;:::i;:::-;28181:139;;27908:419;;;:::o;28333:233::-;28473:34;28469:1;28461:6;28457:14;28450:58;28542:16;28537:2;28529:6;28525:15;28518:41;28333:233;:::o;28572:366::-;28714:3;28735:67;28799:2;28794:3;28735:67;:::i;:::-;28728:74;;28811:93;28900:3;28811:93;:::i;:::-;28929:2;28924:3;28920:12;28913:19;;28572:366;;;:::o;28944:419::-;29110:4;29148:2;29137:9;29133:18;29125:26;;29197:9;29191:4;29187:20;29183:1;29172:9;29168:17;29161:47;29225:131;29351:4;29225:131;:::i;:::-;29217:139;;28944:419;;;:::o;29369:85::-;29414:7;29443:5;29432:16;;29369:85;;;:::o;29460:154::-;29516:9;29549:59;29565:42;29574:32;29600:5;29574:32;:::i;:::-;29565:42;:::i;:::-;29549:59;:::i;:::-;29536:72;;29460:154;;;:::o;29620:143::-;29713:43;29750:5;29713:43;:::i;:::-;29708:3;29701:56;29620:143;;:::o;29769:234::-;29868:4;29906:2;29895:9;29891:18;29883:26;;29919:77;29993:1;29982:9;29978:17;29969:6;29919:77;:::i;:::-;29769:234;;;;:::o;30009:159::-;30149:11;30145:1;30137:6;30133:14;30126:35;30009:159;:::o;30174:365::-;30316:3;30337:66;30401:1;30396:3;30337:66;:::i;:::-;30330:73;;30412:93;30501:3;30412:93;:::i;:::-;30530:2;30525:3;30521:12;30514:19;;30174:365;;;:::o;30545:419::-;30711:4;30749:2;30738:9;30734:18;30726:26;;30798:9;30792:4;30788:20;30784:1;30773:9;30769:17;30762:47;30826:131;30952:4;30826:131;:::i;:::-;30818:139;;30545:419;;;:::o;30970:155::-;31110:7;31106:1;31098:6;31094:14;31087:31;30970:155;:::o;31131:365::-;31273:3;31294:66;31358:1;31353:3;31294:66;:::i;:::-;31287:73;;31369:93;31458:3;31369:93;:::i;:::-;31487:2;31482:3;31478:12;31471:19;;31131:365;;;:::o;31502:419::-;31668:4;31706:2;31695:9;31691:18;31683:26;;31755:9;31749:4;31745:20;31741:1;31730:9;31726:17;31719:47;31783:131;31909:4;31783:131;:::i;:::-;31775:139;;31502:419;;;:::o;31927:225::-;32067:34;32063:1;32055:6;32051:14;32044:58;32136:8;32131:2;32123:6;32119:15;32112:33;31927:225;:::o;32158:366::-;32300:3;32321:67;32385:2;32380:3;32321:67;:::i;:::-;32314:74;;32397:93;32486:3;32397:93;:::i;:::-;32515:2;32510:3;32506:12;32499:19;;32158:366;;;:::o;32530:419::-;32696:4;32734:2;32723:9;32719:18;32711:26;;32783:9;32777:4;32773:20;32769:1;32758:9;32754:17;32747:47;32811:131;32937:4;32811:131;:::i;:::-;32803:139;;32530:419;;;:::o;32955:181::-;33095:33;33091:1;33083:6;33079:14;33072:57;32955:181;:::o;33142:366::-;33284:3;33305:67;33369:2;33364:3;33305:67;:::i;:::-;33298:74;;33381:93;33470:3;33381:93;:::i;:::-;33499:2;33494:3;33490:12;33483:19;;33142:366;;;:::o;33514:419::-;33680:4;33718:2;33707:9;33703:18;33695:26;;33767:9;33761:4;33757:20;33753:1;33742:9;33738:17;33731:47;33795:131;33921:4;33795:131;:::i;:::-;33787:139;;33514:419;;;:::o;33939:182::-;34079:34;34075:1;34067:6;34063:14;34056:58;33939:182;:::o;34127:366::-;34269:3;34290:67;34354:2;34349:3;34290:67;:::i;:::-;34283:74;;34366:93;34455:3;34366:93;:::i;:::-;34484:2;34479:3;34475:12;34468:19;;34127:366;;;:::o;34499:419::-;34665:4;34703:2;34692:9;34688:18;34680:26;;34752:9;34746:4;34742:20;34738:1;34727:9;34723:17;34716:47;34780:131;34906:4;34780:131;:::i;:::-;34772:139;;34499:419;;;:::o;34924:185::-;34964:1;34981:20;34999:1;34981:20;:::i;:::-;34976:25;;35015:20;35033:1;35015:20;:::i;:::-;35010:25;;35054:1;35044:35;;35059:18;;:::i;:::-;35044:35;35101:1;35098;35094:9;35089:14;;34924:185;;;;:::o;35115:180::-;35163:77;35160:1;35153:88;35260:4;35257:1;35250:15;35284:4;35281:1;35274:15;35301:122;35374:24;35392:5;35374:24;:::i;:::-;35367:5;35364:35;35354:63;;35413:1;35410;35403:12;35354:63;35301:122;:::o;35429:143::-;35486:5;35517:6;35511:13;35502:22;;35533:33;35560:5;35533:33;:::i;:::-;35429:143;;;;:::o;35578:351::-;35648:6;35697:2;35685:9;35676:7;35672:23;35668:32;35665:119;;;35703:79;;:::i;:::-;35665:119;35823:1;35848:64;35904:7;35895:6;35884:9;35880:22;35848:64;:::i;:::-;35838:74;;35794:128;35578:351;;;;:::o;35935:233::-;36075:34;36071:1;36063:6;36059:14;36052:58;36144:16;36139:2;36131:6;36127:15;36120:41;35935:233;:::o;36174:366::-;36316:3;36337:67;36401:2;36396:3;36337:67;:::i;:::-;36330:74;;36413:93;36502:3;36413:93;:::i;:::-;36531:2;36526:3;36522:12;36515:19;;36174:366;;;:::o;36546:419::-;36712:4;36750:2;36739:9;36735:18;36727:26;;36799:9;36793:4;36789:20;36785:1;36774:9;36770:17;36763:47;36827:131;36953:4;36827:131;:::i;:::-;36819:139;;36546:419;;;:::o;36971:228::-;37111:34;37107:1;37099:6;37095:14;37088:58;37180:11;37175:2;37167:6;37163:15;37156:36;36971:228;:::o;37205:366::-;37347:3;37368:67;37432:2;37427:3;37368:67;:::i;:::-;37361:74;;37444:93;37533:3;37444:93;:::i;:::-;37562:2;37557:3;37553:12;37546:19;;37205:366;;;:::o;37577:419::-;37743:4;37781:2;37770:9;37766:18;37758:26;;37830:9;37824:4;37820:20;37816:1;37805:9;37801:17;37794:47;37858:131;37984:4;37858:131;:::i;:::-;37850:139;;37577:419;;;:::o;38002:230::-;38142:34;38138:1;38130:6;38126:14;38119:58;38211:13;38206:2;38198:6;38194:15;38187:38;38002:230;:::o;38238:366::-;38380:3;38401:67;38465:2;38460:3;38401:67;:::i;:::-;38394:74;;38477:93;38566:3;38477:93;:::i;:::-;38595:2;38590:3;38586:12;38579:19;;38238:366;;;:::o;38610:419::-;38776:4;38814:2;38803:9;38799:18;38791:26;;38863:9;38857:4;38853:20;38849:1;38838:9;38834:17;38827:47;38891:131;39017:4;38891:131;:::i;:::-;38883:139;;38610:419;;;:::o;39035:232::-;39175:34;39171:1;39163:6;39159:14;39152:58;39244:15;39239:2;39231:6;39227:15;39220:40;39035:232;:::o;39273:366::-;39415:3;39436:67;39500:2;39495:3;39436:67;:::i;:::-;39429:74;;39512:93;39601:3;39512:93;:::i;:::-;39630:2;39625:3;39621:12;39614:19;;39273:366;;;:::o;39645:419::-;39811:4;39849:2;39838:9;39834:18;39826:26;;39898:9;39892:4;39888:20;39884:1;39873:9;39869:17;39862:47;39926:131;40052:4;39926:131;:::i;:::-;39918:139;;39645:419;;;:::o;40070:233::-;40109:3;40132:24;40150:5;40132:24;:::i;:::-;40123:33;;40178:66;40171:5;40168:77;40165:103;;40248:18;;:::i;:::-;40165:103;40295:1;40288:5;40284:13;40277:20;;40070:233;;;:::o;40309:98::-;40360:6;40394:5;40388:12;40378:22;;40309:98;;;:::o;40413:139::-;40502:6;40497:3;40492;40486:23;40543:1;40534:6;40529:3;40525:16;40518:27;40413:139;;;:::o;40558:386::-;40662:3;40690:38;40722:5;40690:38;:::i;:::-;40744:88;40825:6;40820:3;40744:88;:::i;:::-;40737:95;;40841:65;40899:6;40894:3;40887:4;40880:5;40876:16;40841:65;:::i;:::-;40931:6;40926:3;40922:16;40915:23;;40666:278;40558:386;;;;:::o;40950:271::-;41080:3;41102:93;41191:3;41182:6;41102:93;:::i;:::-;41095:100;;41212:3;41205:10;;40950:271;;;;:::o;41227:179::-;41367:31;41363:1;41355:6;41351:14;41344:55;41227:179;:::o;41412:366::-;41554:3;41575:67;41639:2;41634:3;41575:67;:::i;:::-;41568:74;;41651:93;41740:3;41651:93;:::i;:::-;41769:2;41764:3;41760:12;41753:19;;41412:366;;;:::o;41784:419::-;41950:4;41988:2;41977:9;41973:18;41965:26;;42037:9;42031:4;42027:20;42023:1;42012:9;42008:17;42001:47;42065:131;42191:4;42065:131;:::i;:::-;42057:139;;41784:419;;;:::o;42209:99::-;42261:6;42295:5;42289:12;42279:22;;42209:99;;;:::o;42314:377::-;42402:3;42430:39;42463:5;42430:39;:::i;:::-;42485:71;42549:6;42544:3;42485:71;:::i;:::-;42478:78;;42565:65;42623:6;42618:3;42611:4;42604:5;42600:16;42565:65;:::i;:::-;42655:29;42677:6;42655:29;:::i;:::-;42650:3;42646:39;42639:46;;42406:285;42314:377;;;;:::o;42697:313::-;42810:4;42848:2;42837:9;42833:18;42825:26;;42897:9;42891:4;42887:20;42883:1;42872:9;42868:17;42861:47;42925:78;42998:4;42989:6;42925:78;:::i;:::-;42917:86;;42697:313;;;;:::o
Swarm Source
ipfs://c957ec2dfc01665de153430d4756410aa1eb970acaaff982c232dd4572b8e26c
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in HYPE
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.