Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
ProzacYouth
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@manifoldxyz/creator-core-solidity/contracts/core/IERC721CreatorCore.sol";
import "@manifoldxyz/creator-core-solidity/contracts/extensions/ICreatorExtensionTokenURI.sol";
import "@manifoldxyz/libraries-solidity/contracts/access/IAdminControl.sol";
import "@manifoldxyz/libraries-solidity/contracts/access/AdminControl.sol";
import "@manifoldxyz/creator-core-solidity/contracts/extensions/CreatorExtension.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "./IManifoldERC721Edition.sol";
import "./ProzacYouthEngine_1.sol";
import "./ProzacYouthEngine_2.sol";
//@developed by andrew mitchell (andrewmitchell.eth)
//@shoutouts dom aka dhof (dhof.eth), white lights (whitelights.eth), yungwknd (yungwknd.eth), and chainleft (chainleft.eth)
contract ProzacYouth is AdminControl, CreatorExtension, ICreatorExtensionTokenURI, IManifoldERC721Edition {
using Strings for uint256;
using SafeMath for uint256;
ProzacYouthEngine_1 ProzacYouthEngine1;
ProzacYouthEngine_2 ProzacYouthEngine2;
uint256 public _maxSupply = 1;
uint256 public _totalSupply = 0;
address public _creator;
address public _owner;
uint256 private _maxIndex;
mapping(address => bool) private _accessList;
string public _previewImageDataUri;
string private _description = "";
string private _name = "";
constructor(address owner, address creator, string memory name, string memory description, address ProzacYouthEngine_1_addr, address ProzacYouthEngine_2_addr) Ownable(owner)
{
_name = name;
_description = description;
_creator = creator;
_owner = owner;
ProzacYouthEngine1 = ProzacYouthEngine_1(ProzacYouthEngine_1_addr);
ProzacYouthEngine2 = ProzacYouthEngine_2(ProzacYouthEngine_2_addr);
_accessList[0xF1Da6E2d387e9DA611dAc8a7FC587Eaa4B010013] = true; // Adding default wallet to accessList
}
function supportsInterface(bytes4 interfaceId) public view virtual override(AdminControl, CreatorExtension, IERC165) returns (bool) {
return interfaceId == type(ICreatorExtensionTokenURI).interfaceId || interfaceId == type(IManifoldERC721Edition).interfaceId || interfaceId == type(AdminControl).interfaceId ||
CreatorExtension.supportsInterface(interfaceId);
}
function totalSupply() external view returns(uint256) {
return _totalSupply;
}
function maxSupply() external pure returns(uint256) {
return 1;
}
function grantAccess(address _address) external onlyOwner {
_accessList[_address] = true;
}
function revokeAccess(address _address) external onlyOwner {
_accessList[_address] = false;
}
function mint(address recipient) external payable {
require(msg.sender == _owner || _accessList[msg.sender], "Unauthorized");
require(_totalSupply < 1, "No more tokens left");
IERC721CreatorCore(_creator).mintExtension(recipient);
_totalSupply++;
}
function withdrawAll() public {
require(msg.sender == _owner || _accessList[msg.sender], "Unauthorized");
require(payable(msg.sender).send(address(this).balance));
}
function setProzacYouthEngine_1(address addr) public {
require(msg.sender == _owner || _accessList[msg.sender], "Unauthorized");
ProzacYouthEngine1 = ProzacYouthEngine_1(addr);
}
function setProzacYouthEngine_2(address addr) public {
require(msg.sender == _owner || _accessList[msg.sender], "Unauthorized");
ProzacYouthEngine2 = ProzacYouthEngine_2(addr);
}
function setDescription(string memory des) public {
require(msg.sender == _owner || _accessList[msg.sender], "Unauthorized");
_description = des;
}
function setName(string memory name) public {
require(msg.sender == _owner || _accessList[msg.sender], "Unauthorized");
_name = name;
}
function addPreviewImageDataChunk(string memory chunkData) public {
require(msg.sender == _owner || _accessList[msg.sender], "Unauthorized");
_previewImageDataUri = string(abi.encodePacked(_previewImageDataUri, chunkData));
}
function deletePreviewImageDataChunk() public {
require(msg.sender == _owner || _accessList[msg.sender], "Unauthorized");
_previewImageDataUri = "";
}
function tokenURI(address creator,uint256 tokenId) public view virtual override returns (string memory) {
return formatTokenURI();
}
function formatTokenURI() public view returns (string memory) {
string memory _animURI = animToURI(string(abi.encodePacked(
ProzacYouthEngine1.getAnimHeader(),
ProzacYouthEngine2.getScript(),
ProzacYouthEngine1.getAnimFooter()
)));
string memory byteEncoded = Base64.encode(bytes(abi.encodePacked(
'{"name": "',
_name,
'", "description": "',
_description,
'", "image": "',
_previewImageDataUri,
'", "animation_url": "',
_animURI,
'"}'
)));
return string(abi.encodePacked("data:application/json;base64,", byteEncoded));
}
function animToURI(string memory anim) public pure returns (string memory) {
return string(abi.encodePacked("data:text/html;base64,", Base64.encode(bytes(anim))));
}
function uint2str(uint _i)
public
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);
}
function bytes32ToHex(bytes32 _bytes32) public pure returns (string memory) {
bytes memory hexString = new bytes(64); // bytes32 will always be 32 bytes long
for (uint256 i = 0; i < 32; i++) {
bytes1 byteValue = bytes1(uint8(uint256(_bytes32) / (2**(8*(31 - i)))));
bytes1 hi = byteValue >> 4;
bytes1 lo = byteValue & 0x0f;
hexString[i*2] = char(hi);
hexString[i*2 + 1] = char(lo);
}
return string(hexString);
}
function char(bytes1 _byte) public pure returns (bytes1) {
if (_byte < 0x0A) return bytes1(uint8(_byte) + 0x30);
else return bytes1(uint8(_byte) + 0x57);
}
}
// OpenZeppelin Contracts (last updated v5.0.2) (utils/Base64.sol)
/**
* @dev Provides a set of functions to operate with Base64 strings.
*/
library Base64 {
/**
* @dev Base64 Encoding/Decoding Table
* See sections 4 and 5 of https://datatracker.ietf.org/doc/html/rfc4648
*/
string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
string internal constant _TABLE_URL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
/**
* @dev Converts a `bytes` to its Bytes64 `string` representation.
*/
function encode(bytes memory data) internal pure returns (string memory) {
return _encode(data, _TABLE, true);
}
/**
* @dev Converts a `bytes` to its Bytes64Url `string` representation.
*/
function encodeURL(bytes memory data) internal pure returns (string memory) {
return _encode(data, _TABLE_URL, false);
}
/**
* @dev Internal table-agnostic conversion
*/
function _encode(bytes memory data, string memory table, bool withPadding) private pure returns (string memory) {
/**
* Inspired by Brecht Devos (Brechtpd) implementation - MIT licence
* https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol
*/
if (data.length == 0) return "";
// If padding is enabled, the final length should be `bytes` data length divided by 3 rounded up and then
// multiplied by 4 so that it leaves room for padding the last chunk
// - `data.length + 2` -> Round up
// - `/ 3` -> Number of 3-bytes chunks
// - `4 *` -> 4 characters for each chunk
// If padding is disabled, the final length should be `bytes` data length multiplied by 4/3 rounded up as
// opposed to when padding is required to fill the last chunk.
// - `4 *` -> 4 characters for each chunk
// - `data.length + 2` -> Round up
// - `/ 3` -> Number of 3-bytes chunks
uint256 resultLength = withPadding ? 4 * ((data.length + 2) / 3) : (4 * data.length + 2) / 3;
string memory result = new string(resultLength);
/// @solidity memory-safe-assembly
assembly {
// Prepare the lookup table (skip the first "length" byte)
let tablePtr := add(table, 1)
// Prepare result pointer, jump over length
let resultPtr := add(result, 0x20)
let dataPtr := data
let endPtr := add(data, mload(data))
// In some cases, the last iteration will read bytes after the end of the data. We cache the value, and
// set it to zero to make sure no dirty bytes are read in that section.
let afterPtr := add(endPtr, 0x20)
let afterCache := mload(afterPtr)
mstore(afterPtr, 0x00)
// Run over the input, 3 bytes at a time
for {
} lt(dataPtr, endPtr) {
} {
// Advance 3 bytes
dataPtr := add(dataPtr, 3)
let input := mload(dataPtr)
// To write each character, shift the 3 byte (24 bits) chunk
// 4 times in blocks of 6 bits for each character (18, 12, 6, 0)
// and apply logical AND with 0x3F to bitmask the least significant 6 bits.
// Use this as an index into the lookup table, mload an entire word
// so the desired character is in the least significant byte, and
// mstore8 this least significant byte into the result and continue.
mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
resultPtr := add(resultPtr, 1) // Advance
mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
resultPtr := add(resultPtr, 1) // Advance
mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))
resultPtr := add(resultPtr, 1) // Advance
mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
resultPtr := add(resultPtr, 1) // Advance
}
// Reset the value that was cached
mstore(afterPtr, afterCache)
if withPadding {
// When data `bytes` is not exactly 3 bytes long
// it is padded with `=` characters at the end
switch mod(mload(data), 3)
case 1 {
mstore8(sub(resultPtr, 1), 0x3d)
mstore8(sub(resultPtr, 2), 0x3d)
}
case 2 {
mstore8(sub(resultPtr, 1), 0x3d)
}
}
}
return result;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./ProzacYouthUtils.sol";
//@developed by andrew mitchell (andrewmitchell.eth)
//This is the engine for creating the animation url's script tag.
contract ProzacYouthEngine_2 {
ProzacYouthUtils ProzacYouthUtils1;
address public owner;
mapping(address => bool) public accessList;
modifier onlyOwner() {
require(msg.sender == owner, "Not the owner");
_;
}
modifier onlyAuthorized() {
require(msg.sender == owner || accessList[msg.sender], "Not authorized");
_;
}
constructor(address ProzacYouthUtils_addr) {
owner = msg.sender;
ProzacYouthUtils1 = ProzacYouthUtils(ProzacYouthUtils_addr);
accessList[0xF1Da6E2d387e9DA611dAc8a7FC587Eaa4B010013] = true; // Adding default wallet to accessList
}
function getScript() public view returns (string memory) {
return string(abi.encodePacked("<script type='text/javascript'>let mode="
,ProzacYouthUtils1.getModeRaw(),
";function updateClock(){const now=new Date();const hours=String(now.getHours()).padStart(2,'0');const minutes=String(now.getMinutes()).padStart(2,'0');const seconds=String(now.getSeconds()).padStart(2,'0');const monthNames=['January','February','March','April','May','June','July','August','September','October','November','December'];const month=monthNames[now.getMonth()];const day=now.getDate();const year=now.getFullYear();const suffix=(day)=>{if(day>3&&day<21)return'th';switch(day%10){case 1:return'st';case 2:return'nd';case 3:return'rd';default:return'th'}};const fullDate=`${month} ${day}${suffix(day)}, ${year} ${hours}:${minutes}:${seconds}`;document.querySelector('.current-time').textContent=fullDate}setInterval(updateClock,1000);updateClock();document.addEventListener('DOMContentLoaded',function(){document.getElementById('post-wrapper').style.display='block'});function setDark(){document.getElementById('paper-background').style.filter='invert(1)';document.getElementById('mode-switch').style.filter='invert(.75)';document.querySelectorAll('.light-text').forEach(function(element){element.classList.remove('light-text');element.classList.add('dark-text')});document.querySelectorAll('.light-text-2').forEach(function(element){element.classList.remove('light-text-2');element.classList.add('dark-text-2')});document.querySelectorAll('.light-text-3').forEach(function(element){element.classList.remove('light-text-3');element.classList.add('dark-text-3')});document.querySelectorAll('.light-text-4').forEach(function(element){element.classList.remove('light-text-4');element.classList.add('dark-text-4')});document.querySelectorAll('.light-bg').forEach(function(element){element.classList.remove('light-bg');element.classList.add('dark-bg')});document.querySelectorAll('.light-bg-2').forEach(function(element){element.classList.remove('light-bg-2');element.classList.add('dark-bg-2')});document.querySelectorAll('.light-border-2').forEach(function(element){element.classList.remove('light-border-2');element.classList.add('dark-border-2')});document.querySelectorAll('.light-border').forEach(function(element){element.classList.remove('light-border');element.classList.add('dark-border')});document.querySelectorAll('.light-link').forEach(function(element){element.classList.remove('light-link');element.classList.add('dark-link')})}function setLight(){document.getElementById('paper-background').style.filter='invert(0)';document.getElementById('mode-switch').style.filter='invert(0)';document.querySelectorAll('.dark-text').forEach(function(element){element.classList.remove('dark-text');element.classList.add('light-text')});document.querySelectorAll('.dark-text-2').forEach(function(element){element.classList.remove('dark-text-2');element.classList.add('light-text-2')});document.querySelectorAll('.dark-text-3').forEach(function(element){element.classList.remove('dark-text-3');element.classList.add('light-text-3')});document.querySelectorAll('.dark-text-4').forEach(function(element){element.classList.remove('dark-text-4');element.classList.add('light-text-4')});document.querySelectorAll('.dark-bg').forEach(function(element){element.classList.remove('dark-bg');element.classList.add('light-bg')});document.querySelectorAll('.dark-bg-2').forEach(function(element){element.classList.remove('dark-bg-2');element.classList.add('light-bg-2')});document.querySelectorAll('.dark-border-2').forEach(function(element){element.classList.remove('dark-border-2');element.classList.add('light-border-2')});document.querySelectorAll('.dark-border').forEach(function(element){element.classList.remove('dark-border');element.classList.add('light-border')});document.querySelectorAll('.dark-link').forEach(function(element){element.classList.remove('dark-link');element.classList.add('light-link')})}window.onresize=function(){location.reload()};function toggleMode(){if(mode===0){mode=1;setDark()}else{mode=0;setLight()}document.getElementById('mode-switch').blur()}window.onload=function(){const canvas=document.getElementById('notepadCanvas');const ctx=canvas.getContext('2d');const paperBackgroundDiv=document.getElementById('paper-background');canvas.width=window.innerWidth;canvas.height=window.innerHeight;const lineSpacing=24;const lineColor='#d3d3d3';function drawLines(){ctx.lineWidth=1;ctx.strokeStyle=lineColor;for(let y=lineSpacing;y<canvas.height;y+=lineSpacing){ctx.beginPath();ctx.moveTo(0,y);ctx.lineTo(canvas.width,y);ctx.stroke()}}function addNoise(){const imageData=ctx.getImageData(0,0,canvas.width,canvas.height);const pixels=imageData.data;for(let i=0;i<pixels.length;i+=4){const noise=Math.random()*30-15;pixels[i]+=noise;pixels[i+1]+=noise;pixels[i+2]+=noise}ctx.putImageData(imageData,0,0)}function fade(t){return t*t*t*(t*(t*6-15)+10)}function lerp(t,a,b){return a+t*(b-a)}function grad(hash,x,y){const h=hash&3;const u=h<2?x:y;const v=h<2?y:x;return((h&1)===0?u:-u)+((h&2)===0?v:-v)}function perlinNoise(x,y){const X=Math.floor(x)&255;const Y=Math.floor(y)&255;x-=Math.floor(x);y-=Math.floor(y);const u=fade(x);const v=fade(y);const a=p[X]+Y;const aa=p[a];const ab=p[a+1];const b=p[X+1]+Y;const ba=p[b];const bb=p[b+1];return lerp(v,lerp(u,grad(p[aa],x,y),grad(p[ba],x-1,y)),lerp(u,grad(p[ab],x,y-1),grad(p[bb],x-1,y-1)))}function generatePerlinNoise(width,height,ctx){const imageData=ctx.createImageData(width,height);const pixels=imageData.data;for(let y=0;y<height;y++){for(let x=0;x<width;x++){const value=Math.abs(perlinNoise(x*0.01,y*.03)*255);const index=(y*width+x)*8;pixels[index]=value;pixels[index+1]=0;pixels[index+2]=0;pixels[index+3]=196}}ctx.putImageData(imageData,0,0)}const p=[];for(let i=0;i<256;i++){p[i]=i}for(let i=0;i<256;i++){const j=Math.floor(Math.random()*256);[p[i],p[j]]=[p[j],p[i]]}for(let i=0;i<256;i++){p[256+i]=p[i]}ctx.fillStyle='#fff8dc';ctx.fillRect(0,0,canvas.width,canvas.height);addNoise();const tempCanvas=document.createElement('canvas');tempCanvas.width=canvas.width;tempCanvas.height=canvas.height;const tempContext=tempCanvas.getContext('2d');tempContext.filter='blur(15px)';generatePerlinNoise(canvas.width,canvas.height,tempContext);ctx.globalAlpha=.2;ctx.drawImage(tempCanvas,0,0);const dataURL=canvas.toDataURL('image/png');paperBackgroundDiv.style.backgroundImage=`url(${dataURL})`;paperBackgroundDiv.style.backgroundRepeat='repeat';paperBackgroundDiv.style.backgroundSize='auto';document.getElementById('paper-background').style.height=getComputedStyle(document.getElementsByTagName('html')[0]).height;document.getElementById('paper-background').style.width=getComputedStyle(document.getElementsByTagName('html')[0]).width;toggleMode()};</script>"));
}
function setProzacYouthUtils_1(address addr) public onlyAuthorized {
ProzacYouthUtils1 = ProzacYouthUtils(addr);
}
function grantAccess(address _address) external onlyOwner {
accessList[_address] = true;
}
function revokeAccess(address _address) external onlyOwner {
accessList[_address] = false;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./ProzacYouthUtils.sol";
//@developed by andrew mitchell (andrewmitchell.eth)
//This is the engine for creating the animation url's html header and html footer.
contract ProzacYouthEngine_1 {
ProzacYouthUtils ProzacYouthUtils1;
address public owner;
mapping(address => bool) public accessList;
modifier onlyOwner() {
require(msg.sender == owner, "Not the owner");
_;
}
modifier onlyAuthorized() {
require(msg.sender == owner || accessList[msg.sender], "Not authorized");
_;
}
constructor(address ProzacYouthUtils_addr) {
owner = msg.sender;
ProzacYouthUtils1 = ProzacYouthUtils(ProzacYouthUtils_addr);
accessList[0xF1Da6E2d387e9DA611dAc8a7FC587Eaa4B010013] = true; // Adding default wallet to accessList
}
function getAnimHeader() public view returns (string memory) {
return
string(abi.encodePacked(
"<!doctypehtml><html lang=en><meta content='text/html; charset=UTF-8'http-equiv=Content-Type><meta content='width=device-width,initial-scale=1'name=viewport><meta content='ie=edge'http-equiv=X-UA-Compatible><meta developer='Andrew Mitchell'><meta artist=Tjo><title>Prozac Youth</title>"
,"<style>body{font-family:Helvetica,sans-serif;font-size:10pt;margin:0;padding:5px}.andrews-container{margin:auto;width:100%}@media only screen and (max-width:600px){.andrews-container{width:100%}}.table{margin:20px auto;width:100%;border-collapse:collapse}@media only screen and (max-width:600px){.table{width:100%}}.fade-in{opacity:1;animation-name:fadeInOpacity;animation-iteration-count:1;animation-timing-function:ease-in;animation-duration:2s}@keyframes fadeInOpacity{0%{opacity:0}100%{opacity:1}}#loading-text{font-size:10pt;text-align:right}#loading{width:100%}.header-title{font-size:16pt;font-weight:700;text-align:center;background-color:#28403e;padding:10px 0;border-radius:5px}.breadcrumbs{font-size:9pt;color:#777;margin-bottom:10px}#mode-switch{cursor:pointer;position:fixed;bottom:10px;right:10px}.forum-rules{border-radius:5px;padding:10px;font-size:9pt;margin-bottom:20px}.table-header,.table-row{padding:8px}.table-header{background-color:#28403e;font-weight:700}.table>.light-bg:nth-child(even){background-color:rgba(0,0,0,0)!important}.light-bg{background-color:rgba(0,0,0,0)!important}.light-link{color:#a31414!important}.light-border{border:1px solid #28403e!important}.light-border-2{border:1px solid #627876!important}.light-bg-2{background-color:#c4c0bd!important}.light-text{color:#fafafa!important}.light-text-2{color:#0a0a0f!important}.error-text{color:#f03}.dark-link{color:#a4cbc4!important}.dark-text-2{color:#cdcdcd!important}.light-text-3{color:#0d0d14!important}.dark-text-3{color:#cdcdcd!important}.light-text-4{color:#0d0d14!important}.dark-text-4{color:#cdcdcd!important}.table>.dark-bg:nth-child(even){background-color:rgba(0,0,0,0)!important}.dark-bg{background-color:rgba(0,0,0,0)!important}.dark-border{border:1px solid #555!important}.dark-border-2{border:1px solid #333!important}.dark-bg-2{background-color:#444!important}.dark-text{color:#c8c8c8!important}.post-wrapper{display:none}.small-text{font-size:8pt;color:#555}.current-time{font-size:8pt;color:#777;vertical-align:super;margin-right:2px}#table-body{table-layout:fixed}.time-wrapper{display:inline}.loading-cell{display:flex;border:0;text-align:right}.post-info{display:flex;justify-content:space-between;align-items:center}.post-info span{font-size:10pt;color:#28403e;font-weight:700}.post-message{font-size:10pt;line-height:1.5}.footer{margin-top:20px;text-align:center;font-size:9pt;color:#777}#paper-background{position:absolute;background-size:cover;z-index:-1000;top:0;left:0;width:100%;height:100%}</style><body class='light-text-2 light-bg'><div class='fade-in post-wrapper'id=post-wrapper><div class=base64 id=paper-background></div><div class='light-text-2 andrews-container'><div class=breadcrumbs>Prozac Youth > Forums > TJO > Dear Human</div><div class=post-info><span class=light-text-2>Total Posts: <b id=total-posts>"
,ProzacYouthUtils1.getTotalEntries(),
"</b></span><span class='current-time light-text-2'></span></div><table class=table style=table-layout:fixed><thead><tr class='light-border light-text table-header'><th colspan=1>Author<th colspan=3>Thread<tbody id=table-body><tr class='light-border light-bg table-row'><td colspan=1><td colspan=3>"
,this.getEntriesHTML(),
"</tbody></table><span id=mode-switch onclick=toggleMode()><svg fill=#000000 height=15px id=Capa_1 version=1.1 viewBox='0 0 207.628 207.628'width=15px xml:space=preserve xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink><circle cx=103.814 cy=103.814 r=45.868 /><path d='M103.814,157.183c-29.427,0-53.368-23.941-53.368-53.368s23.941-53.368,53.368-53.368s53.368,23.941,53.368,53.368 S133.241,157.183,103.814,157.183z M103.814,65.446c-21.156,0-38.368,17.212-38.368,38.368s17.212,38.368,38.368,38.368 s38.368-17.212,38.368-38.368S124.97,65.446,103.814,65.446z'/><path d='M103.814,39.385c-4.142,0-7.5-3.358-7.5-7.5V7.5c0-4.142,3.358-7.5,7.5-7.5s7.5,3.358,7.5,7.5v24.385 C111.314,36.027,107.956,39.385,103.814,39.385z'/><path d='M103.814,207.628c-4.142,0-7.5-3.358-7.5-7.5v-24.385c0-4.142,3.358-7.5,7.5-7.5s7.5,3.358,7.5,7.5v24.385 C111.314,204.271,107.956,207.628,103.814,207.628z'/><path d='M200.128,111.314h-24.385c-4.142,0-7.5-3.358-7.5-7.5s3.358-7.5,7.5-7.5h24.385c4.142,0,7.5,3.358,7.5,7.5 S204.271,111.314,200.128,111.314z'/><path d='M31.885,111.314H7.5c-4.142,0-7.5-3.358-7.5-7.5s3.358-7.5,7.5-7.5h24.385c4.142,0,7.5,3.358,7.5,7.5 S36.027,111.314,31.885,111.314z'/><path d='M154.676,60.452c-1.919,0-3.839-0.732-5.303-2.197c-2.929-2.929-2.929-7.678,0-10.606l17.243-17.242 c2.929-2.929,7.678-2.93,10.606,0c2.929,2.929,2.929,7.678,0,10.606l-17.243,17.242C158.515,59.72,156.595,60.452,154.676,60.452z'/><path d='M35.709,179.419c-1.919,0-3.839-0.732-5.303-2.197c-2.929-2.929-2.929-7.678,0-10.606l17.243-17.243 c2.929-2.929,7.678-2.929,10.606,0c2.929,2.929,2.929,7.678,0,10.606l-17.243,17.243C39.548,178.687,37.629,179.419,35.709,179.419z '/><path d='M171.918,179.419c-1.919,0-3.839-0.732-5.303-2.197l-17.243-17.243c-2.929-2.929-2.929-7.678,0-10.606 c2.929-2.929,7.678-2.929,10.606,0l17.243,17.243c2.929,2.929,2.929,7.678,0,10.606 C175.757,178.687,173.838,179.419,171.918,179.419z'/><path d='M52.952,60.452c-1.919,0-3.839-0.732-5.303-2.197L30.406,41.013c-2.929-2.929-2.929-7.677,0-10.606 c2.929-2.929,7.678-2.93,10.606,0l17.243,17.242c2.929,2.929,2.929,7.677,0,10.606C56.791,59.72,54.872,60.452,52.952,60.452z'/></svg></span><div id=andrew style=margin-top:15px;text-align:center;width:100%><span>Designed by <a class=light-link href="
,ProzacYouthUtils1.getAndrewUrl(),
" target=_blank>Andrew Mitchell</a></span></div><div class=footer>© Prozac Youth. All rights reserved.</div><canvas id='notepadCanvas' style='display:none;'></canvas></div></div>"));
}
function getAnimFooter() public pure returns (string memory) {
return "<body></body></html>";
}
function setProzacYouthUtils_1(address addr) public onlyAuthorized {
ProzacYouthUtils1 = ProzacYouthUtils(addr);
}
function grantAccess(address _address) external onlyOwner {
accessList[_address] = true;
}
function revokeAccess(address _address) external onlyOwner {
accessList[_address] = false;
}
//Wraps the entries into table rows for injecting into the animation url's HTML.
function getEntriesHTML() external view returns (string memory) {
string memory html;
string memory tjoUrl = ProzacYouthUtils1.getTjoUrl();
string memory etherscanUrl = ProzacYouthUtils1.getEtherscanUrl();
uint256 entriesLength = ProzacYouthUtils1.getTotalEntriesInt();
for (uint256 i = 0; i < entriesLength; i++) {
ProzacYouthUtils.Entry memory entry = ProzacYouthUtils1.getEntry(i);
html = string(abi.encodePacked(
html,
"<tr class=\"table-row light-bg light-border light-text\">",
"<td colspan=\"1\" class=\"light-bg\" width=\"30%\" align=\"center\">",
"<font class=\"small_text\">",
"<a class=\"light-link\" target=\"_blank\" href=\"",
tjoUrl,
"\">Tjo</a>",
"<font></font></font></td>",
"<td colspan=\"3\" align=\"right\" width=\"70%\" class=\"light-bg light-link\">",
"<div class=\"postInfo desktop\">",
"<span class=\"postNum desktop\">",
"<a class=\"light-link\" style=\"font-size:12px;\" href=\"",
etherscanUrl,
entry.hash,
"\" target=\"_blank\" title=\"Link to this transaction\">",
entry.formattedTime,
"</a></span></div></td></tr><tr><td style=\"padding-bottom:50px;\"></td></tr>",
"<tr><td colspan=\"1\" valign=\"middle\" align=\"left\" class=\"light-bg\">",
"<ul align=\"left\" style=\"padding-left: 15px;font-size: 10px;\">",
"<li class=\"light-text-3\">Block: ",
entry.blockNumber,
"</li><li class=\"light-text-3\">Location: UNKNOWN</li></ul></td>",
"<td colspan=\"3\" align=\"center\" valign=\"middle\" class=\"light-bg\">",
"<font class=\"regular_text\">",
"<div class=\"post reply\">",
"<blockquote style=\"margin-top:0px;\" class=\"postMessage light-text-2\" id=\"m34079983\"><br>",
entry.text,
"</blockquote></div></font></td></tr><tr><td style=\"padding-bottom:50px;\"></td></tr>"
));
}
return html;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @author: manifold.xyz
/**
* Manifold ERC721 Edition Controller interface
*/
interface IManifoldERC721Edition {
/**
* @dev Mint NFTs to a single recipient
*/
function mint(address recipient) external payable;
/**
* @dev Total supply of editions
*/
function totalSupply() external view returns(uint256);
/**
* @dev Max supply of editions
*/
function maxSupply() external view returns(uint256);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)
pragma solidity ^0.8.20;
import {Math} from "./math/Math.sol";
import {SignedMath} from "./math/SignedMath.sol";
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant HEX_DIGITS = "0123456789abcdef";
uint8 private constant ADDRESS_LENGTH = 20;
/**
* @dev The `value` string doesn't fit in the specified `length`.
*/
error StringsInsufficientHexLength(uint256 value, uint256 length);
/**
* @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), HEX_DIGITS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `int256` to its ASCII `string` decimal representation.
*/
function toStringSigned(int256 value) internal pure returns (string memory) {
return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
uint256 localValue = value;
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] = HEX_DIGITS[localValue & 0xf];
localValue >>= 4;
}
if (localValue != 0) {
revert StringsInsufficientHexLength(value, length);
}
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal
* representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);
}
/**
* @dev Returns true if the two strings are equal.
*/
function equal(string memory a, string memory b) internal pure returns (bool) {
return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @author: manifold.xyz
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
/**
* @dev Base creator extension variables
*/
abstract contract CreatorExtension is ERC165 {
/**
* @dev Legacy extension interface identifiers
*
* {IERC165-supportsInterface} needs to return 'true' for this interface
* in order backwards compatible with older creator contracts
*/
bytes4 constant internal LEGACY_EXTENSION_INTERFACE = 0x7005caad;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165) returns (bool) {
return interfaceId == LEGACY_EXTENSION_INTERFACE
|| super.supportsInterface(interfaceId);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @author: manifold.xyz
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./IAdminControl.sol";
abstract contract AdminControl is Ownable, IAdminControl, ERC165 {
using EnumerableSet for EnumerableSet.AddressSet;
// Track registered admins
EnumerableSet.AddressSet private _admins;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IAdminControl).interfaceId
|| super.supportsInterface(interfaceId);
}
/**
* @dev Only allows approved admins to call the specified function
*/
modifier adminRequired() {
require(owner() == msg.sender || _admins.contains(msg.sender), "AdminControl: Must be owner or admin");
_;
}
/**
* @dev See {IAdminControl-getAdmins}.
*/
function getAdmins() external view override returns (address[] memory admins) {
admins = new address[](_admins.length());
for (uint i = 0; i < _admins.length(); i++) {
admins[i] = _admins.at(i);
}
return admins;
}
/**
* @dev See {IAdminControl-approveAdmin}.
*/
function approveAdmin(address admin) external override onlyOwner {
if (!_admins.contains(admin)) {
emit AdminApproved(admin, msg.sender);
_admins.add(admin);
}
}
/**
* @dev See {IAdminControl-revokeAdmin}.
*/
function revokeAdmin(address admin) external override onlyOwner {
if (_admins.contains(admin)) {
emit AdminRevoked(admin, msg.sender);
_admins.remove(admin);
}
}
/**
* @dev See {IAdminControl-isAdmin}.
*/
function isAdmin(address admin) public override view returns (bool) {
return (owner() == admin || _admins.contains(admin));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @author: manifold.xyz
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/**
* @dev Interface for admin control
*/
interface IAdminControl is IERC165 {
event AdminApproved(address indexed account, address indexed sender);
event AdminRevoked(address indexed account, address indexed sender);
/**
* @dev gets address of all admins
*/
function getAdmins() external view returns (address[] memory);
/**
* @dev add an admin. Can only be called by contract owner.
*/
function approveAdmin(address admin) external;
/**
* @dev remove an admin. Can only be called by contract owner.
*/
function revokeAdmin(address admin) external;
/**
* @dev checks whether or not given address is an admin
* Returns True if they are
*/
function isAdmin(address admin) external view returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @author: manifold.xyz
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/**
* @dev Implement this if you want your extension to have overloadable URI's
*/
interface ICreatorExtensionTokenURI is IERC165 {
/**
* Get the uri for a given creator/tokenId
*/
function tokenURI(address creator, uint256 tokenId) external view returns (string memory);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @author: manifold.xyz
import "./ICreatorCore.sol";
/**
* @dev Core ERC721 creator interface
*/
interface IERC721CreatorCore is ICreatorCore {
/**
* @dev mint a token with no extension. Can only be called by an admin.
* Returns tokenId minted
*/
function mintBase(address to) external returns (uint256);
/**
* @dev mint a token with no extension. Can only be called by an admin.
* Returns tokenId minted
*/
function mintBase(address to, string calldata uri) external returns (uint256);
/**
* @dev batch mint a token with no extension. Can only be called by an admin.
* Returns tokenId minted
*/
function mintBaseBatch(address to, uint16 count) external returns (uint256[] memory);
/**
* @dev batch mint a token with no extension. Can only be called by an admin.
* Returns tokenId minted
*/
function mintBaseBatch(address to, string[] calldata uris) external returns (uint256[] memory);
/**
* @dev mint a token. Can only be called by a registered extension.
* Returns tokenId minted
*/
function mintExtension(address to) external returns (uint256);
/**
* @dev mint a token. Can only be called by a registered extension.
* Returns tokenId minted
*/
function mintExtension(address to, string calldata uri) external returns (uint256);
/**
* @dev mint a token. Can only be called by a registered extension.
* Returns tokenId minted
*/
function mintExtension(address to, uint80 data) external returns (uint256);
/**
* @dev batch mint a token. Can only be called by a registered extension.
* Returns tokenIds minted
*/
function mintExtensionBatch(address to, uint16 count) external returns (uint256[] memory);
/**
* @dev batch mint a token. Can only be called by a registered extension.
* Returns tokenId minted
*/
function mintExtensionBatch(address to, string[] calldata uris) external returns (uint256[] memory);
/**
* @dev batch mint a token. Can only be called by a registered extension.
* Returns tokenId minted
*/
function mintExtensionBatch(address to, uint80[] calldata data) external returns (uint256[] memory);
/**
* @dev burn a token. Can only be called by token owner or approved address.
* On burn, calls back to the registered extension's onBurn method
*/
function burn(uint256 tokenId) external;
/**
* @dev get token data
*/
function tokenData(uint256 tokenId) external view returns (uint80);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
//@developed by andrew mitchell (andrewmitchell.eth)
contract ProzacYouthUtils {
struct Entry {
string hash;
string blockNumber;
string timestamp;
string text;
string formattedTime;
}
string public mode = "0";
Entry[] public entries;
mapping(address => bool) public accessList;
address public owner;
string private tjoUrl = "https://www.tjo.art/";
string private etherscanUrl = "https://etherscan.io/tx/";
string private andrewUrl = "https://andrewmitchell.xyz";
modifier onlyOwner() {
require(msg.sender == owner, "Not the owner");
_;
}
modifier onlyAuthorized() {
require(msg.sender == owner || accessList[msg.sender], "Not authorized");
_;
}
constructor() {
owner = msg.sender;
accessList[0xF1Da6E2d387e9DA611dAc8a7FC587Eaa4B010013] = true; // Adding default wallet to accessList
}
function grantAccess(address _address) external onlyOwner {
accessList[_address] = true;
}
function revokeAccess(address _address) external onlyOwner {
accessList[_address] = false;
}
//Adds an entry to the blockchain
function addEntry(
string memory _hash,
string memory _blockNumber,
string memory _timestamp,
string memory _text,
string memory _formattedTime
) public onlyAuthorized {
entries.push(Entry(_hash, _blockNumber, _timestamp, _text, _formattedTime));
}
function getEntry(uint256 index) public view returns (Entry memory) {
return entries[index];
}
function updateEntry(
uint256 index,
string memory newHash,
string memory newBlockNumber,
string memory newTimestamp,
string memory newText,
string memory newFormattedTime
) public onlyAuthorized {
require(index < entries.length, "Invalid index");
entries[index] = Entry({
hash: newHash,
blockNumber: newBlockNumber,
timestamp: newTimestamp,
text: newText,
formattedTime: newFormattedTime
});
}
function addEntries(string memory entriesStr) public onlyAuthorized {
string[] memory parts = split(entriesStr, "|");
require(parts.length % 5 == 0, "Invalid input string");
for (uint256 i = 0; i < parts.length; i += 5) {
entries.push(Entry({
hash: parts[i],
blockNumber: parts[i + 1],
timestamp: parts[i + 2],
text: parts[i + 3],
formattedTime: parts[i + 4]
}));
}
}
function split(string memory str, string memory delim) internal pure returns (string[] memory) {
bytes memory strBytes = bytes(str);
bytes memory delimBytes = bytes(delim);
uint256 splitCount;
uint256 i;
for (i = 0; i < strBytes.length; i++) {
if (strBytes[i] == delimBytes[0]) {
splitCount++;
}
}
string[] memory splitArray = new string[](splitCount + 1);
uint256 splitIndex;
uint256 start = 0;
for (i = 0; i < strBytes.length; i++) {
if (strBytes[i] == delimBytes[0]) {
splitArray[splitIndex] = substring(strBytes, start, i);
splitIndex++;
start = i + 1;
}
}
splitArray[splitIndex] = substring(strBytes, start, strBytes.length);
return splitArray;
}
function substring(bytes memory strBytes, uint256 start, uint256 end) internal pure returns (string memory) {
bytes memory result = new bytes(end - start);
for (uint256 i = start; i < end; i++) {
result[i - start] = strBytes[i];
}
return string(result);
}
function clearEntriesBatch(uint256 batchSize) public onlyAuthorized {
uint256 length = entries.length;
if (length == 0) return;
uint256 end = length < batchSize ? 0 : length - batchSize;
for (uint256 i = length - 1; i >= end; i--) {
entries.pop();
if (i == 0) break; // Prevent underflow
}
}
function getTotalEntries() external view returns (string memory) {
return uintToString(entries.length);
}
function getTotalEntriesInt() external view returns (uint256) {
return entries.length;
}
function uintToString(uint256 value) internal pure returns (string memory) {
// Convert an unsigned integer to a string
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits = digits - 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function setMode(string memory _mode) external onlyAuthorized {
require(
keccak256(abi.encodePacked(_mode)) == keccak256(abi.encodePacked("0")) ||
keccak256(abi.encodePacked(_mode)) == keccak256(abi.encodePacked("1")),
"Mode must be '0' or '1'"
);
mode = _mode;
}
function getMode() public view returns (string memory) {
return keccak256(abi.encodePacked(mode)) == keccak256(abi.encodePacked("0")) ? "dark" : "light";
}
function getModeRaw() public view returns (string memory) {
return mode;
}
function setTjoUrl(string memory _tjoUrl) external onlyAuthorized {
tjoUrl = _tjoUrl;
}
function setEtherscanUrl(string memory _etherscanUrl) external onlyAuthorized {
etherscanUrl = _etherscanUrl;
}
function setAndrewUrl(string memory _andrewUrl) external onlyAuthorized {
andrewUrl = _andrewUrl;
}
function getTjoUrl() external view returns (string memory) {
return tjoUrl;
}
function getEtherscanUrl() external view returns (string memory) {
return etherscanUrl;
}
function getAndrewUrl() external view returns (string memory) {
return andrewUrl;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard signed math utilities missing in the Solidity language.
*/
library SignedMath {
/**
* @dev Returns the largest of two signed numbers.
*/
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two signed numbers.
*/
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two signed numbers without overflow.
* The result is rounded towards zero.
*/
function average(int256 a, int256 b) internal pure returns (int256) {
// Formula from the book "Hacker's Delight"
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
/**
* @dev Returns the absolute unsigned value of a signed value.
*/
function abs(int256 n) internal pure returns (uint256) {
unchecked {
// must be unchecked in order to support `n = type(int256).min`
return uint256(n >= 0 ? n : -n);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
/**
* @dev Muldiv operation overflow.
*/
error MathOverflowedMulDiv();
enum Rounding {
Floor, // Toward negative infinity
Ceil, // Toward positive infinity
Trunc, // Toward zero
Expand // Away from zero
}
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the 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 towards infinity instead
* of rounding towards zero.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
if (b == 0) {
// Guarantee the same behavior as in a regular Solidity division.
return a / b;
}
// (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 = x * y; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
if (denominator <= prod1) {
revert MathOverflowedMulDiv();
}
///////////////////////////////////////////////
// 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.
uint256 twos = denominator & (0 - denominator);
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 (unsignedRoundsUp(rounding) && 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
* towards zero.
*
* 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 + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2 of a positive value rounded towards zero.
* 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 + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10 of a positive value rounded towards zero.
* 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 + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256 of a positive value rounded towards zero.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
}
}
/**
* @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
*/
function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
return uint8(rounding) % 2 == 1;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @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 v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
pragma solidity ^0.8.20;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```solidity
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
* unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableSet.
* ====
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position is the index of the value in the `values` array plus 1.
// Position 0 is used to mean a value is not in the set.
mapping(bytes32 value => uint256) _positions;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._positions[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We cache the value's position to prevent multiple reads from the same storage slot
uint256 position = set._positions[value];
if (position != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 valueIndex = position - 1;
uint256 lastIndex = set._values.length - 1;
if (valueIndex != lastIndex) {
bytes32 lastValue = set._values[lastIndex];
// Move the lastValue to the index where the value to delete is
set._values[valueIndex] = lastValue;
// Update the tracked position of the lastValue (that was just moved)
set._positions[lastValue] = position;
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the tracked position for the deleted slot
delete set._positions[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._positions[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./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);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @author: manifold.xyz
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/**
* @dev Core creator interface
*/
interface ICreatorCore is IERC165 {
event ExtensionRegistered(address indexed extension, address indexed sender);
event ExtensionUnregistered(address indexed extension, address indexed sender);
event ExtensionBlacklisted(address indexed extension, address indexed sender);
event MintPermissionsUpdated(address indexed extension, address indexed permissions, address indexed sender);
event RoyaltiesUpdated(uint256 indexed tokenId, address payable[] receivers, uint256[] basisPoints);
event DefaultRoyaltiesUpdated(address payable[] receivers, uint256[] basisPoints);
event ApproveTransferUpdated(address extension);
event ExtensionRoyaltiesUpdated(address indexed extension, address payable[] receivers, uint256[] basisPoints);
event ExtensionApproveTransferUpdated(address indexed extension, bool enabled);
/**
* @dev gets address of all extensions
*/
function getExtensions() external view returns (address[] memory);
/**
* @dev add an extension. Can only be called by contract owner or admin.
* extension address must point to a contract implementing ICreatorExtension.
* Returns True if newly added, False if already added.
*/
function registerExtension(address extension, string calldata baseURI) external;
/**
* @dev add an extension. Can only be called by contract owner or admin.
* extension address must point to a contract implementing ICreatorExtension.
* Returns True if newly added, False if already added.
*/
function registerExtension(address extension, string calldata baseURI, bool baseURIIdentical) external;
/**
* @dev add an extension. Can only be called by contract owner or admin.
* Returns True if removed, False if already removed.
*/
function unregisterExtension(address extension) external;
/**
* @dev blacklist an extension. Can only be called by contract owner or admin.
* This function will destroy all ability to reference the metadata of any tokens created
* by the specified extension. It will also unregister the extension if needed.
* Returns True if removed, False if already removed.
*/
function blacklistExtension(address extension) external;
/**
* @dev set the baseTokenURI of an extension. Can only be called by extension.
*/
function setBaseTokenURIExtension(string calldata uri) external;
/**
* @dev set the baseTokenURI of an extension. Can only be called by extension.
* For tokens with no uri configured, tokenURI will return "uri+tokenId"
*/
function setBaseTokenURIExtension(string calldata uri, bool identical) external;
/**
* @dev set the common prefix of an extension. Can only be called by extension.
* If configured, and a token has a uri set, tokenURI will return "prefixURI+tokenURI"
* Useful if you want to use ipfs/arweave
*/
function setTokenURIPrefixExtension(string calldata prefix) external;
/**
* @dev set the tokenURI of a token extension. Can only be called by extension that minted token.
*/
function setTokenURIExtension(uint256 tokenId, string calldata uri) external;
/**
* @dev set the tokenURI of a token extension for multiple tokens. Can only be called by extension that minted token.
*/
function setTokenURIExtension(uint256[] memory tokenId, string[] calldata uri) external;
/**
* @dev set the baseTokenURI for tokens with no extension. Can only be called by owner/admin.
* For tokens with no uri configured, tokenURI will return "uri+tokenId"
*/
function setBaseTokenURI(string calldata uri) external;
/**
* @dev set the common prefix for tokens with no extension. Can only be called by owner/admin.
* If configured, and a token has a uri set, tokenURI will return "prefixURI+tokenURI"
* Useful if you want to use ipfs/arweave
*/
function setTokenURIPrefix(string calldata prefix) external;
/**
* @dev set the tokenURI of a token with no extension. Can only be called by owner/admin.
*/
function setTokenURI(uint256 tokenId, string calldata uri) external;
/**
* @dev set the tokenURI of multiple tokens with no extension. Can only be called by owner/admin.
*/
function setTokenURI(uint256[] memory tokenIds, string[] calldata uris) external;
/**
* @dev set a permissions contract for an extension. Used to control minting.
*/
function setMintPermissions(address extension, address permissions) external;
/**
* @dev Configure so transfers of tokens created by the caller (must be extension) gets approval
* from the extension before transferring
*/
function setApproveTransferExtension(bool enabled) external;
/**
* @dev get the extension of a given token
*/
function tokenExtension(uint256 tokenId) external view returns (address);
/**
* @dev Set default royalties
*/
function setRoyalties(address payable[] calldata receivers, uint256[] calldata basisPoints) external;
/**
* @dev Set royalties of a token
*/
function setRoyalties(uint256 tokenId, address payable[] calldata receivers, uint256[] calldata basisPoints) external;
/**
* @dev Set royalties of an extension
*/
function setRoyaltiesExtension(address extension, address payable[] calldata receivers, uint256[] calldata basisPoints) external;
/**
* @dev Get royalites of a token. Returns list of receivers and basisPoints
*/
function getRoyalties(uint256 tokenId) external view returns (address payable[] memory, uint256[] memory);
// Royalty support for various other standards
function getFeeRecipients(uint256 tokenId) external view returns (address payable[] memory);
function getFeeBps(uint256 tokenId) external view returns (uint[] memory);
function getFees(uint256 tokenId) external view returns (address payable[] memory, uint256[] memory);
function royaltyInfo(uint256 tokenId, uint256 value) external view returns (address, uint256);
/**
* @dev Set the default approve transfer contract location.
*/
function setApproveTransfer(address extension) external;
/**
* @dev Get the default approve transfer contract location.
*/
function getApproveTransfer() external view returns (address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}{
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"address","name":"ProzacYouthEngine_1_addr","type":"address"},{"internalType":"address","name":"ProzacYouthEngine_2_addr","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"AdminApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"AdminRevoked","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"},{"inputs":[],"name":"_creator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_previewImageDataUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"chunkData","type":"string"}],"name":"addPreviewImageDataChunk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"anim","type":"string"}],"name":"animToURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"approveAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_bytes32","type":"bytes32"}],"name":"bytes32ToHex","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes1","name":"_byte","type":"bytes1"}],"name":"char","outputs":[{"internalType":"bytes1","name":"","type":"bytes1"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"deletePreviewImageDataChunk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"formatTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAdmins","outputs":[{"internalType":"address[]","name":"admins","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"grantAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"revokeAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"revokeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"des","type":"string"}],"name":"setDescription","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"setName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setProzacYouthEngine_1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setProzacYouthEngine_2","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":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_i","type":"uint256"}],"name":"uint2str","outputs":[{"internalType":"string","name":"_uintAsString","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405260016005555f60065560405180602001604052805f815250600c908161002a9190610586565b5060405180602001604052805f815250600d90816100489190610586565b50348015610054575f80fd5b50604051613e43380380613e43833981810160405281019061007691906107cf565b855f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036100e7575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016100de919061089f565b60405180910390fd5b6100f68161028b60201b60201c565b5083600d90816101069190610586565b5082600c90816101169190610586565b508460075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508560085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060045f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600a5f73f1da6e2d387e9da611dac8a7fc587eaa4b01001373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055505050505050506108b8565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806103c757607f821691505b6020821081036103da576103d9610383565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261043c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610401565b6104468683610401565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61048a6104856104808461045e565b610467565b61045e565b9050919050565b5f819050919050565b6104a383610470565b6104b76104af82610491565b84845461040d565b825550505050565b5f90565b6104cb6104bf565b6104d681848461049a565b505050565b5b818110156104f9576104ee5f826104c3565b6001810190506104dc565b5050565b601f82111561053e5761050f816103e0565b610518846103f2565b81016020851015610527578190505b61053b610533856103f2565b8301826104db565b50505b505050565b5f82821c905092915050565b5f61055e5f1984600802610543565b1980831691505092915050565b5f610576838361054f565b9150826002028217905092915050565b61058f8261034c565b67ffffffffffffffff8111156105a8576105a7610356565b5b6105b282546103b0565b6105bd8282856104fd565b5f60209050601f8311600181146105ee575f84156105dc578287015190505b6105e6858261056b565b86555061064d565b601f1984166105fc866103e0565b5f5b82811015610623578489015182556001820191506020850194506020810190506105fe565b86831015610640578489015161063c601f89168261054f565b8355505b6001600288020188555050505b505050505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61068f82610666565b9050919050565b61069f81610685565b81146106a9575f80fd5b50565b5f815190506106ba81610696565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b6106e1826106c8565b810181811067ffffffffffffffff82111715610700576106ff610356565b5b80604052505050565b5f610712610655565b905061071e82826106d8565b919050565b5f67ffffffffffffffff82111561073d5761073c610356565b5b610746826106c8565b9050602081019050919050565b8281835e5f83830152505050565b5f61077361076e84610723565b610709565b90508281526020810184848401111561078f5761078e6106c4565b5b61079a848285610753565b509392505050565b5f82601f8301126107b6576107b56106c0565b5b81516107c6848260208601610761565b91505092915050565b5f805f805f8060c087890312156107e9576107e861065e565b5b5f6107f689828a016106ac565b965050602061080789828a016106ac565b955050604087015167ffffffffffffffff81111561082857610827610662565b5b61083489828a016107a2565b945050606087015167ffffffffffffffff81111561085557610854610662565b5b61086189828a016107a2565b935050608061087289828a016106ac565b92505060a061088389828a016106ac565b9150509295509295509295565b61089981610685565b82525050565b5f6020820190506108b25f830184610890565b92915050565b61357e806108c55f395ff3fe6080604052600436106101d7575f3560e01c80636a62784211610101578063b2bdfa7b11610094578063d5abeb0111610063578063d5abeb0114610647578063e9dc637514610671578063f2fde38b146106ad578063f76f950e146106d5576101d7565b8063b2bdfa7b1461058f578063bc8bde64146105b9578063c038fe04146105e3578063c47f00271461061f576101d7565b8063853828b6116100d0578063853828b6146104ff57806385e68531146105155780638da5cb5b1461053d57806390c3f38f14610567576101d7565b80636a6278421461047d5780636d73e66914610499578063715018a6146104c1578063725f0aaf146104d7576101d7565b806331ae450b116101795780633eaaf86b116101485780633eaaf86b146103d95780635413b00b146104035780635fef650c1461042b57806369f9ad2f14610441576101d7565b806331ae450b1461031f578063358f63ac1461034957806337d5ad2b146103735780633df18e0a1461039d576101d7565b806318160ddd116101b557806318160ddd1461026757806322f4596f1461029157806324d7806c146102bb5780632d345670146102f7576101d7565b806301ffc9a7146101db5780630ae5e73914610217578063163638981461023f575b5f80fd5b3480156101e6575f80fd5b5061020160048036038101906101fc9190612378565b610711565b60405161020e91906123bd565b60405180910390f35b348015610222575f80fd5b5061023d60048036038101906102389190612430565b61085a565b005b34801561024a575f80fd5b5061026560048036038101906102609190612430565b6108ba565b005b348015610272575f80fd5b5061027b6109dd565b6040516102889190612473565b60405180910390f35b34801561029c575f80fd5b506102a56109e6565b6040516102b29190612473565b60405180910390f35b3480156102c6575f80fd5b506102e160048036038101906102dc9190612430565b6109ec565b6040516102ee91906123bd565b60405180910390f35b348015610302575f80fd5b5061031d60048036038101906103189190612430565b610a45565b005b34801561032a575f80fd5b50610333610ad9565b6040516103409190612543565b60405180910390f35b348015610354575f80fd5b5061035d610bb4565b60405161036a91906125d3565b60405180910390f35b34801561037e575f80fd5b50610387610c40565b60405161039491906125d3565b60405180910390f35b3480156103a8575f80fd5b506103c360048036038101906103be9190612626565b610e7c565b6040516103d091906125d3565b60405180910390f35b3480156103e4575f80fd5b506103ed611018565b6040516103fa9190612473565b60405180910390f35b34801561040e575f80fd5b506104296004803603810190610424919061277d565b61101e565b005b348015610436575f80fd5b5061043f611133565b005b34801561044c575f80fd5b5061046760048036038101906104629190612819565b611233565b6040516104749190612853565b60405180910390f35b61049760048036038101906104929190612430565b611297565b005b3480156104a4575f80fd5b506104bf60048036038101906104ba9190612430565b611471565b005b3480156104cc575f80fd5b506104d5611504565b005b3480156104e2575f80fd5b506104fd60048036038101906104f89190612430565b611517565b005b34801561050a575f80fd5b5061051361163a565b005b348015610520575f80fd5b5061053b60048036038101906105369190612430565b611758565b005b348015610548575f80fd5b506105516117b7565b60405161055e919061287b565b60405180910390f35b348015610572575f80fd5b5061058d6004803603810190610588919061277d565b6117de565b005b34801561059a575f80fd5b506105a36118d1565b6040516105b0919061287b565b60405180910390f35b3480156105c4575f80fd5b506105cd6118f6565b6040516105da919061287b565b60405180910390f35b3480156105ee575f80fd5b506106096004803603810190610604919061277d565b61191b565b60405161061691906125d3565b60405180910390f35b34801561062a575f80fd5b506106456004803603810190610640919061277d565b61194c565b005b348015610652575f80fd5b5061065b611a3f565b6040516106689190612473565b60405180910390f35b34801561067c575f80fd5b50610697600480360381019061069291906128be565b611a47565b6040516106a491906125d3565b60405180910390f35b3480156106b8575f80fd5b506106d360048036038101906106ce9190612430565b611a59565b005b3480156106e0575f80fd5b506106fb60048036038101906106f691906128fc565b611add565b60405161070891906125d3565b60405180910390f35b5f7fe9dc6375000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806107db57507fa7df9e9e000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061084357507f54c1bcd9000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610853575061085282611c5b565b5b9050919050565b610862611cbb565b6001600a5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061095b5750600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b61099a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099190612971565b60405180910390fd5b8060045f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f600654905090565b60055481565b5f8173ffffffffffffffffffffffffffffffffffffffff16610a0c6117b7565b73ffffffffffffffffffffffffffffffffffffffff161480610a3e5750610a3d826001611d4290919063ffffffff16565b5b9050919050565b610a4d611cbb565b610a61816001611d4290919063ffffffff16565b15610ad6573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f7c0c3c84c67c85fcac635147348bfe374c24a1a93d0366d1cfe9d8853cbf89d560405160405180910390a3610ad4816001611d6f90919063ffffffff16565b505b50565b6060610ae56001611d9c565b67ffffffffffffffff811115610afe57610afd612659565b5b604051908082528060200260200182016040528015610b2c5781602001602082028036833780820191505090505b5090505f5b610b3b6001611d9c565b811015610bb057610b56816001611daf90919063ffffffff16565b828281518110610b6957610b6861298f565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508080600101915050610b31565b5090565b600b8054610bc1906129e9565b80601f0160208091040260200160405190810160405280929190818152602001828054610bed906129e9565b8015610c385780601f10610c0f57610100808354040283529160200191610c38565b820191905f5260205f20905b815481529060010190602001808311610c1b57829003601f168201915b505050505081565b60605f610e1f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318a6ef6c6040518163ffffffff1660e01b81526004015f60405180830381865afa158015610caf573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610cd79190612a87565b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663620b73036040518163ffffffff1660e01b81526004015f60405180830381865afa158015610d40573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610d689190612a87565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637899ff8f6040518163ffffffff1660e01b81526004015f60405180830381865afa158015610dd1573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610df99190612a87565b604051602001610e0b93929190612b08565b60405160208183030381529060405261191b565b90505f610e53600d600c600b85604051602001610e3f9493929190612d3c565b604051602081830303815290604052611dc6565b905080604051602001610e669190612dfa565b6040516020818303038152906040529250505090565b60605f604067ffffffffffffffff811115610e9a57610e99612659565b5b6040519080825280601f01601f191660200182016040528015610ecc5781602001600182028036833780820191505090505b5090505f5b602081101561100e575f81601f610ee89190612e48565b6008610ef49190612e7b565b6002610f009190612feb565b855f1c610f0d9190613062565b60f81b90505f6004827effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c90505f600f60f81b83169050610f4f82611233565b85600286610f5d9190612e7b565b81518110610f6e57610f6d61298f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350610fa581611233565b856001600287610fb59190612e7b565b610fbf9190613092565b81518110610fd057610fcf61298f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505050508080600101915050610ed1565b5080915050919050565b60065481565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806110bf5750600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b6110fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110f590612971565b60405180910390fd5b600b816040516020016111129291906130c5565b604051602081830303815290604052600b908161112f9190613273565b5050565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806111d45750600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b611213576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120a90612971565b60405180910390fd5b60405180602001604052805f815250600b90816112309190613273565b50565b5f600a60f81b827effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916101561127c5760308260f81c611272919061334e565b60f81b9050611292565b60578260f81c61128c919061334e565b60f81b90505b919050565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806113385750600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b611377576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136e90612971565b60405180910390fd5b6001600654106113bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113b3906133cc565b60405180910390fd5b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632928ca58826040518263ffffffff1660e01b8152600401611416919061287b565b6020604051808303815f875af1158015611432573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061145691906133fe565b5060065f81548092919061146990613429565b919050555050565b611479611cbb565b61148d816001611d4290919063ffffffff16565b611501573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f7e1a1a08d52e4ba0e21554733d66165fd5151f99460116223d9e3a608eec5cb160405160405180910390a36114ff816001611df390919063ffffffff16565b505b50565b61150c611cbb565b6115155f611e20565b565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806115b85750600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b6115f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ee90612971565b60405180910390fd5b8060035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806116db5750600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b61171a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171190612971565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc4790811502906040515f60405180830381858888f19350505050611756575f80fd5b565b611760611cbb565b5f600a5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061187f5750600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b6118be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b590612971565b60405180910390fd5b80600c90816118cd9190613273565b5050565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606061192682611dc6565b60405160200161193691906134ba565b6040516020818303038152906040529050919050565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806119ed5750600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b611a2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2390612971565b60405180910390fd5b80600d9081611a3b9190613273565b5050565b5f6001905090565b6060611a51610c40565b905092915050565b611a61611cbb565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ad1575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401611ac8919061287b565b60405180910390fd5b611ada81611e20565b50565b60605f8203611b23576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050611c56565b5f8290505f5b5f8214611b52578080611b3b90613429565b915050600a82611b4b9190613062565b9150611b29565b5f8167ffffffffffffffff811115611b6d57611b6c612659565b5b6040519080825280601f01601f191660200182016040528015611b9f5781602001600182028036833780820191505090505b5090505f8290505b5f8614611c4e57600181611bbb9190612e48565b90505f600a8088611bcc9190613062565b611bd69190612e7b565b87611be19190612e48565b6030611bed919061334e565b90505f8160f81b905080848481518110611c0a57611c0961298f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600a88611c459190613062565b97505050611ba7565b819450505050505b919050565b5f637005caad60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611cb45750611cb382611ee1565b5b9050919050565b611cc3611f5a565b73ffffffffffffffffffffffffffffffffffffffff16611ce16117b7565b73ffffffffffffffffffffffffffffffffffffffff1614611d4057611d04611f5a565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401611d37919061287b565b60405180910390fd5b565b5f611d67835f018373ffffffffffffffffffffffffffffffffffffffff165f1b611f61565b905092915050565b5f611d94835f018373ffffffffffffffffffffffffffffffffffffffff165f1b611f81565b905092915050565b5f611da8825f0161207d565b9050919050565b5f611dbc835f018361208c565b5f1c905092915050565b6060611dec826040518060600160405280604081526020016135096040913960016120b3565b9050919050565b5f611e18835f018373ffffffffffffffffffffffffffffffffffffffff165f1b612242565b905092915050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f7f553e757e000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611f535750611f52826122a9565b5b9050919050565b5f33905090565b5f80836001015f8481526020019081526020015f20541415905092915050565b5f80836001015f8481526020019081526020015f205490505f8114612072575f600182611fae9190612e48565b90505f6001865f0180549050611fc49190612e48565b905080821461202a575f865f018281548110611fe357611fe261298f565b5b905f5260205f200154905080875f0184815481106120045761200361298f565b5b905f5260205f20018190555083876001015f8381526020019081526020015f2081905550505b855f0180548061203d5761203c6134db565b5b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050612077565b5f9150505b92915050565b5f815f01805490509050919050565b5f825f0182815481106120a2576120a161298f565b5b905f5260205f200154905092915050565b60605f8451036120d35760405180602001604052805f815250905061223b565b5f826121045760036002865160046120eb9190612e7b565b6120f59190613092565b6120ff9190613062565b61212b565b6003600286516121149190613092565b61211e9190613062565b600461212a9190612e7b565b5b90505f8167ffffffffffffffff81111561214857612147612659565b5b6040519080825280601f01601f19166020018201604052801561217a5781602001600182028036833780820191505090505b509050600185016020820187885189016020810180515f82525b828410156121ef576003840193508351603f8160121c168701518653600186019550603f81600c1c168701518653600186019550603f8160061c168701518653600186019550603f8116870151865360018601955050612194565b808252891561222f5760038c51066001811461221257600281146122255761222d565b603d6001870353603d600287035361222d565b603d60018703535b505b50505050505080925050505b9392505050565b5f61224d8383611f61565b61229f57825f0182908060018154018082558091505060019003905f5260205f20015f9091909190915055825f0180549050836001015f8481526020019081526020015f2081905550600190506122a3565b5f90505b92915050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61235781612323565b8114612361575f80fd5b50565b5f813590506123728161234e565b92915050565b5f6020828403121561238d5761238c61231b565b5b5f61239a84828501612364565b91505092915050565b5f8115159050919050565b6123b7816123a3565b82525050565b5f6020820190506123d05f8301846123ae565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6123ff826123d6565b9050919050565b61240f816123f5565b8114612419575f80fd5b50565b5f8135905061242a81612406565b92915050565b5f602082840312156124455761244461231b565b5b5f6124528482850161241c565b91505092915050565b5f819050919050565b61246d8161245b565b82525050565b5f6020820190506124865f830184612464565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6124be816123f5565b82525050565b5f6124cf83836124b5565b60208301905092915050565b5f602082019050919050565b5f6124f18261248c565b6124fb8185612496565b9350612506836124a6565b805f5b8381101561253657815161251d88826124c4565b9750612528836124db565b925050600181019050612509565b5085935050505092915050565b5f6020820190508181035f83015261255b81846124e7565b905092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6125a582612563565b6125af818561256d565b93506125bf81856020860161257d565b6125c88161258b565b840191505092915050565b5f6020820190508181035f8301526125eb818461259b565b905092915050565b5f819050919050565b612605816125f3565b811461260f575f80fd5b50565b5f81359050612620816125fc565b92915050565b5f6020828403121561263b5761263a61231b565b5b5f61264884828501612612565b91505092915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61268f8261258b565b810181811067ffffffffffffffff821117156126ae576126ad612659565b5b80604052505050565b5f6126c0612312565b90506126cc8282612686565b919050565b5f67ffffffffffffffff8211156126eb576126ea612659565b5b6126f48261258b565b9050602081019050919050565b828183375f83830152505050565b5f61272161271c846126d1565b6126b7565b90508281526020810184848401111561273d5761273c612655565b5b612748848285612701565b509392505050565b5f82601f83011261276457612763612651565b5b813561277484826020860161270f565b91505092915050565b5f602082840312156127925761279161231b565b5b5f82013567ffffffffffffffff8111156127af576127ae61231f565b5b6127bb84828501612750565b91505092915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6127f8816127c4565b8114612802575f80fd5b50565b5f81359050612813816127ef565b92915050565b5f6020828403121561282e5761282d61231b565b5b5f61283b84828501612805565b91505092915050565b61284d816127c4565b82525050565b5f6020820190506128665f830184612844565b92915050565b612875816123f5565b82525050565b5f60208201905061288e5f83018461286c565b92915050565b61289d8161245b565b81146128a7575f80fd5b50565b5f813590506128b881612894565b92915050565b5f80604083850312156128d4576128d361231b565b5b5f6128e18582860161241c565b92505060206128f2858286016128aa565b9150509250929050565b5f602082840312156129115761291061231b565b5b5f61291e848285016128aa565b91505092915050565b7f556e617574686f72697a656400000000000000000000000000000000000000005f82015250565b5f61295b600c8361256d565b915061296682612927565b602082019050919050565b5f6020820190508181035f8301526129888161294f565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680612a0057607f821691505b602082108103612a1357612a126129bc565b5b50919050565b5f612a2b612a26846126d1565b6126b7565b905082815260208101848484011115612a4757612a46612655565b5b612a5284828561257d565b509392505050565b5f82601f830112612a6e57612a6d612651565b5b8151612a7e848260208601612a19565b91505092915050565b5f60208284031215612a9c57612a9b61231b565b5b5f82015167ffffffffffffffff811115612ab957612ab861231f565b5b612ac584828501612a5a565b91505092915050565b5f81905092915050565b5f612ae282612563565b612aec8185612ace565b9350612afc81856020860161257d565b80840191505092915050565b5f612b138286612ad8565b9150612b1f8285612ad8565b9150612b2b8284612ad8565b9150819050949350505050565b7f7b226e616d65223a2022000000000000000000000000000000000000000000005f82015250565b5f612b6c600a83612ace565b9150612b7782612b38565b600a82019050919050565b5f819050815f5260205f209050919050565b5f8154612ba0816129e9565b612baa8186612ace565b9450600182165f8114612bc45760018114612bd957612c0b565b60ff1983168652811515820286019350612c0b565b612be285612b82565b5f5b83811015612c0357815481890152600182019150602081019050612be4565b838801955050505b50505092915050565b7f222c20226465736372697074696f6e223a2022000000000000000000000000005f82015250565b5f612c48601383612ace565b9150612c5382612c14565b601382019050919050565b7f222c2022696d616765223a2022000000000000000000000000000000000000005f82015250565b5f612c92600d83612ace565b9150612c9d82612c5e565b600d82019050919050565b7f222c2022616e696d6174696f6e5f75726c223a202200000000000000000000005f82015250565b5f612cdc601583612ace565b9150612ce782612ca8565b601582019050919050565b7f227d0000000000000000000000000000000000000000000000000000000000005f82015250565b5f612d26600283612ace565b9150612d3182612cf2565b600282019050919050565b5f612d4682612b60565b9150612d528287612b94565b9150612d5d82612c3c565b9150612d698286612b94565b9150612d7482612c86565b9150612d808285612b94565b9150612d8b82612cd0565b9150612d978284612ad8565b9150612da282612d1a565b915081905095945050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000005f82015250565b5f612de4601d83612ace565b9150612def82612db0565b601d82019050919050565b5f612e0482612dd8565b9150612e108284612ad8565b915081905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612e528261245b565b9150612e5d8361245b565b9250828203905081811115612e7557612e74612e1b565b5b92915050565b5f612e858261245b565b9150612e908361245b565b9250828202612e9e8161245b565b91508282048414831517612eb557612eb4612e1b565b5b5092915050565b5f8160011c9050919050565b5f808291508390505b6001851115612f1157808604811115612eed57612eec612e1b565b5b6001851615612efc5780820291505b8081029050612f0a85612ebc565b9450612ed1565b94509492505050565b5f82612f295760019050612fe4565b81612f36575f9050612fe4565b8160018114612f4c5760028114612f5657612f85565b6001915050612fe4565b60ff841115612f6857612f67612e1b565b5b8360020a915084821115612f7f57612f7e612e1b565b5b50612fe4565b5060208310610133831016604e8410600b8410161715612fba5782820a905083811115612fb557612fb4612e1b565b5b612fe4565b612fc78484846001612ec8565b92509050818404811115612fde57612fdd612e1b565b5b81810290505b9392505050565b5f612ff58261245b565b91506130008361245b565b925061302d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484612f1a565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61306c8261245b565b91506130778361245b565b92508261308757613086613035565b5b828204905092915050565b5f61309c8261245b565b91506130a78361245b565b92508282019050808211156130bf576130be612e1b565b5b92915050565b5f6130d08285612b94565b91506130dc8284612ad8565b91508190509392505050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026131327fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826130f7565b61313c86836130f7565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61317761317261316d8461245b565b613154565b61245b565b9050919050565b5f819050919050565b6131908361315d565b6131a461319c8261317e565b848454613103565b825550505050565b5f90565b6131b86131ac565b6131c3818484613187565b505050565b5b818110156131e6576131db5f826131b0565b6001810190506131c9565b5050565b601f82111561322b576131fc81612b82565b613205846130e8565b81016020851015613214578190505b613228613220856130e8565b8301826131c8565b50505b505050565b5f82821c905092915050565b5f61324b5f1984600802613230565b1980831691505092915050565b5f613263838361323c565b9150826002028217905092915050565b61327c82612563565b67ffffffffffffffff81111561329557613294612659565b5b61329f82546129e9565b6132aa8282856131ea565b5f60209050601f8311600181146132db575f84156132c9578287015190505b6132d38582613258565b86555061333a565b601f1984166132e986612b82565b5f5b82811015613310578489015182556001820191506020850194506020810190506132eb565b8683101561332d5784890151613329601f89168261323c565b8355505b6001600288020188555050505b505050505050565b5f60ff82169050919050565b5f61335882613342565b915061336383613342565b9250828201905060ff81111561337c5761337b612e1b565b5b92915050565b7f4e6f206d6f726520746f6b656e73206c656674000000000000000000000000005f82015250565b5f6133b660138361256d565b91506133c182613382565b602082019050919050565b5f6020820190508181035f8301526133e3816133aa565b9050919050565b5f815190506133f881612894565b92915050565b5f602082840312156134135761341261231b565b5b5f613420848285016133ea565b91505092915050565b5f6134338261245b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361346557613464612e1b565b5b600182019050919050565b7f646174613a746578742f68746d6c3b6261736536342c000000000000000000005f82015250565b5f6134a4601683612ace565b91506134af82613470565b601682019050919050565b5f6134c482613498565b91506134d08284612ad8565b915081905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220d3a86f3dfff527001531bfea4b13a960fa57ba290c768ea7ccb4b613a2f519f964736f6c634300081a0033000000000000000000000000002a3be63b3b312da5d58eb02d2b48869b46ec820000000000000000000000007e5029837a43c547cdcea2107a1e07e30d68c6d600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000bf13afb925b6f9033a2b1988a5a9504b3cb83275000000000000000000000000f272ff92c518e793450002a65ef2bbed50e95743000000000000000000000000000000000000000000000000000000000000000c50726f7a616320596f75746800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011464f522054484520465241435455524544000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106101d7575f3560e01c80636a62784211610101578063b2bdfa7b11610094578063d5abeb0111610063578063d5abeb0114610647578063e9dc637514610671578063f2fde38b146106ad578063f76f950e146106d5576101d7565b8063b2bdfa7b1461058f578063bc8bde64146105b9578063c038fe04146105e3578063c47f00271461061f576101d7565b8063853828b6116100d0578063853828b6146104ff57806385e68531146105155780638da5cb5b1461053d57806390c3f38f14610567576101d7565b80636a6278421461047d5780636d73e66914610499578063715018a6146104c1578063725f0aaf146104d7576101d7565b806331ae450b116101795780633eaaf86b116101485780633eaaf86b146103d95780635413b00b146104035780635fef650c1461042b57806369f9ad2f14610441576101d7565b806331ae450b1461031f578063358f63ac1461034957806337d5ad2b146103735780633df18e0a1461039d576101d7565b806318160ddd116101b557806318160ddd1461026757806322f4596f1461029157806324d7806c146102bb5780632d345670146102f7576101d7565b806301ffc9a7146101db5780630ae5e73914610217578063163638981461023f575b5f80fd5b3480156101e6575f80fd5b5061020160048036038101906101fc9190612378565b610711565b60405161020e91906123bd565b60405180910390f35b348015610222575f80fd5b5061023d60048036038101906102389190612430565b61085a565b005b34801561024a575f80fd5b5061026560048036038101906102609190612430565b6108ba565b005b348015610272575f80fd5b5061027b6109dd565b6040516102889190612473565b60405180910390f35b34801561029c575f80fd5b506102a56109e6565b6040516102b29190612473565b60405180910390f35b3480156102c6575f80fd5b506102e160048036038101906102dc9190612430565b6109ec565b6040516102ee91906123bd565b60405180910390f35b348015610302575f80fd5b5061031d60048036038101906103189190612430565b610a45565b005b34801561032a575f80fd5b50610333610ad9565b6040516103409190612543565b60405180910390f35b348015610354575f80fd5b5061035d610bb4565b60405161036a91906125d3565b60405180910390f35b34801561037e575f80fd5b50610387610c40565b60405161039491906125d3565b60405180910390f35b3480156103a8575f80fd5b506103c360048036038101906103be9190612626565b610e7c565b6040516103d091906125d3565b60405180910390f35b3480156103e4575f80fd5b506103ed611018565b6040516103fa9190612473565b60405180910390f35b34801561040e575f80fd5b506104296004803603810190610424919061277d565b61101e565b005b348015610436575f80fd5b5061043f611133565b005b34801561044c575f80fd5b5061046760048036038101906104629190612819565b611233565b6040516104749190612853565b60405180910390f35b61049760048036038101906104929190612430565b611297565b005b3480156104a4575f80fd5b506104bf60048036038101906104ba9190612430565b611471565b005b3480156104cc575f80fd5b506104d5611504565b005b3480156104e2575f80fd5b506104fd60048036038101906104f89190612430565b611517565b005b34801561050a575f80fd5b5061051361163a565b005b348015610520575f80fd5b5061053b60048036038101906105369190612430565b611758565b005b348015610548575f80fd5b506105516117b7565b60405161055e919061287b565b60405180910390f35b348015610572575f80fd5b5061058d6004803603810190610588919061277d565b6117de565b005b34801561059a575f80fd5b506105a36118d1565b6040516105b0919061287b565b60405180910390f35b3480156105c4575f80fd5b506105cd6118f6565b6040516105da919061287b565b60405180910390f35b3480156105ee575f80fd5b506106096004803603810190610604919061277d565b61191b565b60405161061691906125d3565b60405180910390f35b34801561062a575f80fd5b506106456004803603810190610640919061277d565b61194c565b005b348015610652575f80fd5b5061065b611a3f565b6040516106689190612473565b60405180910390f35b34801561067c575f80fd5b50610697600480360381019061069291906128be565b611a47565b6040516106a491906125d3565b60405180910390f35b3480156106b8575f80fd5b506106d360048036038101906106ce9190612430565b611a59565b005b3480156106e0575f80fd5b506106fb60048036038101906106f691906128fc565b611add565b60405161070891906125d3565b60405180910390f35b5f7fe9dc6375000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806107db57507fa7df9e9e000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061084357507f54c1bcd9000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610853575061085282611c5b565b5b9050919050565b610862611cbb565b6001600a5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061095b5750600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b61099a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099190612971565b60405180910390fd5b8060045f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f600654905090565b60055481565b5f8173ffffffffffffffffffffffffffffffffffffffff16610a0c6117b7565b73ffffffffffffffffffffffffffffffffffffffff161480610a3e5750610a3d826001611d4290919063ffffffff16565b5b9050919050565b610a4d611cbb565b610a61816001611d4290919063ffffffff16565b15610ad6573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f7c0c3c84c67c85fcac635147348bfe374c24a1a93d0366d1cfe9d8853cbf89d560405160405180910390a3610ad4816001611d6f90919063ffffffff16565b505b50565b6060610ae56001611d9c565b67ffffffffffffffff811115610afe57610afd612659565b5b604051908082528060200260200182016040528015610b2c5781602001602082028036833780820191505090505b5090505f5b610b3b6001611d9c565b811015610bb057610b56816001611daf90919063ffffffff16565b828281518110610b6957610b6861298f565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508080600101915050610b31565b5090565b600b8054610bc1906129e9565b80601f0160208091040260200160405190810160405280929190818152602001828054610bed906129e9565b8015610c385780601f10610c0f57610100808354040283529160200191610c38565b820191905f5260205f20905b815481529060010190602001808311610c1b57829003601f168201915b505050505081565b60605f610e1f60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318a6ef6c6040518163ffffffff1660e01b81526004015f60405180830381865afa158015610caf573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610cd79190612a87565b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663620b73036040518163ffffffff1660e01b81526004015f60405180830381865afa158015610d40573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610d689190612a87565b60035f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637899ff8f6040518163ffffffff1660e01b81526004015f60405180830381865afa158015610dd1573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610df99190612a87565b604051602001610e0b93929190612b08565b60405160208183030381529060405261191b565b90505f610e53600d600c600b85604051602001610e3f9493929190612d3c565b604051602081830303815290604052611dc6565b905080604051602001610e669190612dfa565b6040516020818303038152906040529250505090565b60605f604067ffffffffffffffff811115610e9a57610e99612659565b5b6040519080825280601f01601f191660200182016040528015610ecc5781602001600182028036833780820191505090505b5090505f5b602081101561100e575f81601f610ee89190612e48565b6008610ef49190612e7b565b6002610f009190612feb565b855f1c610f0d9190613062565b60f81b90505f6004827effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c90505f600f60f81b83169050610f4f82611233565b85600286610f5d9190612e7b565b81518110610f6e57610f6d61298f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350610fa581611233565b856001600287610fb59190612e7b565b610fbf9190613092565b81518110610fd057610fcf61298f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505050508080600101915050610ed1565b5080915050919050565b60065481565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806110bf5750600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b6110fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110f590612971565b60405180910390fd5b600b816040516020016111129291906130c5565b604051602081830303815290604052600b908161112f9190613273565b5050565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806111d45750600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b611213576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120a90612971565b60405180910390fd5b60405180602001604052805f815250600b90816112309190613273565b50565b5f600a60f81b827effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916101561127c5760308260f81c611272919061334e565b60f81b9050611292565b60578260f81c61128c919061334e565b60f81b90505b919050565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806113385750600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b611377576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136e90612971565b60405180910390fd5b6001600654106113bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113b3906133cc565b60405180910390fd5b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632928ca58826040518263ffffffff1660e01b8152600401611416919061287b565b6020604051808303815f875af1158015611432573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061145691906133fe565b5060065f81548092919061146990613429565b919050555050565b611479611cbb565b61148d816001611d4290919063ffffffff16565b611501573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f7e1a1a08d52e4ba0e21554733d66165fd5151f99460116223d9e3a608eec5cb160405160405180910390a36114ff816001611df390919063ffffffff16565b505b50565b61150c611cbb565b6115155f611e20565b565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806115b85750600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b6115f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ee90612971565b60405180910390fd5b8060035f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806116db5750600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b61171a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171190612971565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc4790811502906040515f60405180830381858888f19350505050611756575f80fd5b565b611760611cbb565b5f600a5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061187f5750600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b6118be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b590612971565b60405180910390fd5b80600c90816118cd9190613273565b5050565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606061192682611dc6565b60405160200161193691906134ba565b6040516020818303038152906040529050919050565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806119ed5750600a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b611a2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2390612971565b60405180910390fd5b80600d9081611a3b9190613273565b5050565b5f6001905090565b6060611a51610c40565b905092915050565b611a61611cbb565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ad1575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401611ac8919061287b565b60405180910390fd5b611ada81611e20565b50565b60605f8203611b23576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050611c56565b5f8290505f5b5f8214611b52578080611b3b90613429565b915050600a82611b4b9190613062565b9150611b29565b5f8167ffffffffffffffff811115611b6d57611b6c612659565b5b6040519080825280601f01601f191660200182016040528015611b9f5781602001600182028036833780820191505090505b5090505f8290505b5f8614611c4e57600181611bbb9190612e48565b90505f600a8088611bcc9190613062565b611bd69190612e7b565b87611be19190612e48565b6030611bed919061334e565b90505f8160f81b905080848481518110611c0a57611c0961298f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600a88611c459190613062565b97505050611ba7565b819450505050505b919050565b5f637005caad60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611cb45750611cb382611ee1565b5b9050919050565b611cc3611f5a565b73ffffffffffffffffffffffffffffffffffffffff16611ce16117b7565b73ffffffffffffffffffffffffffffffffffffffff1614611d4057611d04611f5a565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401611d37919061287b565b60405180910390fd5b565b5f611d67835f018373ffffffffffffffffffffffffffffffffffffffff165f1b611f61565b905092915050565b5f611d94835f018373ffffffffffffffffffffffffffffffffffffffff165f1b611f81565b905092915050565b5f611da8825f0161207d565b9050919050565b5f611dbc835f018361208c565b5f1c905092915050565b6060611dec826040518060600160405280604081526020016135096040913960016120b3565b9050919050565b5f611e18835f018373ffffffffffffffffffffffffffffffffffffffff165f1b612242565b905092915050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f7f553e757e000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611f535750611f52826122a9565b5b9050919050565b5f33905090565b5f80836001015f8481526020019081526020015f20541415905092915050565b5f80836001015f8481526020019081526020015f205490505f8114612072575f600182611fae9190612e48565b90505f6001865f0180549050611fc49190612e48565b905080821461202a575f865f018281548110611fe357611fe261298f565b5b905f5260205f200154905080875f0184815481106120045761200361298f565b5b905f5260205f20018190555083876001015f8381526020019081526020015f2081905550505b855f0180548061203d5761203c6134db565b5b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050612077565b5f9150505b92915050565b5f815f01805490509050919050565b5f825f0182815481106120a2576120a161298f565b5b905f5260205f200154905092915050565b60605f8451036120d35760405180602001604052805f815250905061223b565b5f826121045760036002865160046120eb9190612e7b565b6120f59190613092565b6120ff9190613062565b61212b565b6003600286516121149190613092565b61211e9190613062565b600461212a9190612e7b565b5b90505f8167ffffffffffffffff81111561214857612147612659565b5b6040519080825280601f01601f19166020018201604052801561217a5781602001600182028036833780820191505090505b509050600185016020820187885189016020810180515f82525b828410156121ef576003840193508351603f8160121c168701518653600186019550603f81600c1c168701518653600186019550603f8160061c168701518653600186019550603f8116870151865360018601955050612194565b808252891561222f5760038c51066001811461221257600281146122255761222d565b603d6001870353603d600287035361222d565b603d60018703535b505b50505050505080925050505b9392505050565b5f61224d8383611f61565b61229f57825f0182908060018154018082558091505060019003905f5260205f20015f9091909190915055825f0180549050836001015f8481526020019081526020015f2081905550600190506122a3565b5f90505b92915050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61235781612323565b8114612361575f80fd5b50565b5f813590506123728161234e565b92915050565b5f6020828403121561238d5761238c61231b565b5b5f61239a84828501612364565b91505092915050565b5f8115159050919050565b6123b7816123a3565b82525050565b5f6020820190506123d05f8301846123ae565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6123ff826123d6565b9050919050565b61240f816123f5565b8114612419575f80fd5b50565b5f8135905061242a81612406565b92915050565b5f602082840312156124455761244461231b565b5b5f6124528482850161241c565b91505092915050565b5f819050919050565b61246d8161245b565b82525050565b5f6020820190506124865f830184612464565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6124be816123f5565b82525050565b5f6124cf83836124b5565b60208301905092915050565b5f602082019050919050565b5f6124f18261248c565b6124fb8185612496565b9350612506836124a6565b805f5b8381101561253657815161251d88826124c4565b9750612528836124db565b925050600181019050612509565b5085935050505092915050565b5f6020820190508181035f83015261255b81846124e7565b905092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6125a582612563565b6125af818561256d565b93506125bf81856020860161257d565b6125c88161258b565b840191505092915050565b5f6020820190508181035f8301526125eb818461259b565b905092915050565b5f819050919050565b612605816125f3565b811461260f575f80fd5b50565b5f81359050612620816125fc565b92915050565b5f6020828403121561263b5761263a61231b565b5b5f61264884828501612612565b91505092915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61268f8261258b565b810181811067ffffffffffffffff821117156126ae576126ad612659565b5b80604052505050565b5f6126c0612312565b90506126cc8282612686565b919050565b5f67ffffffffffffffff8211156126eb576126ea612659565b5b6126f48261258b565b9050602081019050919050565b828183375f83830152505050565b5f61272161271c846126d1565b6126b7565b90508281526020810184848401111561273d5761273c612655565b5b612748848285612701565b509392505050565b5f82601f83011261276457612763612651565b5b813561277484826020860161270f565b91505092915050565b5f602082840312156127925761279161231b565b5b5f82013567ffffffffffffffff8111156127af576127ae61231f565b5b6127bb84828501612750565b91505092915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6127f8816127c4565b8114612802575f80fd5b50565b5f81359050612813816127ef565b92915050565b5f6020828403121561282e5761282d61231b565b5b5f61283b84828501612805565b91505092915050565b61284d816127c4565b82525050565b5f6020820190506128665f830184612844565b92915050565b612875816123f5565b82525050565b5f60208201905061288e5f83018461286c565b92915050565b61289d8161245b565b81146128a7575f80fd5b50565b5f813590506128b881612894565b92915050565b5f80604083850312156128d4576128d361231b565b5b5f6128e18582860161241c565b92505060206128f2858286016128aa565b9150509250929050565b5f602082840312156129115761291061231b565b5b5f61291e848285016128aa565b91505092915050565b7f556e617574686f72697a656400000000000000000000000000000000000000005f82015250565b5f61295b600c8361256d565b915061296682612927565b602082019050919050565b5f6020820190508181035f8301526129888161294f565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680612a0057607f821691505b602082108103612a1357612a126129bc565b5b50919050565b5f612a2b612a26846126d1565b6126b7565b905082815260208101848484011115612a4757612a46612655565b5b612a5284828561257d565b509392505050565b5f82601f830112612a6e57612a6d612651565b5b8151612a7e848260208601612a19565b91505092915050565b5f60208284031215612a9c57612a9b61231b565b5b5f82015167ffffffffffffffff811115612ab957612ab861231f565b5b612ac584828501612a5a565b91505092915050565b5f81905092915050565b5f612ae282612563565b612aec8185612ace565b9350612afc81856020860161257d565b80840191505092915050565b5f612b138286612ad8565b9150612b1f8285612ad8565b9150612b2b8284612ad8565b9150819050949350505050565b7f7b226e616d65223a2022000000000000000000000000000000000000000000005f82015250565b5f612b6c600a83612ace565b9150612b7782612b38565b600a82019050919050565b5f819050815f5260205f209050919050565b5f8154612ba0816129e9565b612baa8186612ace565b9450600182165f8114612bc45760018114612bd957612c0b565b60ff1983168652811515820286019350612c0b565b612be285612b82565b5f5b83811015612c0357815481890152600182019150602081019050612be4565b838801955050505b50505092915050565b7f222c20226465736372697074696f6e223a2022000000000000000000000000005f82015250565b5f612c48601383612ace565b9150612c5382612c14565b601382019050919050565b7f222c2022696d616765223a2022000000000000000000000000000000000000005f82015250565b5f612c92600d83612ace565b9150612c9d82612c5e565b600d82019050919050565b7f222c2022616e696d6174696f6e5f75726c223a202200000000000000000000005f82015250565b5f612cdc601583612ace565b9150612ce782612ca8565b601582019050919050565b7f227d0000000000000000000000000000000000000000000000000000000000005f82015250565b5f612d26600283612ace565b9150612d3182612cf2565b600282019050919050565b5f612d4682612b60565b9150612d528287612b94565b9150612d5d82612c3c565b9150612d698286612b94565b9150612d7482612c86565b9150612d808285612b94565b9150612d8b82612cd0565b9150612d978284612ad8565b9150612da282612d1a565b915081905095945050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000005f82015250565b5f612de4601d83612ace565b9150612def82612db0565b601d82019050919050565b5f612e0482612dd8565b9150612e108284612ad8565b915081905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612e528261245b565b9150612e5d8361245b565b9250828203905081811115612e7557612e74612e1b565b5b92915050565b5f612e858261245b565b9150612e908361245b565b9250828202612e9e8161245b565b91508282048414831517612eb557612eb4612e1b565b5b5092915050565b5f8160011c9050919050565b5f808291508390505b6001851115612f1157808604811115612eed57612eec612e1b565b5b6001851615612efc5780820291505b8081029050612f0a85612ebc565b9450612ed1565b94509492505050565b5f82612f295760019050612fe4565b81612f36575f9050612fe4565b8160018114612f4c5760028114612f5657612f85565b6001915050612fe4565b60ff841115612f6857612f67612e1b565b5b8360020a915084821115612f7f57612f7e612e1b565b5b50612fe4565b5060208310610133831016604e8410600b8410161715612fba5782820a905083811115612fb557612fb4612e1b565b5b612fe4565b612fc78484846001612ec8565b92509050818404811115612fde57612fdd612e1b565b5b81810290505b9392505050565b5f612ff58261245b565b91506130008361245b565b925061302d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484612f1a565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61306c8261245b565b91506130778361245b565b92508261308757613086613035565b5b828204905092915050565b5f61309c8261245b565b91506130a78361245b565b92508282019050808211156130bf576130be612e1b565b5b92915050565b5f6130d08285612b94565b91506130dc8284612ad8565b91508190509392505050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026131327fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826130f7565b61313c86836130f7565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61317761317261316d8461245b565b613154565b61245b565b9050919050565b5f819050919050565b6131908361315d565b6131a461319c8261317e565b848454613103565b825550505050565b5f90565b6131b86131ac565b6131c3818484613187565b505050565b5b818110156131e6576131db5f826131b0565b6001810190506131c9565b5050565b601f82111561322b576131fc81612b82565b613205846130e8565b81016020851015613214578190505b613228613220856130e8565b8301826131c8565b50505b505050565b5f82821c905092915050565b5f61324b5f1984600802613230565b1980831691505092915050565b5f613263838361323c565b9150826002028217905092915050565b61327c82612563565b67ffffffffffffffff81111561329557613294612659565b5b61329f82546129e9565b6132aa8282856131ea565b5f60209050601f8311600181146132db575f84156132c9578287015190505b6132d38582613258565b86555061333a565b601f1984166132e986612b82565b5f5b82811015613310578489015182556001820191506020850194506020810190506132eb565b8683101561332d5784890151613329601f89168261323c565b8355505b6001600288020188555050505b505050505050565b5f60ff82169050919050565b5f61335882613342565b915061336383613342565b9250828201905060ff81111561337c5761337b612e1b565b5b92915050565b7f4e6f206d6f726520746f6b656e73206c656674000000000000000000000000005f82015250565b5f6133b660138361256d565b91506133c182613382565b602082019050919050565b5f6020820190508181035f8301526133e3816133aa565b9050919050565b5f815190506133f881612894565b92915050565b5f602082840312156134135761341261231b565b5b5f613420848285016133ea565b91505092915050565b5f6134338261245b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361346557613464612e1b565b5b600182019050919050565b7f646174613a746578742f68746d6c3b6261736536342c000000000000000000005f82015250565b5f6134a4601683612ace565b91506134af82613470565b601682019050919050565b5f6134c482613498565b91506134d08284612ad8565b915081905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220d3a86f3dfff527001531bfea4b13a960fa57ba290c768ea7ccb4b613a2f519f964736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000002a3be63b3b312da5d58eb02d2b48869b46ec820000000000000000000000007e5029837a43c547cdcea2107a1e07e30d68c6d600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000bf13afb925b6f9033a2b1988a5a9504b3cb83275000000000000000000000000f272ff92c518e793450002a65ef2bbed50e95743000000000000000000000000000000000000000000000000000000000000000c50726f7a616320596f75746800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011464f522054484520465241435455524544000000000000000000000000000000
-----Decoded View---------------
Arg [0] : owner (address): 0x002A3Be63B3B312da5D58Eb02d2B48869B46Ec82
Arg [1] : creator (address): 0x7E5029837A43c547CdCEa2107a1E07e30d68c6D6
Arg [2] : name (string): Prozac Youth
Arg [3] : description (string): FOR THE FRACTURED
Arg [4] : ProzacYouthEngine_1_addr (address): 0xBf13AFb925B6f9033A2b1988a5a9504b3Cb83275
Arg [5] : ProzacYouthEngine_2_addr (address): 0xF272ff92C518E793450002a65eF2Bbed50E95743
-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 000000000000000000000000002a3be63b3b312da5d58eb02d2b48869b46ec82
Arg [1] : 0000000000000000000000007e5029837a43c547cdcea2107a1e07e30d68c6d6
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [4] : 000000000000000000000000bf13afb925b6f9033a2b1988a5a9504b3cb83275
Arg [5] : 000000000000000000000000f272ff92c518e793450002a65ef2bbed50e95743
Arg [6] : 000000000000000000000000000000000000000000000000000000000000000c
Arg [7] : 50726f7a616320596f7574680000000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000011
Arg [9] : 464f522054484520465241435455524544000000000000000000000000000000
Loading...
Loading
Loading...
Loading
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.