Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 129 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Burn Cells | 16908090 | 1068 days ago | IN | 0 ETH | 0.00208673 | ||||
| Burn Cells | 16908081 | 1068 days ago | IN | 0 ETH | 0.00205416 | ||||
| Burn Cells | 16908074 | 1068 days ago | IN | 0 ETH | 0.00204318 | ||||
| Burn Cells | 16908060 | 1068 days ago | IN | 0 ETH | 0.00208585 | ||||
| Burn Cells | 16908046 | 1068 days ago | IN | 0 ETH | 0.00199192 | ||||
| Burn Cells | 16908042 | 1068 days ago | IN | 0 ETH | 0.00228949 | ||||
| Burn Cells | 16908036 | 1068 days ago | IN | 0 ETH | 0.00236885 | ||||
| Burn Cells | 16908026 | 1068 days ago | IN | 0 ETH | 0.00248168 | ||||
| Burn Cells | 16908023 | 1068 days ago | IN | 0 ETH | 0.00238345 | ||||
| Burn Cells | 16908014 | 1068 days ago | IN | 0 ETH | 0.00282827 | ||||
| Set Approval For... | 16814632 | 1081 days ago | IN | 0 ETH | 0.00110983 | ||||
| Burn Cells | 16810743 | 1081 days ago | IN | 0 ETH | 0.00810811 | ||||
| Burn Cells | 16809262 | 1082 days ago | IN | 0 ETH | 0.00244221 | ||||
| Burn Cells | 16802562 | 1083 days ago | IN | 0 ETH | 0.0216624 | ||||
| Set Approval For... | 16801087 | 1083 days ago | IN | 0 ETH | 0.00182337 | ||||
| Burn Cells | 16799687 | 1083 days ago | IN | 0 ETH | 0.00427737 | ||||
| Burn Cells | 16799678 | 1083 days ago | IN | 0 ETH | 0.00399835 | ||||
| Burn Cells | 16799670 | 1083 days ago | IN | 0 ETH | 0.00370019 | ||||
| Burn Cells | 16799658 | 1083 days ago | IN | 0 ETH | 0.00463598 | ||||
| Burn Cells | 16799475 | 1083 days ago | IN | 0 ETH | 0.00463688 | ||||
| Burn Cells | 16798367 | 1083 days ago | IN | 0 ETH | 0.00755682 | ||||
| Set Approval For... | 16798079 | 1083 days ago | IN | 0 ETH | 0.0014003 | ||||
| Burn Cells | 16796720 | 1083 days ago | IN | 0 ETH | 0.00272055 | ||||
| Burn Cells | 16796710 | 1083 days ago | IN | 0 ETH | 0.00263035 | ||||
| Burn Cells | 16794807 | 1084 days ago | IN | 0 ETH | 0.00490249 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Chaos
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/common/ERC2981.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
/// [MIT License]
/// @title Base64
/// @notice Provides a function for encoding some bytes in base64
/// @author Brecht Devos <brecht@loopring.org>
library Base64 {
bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/// @notice Encodes some bytes to the base64 representation
function encode(bytes memory data) internal pure returns (string memory) {
uint256 len = data.length;
if (len == 0) return "";
// multiply by 4/3 rounded up
uint256 encodedLen = 4 * ((len + 2) / 3);
// Add some extra buffer at the end
bytes memory result = new bytes(encodedLen + 32);
bytes memory table = TABLE;
assembly {
let tablePtr := add(table, 1)
let resultPtr := add(result, 32)
for {
let i := 0
} lt(i, len) {
} {
i := add(i, 3)
let input := and(mload(add(data, i)), 0xffffff)
let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
out := shl(8, out)
out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF))
out := shl(8, out)
out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF))
out := shl(8, out)
out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF))
out := shl(224, out)
mstore(resultPtr, out)
resultPtr := add(resultPtr, 4)
}
switch mod(len, 3)
case 1 {
mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
}
case 2 {
mstore(sub(resultPtr, 1), shl(248, 0x3d))
}
mstore(result, encodedLen)
}
return string(result);
}
}
contract Chaos is ERC721, Ownable, ERC2981 {
using Strings for uint256;
// =================================
// Storage
// =================================
bool public burnIsActive;
uint256 public numMinted;
address immutable public cells;
// =================================
// Metadata
// =================================
string constant internal sprott_linz_a = '({ x, y, z }, dt) { x += y * dt; y += (-x + y * z) * dt; z += (1 - y * y) * dt; return { x, y, z }; }';
string constant internal halvorsen = '({ x, y, z }, dt) { const a = 1.4; x += (-a * x - 4 * y - 4 * z - y * y) * dt; y += (-a * y - 4 * z - 4 * x - z * z) * dt; z += (-a * z - 4 * x - 4 * y - x * x) * dt; return { x, y, z }; }';
string constant internal aizawa = '({ x, y, z }, dt) { const a = 0.95; const b = 0.7; const c = 0.6; const d = 3.5; const e = 0.25; const f = 0.1; x += ((z - b) * x - d * y) * dt; y += (d * x + (z - b) * y) * dt; z += (c + a * z - (z * z * z) / 3 - (x * x + y * y) * (1 + e * z) + f * z * (x * x * x)) * dt; return { x, y, z }; }';
function generateHTMLandSVG(address _address, uint256 funcNum) internal pure returns (string memory finalHtml, string memory finalSvg) {
(string memory color1, string memory color2, string memory color3) = getColors(_address);
string memory HTMLfirstBlock = '<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Chaos</title> </head> <body> <canvas class="canvas" id="golCanvas"></canvas> <style> .canvas { width: 600px; height: 400px; position: absolute; top: 60%; left: 50%; transform: translate(-50%, -50%); } </style> <script> function lines';
string memory HTMLsecondBlock = 'const canvas = document.getElementById("golCanvas"); canvas.width = window.innerWidth; canvas.height = window.innerHeight; const ctx = canvas.getContext("2d"); const dt = 0.01; var rotation_speed = 0.01; var steps_per_frame = 5; var duration_till_replace_path = 100000; const FPS = 150; const scale_factor = Math.min(canvas.width, canvas.height) / 2 - 10; var q = 0; var a = canvas.width / 7; var b = canvas.width / 6; var c = canvas.width / 2; let paths = []; let colors = ["#';
string memory HTMLthirdBlock = '"]; let chosenAttractorFunction = lines; var number_of_paths = 3; updatePaths(); function updatePaths() { paths = []; let epsilon_base = Math.random() - Math.random(); for (var i = 0; i < number_of_paths; i++) { let epsilon = epsilon_base + (Math.random() - 0.01) * 0.001; let withing_point_epsilon = (Math.random() - 0.01) * 0.001; paths.push([ { x: epsilon + withing_point_epsilon, y: epsilon + withing_point_epsilon, z: epsilon + withing_point_epsilon, }, ]); } } function extendPath(path, steps) { for (var i = 0; i < steps; i++) { const lastP = path[path.length - 1]; const p = chosenAttractorFunction(lastP, dt); path.push(p); } return path; } function scale(points, size) { const mx = Math.min(...points.slice(1).map(({ x, y, z }) => x)); const Mx = Math.max(...points.slice(1).map(({ x, y, z }) => x)); const my = Math.min(...points.slice(1).map(({ x, y, z }) => y)); const My = Math.max(...points.slice(1).map(({ x, y, z }) => y)); const mz = Math.min(...points.slice(1).map(({ x, y, z }) => z)); const Mz = Math.max(...points.slice(1).map(({ x, y, z }) => z)); const s = (v, mv, Mv) => (size * (v - mv)) / (Mv - mv); return points.slice(1).map(({ x, y, z }) => { x = s(x, mx, Mx); y = s(y, my, My); z = s(z, mz, Mz); return { x, y, z }; }); } function draw(path, i) { if (q > 2 * Math.PI) q = 0; const map = ({ x, y, z }) => [ (x - a) * Math.cos(q) - (y - b) * Math.sin(q) + c, z, ]; ctx.beginPath(); ctx.strokeStyle = colors[i]; path .slice(1) .map(map) .forEach((p) => ctx.lineTo(p[0], p[1])); ctx.stroke(); } function update() { ctx.clearRect(0, 0, canvas.width, canvas.height); q -= rotation_speed; for (var i = 0; i < paths.length; i++) { paths[i] = extendPath(paths[i], steps_per_frame); draw(scale(paths[i], scale_factor), i); while (paths[i].length > duration_till_replace_path) paths[i].shift(); } } function main() { resize(); setInterval(update, 1000 / FPS); } function resize() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; a = canvas.width / 7; b = canvas.width / 6; c = canvas.width / 2; } window.addEventListener("resize", resize, false); main(); </script> </body> </html>';
string memory SVGfirstBlock = '<svg xmlns="http://www.w3.org/2000/svg" width="350" height="350"> <rect width="350" height="350" style="fill:rgb(37,38,30)" /> <defs> <linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="0%"> <stop offset="0%" style="stop-color:#';
string memory SVGsecondBlock = ';stop-opacity:1" /> <stop offset="50%" style="stop-color:#';
string memory SVGthirdBlock = ';stop-opacity:1" /> <stop offset="100%" style="stop-color:#';
string memory SVGfourthBlock = ';stop-opacity:1" /> </linearGradient> </defs> <path d="M50 300 C 40 220, 75 10, 150 150 S 270 200, 300 50" style="fill:none;stroke:url(#grad);stroke-width:10"/> </svg>';
if (funcNum == 0) {
return(
string(abi.encodePacked(HTMLfirstBlock, sprott_linz_a, HTMLsecondBlock, color1, '", "#', color2, '", "#', color3, HTMLthirdBlock)),
string(abi.encodePacked(SVGfirstBlock, color1, SVGsecondBlock, color2, SVGthirdBlock, color3, SVGfourthBlock))
);
} else if (funcNum == 1) {
return(
string(abi.encodePacked(HTMLfirstBlock, halvorsen, HTMLsecondBlock, color1, '", "#', color2, '", "#', color3, HTMLthirdBlock)),
string(abi.encodePacked(SVGfirstBlock, color1, SVGsecondBlock, color2, SVGthirdBlock, color3, SVGfourthBlock))
);
} else {
return(
string(abi.encodePacked(HTMLfirstBlock, aizawa, HTMLsecondBlock, color1, '", "#', color2, '", "#', color3, HTMLthirdBlock)),
string(abi.encodePacked(SVGfirstBlock, color1, SVGsecondBlock, color2, SVGthirdBlock, color3, SVGfourthBlock))
);
}
}
function getColors(address _address) internal pure returns (string memory color1, string memory color2, string memory color3){
string memory addr = toString(abi.encodePacked(_address));
color1 = getSlice(3, 8, addr);
color2 = getSlice(9, 14, addr);
color3 = getSlice(15, 20, addr);
}
function toString(bytes memory data) internal pure returns(string memory) {
bytes memory alphabet = "0123456789abcdef";
bytes memory str = new bytes(2 + data.length * 2);
str[0] = "0";
str[1] = "x";
for (uint i = 0; i < data.length; i++) {
str[2+i*2] = alphabet[uint(uint8(data[i] >> 4))];
str[3+i*2] = alphabet[uint(uint8(data[i] & 0x0f))];
}
return string(str);
}
function getSlice(uint256 begin, uint256 end, string memory text) internal pure returns (string memory) {
bytes memory a = new bytes(end-begin+1);
for(uint i=0;i<=end-begin;i++){
a[i] = bytes(text)[i+begin-1];
}
return string(a);
}
function htmlToImageURI(string memory html) internal pure returns (string memory) {
string memory baseURL = "data:text/html;base64,";
string memory htmlBase64Encoded = Base64.encode(bytes(string(abi.encodePacked(html))));
return string(abi.encodePacked(baseURL,htmlBase64Encoded));
}
function svgToImageURI(string memory svg) internal pure returns (string memory) {
string memory baseURL = "data:image/svg+xml;base64,";
string memory svgBase64Encoded = Base64.encode(bytes(string(abi.encodePacked(svg))));
return string(abi.encodePacked(baseURL,svgBase64Encoded));
}
function tokenURI(uint256 tokenId) override public view returns (string memory) {
(string memory html, string memory svg) = generateHTMLandSVG(ownerOf(tokenId), (tokenId % 3));
string memory imageURIhtml = htmlToImageURI(html);
string memory imageURIsvg = svgToImageURI(svg);
return string(
abi.encodePacked(
"data:application/json;base64,",
Base64.encode(
bytes(
abi.encodePacked(
'{"name":"',
"Chaos | ", uint2str(tokenId),"",
'", "description":"", "attributes":"", "image":"', imageURIsvg,'", "animation_url":"', imageURIhtml,'"}'
)
)
)
)
);
}
function uint2str(uint _i) internal pure returns (string memory _uintAsString) {
if (_i == 0) {
return "0";
}
uint j = _i;
uint len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint k = len;
while (_i != 0) {
k = k-1;
uint8 temp = (48 + uint8(_i - _i / 10 * 10));
bytes1 b1 = bytes1(temp);
bstr[k] = b1;
_i /= 10;
}
return string(bstr);
}
// =================================
// Mint
// =================================
function burnCells(uint256 firstId, uint256 secondId, uint256 thirdId) public {
require(burnIsActive, "Burn is not active");
IERC721(cells).safeTransferFrom(msg.sender, address(0x000000000000000000000000000000000000dEaD), firstId);
IERC721(cells).safeTransferFrom(msg.sender, address(0x000000000000000000000000000000000000dEaD), secondId);
IERC721(cells).safeTransferFrom(msg.sender, address(0x000000000000000000000000000000000000dEaD), thirdId);
numMinted += 1;
_safeMint(msg.sender, numMinted);
}
// =================================
// Owner functions
// =================================
function withdraw() public onlyOwner {
payable(msg.sender).transfer(address(this).balance);
}
function setBurnStatus(bool state) public onlyOwner {
burnIsActive = state;
}
// =================================
// Overrides
// =================================
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC2981) returns (bool) {
return super.supportsInterface(interfaceId);
}
// =================================
// Constructor
// =================================
constructor(address _cells) ERC721("Chaos", "CHA") {
cells = _cells;
_setDefaultRoyalty(msg.sender, 300);
numMinted += 1;
_safeMint(msg.sender, numMinted);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing 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);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)
pragma solidity ^0.8.0;
import "../utils/introspection/IERC165.sol";
/**
* @dev Interface for the NFT Royalty Standard.
*
* A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
* support for royalty payments across all NFT marketplaces and ecosystem participants.
*
* _Available since v4.5._
*/
interface IERC2981 is IERC165 {
/**
* @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
* exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
*/
function royaltyInfo(uint256 tokenId, uint256 salePrice)
external
view
returns (address receiver, uint256 royaltyAmount);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol)
pragma solidity ^0.8.0;
import "../../interfaces/IERC2981.sol";
import "../../utils/introspection/ERC165.sol";
/**
* @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
*
* Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
* specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
*
* Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
* fee is specified in basis points by default.
*
* IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
* https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
* voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
*
* _Available since v4.5._
*/
abstract contract ERC2981 is IERC2981, ERC165 {
struct RoyaltyInfo {
address receiver;
uint96 royaltyFraction;
}
RoyaltyInfo private _defaultRoyaltyInfo;
mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @inheritdoc IERC2981
*/
function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) {
RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId];
if (royalty.receiver == address(0)) {
royalty = _defaultRoyaltyInfo;
}
uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator();
return (royalty.receiver, royaltyAmount);
}
/**
* @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
* fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
* override.
*/
function _feeDenominator() internal pure virtual returns (uint96) {
return 10000;
}
/**
* @dev Sets the royalty information that all ids in this contract will default to.
*
* Requirements:
*
* - `receiver` cannot be the zero address.
* - `feeNumerator` cannot be greater than the fee denominator.
*/
function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
require(receiver != address(0), "ERC2981: invalid receiver");
_defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
}
/**
* @dev Removes default royalty information.
*/
function _deleteDefaultRoyalty() internal virtual {
delete _defaultRoyaltyInfo;
}
/**
* @dev Sets the royalty information for a specific token id, overriding the global default.
*
* Requirements:
*
* - `receiver` cannot be the zero address.
* - `feeNumerator` cannot be greater than the fee denominator.
*/
function _setTokenRoyalty(
uint256 tokenId,
address receiver,
uint96 feeNumerator
) internal virtual {
require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
require(receiver != address(0), "ERC2981: Invalid parameters");
_tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
}
/**
* @dev Resets royalty information for the token id back to the global default.
*/
function _resetTokenRoyalty(uint256 tokenId) internal virtual {
delete _tokenRoyaltyInfo[tokenId];
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.2) (token/ERC721/ERC721.sol)
pragma solidity ^0.8.0;
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";
/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
* the Metadata extension, but not including the Enumerable extension, which is available separately as
* {ERC721Enumerable}.
*/
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Mapping from token ID to owner address
mapping(uint256 => address) private _owners;
// Mapping owner address to token count
mapping(address => uint256) private _balances;
// Mapping from token ID to approved address
mapping(uint256 => address) private _tokenApprovals;
// Mapping from owner to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721-balanceOf}.
*/
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: address zero is not a valid owner");
return _balances[owner];
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _ownerOf(tokenId);
require(owner != address(0), "ERC721: invalid token ID");
return owner;
}
/**
* @dev See {IERC721Metadata-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
_requireMinted(tokenId);
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
/**
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overridden in child contracts.
*/
function _baseURI() internal view virtual returns (string memory) {
return "";
}
/**
* @dev See {IERC721-approve}.
*/
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not token owner or approved for all"
);
_approve(to, tokenId);
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
_requireMinted(tokenId);
return _tokenApprovals[tokenId];
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory data
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");
_safeTransfer(from, to, tokenId, data);
}
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* `data` is additional data, it has no specified format and it is sent in call to `to`.
*
* This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
* implement alternative mechanisms to perform token transfer, such as signature-based.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory data
) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
}
/**
* @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
*/
function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
return _owners[tokenId];
}
/**
* @dev Returns whether `tokenId` exists.
*
* Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
*
* Tokens start existing when they are minted (`_mint`),
* and stop existing when they are burned (`_burn`).
*/
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _ownerOf(tokenId) != address(0);
}
/**
* @dev Returns whether `spender` is allowed to manage `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
}
/**
* @dev Safely mints `tokenId` and transfers it to `to`.
*
* Requirements:
*
* - `tokenId` must not exist.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeMint(
address to,
uint256 tokenId,
bytes memory data
) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
/**
* @dev Mints `tokenId` and transfers it to `to`.
*
* WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
*
* Requirements:
*
* - `tokenId` must not exist.
* - `to` cannot be the zero address.
*
* Emits a {Transfer} event.
*/
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId, 1);
// Check that tokenId was not minted by `_beforeTokenTransfer` hook
require(!_exists(tokenId), "ERC721: token already minted");
unchecked {
// Will not overflow unless all 2**256 token ids are minted to the same owner.
// Given that tokens are minted one by one, it is impossible in practice that
// this ever happens. Might change if we allow batch minting.
// The ERC fails to describe this case.
_balances[to] += 1;
}
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
_afterTokenTransfer(address(0), to, tokenId, 1);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
* This is an internal function that does not check if the sender is authorized to operate on the token.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId, 1);
// Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
owner = ERC721.ownerOf(tokenId);
// Clear approvals
delete _tokenApprovals[tokenId];
unchecked {
// Cannot overflow, as that would require more tokens to be burned/transferred
// out than the owner initially received through minting and transferring in.
_balances[owner] -= 1;
}
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
_afterTokenTransfer(owner, address(0), tokenId, 1);
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
* As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
*
* Emits a {Transfer} event.
*/
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId, 1);
// Check that tokenId was not transferred by `_beforeTokenTransfer` hook
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
// Clear approvals from the previous owner
delete _tokenApprovals[tokenId];
unchecked {
// `_balances[from]` cannot overflow for the same reason as described in `_burn`:
// `from`'s balance is the number of token held, which is at least one before the current
// transfer.
// `_balances[to]` could overflow in the conditions described in `_mint`. That would require
// all 2**256 token ids to be minted, which in practice is impossible.
_balances[from] -= 1;
_balances[to] += 1;
}
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
_afterTokenTransfer(from, to, tokenId, 1);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* Emits an {Approval} event.
*/
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits an {ApprovalForAll} event.
*/
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC721: approve to caller");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Reverts if the `tokenId` has not been minted yet.
*/
function _requireMinted(uint256 tokenId) internal view virtual {
require(_exists(tokenId), "ERC721: invalid token ID");
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
* The call is not executed if the target address is not a contract.
*
* @param from address representing the previous owner of the given token ID
* @param to target address that will receive the tokens
* @param tokenId uint256 ID of the token to be transferred
* @param data bytes optional data to send along with the call
* @return bool whether the call correctly returned the expected magic value
*/
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory data
) private returns (bool) {
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
/// @solidity memory-safe-assembly
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
/**
* @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is
* used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
* - When `from` is zero, the tokens will be minted for `to`.
* - When `to` is zero, ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
* - `batchSize` is non-zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 firstTokenId,
uint256 batchSize
) internal virtual {}
/**
* @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
* used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
* - When `from` is zero, the tokens were minted for `to`.
* - When `to` is zero, ``from``'s tokens were burned.
* - `from` and `to` are never both zero.
* - `batchSize` is non-zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 firstTokenId,
uint256 batchSize
) internal virtual {}
/**
* @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
*
* WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant
* being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such
* that `ownerOf(tokenId)` is `a`.
*/
// solhint-disable-next-line func-name-mixedcase
function __unsafe_increaseBalance(address account, uint256 amount) internal {
_balances[account] += amount;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC721.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Metadata is IERC721 {
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
* or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
* understand this adds an external call which potentially creates a reentrancy vulnerability.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool _approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [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://diligence.consensys.net/posts/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.5.11/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 v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1);
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10**64) {
value /= 10**64;
result += 64;
}
if (value >= 10**32) {
value /= 10**32;
result += 32;
}
if (value >= 10**16) {
value /= 10**16;
result += 16;
}
if (value >= 10**8) {
value /= 10**8;
result += 8;
}
if (value >= 10**4) {
value /= 10**4;
result += 4;
}
if (value >= 10**2) {
value /= 10**2;
result += 2;
}
if (value >= 10**1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
import "./math/Math.sol";
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}{
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_cells","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"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":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"firstId","type":"uint256"},{"internalType":"uint256","name":"secondId","type":"uint256"},{"internalType":"uint256","name":"thirdId","type":"uint256"}],"name":"burnCells","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burnIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cells","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"state","type":"bool"}],"name":"setBurnStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60a06040523480156200001157600080fd5b506040516200604f3803806200604f833981810160405281019062000037919062000a56565b6040518060400160405280600581526020017f4368616f730000000000000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f43484100000000000000000000000000000000000000000000000000000000008152508160009080519060200190620000bb9291906200093c565b508060019080519060200190620000d49291906200093c565b505050620000f7620000eb6200017660201b60201c565b6200017e60201b60201c565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250506200013f3361012c6200024460201b60201c565b6001600a600082825462000154919062000ac1565b925050819055506200016f33600a54620003e860201b60201c565b5062000fc3565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b620002546200040e60201b60201c565b6bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115620002b5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002ac9062000ba5565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141562000328576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200031f9062000c17565b60405180910390fd5b60405180604001604052808373ffffffffffffffffffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff16815250600760008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055509050505050565b6200040a8282604051806020016040528060008152506200041860201b60201c565b5050565b6000612710905090565b6200042a83836200048660201b60201c565b6200043f6000848484620006cd60201b60201c565b62000481576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004789062000caf565b60405180910390fd5b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415620004f9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004f09062000d21565b60405180910390fd5b6200050a816200088760201b60201c565b156200054d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620005449062000d93565b60405180910390fd5b62000563600083836001620008d060201b60201c565b62000574816200088760201b60201c565b15620005b7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620005ae9062000d93565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4620006c9600083836001620008d660201b60201c565b5050565b6000620006fb8473ffffffffffffffffffffffffffffffffffffffff16620008dc60201b62000fd61760201c565b156200087a578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026200072d6200017660201b60201c565b8786866040518563ffffffff1660e01b815260040162000751949392919062000e7b565b602060405180830381600087803b1580156200076c57600080fd5b505af1925050508015620007a057506040513d601f19601f820116820180604052508101906200079d919062000f2c565b60015b62000829573d8060008114620007d3576040519150601f19603f3d011682016040523d82523d6000602084013e620007d8565b606091505b5060008151141562000821576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620008189062000caf565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506200087f565b600190505b949350505050565b60008073ffffffffffffffffffffffffffffffffffffffff16620008b183620008ff60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b50505050565b50505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8280546200094a9062000f8d565b90600052602060002090601f0160209004810192826200096e5760008555620009ba565b82601f106200098957805160ff1916838001178555620009ba565b82800160010185558215620009ba579182015b82811115620009b95782518255916020019190600101906200099c565b5b509050620009c99190620009cd565b5090565b5b80821115620009e8576000816000905550600101620009ce565b5090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000a1e82620009f1565b9050919050565b62000a308162000a11565b811462000a3c57600080fd5b50565b60008151905062000a508162000a25565b92915050565b60006020828403121562000a6f5762000a6e620009ec565b5b600062000a7f8482850162000a3f565b91505092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600062000ace8262000a88565b915062000adb8362000a88565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111562000b135762000b1262000a92565b5b828201905092915050565b600082825260208201905092915050565b7f455243323938313a20726f79616c7479206665652077696c6c2065786365656460008201527f2073616c65507269636500000000000000000000000000000000000000000000602082015250565b600062000b8d602a8362000b1e565b915062000b9a8262000b2f565b604082019050919050565b6000602082019050818103600083015262000bc08162000b7e565b9050919050565b7f455243323938313a20696e76616c696420726563656976657200000000000000600082015250565b600062000bff60198362000b1e565b915062000c0c8262000bc7565b602082019050919050565b6000602082019050818103600083015262000c328162000bf0565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b600062000c9760328362000b1e565b915062000ca48262000c39565b604082019050919050565b6000602082019050818103600083015262000cca8162000c88565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b600062000d0960208362000b1e565b915062000d168262000cd1565b602082019050919050565b6000602082019050818103600083015262000d3c8162000cfa565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b600062000d7b601c8362000b1e565b915062000d888262000d43565b602082019050919050565b6000602082019050818103600083015262000dae8162000d6c565b9050919050565b62000dc08162000a11565b82525050565b62000dd18162000a88565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b8381101562000e1357808201518184015260208101905062000df6565b8381111562000e23576000848401525b50505050565b6000601f19601f8301169050919050565b600062000e478262000dd7565b62000e53818562000de2565b935062000e6581856020860162000df3565b62000e708162000e29565b840191505092915050565b600060808201905062000e92600083018762000db5565b62000ea1602083018662000db5565b62000eb0604083018562000dc6565b818103606083015262000ec4818462000e3a565b905095945050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b62000f068162000ecf565b811462000f1257600080fd5b50565b60008151905062000f268162000efb565b92915050565b60006020828403121562000f455762000f44620009ec565b5b600062000f558482850162000f15565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168062000fa657607f821691505b6020821081141562000fbd5762000fbc62000f5e565b5b50919050565b60805161505b62000ff46000396000818161069e0152818161072f015281816107c00152610fb4015261505b6000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c806370a08231116100c3578063b88d4fde1161007c578063b88d4fde14610377578063c87b56dd14610393578063d52079b4146103c3578063e985e9c5146103e1578063f2fde38b14610411578063fa11510c1461042d5761014d565b806370a08231146102c9578063715018a6146102f95780638da5cb5b1461030357806395d89b411461032157806397a2d0eb1461033f578063a22cb4651461035b5761014d565b806323b872dd1161011557806323b872dd146102085780632a55205a146102245780633ccfd60b1461025557806342842e0e1461025f5780636352211e1461027b57806366caa6ab146102ab5761014d565b806301ffc9a71461015257806306fdde0314610182578063081812fc146101a0578063095ea7b3146101d05780631c6a8d0d146101ec575b600080fd5b61016c600480360381019061016791906129de565b61044b565b6040516101799190612a26565b60405180910390f35b61018a61045d565b6040516101979190612ada565b60405180910390f35b6101ba60048036038101906101b59190612b32565b6104ef565b6040516101c79190612ba0565b60405180910390f35b6101ea60048036038101906101e59190612be7565b610535565b005b61020660048036038101906102019190612c27565b61064d565b005b610222600480360381019061021d9190612c7a565b61087a565b005b61023e60048036038101906102399190612ccd565b6108da565b60405161024c929190612d1c565b60405180910390f35b61025d610ac5565b005b61027960048036038101906102749190612c7a565b610b16565b005b61029560048036038101906102909190612b32565b610b36565b6040516102a29190612ba0565b60405180910390f35b6102b3610bbd565b6040516102c09190612a26565b60405180910390f35b6102e360048036038101906102de9190612d45565b610bd0565b6040516102f09190612d72565b60405180910390f35b610301610c88565b005b61030b610c9c565b6040516103189190612ba0565b60405180910390f35b610329610cc6565b6040516103369190612ada565b60405180910390f35b61035960048036038101906103549190612db9565b610d58565b005b61037560048036038101906103709190612de6565b610d7d565b005b610391600480360381019061038c9190612f5b565b610d93565b005b6103ad60048036038101906103a89190612b32565b610df5565b6040516103ba9190612ada565b60405180910390f35b6103cb610e94565b6040516103d89190612d72565b60405180910390f35b6103fb60048036038101906103f69190612fde565b610e9a565b6040516104089190612a26565b60405180910390f35b61042b60048036038101906104269190612d45565b610f2e565b005b610435610fb2565b6040516104429190612ba0565b60405180910390f35b600061045682610ff9565b9050919050565b60606000805461046c9061304d565b80601f01602080910402602001604051908101604052809291908181526020018280546104989061304d565b80156104e55780601f106104ba576101008083540402835291602001916104e5565b820191906000526020600020905b8154815290600101906020018083116104c857829003601f168201915b5050505050905090565b60006104fa82611073565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061054082610b36565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156105b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a8906130f1565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166105d06110be565b73ffffffffffffffffffffffffffffffffffffffff1614806105ff57506105fe816105f96110be565b610e9a565b5b61063e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161063590613183565b60405180910390fd5b61064883836110c6565b505050565b600960009054906101000a900460ff1661069c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610693906131ef565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166342842e0e3361dead866040518463ffffffff1660e01b81526004016106fb9392919061320f565b600060405180830381600087803b15801561071557600080fd5b505af1158015610729573d6000803e3d6000fd5b505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166342842e0e3361dead856040518463ffffffff1660e01b815260040161078c9392919061320f565b600060405180830381600087803b1580156107a657600080fd5b505af11580156107ba573d6000803e3d6000fd5b505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166342842e0e3361dead846040518463ffffffff1660e01b815260040161081d9392919061320f565b600060405180830381600087803b15801561083757600080fd5b505af115801561084b573d6000803e3d6000fd5b505050506001600a60008282546108629190613275565b9250508190555061087533600a5461117f565b505050565b61088b6108856110be565b8261119d565b6108ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c19061333d565b60405180910390fd5b6108d5838383611232565b505050565b6000806000600860008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff161415610a705760076040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b6000610a7a61152c565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff1686610aa6919061335d565b610ab091906133e6565b90508160000151819350935050509250929050565b610acd611536565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015610b13573d6000803e3d6000fd5b50565b610b3183838360405180602001604052806000815250610d93565b505050565b600080610b42836115b4565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610bb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bab90613463565b60405180910390fd5b80915050919050565b600960009054906101000a900460ff1681565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610c41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c38906134f5565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610c90611536565b610c9a60006115f1565b565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060018054610cd59061304d565b80601f0160208091040260200160405190810160405280929190818152602001828054610d019061304d565b8015610d4e5780601f10610d2357610100808354040283529160200191610d4e565b820191906000526020600020905b815481529060010190602001808311610d3157829003601f168201915b5050505050905090565b610d60611536565b80600960006101000a81548160ff02191690831515021790555050565b610d8f610d886110be565b83836116b7565b5050565b610da4610d9e6110be565b8361119d565b610de3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dda9061333d565b60405180910390fd5b610def84848484611824565b50505050565b6060600080610e18610e0685610b36565b600386610e139190613515565b611880565b915091506000610e2783611b0d565b90506000610e3483611ba0565b9050610e6a610e4287611c33565b8284604051602001610e569392919061374a565b604051602081830303815290604052611dbc565b604051602001610e7a9190613809565b604051602081830303815290604052945050505050919050565b600a5481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b610f36611536565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610fa6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f9d9061389d565b60405180910390fd5b610faf816115f1565b50565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061106c575061106b82611f54565b5b9050919050565b61107c81612036565b6110bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b290613463565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff1661113983610b36565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611199828260405180602001604052806000815250612077565b5050565b6000806111a983610b36565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806111eb57506111ea8185610e9a565b5b8061122957508373ffffffffffffffffffffffffffffffffffffffff16611211846104ef565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661125282610b36565b73ffffffffffffffffffffffffffffffffffffffff16146112a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129f9061392f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611318576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130f906139c1565b60405180910390fd5b61132583838360016120d2565b8273ffffffffffffffffffffffffffffffffffffffff1661134582610b36565b73ffffffffffffffffffffffffffffffffffffffff161461139b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113929061392f565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461152783838360016120d8565b505050565b6000612710905090565b61153e6110be565b73ffffffffffffffffffffffffffffffffffffffff1661155c610c9c565b73ffffffffffffffffffffffffffffffffffffffff16146115b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115a990613a2d565b60405180910390fd5b565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611726576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171d90613a99565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516118179190612a26565b60405180910390a3505050565b61182f848484611232565b61183b848484846120de565b61187a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187190613b2b565b60405180910390fd5b50505050565b606080600080600061189187612275565b9250925092506000604051806101e001604052806101b28152602001614db86101b29139905060006040518061020001604052806101dd8152602001614bdb6101dd91399050600060405180610880016040528061084b815260200161426f61084b91399050600060405180610120016040528060e88152602001613fc160e89139905060006040518060600160405280603a8152602001614aba603a9139905060006040518060600160405280603b815260200161410e603b9139905060006040518060e0016040528060a78152602001614b3460a79139905060008d14156119f857866040518060a00160405280606581526020016140a960659139878c8c8c8a6040516020016119aa9796959493929190613b97565b604051602081830303815290604052848b858c868d876040516020016119d69796959493929190613c12565b6040516020818303038152906040529b509b5050505050505050505050611b06565b60018d1415611a8457866040518060e0016040528060bc8152602001614f6a60bc9139878c8c8c8a604051602001611a369796959493929190613b97565b604051602081830303815290604052848b858c868d87604051602001611a629796959493929190613c12565b6040516020818303038152906040529b509b5050505050505050505050611b06565b8660405180610160016040528061012681526020016141496101269139878c8c8c8a604051602001611abc9796959493929190613b97565b604051602081830303815290604052848b858c868d87604051602001611ae89796959493929190613c12565b6040516020818303038152906040529b509b50505050505050505050505b9250929050565b606060006040518060400160405280601681526020017f646174613a746578742f68746d6c3b6261736536342c0000000000000000000081525090506000611b7384604051602001611b5f9190613c77565b604051602081830303815290604052611dbc565b90508181604051602001611b88929190613c8e565b60405160208183030381529060405292505050919050565b606060006040518060400160405280601a81526020017f646174613a696d6167652f7376672b786d6c3b6261736536342c00000000000081525090506000611c0684604051602001611bf29190613c77565b604051602081830303815290604052611dbc565b90508181604051602001611c1b929190613c8e565b60405160208183030381529060405292505050919050565b60606000821415611c7b576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050611db7565b600082905060005b60008214611cad578080611c9690613cb2565b915050600a82611ca691906133e6565b9150611c83565b60008167ffffffffffffffff811115611cc957611cc8612e30565b5b6040519080825280601f01601f191660200182016040528015611cfb5781602001600182028036833780820191505090505b50905060008290505b60008614611daf57600181611d199190613cfb565b90506000600a8088611d2b91906133e6565b611d35919061335d565b87611d409190613cfb565b6030611d4c9190613d3c565b905060008160f81b905080848481518110611d6a57611d69613d73565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a88611da691906133e6565b97505050611d04565b819450505050505b919050565b60606000825190506000811415611de55760405180602001604052806000815250915050611f4f565b60006003600283611df69190613275565b611e0091906133e6565b6004611e0c919061335d565b90506000602082611e1d9190613275565b67ffffffffffffffff811115611e3657611e35612e30565b5b6040519080825280601f01601f191660200182016040528015611e685781602001600182028036833780820191505090505b5090506000604051806060016040528060408152602001614af4604091399050600181016020830160005b86811015611f0c5760038101905062ffffff818a015116603f8160121c168401518060081b905060ff603f83600c1c1686015116810190508060081b905060ff603f8360061c1686015116810190508060081b905060ff603f831686015116810190508060e01b90508084526004840193505050611e93565b506003860660018114611f265760028114611f3657611f41565b613d3d60f01b6002830352611f41565b603d60f81b60018303525b508484525050819450505050505b919050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061201f57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061202f575061202e826122db565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff16612058836115b4565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6120818383612345565b61208e60008484846120de565b6120cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c490613b2b565b60405180910390fd5b505050565b50505050565b50505050565b60006120ff8473ffffffffffffffffffffffffffffffffffffffff16610fd6565b15612268578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026121286110be565b8786866040518563ffffffff1660e01b815260040161214a9493929190613df7565b602060405180830381600087803b15801561216457600080fd5b505af192505050801561219557506040513d601f19601f820116820180604052508101906121929190613e58565b60015b612218573d80600081146121c5576040519150601f19603f3d011682016040523d82523d6000602084013e6121ca565b606091505b50600081511415612210576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161220790613b2b565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061226d565b600190505b949350505050565b606080606060006122a4856040516020016122909190613ecd565b604051602081830303815290604052612563565b90506122b3600360088361285d565b93506122c26009600e8361285d565b92506122d1600f60148361285d565b9150509193909250565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156123b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123ac90613f34565b60405180910390fd5b6123be81612036565b156123fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123f590613fa0565b60405180910390fd5b61240c6000838360016120d2565b61241581612036565b15612455576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244c90613fa0565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461255f6000838360016120d8565b5050565b606060006040518060400160405280601081526020017f303132333435363738396162636465660000000000000000000000000000000081525090506000600284516125af919061335d565b60026125bb9190613275565b67ffffffffffffffff8111156125d4576125d3612e30565b5b6040519080825280601f01601f1916602001820160405280156126065781602001600182028036833780820191505090505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061263e5761263d613d73565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106126a2576126a1613d73565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060005b8451811015612852578260048683815181106126f3576126f2613d73565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60f81c60ff168151811061273957612738613d73565b5b602001015160f81c60f81b82600283612752919061335d565b600261275e9190613275565b8151811061276f5761276e613d73565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535082600f60f81b8683815181106127b7576127b6613d73565b5b602001015160f81c60f81b1660f81c60ff16815181106127da576127d9613d73565b5b602001015160f81c60f81b826002836127f3919061335d565b60036127ff9190613275565b815181106128105761280f613d73565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808061284a90613cb2565b9150506126d4565b508092505050919050565b606060006001858561286f9190613cfb565b6128799190613275565b67ffffffffffffffff81111561289257612891612e30565b5b6040519080825280601f01601f1916602001820160405280156128c45781602001600182028036833780820191505090505b50905060005b85856128d69190613cfb565b81116129665783600187836128eb9190613275565b6128f59190613cfb565b8151811061290657612905613d73565b5b602001015160f81c60f81b82828151811061292457612923613d73565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808061295e90613cb2565b9150506128ca565b50809150509392505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6129bb81612986565b81146129c657600080fd5b50565b6000813590506129d8816129b2565b92915050565b6000602082840312156129f4576129f361297c565b5b6000612a02848285016129c9565b91505092915050565b60008115159050919050565b612a2081612a0b565b82525050565b6000602082019050612a3b6000830184612a17565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612a7b578082015181840152602081019050612a60565b83811115612a8a576000848401525b50505050565b6000601f19601f8301169050919050565b6000612aac82612a41565b612ab68185612a4c565b9350612ac6818560208601612a5d565b612acf81612a90565b840191505092915050565b60006020820190508181036000830152612af48184612aa1565b905092915050565b6000819050919050565b612b0f81612afc565b8114612b1a57600080fd5b50565b600081359050612b2c81612b06565b92915050565b600060208284031215612b4857612b4761297c565b5b6000612b5684828501612b1d565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612b8a82612b5f565b9050919050565b612b9a81612b7f565b82525050565b6000602082019050612bb56000830184612b91565b92915050565b612bc481612b7f565b8114612bcf57600080fd5b50565b600081359050612be181612bbb565b92915050565b60008060408385031215612bfe57612bfd61297c565b5b6000612c0c85828601612bd2565b9250506020612c1d85828601612b1d565b9150509250929050565b600080600060608486031215612c4057612c3f61297c565b5b6000612c4e86828701612b1d565b9350506020612c5f86828701612b1d565b9250506040612c7086828701612b1d565b9150509250925092565b600080600060608486031215612c9357612c9261297c565b5b6000612ca186828701612bd2565b9350506020612cb286828701612bd2565b9250506040612cc386828701612b1d565b9150509250925092565b60008060408385031215612ce457612ce361297c565b5b6000612cf285828601612b1d565b9250506020612d0385828601612b1d565b9150509250929050565b612d1681612afc565b82525050565b6000604082019050612d316000830185612b91565b612d3e6020830184612d0d565b9392505050565b600060208284031215612d5b57612d5a61297c565b5b6000612d6984828501612bd2565b91505092915050565b6000602082019050612d876000830184612d0d565b92915050565b612d9681612a0b565b8114612da157600080fd5b50565b600081359050612db381612d8d565b92915050565b600060208284031215612dcf57612dce61297c565b5b6000612ddd84828501612da4565b91505092915050565b60008060408385031215612dfd57612dfc61297c565b5b6000612e0b85828601612bd2565b9250506020612e1c85828601612da4565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e6882612a90565b810181811067ffffffffffffffff82111715612e8757612e86612e30565b5b80604052505050565b6000612e9a612972565b9050612ea68282612e5f565b919050565b600067ffffffffffffffff821115612ec657612ec5612e30565b5b612ecf82612a90565b9050602081019050919050565b82818337600083830152505050565b6000612efe612ef984612eab565b612e90565b905082815260208101848484011115612f1a57612f19612e2b565b5b612f25848285612edc565b509392505050565b600082601f830112612f4257612f41612e26565b5b8135612f52848260208601612eeb565b91505092915050565b60008060008060808587031215612f7557612f7461297c565b5b6000612f8387828801612bd2565b9450506020612f9487828801612bd2565b9350506040612fa587828801612b1d565b925050606085013567ffffffffffffffff811115612fc657612fc5612981565b5b612fd287828801612f2d565b91505092959194509250565b60008060408385031215612ff557612ff461297c565b5b600061300385828601612bd2565b925050602061301485828601612bd2565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061306557607f821691505b602082108114156130795761307861301e565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006130db602183612a4c565b91506130e68261307f565b604082019050919050565b6000602082019050818103600083015261310a816130ce565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b600061316d603d83612a4c565b915061317882613111565b604082019050919050565b6000602082019050818103600083015261319c81613160565b9050919050565b7f4275726e206973206e6f74206163746976650000000000000000000000000000600082015250565b60006131d9601283612a4c565b91506131e4826131a3565b602082019050919050565b60006020820190508181036000830152613208816131cc565b9050919050565b60006060820190506132246000830186612b91565b6132316020830185612b91565b61323e6040830184612d0d565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061328082612afc565b915061328b83612afc565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156132c0576132bf613246565b5b828201905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000613327602d83612a4c565b9150613332826132cb565b604082019050919050565b600060208201905081810360008301526133568161331a565b9050919050565b600061336882612afc565b915061337383612afc565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156133ac576133ab613246565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006133f182612afc565b91506133fc83612afc565b92508261340c5761340b6133b7565b5b828204905092915050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b600061344d601883612a4c565b915061345882613417565b602082019050919050565b6000602082019050818103600083015261347c81613440565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b60006134df602983612a4c565b91506134ea82613483565b604082019050919050565b6000602082019050818103600083015261350e816134d2565b9050919050565b600061352082612afc565b915061352b83612afc565b92508261353b5761353a6133b7565b5b828206905092915050565b600081905092915050565b7f7b226e616d65223a220000000000000000000000000000000000000000000000600082015250565b6000613587600983613546565b915061359282613551565b600982019050919050565b7f4368616f73207c20000000000000000000000000000000000000000000000000600082015250565b60006135d3600883613546565b91506135de8261359d565b600882019050919050565b60006135f482612a41565b6135fe8185613546565b935061360e818560208601612a5d565b80840191505092915050565b50565b600061362a600083613546565b91506136358261361a565b600082019050919050565b7f222c20226465736372697074696f6e223a22222c20226174747269627574657360008201527f223a22222c2022696d616765223a220000000000000000000000000000000000602082015250565b600061369c602f83613546565b91506136a782613640565b602f82019050919050565b7f222c2022616e696d6174696f6e5f75726c223a22000000000000000000000000600082015250565b60006136e8601483613546565b91506136f3826136b2565b601482019050919050565b7f227d000000000000000000000000000000000000000000000000000000000000600082015250565b6000613734600283613546565b915061373f826136fe565b600282019050919050565b60006137558261357a565b9150613760826135c6565b915061376c82866135e9565b91506137778261361d565b91506137828261368f565b915061378e82856135e9565b9150613799826136db565b91506137a582846135e9565b91506137b082613727565b9150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b60006137f3601d83613546565b91506137fe826137bd565b601d82019050919050565b6000613814826137e6565b915061382082846135e9565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613887602683612a4c565b91506138928261382b565b604082019050919050565b600060208201905081810360008301526138b68161387a565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000613919602583612a4c565b9150613924826138bd565b604082019050919050565b600060208201905081810360008301526139488161390c565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006139ab602483612a4c565b91506139b68261394f565b604082019050919050565b600060208201905081810360008301526139da8161399e565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613a17602083612a4c565b9150613a22826139e1565b602082019050919050565b60006020820190508181036000830152613a4681613a0a565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000613a83601983612a4c565b9150613a8e82613a4d565b602082019050919050565b60006020820190508181036000830152613ab281613a76565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000613b15603283612a4c565b9150613b2082613ab9565b604082019050919050565b60006020820190508181036000830152613b4481613b08565b9050919050565b7f222c202223000000000000000000000000000000000000000000000000000000600082015250565b6000613b81600583613546565b9150613b8c82613b4b565b600582019050919050565b6000613ba3828a6135e9565b9150613baf82896135e9565b9150613bbb82886135e9565b9150613bc782876135e9565b9150613bd282613b74565b9150613bde82866135e9565b9150613be982613b74565b9150613bf582856135e9565b9150613c0182846135e9565b915081905098975050505050505050565b6000613c1e828a6135e9565b9150613c2a82896135e9565b9150613c3682886135e9565b9150613c4282876135e9565b9150613c4e82866135e9565b9150613c5a82856135e9565b9150613c6682846135e9565b915081905098975050505050505050565b6000613c8382846135e9565b915081905092915050565b6000613c9a82856135e9565b9150613ca682846135e9565b91508190509392505050565b6000613cbd82612afc565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613cf057613cef613246565b5b600182019050919050565b6000613d0682612afc565b9150613d1183612afc565b925082821015613d2457613d23613246565b5b828203905092915050565b600060ff82169050919050565b6000613d4782613d2f565b9150613d5283613d2f565b92508260ff03821115613d6857613d67613246565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000613dc982613da2565b613dd38185613dad565b9350613de3818560208601612a5d565b613dec81612a90565b840191505092915050565b6000608082019050613e0c6000830187612b91565b613e196020830186612b91565b613e266040830185612d0d565b8181036060830152613e388184613dbe565b905095945050505050565b600081519050613e52816129b2565b92915050565b600060208284031215613e6e57613e6d61297c565b5b6000613e7c84828501613e43565b91505092915050565b60008160601b9050919050565b6000613e9d82613e85565b9050919050565b6000613eaf82613e92565b9050919050565b613ec7613ec282612b7f565b613ea4565b82525050565b6000613ed98284613eb6565b60148201915081905092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000613f1e602083612a4c565b9150613f2982613ee8565b602082019050919050565b60006020820190508181036000830152613f4d81613f11565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000613f8a601c83612a4c565b9150613f9582613f54565b602082019050919050565b60006020820190508181036000830152613fb981613f7d565b905091905056fe3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737667222077696474683d2233353022206865696768743d22333530223e203c726563742077696474683d2233353022206865696768743d2233353022207374796c653d2266696c6c3a7267622833372c33382c33302922202f3e203c646566733e203c6c696e6561724772616469656e742069643d2267726164222078313d223025222079313d223025222078323d2231303025222079323d223025223e203c73746f70206f66667365743d22302522207374796c653d2273746f702d636f6c6f723a23287b20782c20792c207a207d2c20647429207b2078202b3d2079202a2064743b2079202b3d20282d78202b2079202a207a29202a2064743b207a202b3d202831202d2079202a207929202a2064743b2072657475726e207b20782c20792c207a207d3b207d3b73746f702d6f7061636974793a3122202f3e203c73746f70206f66667365743d223130302522207374796c653d2273746f702d636f6c6f723a23287b20782c20792c207a207d2c20647429207b20636f6e73742061203d20302e39353b20636f6e73742062203d20302e373b20636f6e73742063203d20302e363b20636f6e73742064203d20332e353b20636f6e73742065203d20302e32353b20636f6e73742066203d20302e313b2078202b3d2028287a202d206229202a2078202d2064202a207929202a2064743b2079202b3d202864202a2078202b20287a202d206229202a207929202a2064743b207a202b3d202863202b2061202a207a202d20287a202a207a202a207a29202f2033202d202878202a2078202b2079202a207929202a202831202b2065202a207a29202b2066202a207a202a202878202a2078202a20782929202a2064743b2072657475726e207b20782c20792c207a207d3b207d225d3b206c65742063686f73656e417474726163746f7246756e6374696f6e203d206c696e65733b20766172206e756d6265725f6f665f7061746873203d20333b20757064617465506174687328293b2066756e6374696f6e2075706461746550617468732829207b207061746873203d205b5d3b206c657420657073696c6f6e5f62617365203d204d6174682e72616e646f6d2829202d204d6174682e72616e646f6d28293b20666f7220287661722069203d20303b2069203c206e756d6265725f6f665f70617468733b20692b2b29207b206c657420657073696c6f6e203d20657073696c6f6e5f62617365202b20284d6174682e72616e646f6d2829202d20302e303129202a20302e3030313b206c65742077697468696e675f706f696e745f657073696c6f6e203d20284d6174682e72616e646f6d2829202d20302e303129202a20302e3030313b2070617468732e70757368285b207b20783a20657073696c6f6e202b2077697468696e675f706f696e745f657073696c6f6e2c20793a20657073696c6f6e202b2077697468696e675f706f696e745f657073696c6f6e2c207a3a20657073696c6f6e202b2077697468696e675f706f696e745f657073696c6f6e2c207d2c205d293b207d207d2066756e6374696f6e20657874656e645061746828706174682c20737465707329207b20666f7220287661722069203d20303b2069203c2073746570733b20692b2b29207b20636f6e7374206c61737450203d20706174685b706174682e6c656e677468202d20315d3b20636f6e73742070203d2063686f73656e417474726163746f7246756e6374696f6e286c617374502c206474293b20706174682e707573682870293b207d2072657475726e20706174683b207d2066756e6374696f6e207363616c6528706f696e74732c2073697a6529207b20636f6e7374206d78203d204d6174682e6d696e282e2e2e706f696e74732e736c6963652831292e6d617028287b20782c20792c207a207d29203d3e207829293b20636f6e7374204d78203d204d6174682e6d6178282e2e2e706f696e74732e736c6963652831292e6d617028287b20782c20792c207a207d29203d3e207829293b20636f6e7374206d79203d204d6174682e6d696e282e2e2e706f696e74732e736c6963652831292e6d617028287b20782c20792c207a207d29203d3e207929293b20636f6e7374204d79203d204d6174682e6d6178282e2e2e706f696e74732e736c6963652831292e6d617028287b20782c20792c207a207d29203d3e207929293b20636f6e7374206d7a203d204d6174682e6d696e282e2e2e706f696e74732e736c6963652831292e6d617028287b20782c20792c207a207d29203d3e207a29293b20636f6e7374204d7a203d204d6174682e6d6178282e2e2e706f696e74732e736c6963652831292e6d617028287b20782c20792c207a207d29203d3e207a29293b20636f6e73742073203d2028762c206d762c204d7629203d3e202873697a65202a202876202d206d762929202f20284d76202d206d76293b2072657475726e20706f696e74732e736c6963652831292e6d617028287b20782c20792c207a207d29203d3e207b2078203d207328782c206d782c204d78293b2079203d207328792c206d792c204d79293b207a203d2073287a2c206d7a2c204d7a293b2072657475726e207b20782c20792c207a207d3b207d293b207d2066756e6374696f6e206472617728706174682c206929207b206966202871203e2032202a204d6174682e5049292071203d20303b20636f6e7374206d6170203d20287b20782c20792c207a207d29203d3e205b202878202d206129202a204d6174682e636f73287129202d202879202d206229202a204d6174682e73696e287129202b20632c207a2c205d3b206374782e626567696e5061746828293b206374782e7374726f6b655374796c65203d20636f6c6f72735b695d3b2070617468202e736c696365283129202e6d6170286d617029202e666f724561636828287029203d3e206374782e6c696e65546f28705b305d2c20705b315d29293b206374782e7374726f6b6528293b207d2066756e6374696f6e207570646174652829207b206374782e636c6561725265637428302c20302c2063616e7661732e77696474682c2063616e7661732e686569676874293b2071202d3d20726f746174696f6e5f73706565643b20666f7220287661722069203d20303b2069203c2070617468732e6c656e6774683b20692b2b29207b2070617468735b695d203d20657874656e64506174682870617468735b695d2c2073746570735f7065725f6672616d65293b2064726177287363616c652870617468735b695d2c207363616c655f666163746f72292c2069293b207768696c65202870617468735b695d2e6c656e677468203e206475726174696f6e5f74696c6c5f7265706c6163655f70617468292070617468735b695d2e736869667428293b207d207d2066756e6374696f6e206d61696e2829207b20726573697a6528293b20736574496e74657276616c287570646174652c2031303030202f20465053293b207d2066756e6374696f6e20726573697a652829207b2063616e7661732e7769647468203d2077696e646f772e696e6e657257696474683b2063616e7661732e686569676874203d2077696e646f772e696e6e65724865696768743b2061203d2063616e7661732e7769647468202f20373b2062203d2063616e7661732e7769647468202f20363b2063203d2063616e7661732e7769647468202f20323b207d2077696e646f772e6164644576656e744c697374656e65722822726573697a65222c20726573697a652c2066616c7365293b206d61696e28293b203c2f7363726970743e203c2f626f64793e203c2f68746d6c3e3b73746f702d6f7061636974793a3122202f3e203c73746f70206f66667365743d2235302522207374796c653d2273746f702d636f6c6f723a234142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f3b73746f702d6f7061636974793a3122202f3e203c2f6c696e6561724772616469656e743e203c2f646566733e203c7061746820643d224d3530203330302043203430203232302c2037352031302c2031353020313530205320323730203230302c2033303020353022207374796c653d2266696c6c3a6e6f6e653b7374726f6b653a75726c282367726164293b7374726f6b652d77696474683a3130222f3e203c2f7376673e636f6e73742063616e766173203d20646f63756d656e742e676574456c656d656e74427949642822676f6c43616e76617322293b2063616e7661732e7769647468203d2077696e646f772e696e6e657257696474683b2063616e7661732e686569676874203d2077696e646f772e696e6e65724865696768743b20636f6e737420637478203d2063616e7661732e676574436f6e746578742822326422293b20636f6e7374206474203d20302e30313b2076617220726f746174696f6e5f7370656564203d20302e30313b207661722073746570735f7065725f6672616d65203d20353b20766172206475726174696f6e5f74696c6c5f7265706c6163655f70617468203d203130303030303b20636f6e737420465053203d203135303b20636f6e7374207363616c655f666163746f72203d204d6174682e6d696e2863616e7661732e77696474682c2063616e7661732e68656967687429202f2032202d2031303b207661722071203d20303b207661722061203d2063616e7661732e7769647468202f20373b207661722062203d2063616e7661732e7769647468202f20363b207661722063203d2063616e7661732e7769647468202f20323b206c6574207061746873203d205b5d3b206c657420636f6c6f7273203d205b22233c21444f43545950452068746d6c3e203c68746d6c206c616e673d22656e223e203c686561643e203c6d65746120636861727365743d225554462d3822202f3e203c6d65746120687474702d65717569763d22582d55412d436f6d70617469626c652220636f6e74656e743d2249453d6564676522202f3e203c6d657461206e616d653d2276696577706f72742220636f6e74656e743d2277696474683d6465766963652d77696474682c20696e697469616c2d7363616c653d312e3022202f3e203c7469746c653e4368616f733c2f7469746c653e203c2f686561643e203c626f64793e203c63616e76617320636c6173733d2263616e766173222069643d22676f6c43616e766173223e3c2f63616e7661733e203c7374796c653e202e63616e766173207b2077696474683a2036303070783b206865696768743a2034303070783b20706f736974696f6e3a206162736f6c7574653b20746f703a203630253b206c6566743a203530253b207472616e73666f726d3a207472616e736c617465282d3530252c202d353025293b207d203c2f7374796c653e203c7363726970743e2066756e6374696f6e206c696e6573287b20782c20792c207a207d2c20647429207b20636f6e73742061203d20312e343b2078202b3d20282d61202a2078202d2034202a2079202d2034202a207a202d2079202a207929202a2064743b2079202b3d20282d61202a2079202d2034202a207a202d2034202a2078202d207a202a207a29202a2064743b207a202b3d20282d61202a207a202d2034202a2078202d2034202a2079202d2078202a207829202a2064743b2072657475726e207b20782c20792c207a207d3b207da264697066735822122097a026bcdfd2d8ae5b7f69367d59d5bc63ffbdc012868c3e5ecab36a8360c23564736f6c63430008090033000000000000000000000000531c24a152060bad20ce77079fcb5bfe56726a4e
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061014d5760003560e01c806370a08231116100c3578063b88d4fde1161007c578063b88d4fde14610377578063c87b56dd14610393578063d52079b4146103c3578063e985e9c5146103e1578063f2fde38b14610411578063fa11510c1461042d5761014d565b806370a08231146102c9578063715018a6146102f95780638da5cb5b1461030357806395d89b411461032157806397a2d0eb1461033f578063a22cb4651461035b5761014d565b806323b872dd1161011557806323b872dd146102085780632a55205a146102245780633ccfd60b1461025557806342842e0e1461025f5780636352211e1461027b57806366caa6ab146102ab5761014d565b806301ffc9a71461015257806306fdde0314610182578063081812fc146101a0578063095ea7b3146101d05780631c6a8d0d146101ec575b600080fd5b61016c600480360381019061016791906129de565b61044b565b6040516101799190612a26565b60405180910390f35b61018a61045d565b6040516101979190612ada565b60405180910390f35b6101ba60048036038101906101b59190612b32565b6104ef565b6040516101c79190612ba0565b60405180910390f35b6101ea60048036038101906101e59190612be7565b610535565b005b61020660048036038101906102019190612c27565b61064d565b005b610222600480360381019061021d9190612c7a565b61087a565b005b61023e60048036038101906102399190612ccd565b6108da565b60405161024c929190612d1c565b60405180910390f35b61025d610ac5565b005b61027960048036038101906102749190612c7a565b610b16565b005b61029560048036038101906102909190612b32565b610b36565b6040516102a29190612ba0565b60405180910390f35b6102b3610bbd565b6040516102c09190612a26565b60405180910390f35b6102e360048036038101906102de9190612d45565b610bd0565b6040516102f09190612d72565b60405180910390f35b610301610c88565b005b61030b610c9c565b6040516103189190612ba0565b60405180910390f35b610329610cc6565b6040516103369190612ada565b60405180910390f35b61035960048036038101906103549190612db9565b610d58565b005b61037560048036038101906103709190612de6565b610d7d565b005b610391600480360381019061038c9190612f5b565b610d93565b005b6103ad60048036038101906103a89190612b32565b610df5565b6040516103ba9190612ada565b60405180910390f35b6103cb610e94565b6040516103d89190612d72565b60405180910390f35b6103fb60048036038101906103f69190612fde565b610e9a565b6040516104089190612a26565b60405180910390f35b61042b60048036038101906104269190612d45565b610f2e565b005b610435610fb2565b6040516104429190612ba0565b60405180910390f35b600061045682610ff9565b9050919050565b60606000805461046c9061304d565b80601f01602080910402602001604051908101604052809291908181526020018280546104989061304d565b80156104e55780601f106104ba576101008083540402835291602001916104e5565b820191906000526020600020905b8154815290600101906020018083116104c857829003601f168201915b5050505050905090565b60006104fa82611073565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061054082610b36565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156105b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a8906130f1565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166105d06110be565b73ffffffffffffffffffffffffffffffffffffffff1614806105ff57506105fe816105f96110be565b610e9a565b5b61063e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161063590613183565b60405180910390fd5b61064883836110c6565b505050565b600960009054906101000a900460ff1661069c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610693906131ef565b60405180910390fd5b7f000000000000000000000000531c24a152060bad20ce77079fcb5bfe56726a4e73ffffffffffffffffffffffffffffffffffffffff166342842e0e3361dead866040518463ffffffff1660e01b81526004016106fb9392919061320f565b600060405180830381600087803b15801561071557600080fd5b505af1158015610729573d6000803e3d6000fd5b505050507f000000000000000000000000531c24a152060bad20ce77079fcb5bfe56726a4e73ffffffffffffffffffffffffffffffffffffffff166342842e0e3361dead856040518463ffffffff1660e01b815260040161078c9392919061320f565b600060405180830381600087803b1580156107a657600080fd5b505af11580156107ba573d6000803e3d6000fd5b505050507f000000000000000000000000531c24a152060bad20ce77079fcb5bfe56726a4e73ffffffffffffffffffffffffffffffffffffffff166342842e0e3361dead846040518463ffffffff1660e01b815260040161081d9392919061320f565b600060405180830381600087803b15801561083757600080fd5b505af115801561084b573d6000803e3d6000fd5b505050506001600a60008282546108629190613275565b9250508190555061087533600a5461117f565b505050565b61088b6108856110be565b8261119d565b6108ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c19061333d565b60405180910390fd5b6108d5838383611232565b505050565b6000806000600860008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff161415610a705760076040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b6000610a7a61152c565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff1686610aa6919061335d565b610ab091906133e6565b90508160000151819350935050509250929050565b610acd611536565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015610b13573d6000803e3d6000fd5b50565b610b3183838360405180602001604052806000815250610d93565b505050565b600080610b42836115b4565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610bb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bab90613463565b60405180910390fd5b80915050919050565b600960009054906101000a900460ff1681565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610c41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c38906134f5565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610c90611536565b610c9a60006115f1565b565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060018054610cd59061304d565b80601f0160208091040260200160405190810160405280929190818152602001828054610d019061304d565b8015610d4e5780601f10610d2357610100808354040283529160200191610d4e565b820191906000526020600020905b815481529060010190602001808311610d3157829003601f168201915b5050505050905090565b610d60611536565b80600960006101000a81548160ff02191690831515021790555050565b610d8f610d886110be565b83836116b7565b5050565b610da4610d9e6110be565b8361119d565b610de3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dda9061333d565b60405180910390fd5b610def84848484611824565b50505050565b6060600080610e18610e0685610b36565b600386610e139190613515565b611880565b915091506000610e2783611b0d565b90506000610e3483611ba0565b9050610e6a610e4287611c33565b8284604051602001610e569392919061374a565b604051602081830303815290604052611dbc565b604051602001610e7a9190613809565b604051602081830303815290604052945050505050919050565b600a5481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b610f36611536565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610fa6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f9d9061389d565b60405180910390fd5b610faf816115f1565b50565b7f000000000000000000000000531c24a152060bad20ce77079fcb5bfe56726a4e81565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061106c575061106b82611f54565b5b9050919050565b61107c81612036565b6110bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b290613463565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff1661113983610b36565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611199828260405180602001604052806000815250612077565b5050565b6000806111a983610b36565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806111eb57506111ea8185610e9a565b5b8061122957508373ffffffffffffffffffffffffffffffffffffffff16611211846104ef565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661125282610b36565b73ffffffffffffffffffffffffffffffffffffffff16146112a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129f9061392f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611318576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130f906139c1565b60405180910390fd5b61132583838360016120d2565b8273ffffffffffffffffffffffffffffffffffffffff1661134582610b36565b73ffffffffffffffffffffffffffffffffffffffff161461139b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113929061392f565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461152783838360016120d8565b505050565b6000612710905090565b61153e6110be565b73ffffffffffffffffffffffffffffffffffffffff1661155c610c9c565b73ffffffffffffffffffffffffffffffffffffffff16146115b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115a990613a2d565b60405180910390fd5b565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611726576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171d90613a99565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516118179190612a26565b60405180910390a3505050565b61182f848484611232565b61183b848484846120de565b61187a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187190613b2b565b60405180910390fd5b50505050565b606080600080600061189187612275565b9250925092506000604051806101e001604052806101b28152602001614db86101b29139905060006040518061020001604052806101dd8152602001614bdb6101dd91399050600060405180610880016040528061084b815260200161426f61084b91399050600060405180610120016040528060e88152602001613fc160e89139905060006040518060600160405280603a8152602001614aba603a9139905060006040518060600160405280603b815260200161410e603b9139905060006040518060e0016040528060a78152602001614b3460a79139905060008d14156119f857866040518060a00160405280606581526020016140a960659139878c8c8c8a6040516020016119aa9796959493929190613b97565b604051602081830303815290604052848b858c868d876040516020016119d69796959493929190613c12565b6040516020818303038152906040529b509b5050505050505050505050611b06565b60018d1415611a8457866040518060e0016040528060bc8152602001614f6a60bc9139878c8c8c8a604051602001611a369796959493929190613b97565b604051602081830303815290604052848b858c868d87604051602001611a629796959493929190613c12565b6040516020818303038152906040529b509b5050505050505050505050611b06565b8660405180610160016040528061012681526020016141496101269139878c8c8c8a604051602001611abc9796959493929190613b97565b604051602081830303815290604052848b858c868d87604051602001611ae89796959493929190613c12565b6040516020818303038152906040529b509b50505050505050505050505b9250929050565b606060006040518060400160405280601681526020017f646174613a746578742f68746d6c3b6261736536342c0000000000000000000081525090506000611b7384604051602001611b5f9190613c77565b604051602081830303815290604052611dbc565b90508181604051602001611b88929190613c8e565b60405160208183030381529060405292505050919050565b606060006040518060400160405280601a81526020017f646174613a696d6167652f7376672b786d6c3b6261736536342c00000000000081525090506000611c0684604051602001611bf29190613c77565b604051602081830303815290604052611dbc565b90508181604051602001611c1b929190613c8e565b60405160208183030381529060405292505050919050565b60606000821415611c7b576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050611db7565b600082905060005b60008214611cad578080611c9690613cb2565b915050600a82611ca691906133e6565b9150611c83565b60008167ffffffffffffffff811115611cc957611cc8612e30565b5b6040519080825280601f01601f191660200182016040528015611cfb5781602001600182028036833780820191505090505b50905060008290505b60008614611daf57600181611d199190613cfb565b90506000600a8088611d2b91906133e6565b611d35919061335d565b87611d409190613cfb565b6030611d4c9190613d3c565b905060008160f81b905080848481518110611d6a57611d69613d73565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a88611da691906133e6565b97505050611d04565b819450505050505b919050565b60606000825190506000811415611de55760405180602001604052806000815250915050611f4f565b60006003600283611df69190613275565b611e0091906133e6565b6004611e0c919061335d565b90506000602082611e1d9190613275565b67ffffffffffffffff811115611e3657611e35612e30565b5b6040519080825280601f01601f191660200182016040528015611e685781602001600182028036833780820191505090505b5090506000604051806060016040528060408152602001614af4604091399050600181016020830160005b86811015611f0c5760038101905062ffffff818a015116603f8160121c168401518060081b905060ff603f83600c1c1686015116810190508060081b905060ff603f8360061c1686015116810190508060081b905060ff603f831686015116810190508060e01b90508084526004840193505050611e93565b506003860660018114611f265760028114611f3657611f41565b613d3d60f01b6002830352611f41565b603d60f81b60018303525b508484525050819450505050505b919050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061201f57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061202f575061202e826122db565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff16612058836115b4565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6120818383612345565b61208e60008484846120de565b6120cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c490613b2b565b60405180910390fd5b505050565b50505050565b50505050565b60006120ff8473ffffffffffffffffffffffffffffffffffffffff16610fd6565b15612268578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026121286110be565b8786866040518563ffffffff1660e01b815260040161214a9493929190613df7565b602060405180830381600087803b15801561216457600080fd5b505af192505050801561219557506040513d601f19601f820116820180604052508101906121929190613e58565b60015b612218573d80600081146121c5576040519150601f19603f3d011682016040523d82523d6000602084013e6121ca565b606091505b50600081511415612210576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161220790613b2b565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061226d565b600190505b949350505050565b606080606060006122a4856040516020016122909190613ecd565b604051602081830303815290604052612563565b90506122b3600360088361285d565b93506122c26009600e8361285d565b92506122d1600f60148361285d565b9150509193909250565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156123b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123ac90613f34565b60405180910390fd5b6123be81612036565b156123fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123f590613fa0565b60405180910390fd5b61240c6000838360016120d2565b61241581612036565b15612455576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244c90613fa0565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461255f6000838360016120d8565b5050565b606060006040518060400160405280601081526020017f303132333435363738396162636465660000000000000000000000000000000081525090506000600284516125af919061335d565b60026125bb9190613275565b67ffffffffffffffff8111156125d4576125d3612e30565b5b6040519080825280601f01601f1916602001820160405280156126065781602001600182028036833780820191505090505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061263e5761263d613d73565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106126a2576126a1613d73565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060005b8451811015612852578260048683815181106126f3576126f2613d73565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60f81c60ff168151811061273957612738613d73565b5b602001015160f81c60f81b82600283612752919061335d565b600261275e9190613275565b8151811061276f5761276e613d73565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535082600f60f81b8683815181106127b7576127b6613d73565b5b602001015160f81c60f81b1660f81c60ff16815181106127da576127d9613d73565b5b602001015160f81c60f81b826002836127f3919061335d565b60036127ff9190613275565b815181106128105761280f613d73565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808061284a90613cb2565b9150506126d4565b508092505050919050565b606060006001858561286f9190613cfb565b6128799190613275565b67ffffffffffffffff81111561289257612891612e30565b5b6040519080825280601f01601f1916602001820160405280156128c45781602001600182028036833780820191505090505b50905060005b85856128d69190613cfb565b81116129665783600187836128eb9190613275565b6128f59190613cfb565b8151811061290657612905613d73565b5b602001015160f81c60f81b82828151811061292457612923613d73565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808061295e90613cb2565b9150506128ca565b50809150509392505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6129bb81612986565b81146129c657600080fd5b50565b6000813590506129d8816129b2565b92915050565b6000602082840312156129f4576129f361297c565b5b6000612a02848285016129c9565b91505092915050565b60008115159050919050565b612a2081612a0b565b82525050565b6000602082019050612a3b6000830184612a17565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612a7b578082015181840152602081019050612a60565b83811115612a8a576000848401525b50505050565b6000601f19601f8301169050919050565b6000612aac82612a41565b612ab68185612a4c565b9350612ac6818560208601612a5d565b612acf81612a90565b840191505092915050565b60006020820190508181036000830152612af48184612aa1565b905092915050565b6000819050919050565b612b0f81612afc565b8114612b1a57600080fd5b50565b600081359050612b2c81612b06565b92915050565b600060208284031215612b4857612b4761297c565b5b6000612b5684828501612b1d565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612b8a82612b5f565b9050919050565b612b9a81612b7f565b82525050565b6000602082019050612bb56000830184612b91565b92915050565b612bc481612b7f565b8114612bcf57600080fd5b50565b600081359050612be181612bbb565b92915050565b60008060408385031215612bfe57612bfd61297c565b5b6000612c0c85828601612bd2565b9250506020612c1d85828601612b1d565b9150509250929050565b600080600060608486031215612c4057612c3f61297c565b5b6000612c4e86828701612b1d565b9350506020612c5f86828701612b1d565b9250506040612c7086828701612b1d565b9150509250925092565b600080600060608486031215612c9357612c9261297c565b5b6000612ca186828701612bd2565b9350506020612cb286828701612bd2565b9250506040612cc386828701612b1d565b9150509250925092565b60008060408385031215612ce457612ce361297c565b5b6000612cf285828601612b1d565b9250506020612d0385828601612b1d565b9150509250929050565b612d1681612afc565b82525050565b6000604082019050612d316000830185612b91565b612d3e6020830184612d0d565b9392505050565b600060208284031215612d5b57612d5a61297c565b5b6000612d6984828501612bd2565b91505092915050565b6000602082019050612d876000830184612d0d565b92915050565b612d9681612a0b565b8114612da157600080fd5b50565b600081359050612db381612d8d565b92915050565b600060208284031215612dcf57612dce61297c565b5b6000612ddd84828501612da4565b91505092915050565b60008060408385031215612dfd57612dfc61297c565b5b6000612e0b85828601612bd2565b9250506020612e1c85828601612da4565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e6882612a90565b810181811067ffffffffffffffff82111715612e8757612e86612e30565b5b80604052505050565b6000612e9a612972565b9050612ea68282612e5f565b919050565b600067ffffffffffffffff821115612ec657612ec5612e30565b5b612ecf82612a90565b9050602081019050919050565b82818337600083830152505050565b6000612efe612ef984612eab565b612e90565b905082815260208101848484011115612f1a57612f19612e2b565b5b612f25848285612edc565b509392505050565b600082601f830112612f4257612f41612e26565b5b8135612f52848260208601612eeb565b91505092915050565b60008060008060808587031215612f7557612f7461297c565b5b6000612f8387828801612bd2565b9450506020612f9487828801612bd2565b9350506040612fa587828801612b1d565b925050606085013567ffffffffffffffff811115612fc657612fc5612981565b5b612fd287828801612f2d565b91505092959194509250565b60008060408385031215612ff557612ff461297c565b5b600061300385828601612bd2565b925050602061301485828601612bd2565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061306557607f821691505b602082108114156130795761307861301e565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006130db602183612a4c565b91506130e68261307f565b604082019050919050565b6000602082019050818103600083015261310a816130ce565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b600061316d603d83612a4c565b915061317882613111565b604082019050919050565b6000602082019050818103600083015261319c81613160565b9050919050565b7f4275726e206973206e6f74206163746976650000000000000000000000000000600082015250565b60006131d9601283612a4c565b91506131e4826131a3565b602082019050919050565b60006020820190508181036000830152613208816131cc565b9050919050565b60006060820190506132246000830186612b91565b6132316020830185612b91565b61323e6040830184612d0d565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061328082612afc565b915061328b83612afc565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156132c0576132bf613246565b5b828201905092915050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000613327602d83612a4c565b9150613332826132cb565b604082019050919050565b600060208201905081810360008301526133568161331a565b9050919050565b600061336882612afc565b915061337383612afc565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156133ac576133ab613246565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006133f182612afc565b91506133fc83612afc565b92508261340c5761340b6133b7565b5b828204905092915050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b600061344d601883612a4c565b915061345882613417565b602082019050919050565b6000602082019050818103600083015261347c81613440565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b60006134df602983612a4c565b91506134ea82613483565b604082019050919050565b6000602082019050818103600083015261350e816134d2565b9050919050565b600061352082612afc565b915061352b83612afc565b92508261353b5761353a6133b7565b5b828206905092915050565b600081905092915050565b7f7b226e616d65223a220000000000000000000000000000000000000000000000600082015250565b6000613587600983613546565b915061359282613551565b600982019050919050565b7f4368616f73207c20000000000000000000000000000000000000000000000000600082015250565b60006135d3600883613546565b91506135de8261359d565b600882019050919050565b60006135f482612a41565b6135fe8185613546565b935061360e818560208601612a5d565b80840191505092915050565b50565b600061362a600083613546565b91506136358261361a565b600082019050919050565b7f222c20226465736372697074696f6e223a22222c20226174747269627574657360008201527f223a22222c2022696d616765223a220000000000000000000000000000000000602082015250565b600061369c602f83613546565b91506136a782613640565b602f82019050919050565b7f222c2022616e696d6174696f6e5f75726c223a22000000000000000000000000600082015250565b60006136e8601483613546565b91506136f3826136b2565b601482019050919050565b7f227d000000000000000000000000000000000000000000000000000000000000600082015250565b6000613734600283613546565b915061373f826136fe565b600282019050919050565b60006137558261357a565b9150613760826135c6565b915061376c82866135e9565b91506137778261361d565b91506137828261368f565b915061378e82856135e9565b9150613799826136db565b91506137a582846135e9565b91506137b082613727565b9150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b60006137f3601d83613546565b91506137fe826137bd565b601d82019050919050565b6000613814826137e6565b915061382082846135e9565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613887602683612a4c565b91506138928261382b565b604082019050919050565b600060208201905081810360008301526138b68161387a565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000613919602583612a4c565b9150613924826138bd565b604082019050919050565b600060208201905081810360008301526139488161390c565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006139ab602483612a4c565b91506139b68261394f565b604082019050919050565b600060208201905081810360008301526139da8161399e565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613a17602083612a4c565b9150613a22826139e1565b602082019050919050565b60006020820190508181036000830152613a4681613a0a565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000613a83601983612a4c565b9150613a8e82613a4d565b602082019050919050565b60006020820190508181036000830152613ab281613a76565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000613b15603283612a4c565b9150613b2082613ab9565b604082019050919050565b60006020820190508181036000830152613b4481613b08565b9050919050565b7f222c202223000000000000000000000000000000000000000000000000000000600082015250565b6000613b81600583613546565b9150613b8c82613b4b565b600582019050919050565b6000613ba3828a6135e9565b9150613baf82896135e9565b9150613bbb82886135e9565b9150613bc782876135e9565b9150613bd282613b74565b9150613bde82866135e9565b9150613be982613b74565b9150613bf582856135e9565b9150613c0182846135e9565b915081905098975050505050505050565b6000613c1e828a6135e9565b9150613c2a82896135e9565b9150613c3682886135e9565b9150613c4282876135e9565b9150613c4e82866135e9565b9150613c5a82856135e9565b9150613c6682846135e9565b915081905098975050505050505050565b6000613c8382846135e9565b915081905092915050565b6000613c9a82856135e9565b9150613ca682846135e9565b91508190509392505050565b6000613cbd82612afc565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613cf057613cef613246565b5b600182019050919050565b6000613d0682612afc565b9150613d1183612afc565b925082821015613d2457613d23613246565b5b828203905092915050565b600060ff82169050919050565b6000613d4782613d2f565b9150613d5283613d2f565b92508260ff03821115613d6857613d67613246565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000613dc982613da2565b613dd38185613dad565b9350613de3818560208601612a5d565b613dec81612a90565b840191505092915050565b6000608082019050613e0c6000830187612b91565b613e196020830186612b91565b613e266040830185612d0d565b8181036060830152613e388184613dbe565b905095945050505050565b600081519050613e52816129b2565b92915050565b600060208284031215613e6e57613e6d61297c565b5b6000613e7c84828501613e43565b91505092915050565b60008160601b9050919050565b6000613e9d82613e85565b9050919050565b6000613eaf82613e92565b9050919050565b613ec7613ec282612b7f565b613ea4565b82525050565b6000613ed98284613eb6565b60148201915081905092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000613f1e602083612a4c565b9150613f2982613ee8565b602082019050919050565b60006020820190508181036000830152613f4d81613f11565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000613f8a601c83612a4c565b9150613f9582613f54565b602082019050919050565b60006020820190508181036000830152613fb981613f7d565b905091905056fe3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737667222077696474683d2233353022206865696768743d22333530223e203c726563742077696474683d2233353022206865696768743d2233353022207374796c653d2266696c6c3a7267622833372c33382c33302922202f3e203c646566733e203c6c696e6561724772616469656e742069643d2267726164222078313d223025222079313d223025222078323d2231303025222079323d223025223e203c73746f70206f66667365743d22302522207374796c653d2273746f702d636f6c6f723a23287b20782c20792c207a207d2c20647429207b2078202b3d2079202a2064743b2079202b3d20282d78202b2079202a207a29202a2064743b207a202b3d202831202d2079202a207929202a2064743b2072657475726e207b20782c20792c207a207d3b207d3b73746f702d6f7061636974793a3122202f3e203c73746f70206f66667365743d223130302522207374796c653d2273746f702d636f6c6f723a23287b20782c20792c207a207d2c20647429207b20636f6e73742061203d20302e39353b20636f6e73742062203d20302e373b20636f6e73742063203d20302e363b20636f6e73742064203d20332e353b20636f6e73742065203d20302e32353b20636f6e73742066203d20302e313b2078202b3d2028287a202d206229202a2078202d2064202a207929202a2064743b2079202b3d202864202a2078202b20287a202d206229202a207929202a2064743b207a202b3d202863202b2061202a207a202d20287a202a207a202a207a29202f2033202d202878202a2078202b2079202a207929202a202831202b2065202a207a29202b2066202a207a202a202878202a2078202a20782929202a2064743b2072657475726e207b20782c20792c207a207d3b207d225d3b206c65742063686f73656e417474726163746f7246756e6374696f6e203d206c696e65733b20766172206e756d6265725f6f665f7061746873203d20333b20757064617465506174687328293b2066756e6374696f6e2075706461746550617468732829207b207061746873203d205b5d3b206c657420657073696c6f6e5f62617365203d204d6174682e72616e646f6d2829202d204d6174682e72616e646f6d28293b20666f7220287661722069203d20303b2069203c206e756d6265725f6f665f70617468733b20692b2b29207b206c657420657073696c6f6e203d20657073696c6f6e5f62617365202b20284d6174682e72616e646f6d2829202d20302e303129202a20302e3030313b206c65742077697468696e675f706f696e745f657073696c6f6e203d20284d6174682e72616e646f6d2829202d20302e303129202a20302e3030313b2070617468732e70757368285b207b20783a20657073696c6f6e202b2077697468696e675f706f696e745f657073696c6f6e2c20793a20657073696c6f6e202b2077697468696e675f706f696e745f657073696c6f6e2c207a3a20657073696c6f6e202b2077697468696e675f706f696e745f657073696c6f6e2c207d2c205d293b207d207d2066756e6374696f6e20657874656e645061746828706174682c20737465707329207b20666f7220287661722069203d20303b2069203c2073746570733b20692b2b29207b20636f6e7374206c61737450203d20706174685b706174682e6c656e677468202d20315d3b20636f6e73742070203d2063686f73656e417474726163746f7246756e6374696f6e286c617374502c206474293b20706174682e707573682870293b207d2072657475726e20706174683b207d2066756e6374696f6e207363616c6528706f696e74732c2073697a6529207b20636f6e7374206d78203d204d6174682e6d696e282e2e2e706f696e74732e736c6963652831292e6d617028287b20782c20792c207a207d29203d3e207829293b20636f6e7374204d78203d204d6174682e6d6178282e2e2e706f696e74732e736c6963652831292e6d617028287b20782c20792c207a207d29203d3e207829293b20636f6e7374206d79203d204d6174682e6d696e282e2e2e706f696e74732e736c6963652831292e6d617028287b20782c20792c207a207d29203d3e207929293b20636f6e7374204d79203d204d6174682e6d6178282e2e2e706f696e74732e736c6963652831292e6d617028287b20782c20792c207a207d29203d3e207929293b20636f6e7374206d7a203d204d6174682e6d696e282e2e2e706f696e74732e736c6963652831292e6d617028287b20782c20792c207a207d29203d3e207a29293b20636f6e7374204d7a203d204d6174682e6d6178282e2e2e706f696e74732e736c6963652831292e6d617028287b20782c20792c207a207d29203d3e207a29293b20636f6e73742073203d2028762c206d762c204d7629203d3e202873697a65202a202876202d206d762929202f20284d76202d206d76293b2072657475726e20706f696e74732e736c6963652831292e6d617028287b20782c20792c207a207d29203d3e207b2078203d207328782c206d782c204d78293b2079203d207328792c206d792c204d79293b207a203d2073287a2c206d7a2c204d7a293b2072657475726e207b20782c20792c207a207d3b207d293b207d2066756e6374696f6e206472617728706174682c206929207b206966202871203e2032202a204d6174682e5049292071203d20303b20636f6e7374206d6170203d20287b20782c20792c207a207d29203d3e205b202878202d206129202a204d6174682e636f73287129202d202879202d206229202a204d6174682e73696e287129202b20632c207a2c205d3b206374782e626567696e5061746828293b206374782e7374726f6b655374796c65203d20636f6c6f72735b695d3b2070617468202e736c696365283129202e6d6170286d617029202e666f724561636828287029203d3e206374782e6c696e65546f28705b305d2c20705b315d29293b206374782e7374726f6b6528293b207d2066756e6374696f6e207570646174652829207b206374782e636c6561725265637428302c20302c2063616e7661732e77696474682c2063616e7661732e686569676874293b2071202d3d20726f746174696f6e5f73706565643b20666f7220287661722069203d20303b2069203c2070617468732e6c656e6774683b20692b2b29207b2070617468735b695d203d20657874656e64506174682870617468735b695d2c2073746570735f7065725f6672616d65293b2064726177287363616c652870617468735b695d2c207363616c655f666163746f72292c2069293b207768696c65202870617468735b695d2e6c656e677468203e206475726174696f6e5f74696c6c5f7265706c6163655f70617468292070617468735b695d2e736869667428293b207d207d2066756e6374696f6e206d61696e2829207b20726573697a6528293b20736574496e74657276616c287570646174652c2031303030202f20465053293b207d2066756e6374696f6e20726573697a652829207b2063616e7661732e7769647468203d2077696e646f772e696e6e657257696474683b2063616e7661732e686569676874203d2077696e646f772e696e6e65724865696768743b2061203d2063616e7661732e7769647468202f20373b2062203d2063616e7661732e7769647468202f20363b2063203d2063616e7661732e7769647468202f20323b207d2077696e646f772e6164644576656e744c697374656e65722822726573697a65222c20726573697a652c2066616c7365293b206d61696e28293b203c2f7363726970743e203c2f626f64793e203c2f68746d6c3e3b73746f702d6f7061636974793a3122202f3e203c73746f70206f66667365743d2235302522207374796c653d2273746f702d636f6c6f723a234142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f3b73746f702d6f7061636974793a3122202f3e203c2f6c696e6561724772616469656e743e203c2f646566733e203c7061746820643d224d3530203330302043203430203232302c2037352031302c2031353020313530205320323730203230302c2033303020353022207374796c653d2266696c6c3a6e6f6e653b7374726f6b653a75726c282367726164293b7374726f6b652d77696474683a3130222f3e203c2f7376673e636f6e73742063616e766173203d20646f63756d656e742e676574456c656d656e74427949642822676f6c43616e76617322293b2063616e7661732e7769647468203d2077696e646f772e696e6e657257696474683b2063616e7661732e686569676874203d2077696e646f772e696e6e65724865696768743b20636f6e737420637478203d2063616e7661732e676574436f6e746578742822326422293b20636f6e7374206474203d20302e30313b2076617220726f746174696f6e5f7370656564203d20302e30313b207661722073746570735f7065725f6672616d65203d20353b20766172206475726174696f6e5f74696c6c5f7265706c6163655f70617468203d203130303030303b20636f6e737420465053203d203135303b20636f6e7374207363616c655f666163746f72203d204d6174682e6d696e2863616e7661732e77696474682c2063616e7661732e68656967687429202f2032202d2031303b207661722071203d20303b207661722061203d2063616e7661732e7769647468202f20373b207661722062203d2063616e7661732e7769647468202f20363b207661722063203d2063616e7661732e7769647468202f20323b206c6574207061746873203d205b5d3b206c657420636f6c6f7273203d205b22233c21444f43545950452068746d6c3e203c68746d6c206c616e673d22656e223e203c686561643e203c6d65746120636861727365743d225554462d3822202f3e203c6d65746120687474702d65717569763d22582d55412d436f6d70617469626c652220636f6e74656e743d2249453d6564676522202f3e203c6d657461206e616d653d2276696577706f72742220636f6e74656e743d2277696474683d6465766963652d77696474682c20696e697469616c2d7363616c653d312e3022202f3e203c7469746c653e4368616f733c2f7469746c653e203c2f686561643e203c626f64793e203c63616e76617320636c6173733d2263616e766173222069643d22676f6c43616e766173223e3c2f63616e7661733e203c7374796c653e202e63616e766173207b2077696474683a2036303070783b206865696768743a2034303070783b20706f736974696f6e3a206162736f6c7574653b20746f703a203630253b206c6566743a203530253b207472616e73666f726d3a207472616e736c617465282d3530252c202d353025293b207d203c2f7374796c653e203c7363726970743e2066756e6374696f6e206c696e6573287b20782c20792c207a207d2c20647429207b20636f6e73742061203d20312e343b2078202b3d20282d61202a2078202d2034202a2079202d2034202a207a202d2079202a207929202a2064743b2079202b3d20282d61202a2079202d2034202a207a202d2034202a2078202d207a202a207a29202a2064743b207a202b3d20282d61202a207a202d2034202a2078202d2034202a2079202d2078202a207829202a2064743b2072657475726e207b20782c20792c207a207d3b207da264697066735822122097a026bcdfd2d8ae5b7f69367d59d5bc63ffbdc012868c3e5ecab36a8360c23564736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000531c24a152060bad20ce77079fcb5bfe56726a4e
-----Decoded View---------------
Arg [0] : _cells (address): 0x531c24A152060BAd20cE77079fCB5BfE56726a4e
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000531c24a152060bad20ce77079fcb5bfe56726a4e
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.