ETH Price: $3,331.47 (+0.14%)
 

Overview

ETH Balance

100 wei

Eth Value

Less Than $0.01 (@ $3,331.47/ETH)

Token Holdings

More Info

Private Name Tags

TokenTracker

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Approval For...240691902025-12-22 15:57:2323 days ago1766419043IN
0x5DF18177...F9bAeE8D6
0 ETH0.000001460.06081182
Transfer From227984452025-06-27 21:25:47201 days ago1751059547IN
0x5DF18177...F9bAeE8D6
0 ETH0.000147542.66657487
Safe Transfer Fr...223613112025-04-27 15:32:47262 days ago1745767967IN
0x5DF18177...F9bAeE8D6
0 ETH0.000039330.62167243
Set Approval For...221679102025-03-31 15:52:59289 days ago1743436379IN
0x5DF18177...F9bAeE8D6
0 ETH0.000059822.48260195
Safe Transfer Fr...217323302025-01-29 19:39:11350 days ago1738179551IN
0x5DF18177...F9bAeE8D6
0 ETH0.00018077.26956013
Transfer From217318872025-01-29 18:10:11350 days ago1738174211IN
0x5DF18177...F9bAeE8D6
0 ETH0.150124935.00804146
Safe Transfer Fr...217172162025-01-27 17:00:59352 days ago1737997259IN
0x5DF18177...F9bAeE8D6
0 ETH0.0012669617.11749469
Decrease207084682024-09-08 21:06:47493 days ago1725829607IN
0x5DF18177...F9bAeE8D6
0 ETH0.000036791.38497181
Increase207084672024-09-08 21:06:35493 days ago1725829595IN
0x5DF18177...F9bAeE8D6
0 ETH0.000034491.30077359
Update Transitor...207084652024-09-08 21:06:11493 days ago1725829571IN
0x5DF18177...F9bAeE8D6
0 ETH0.000070081.30463874
Set Approval For...206360052024-08-29 18:23:23503 days ago1724955803IN
0x5DF18177...F9bAeE8D6
0 ETH0.000191414.15298678
Safe Transfer Fr...202145342024-07-01 22:03:47562 days ago1719871427IN
0x5DF18177...F9bAeE8D6
0 ETH0.0002915
Decrease197086402024-04-22 4:45:35633 days ago1713761135IN
0x5DF18177...F9bAeE8D6
100 wei0.000155585.85607332
Transfer From196692822024-04-16 16:38:11638 days ago1713285491IN
0x5DF18177...F9bAeE8D6
0 ETH0.0015154727.38875884
Increase196691172024-04-16 16:04:47638 days ago1713283487IN
0x5DF18177...F9bAeE8D6
0 ETH0.00068725.90703312
Decrease196691122024-04-16 16:03:47638 days ago1713283427IN
0x5DF18177...F9bAeE8D6
0 ETH0.0006383824.02849712
Safe Transfer Fr...196690692024-04-16 15:55:11638 days ago1713282911IN
0x5DF18177...F9bAeE8D6
0 ETH0.0008917816.06566173
Safe Transfer Fr...193180922024-02-27 9:47:59687 days ago1709027279IN
0x5DF18177...F9bAeE8D6
0 ETH0.0021759734.55353433
Withdraw191684792024-02-06 10:01:59708 days ago1707213719IN
0x5DF18177...F9bAeE8D6
0 ETH0.0008750426.21157708
Buy At Fair Pric...191684742024-02-06 10:00:59708 days ago1707213659IN
0x5DF18177...F9bAeE8D6
16 ETH0.0009709726.39164595
Withdraw191684402024-02-06 9:54:11708 days ago1707213251IN
0x5DF18177...F9bAeE8D6
0 ETH0.0007281427.28775496
Transfer From190627452024-01-22 14:04:11723 days ago1705932251IN
0x5DF18177...F9bAeE8D6
0 ETH0.000947317.12785138
Transfer From190627352024-01-22 14:01:59723 days ago1705932119IN
0x5DF18177...F9bAeE8D6
0 ETH0.0009552917.2723146
Increase189427422024-01-05 18:06:59740 days ago1704478019IN
0x5DF18177...F9bAeE8D6
0 ETH0.0005641221.27328722
Set Approval For...184345672023-10-26 13:03:47811 days ago1698325427IN
0x5DF18177...F9bAeE8D6
0 ETH0.0010279622.34313654
View all transactions

Latest 13 internal transactions

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer191684792024-02-06 10:01:59708 days ago1707213719
0x5DF18177...F9bAeE8D6
16 ETH
Transfer175195962023-06-20 8:02:23940 days ago1687248143
0x5DF18177...F9bAeE8D6
0.1 ETH
Transfer174623172023-06-12 6:51:47948 days ago1686552707
0x5DF18177...F9bAeE8D6
0.4 ETH
Transfer174421782023-06-09 10:47:59950 days ago1686307679
0x5DF18177...F9bAeE8D6
1 ETH
Transfer174418842023-06-09 9:47:47950 days ago1686304067
0x5DF18177...F9bAeE8D6
3.211 ETH
Mint174406772023-06-09 5:42:11951 days ago1686289331
0x5DF18177...F9bAeE8D6
0.1 ETH
Mint174406652023-06-09 5:39:47951 days ago1686289187
0x5DF18177...F9bAeE8D6
0.1 ETH
Mint174392452023-06-09 0:53:35951 days ago1686272015
0x5DF18177...F9bAeE8D6
0.1 ETH
Mint174392452023-06-09 0:53:35951 days ago1686272015
0x5DF18177...F9bAeE8D6
0.1 ETH
Mint174392452023-06-09 0:53:35951 days ago1686272015
0x5DF18177...F9bAeE8D6
0.1 ETH
Mint174391132023-06-09 0:26:59951 days ago1686270419
0x5DF18177...F9bAeE8D6
0.1 ETH
Transfer174368012023-06-08 16:37:35951 days ago1686242255
0x5DF18177...F9bAeE8D6
0.7 ETH
Transfer174367272023-06-08 16:22:23951 days ago1686241343
0x5DF18177...F9bAeE8D6
0.3 ETH
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Beef

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
Yes with 2000000 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.15;

////////////////////////////////////////////////////////////////////////
//                                                                    //
//                                                                    //
//                                                                    //
//                                                                    //
//                                                                    //
//                                                                    //
//                                                                    //
//                     need no permission                             //
//                     grazing on the lush grass hills                //
//                     both beef and babe chew                        //
//                                                                    //
//                                                                    //
//                                                                    //
//                                                                    //
//                                                                    //
//                                                       0xfff.eth    //
//                                                                    //
////////////////////////////////////////////////////////////////////////

import "./BeefERC721.sol";

import {ConceptStruct} from "../libraries/ConceptStruct.sol";
import {Render} from "../libraries/Render.sol";
import {Util} from "../libraries/Util.sol";

uint256 constant PERMISSIONLESS = 1;
uint256 constant NO_EXTERNALITIES = 2;
uint256 constant OPENING_HOURS = 3;
uint256 constant DEAD_BEEF = 4;
uint256 constant MUTUAL_A = 5;
uint256 constant MUTUAL_B = 6;
uint256 constant FAIR_PRICE = 7;
uint256 constant BEEF_BABE = 8;
uint256 constant SATED = 9;
uint256 constant DARK = 10;
uint256 constant RETRACTED = 11;
uint256 constant BAD_BEEF = 12;
uint256 constant EOA = 13;
uint256 constant SAMEBLOCK_I = 14;
uint256 constant SAMEBLOCK_II = 15;
uint256 constant SAMEBLOCK_III = 16;
uint256 constant LIMITED_USE = 17;
uint256 constant DEAF_BABE = 18;
uint256 constant DECREASE = 19;
uint256 constant SECRET_POEM = 20;
uint256 constant LOCUS = 21;
uint256 constant PERMANENCE_I = 22;
uint256 constant BEEF_BEEF = 23;
uint256 constant DEPENDENT_A = 24;
uint256 constant DEPENDENT_B = 25;
uint256 constant LIGHT = 26;
uint256 constant INCREASE = 27;
uint256 constant DEAD_BABE = 28;
uint256 constant CONTINUOUS = 29;
uint256 constant SECRET_JOKE = 30;
uint256 constant PERMANENCE_II = 31;
uint256 constant DEAF_BEEF = 32;
uint256 constant MAXIMALISM = 33;
uint256 constant COINBASE = 34;
uint256 constant BABE_BEEF = 35;
uint256 constant BEEF_FACE = 36;
uint256 constant FEED_BEEF = 37;
uint256 constant SECRET_TRUTH = 38;
uint256 constant CHROMATIC = 39;
uint256 constant UNWIELDY = 40;
uint256 constant BAD_BABE = 41;
uint256 constant TRANSITORY_OWNERSHIP = 42;

error NoBeef();
error CurrentlyClosed();
error HalfOfTheTime();
error Codependent();
error MutuallyExclusive();
error NotFairPrice();
error NotLight();
error NotDark();
error NotChromatic();
error NotContract();
error NotCoinbase();
error NotContinuous();

contract Beef is BeefERC721 {

    /*//////////////////////////////////////////////////////////////
                             Constructor
    //////////////////////////////////////////////////////////////*/

    constructor() BeefERC721("BEEF", "BEEF") {
        _mint(block.coinbase, TRANSITORY_OWNERSHIP);
        totalSupply++;
    }

    /*//////////////////////////////////////////////////////////////
                            Tokens / Mint
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply = 0;
    uint256 public editionSize = 42;
    uint256 constant public price = 0.1 ether;

    function mint(uint256 _tokenId) external payable {
        require(_tokenId > 0 && _tokenId <= editionSize); // starts at 1
        uint256 mintPrice = (_tokenId == UNWIELDY ? (1 ether + price) : price);
        require(msg.value == mintPrice);
        _mint(msg.sender, _tokenId);
        totalSupply++;
    }

    function withdraw(address payable _to) public onlyArtist {
        (bool success,) = _to.call{value: address(this).balance}("");
        require(success);
    }

    /*//////////////////////////////////////////////////////////////
                            Concept Data
    //////////////////////////////////////////////////////////////*/

    mapping (uint256 => ConceptStruct.Concept) concepts;
    mapping (uint256 => uint256) tokenIdToConcept;

    function setConceptData(ConceptStruct.Concept[] memory _concepts) public onlyArtist {
        for (uint i = 0; i < _concepts.length; i++) {
            ConceptStruct.Concept memory concept = _concepts[i];
            uint256 conceptId = concept._editionTokenRangeStart;
            concepts[conceptId] = concept;
            for (uint j = concept._editionTokenRangeStart; j < concept._editionTokenRangeStart + concept._editionSize; j++) {
                tokenIdToConcept[j] = conceptId;
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                            Custom State
    //////////////////////////////////////////////////////////////*/

    mapping (uint256 => uint256) sameBlockAt;
    mapping (uint256 => address) sameBlockTo;
    uint256 public fairPrice = 0.1 ether;
    uint96 public increasable = 1;
    uint96 public decreasable = 1111111111111111111111111111;
    uint256 public transfersLeft = 7;

    /*//////////////////////////////////////////////////////////////
                            Custom Methods
    //////////////////////////////////////////////////////////////*/

    function buyAtFairPrice() external payable {
        // Anyone can buy at fair price
        if (_ownerOf[FAIR_PRICE] == address(0)) {
            if (msg.value < fairPrice) revert NotFairPrice();
            _mint(msg.sender, FAIR_PRICE);
        } else if (msg.value > fairPrice) {
            fairPrice = msg.value;
            _transferFromInternal(_ownerOf[FAIR_PRICE], msg.sender, FAIR_PRICE);
        } else {
            revert NotFairPrice();
        }
    }

    function increase() external payable {
        // Anyone can increase
        increasable++;
    }

    function decrease() external payable {
        // Anyone can decrease
        decreasable--;
    }

    function retract() external onlyArtist {
        // The artist can retract this piece at any time
        _transferFromInternalNoHooksAndChecks(_ownerOf[RETRACTED], artist(), RETRACTED);
    }

    function isOpenHours() public view returns (bool) {
        // Opening hours are from  9-5 UTC
        uint256 daytime = block.timestamp % (24 * 3600);
        return (daytime >= 9 * 3600) && (daytime <= 17 * 3600);
    }

    function whereIs(address _address) public pure returns (uint256 x, uint256 y , uint256 z) {
        // This piece will output three spacial coordinates for the current address.
        // It can be used to spacially relate addresses
        uint256 addressNumber = uint256(keccak256(abi.encodePacked(_address)));
        x = addressNumber % 10e4;
        y = (addressNumber >> 8) % 10e4;
        z = (addressNumber >> 16) % 10e3;
    }

    function updateTransitory() external {
        _transferFromInternal(_ownerOf[TRANSITORY_OWNERSHIP], block.coinbase, TRANSITORY_OWNERSHIP);
    }

    /*//////////////////////////////////////////////////////////////
                          Hooks and Overrides
    //////////////////////////////////////////////////////////////*/

    function ownerOf(uint256 id) public view override returns (address) {
        if (id == TRANSITORY_OWNERSHIP) {
            return block.coinbase;
        } else if (
            (id == PERMANENCE_I  && block.number % 2 == 0) ||
            (id == PERMANENCE_II && block.number % 2 == 1)
        ) {
            revert HalfOfTheTime();
        } else if (id == OPENING_HOURS) {
            if(!isOpenHours()) revert CurrentlyClosed();
        }
        return super.ownerOf(id);
    }

    function balanceOf(address owner) public view override returns (uint256) {
        if (owner == block.coinbase) {
            return 1 + _balanceOf[owner];
        }
        return super.balanceOf(owner);
    }

    function transferFrom(
        address from,
        address to,
        uint256 id
    ) public override payable {
        if (id == PERMISSIONLESS) {
            _transferFromInternal(from, to, id);
        } else if (id == TRANSITORY_OWNERSHIP) {
            _transferFromInternal(from, to, id);
        } else {
            super.transferFrom(from, to, id);
        }
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id
    ) public override payable {
        if (id == PERMISSIONLESS) {
            _transferFromInternal(from, to, id);
        } else if (id == TRANSITORY_OWNERSHIP) {
            _transferFromInternal(from, to, id);
        } else {
            super.transferFrom(from, to, id);
        }

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );

    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        bytes calldata data
    ) public override payable {
        if (id == PERMISSIONLESS) {
            _transferFromInternal(from, to, id);
        } else if (id == TRANSITORY_OWNERSHIP) {
            _transferFromInternal(from, to, id);
        } else {
            super.transferFrom(from, to, id);
        }

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal override {}

    function _beforeTokenTransfer(
        address /* from */,
        address to,
        uint256 tokenId
    ) internal override returns (bool) {
        if (tokenId == SATED) {

            // PERMANENCE SATED
            // This piece can only be transfered as the only transaction in a block
            uint256 waste; for (uint256 i = 0; i < 159160; i++) waste++;

        } else if (
            (tokenId == PERMANENCE_I  && block.number % 2 == 0) ||
            (tokenId == PERMANENCE_II && block.number % 2 == 1)
        ) {

            // PERMANENCE I & II
            // This piece exists half of the time
            revert HalfOfTheTime();

        } else if (tokenId == TRANSITORY_OWNERSHIP) {

            // TRANSITORY OWNERSHIP
            // This piece will always belong to the current validator
            require(to == block.coinbase);

        } else if (tokenId == OPENING_HOURS) {

            // OPENING HOURS
            // This piece has opening hours during which it exists and can be transferred
            if (!isOpenHours()) revert CurrentlyClosed();

        } else if (tokenId == DEAD_BEEF || tokenId == BEEF_BEEF || tokenId == FEED_BEEF || tokenId == DEAF_BEEF
                || tokenId == BAD_BEEF  || tokenId == BEEF_FACE || tokenId == BABE_BEEF || tokenId == BEEF_BABE
                || tokenId == BAD_BABE  || tokenId == DEAF_BABE || tokenId == DEAD_BABE
        ) {

            // DEAD BEEF
            // This piece can only be held by an address starting with DEAD and ending with BEEF
            bytes20 addr = bytes20(to);
            if (
                (
                    (tokenId == DEAD_BEEF && (addr & hex"ffff00000000000000000000000000000000ffff" == hex"dead00000000000000000000000000000000beef"))
                    ||
                    (tokenId == BEEF_BEEF && (addr & hex"ffff00000000000000000000000000000000ffff" == hex"beef00000000000000000000000000000000beef"))
                    ||
                    (tokenId == FEED_BEEF && (addr & hex"ffff00000000000000000000000000000000ffff" == hex"feed00000000000000000000000000000000beef"))
                    ||
                    (tokenId == DEAF_BEEF && (addr & hex"ffff00000000000000000000000000000000ffff" == hex"deaf00000000000000000000000000000000beef"))
                    ||
                    (tokenId == BAD_BEEF && (addr & hex"fff000000000000000000000000000000000ffff" == hex"bad000000000000000000000000000000000beef"))
                    ||
                    (tokenId == BEEF_FACE && (addr & hex"ffff00000000000000000000000000000000ffff" == hex"beef00000000000000000000000000000000face"))
                    ||
                    (tokenId == BABE_BEEF && (addr & hex"ffff00000000000000000000000000000000ffff" == hex"babe00000000000000000000000000000000beef"))
                    ||
                    (tokenId == BEEF_BABE && (addr & hex"ffff00000000000000000000000000000000ffff" == hex"beef00000000000000000000000000000000babe"))
                    ||
                    (tokenId == BAD_BABE && (addr & hex"fff000000000000000000000000000000000ffff" == hex"bad000000000000000000000000000000000babe"))
                    ||
                    (tokenId == DEAF_BABE && (addr & hex"ffff00000000000000000000000000000000ffff" == hex"deaf00000000000000000000000000000000babe"))
                    ||
                    (tokenId == DEAD_BABE && (addr & hex"ffff00000000000000000000000000000000ffff" == hex"dead00000000000000000000000000000000babe"))
                ) == false
            ) {
                revert NoBeef();
            }

        } else if (tokenId >= SAMEBLOCK_I && tokenId <= SAMEBLOCK_III) {

            // SAME BLOCK
            // The three pieces from this edition can only be transferred in the same block
            uint256 dependentIdA = tokenId == SAMEBLOCK_I ? SAMEBLOCK_II : SAMEBLOCK_I;
            uint256 dependentIdB = tokenId == SAMEBLOCK_I ? SAMEBLOCK_III : tokenId == SAMEBLOCK_II ? SAMEBLOCK_III : SAMEBLOCK_II;
            if (sameBlockAt[dependentIdA] == block.number && sameBlockAt[dependentIdB] == block.number) {
                _ownerOf[dependentIdA] == address(0)
                    ? _mintNoHooks(sameBlockTo[dependentIdA], dependentIdA)
                    : _transferFromInternalNoHooksAndChecks(_ownerOf[dependentIdA], sameBlockTo[dependentIdA], dependentIdA);
                _ownerOf[dependentIdB] == address(0)
                    ? _mintNoHooks(sameBlockTo[dependentIdB], dependentIdB)
                    : _transferFromInternalNoHooksAndChecks(_ownerOf[dependentIdB], sameBlockTo[dependentIdB], dependentIdB);
                return true;
            } else {
                sameBlockAt[tokenId] = block.number;
                sameBlockTo[tokenId] = to;
                return false;
            }

        } else if (tokenId == DEPENDENT_A || tokenId == DEPENDENT_B) {

            // CO-DEPENDENT
            // The two pieces of this edition are co-dependent. A piece can only be acquired if the sum of the
            // first three and of the last three digits of both the owning addresses are smaller than or equal
            // to 0xFFF = 4095 respectively
            uint256 dependentId = tokenId == DEPENDENT_A ? DEPENDENT_B : DEPENDENT_A;
            if (
                (
                    uint160(_ownerOf[dependentId]) % 4096 + uint160(to) % 4096 < 4096
                    &&
                    uint160(bytes20(_ownerOf[dependentId]) >> 148) % 4096 + uint160(bytes20(to) >> 148) % 4096 < 4096
                ) == false
            ) {
                revert Codependent();
            }

        } else if (tokenId == MUTUAL_A || tokenId == MUTUAL_B) {

            // MUTUALLY EXCLUSIVE
            // The two pieces of this edition are mutually exclusive. Each piece can only be
            // owned if the other owning address has no matching digits
            uint256 dependentId = tokenId == MUTUAL_A ? MUTUAL_B : MUTUAL_A;
            bytes20 bytesDependent = bytes20(_ownerOf[dependentId]);
            bytes20 bytesTo = bytes20(to);
            for (uint i = 0; i < 40; i++) {
                if (uint160(bytesDependent >> i * 4) % 16 == uint160(bytesTo >> i * 4) % 16) {
                    revert MutuallyExclusive();
                }
            }

        } else if (tokenId == LIGHT) {

            // LIGHT
            // This piece can only be held by addresses containing at least 13 instances of F and no instances of 0
            bytes20 bytesTo = bytes20(to);
            uint16 count;
            for (uint i ; i < 40; i++) {
                if (uint160(bytesTo >> i * 4) % 16 == 0) break;
                if (uint160(bytesTo >> i * 4) % 16 == 15) count++;
                if (count > 13) return true;
            }
            revert NotLight();

        } else if (tokenId == DARK) {

            // DARK
            // This piece can only be held by addresses containing at least 13 instances of 0 and no instances of F
            bytes20 bytesTo = bytes20(to);
            uint16 count;
            for (uint i ; i < 40; i++) {
                if (uint160(bytesTo >> i * 4) % 16 == 15) break;
                if (uint160(bytesTo >> i * 4) % 16 == 0) count++;
                if (count > 13) return true;
            }
            revert NotDark();

        } else if (tokenId == CHROMATIC) {

            // CHROMATIC
            // This piece can only be held by addresses containg at least 1 of each hexadecimal digit
            bytes20 bytesTo = bytes20(to);
            uint256 bitmap;
            for (uint256 i; i < 40; i++) {
                bitmap |= (1 << (uint160(bytesTo >> i * 4) % 16));
                if (bitmap == 65535) return true;
            }
            revert NotChromatic();

        } else if (tokenId == NO_EXTERNALITIES) {

            // NO EXTERNALITIES
            // This piece can only be held by a contract
            uint size;
            assembly { size := extcodesize(to) }
            if (size == 0) revert NotContract();

        } else if (tokenId == EOA) {

            // EOA
            // This piece cannot be held by a contract
            uint size;
            assembly { size := extcodesize(to) }
            require(size == 0);
            require(tx.origin == msg.sender);

        } else if (tokenId == LIMITED_USE) {

            // LIMITED USE
            // This piece can only be transfered 7 times after which it will self destruct
            if (transfersLeft > 0) {
                transfersLeft--;
            } else {
                // bye
                _transferFromInternalNoHooksAndChecks(_ownerOf[LIMITED_USE], address(0xdEaD), LIMITED_USE);
                return false; // don't transfer
            }

        } else if (tokenId == UNWIELDY) {

            // UNWIELDY
            // This piece requires burning 1 ETH to be transfered.
            require(msg.value >= 1 ether && msg.value <= 1 ether + price);
            (bool success,) = address(0).call{value: 1 ether}(""); // good bye
            require (success);

        } else if (tokenId == COINBASE) {

            // COINBASE
            // This piece can only transfered to the block.coinbase address.
            // As such it can only be received by validators
            if (to != block.coinbase) revert NotCoinbase();

        } else if (tokenId == CONTINUOUS) {

            // CONTINUOUS
            // This piece can only be transfered to an address that has the
            // first three digits of the previous address as its last three
            bytes20 bytesFrom = bytes20(_ownerOf[CONTINUOUS]);
            bytes20 bytesTo = bytes20(to);
            for (uint i = 0; i < 3; i++) {
                if (uint160(bytesFrom >> (i) * 4) % 16 != uint160(bytesTo >> (40 - (3 - i)) * 4) % 16) {
                    revert NotContinuous();
                }
            }

        }

        return true;
    }

    ///////////////////////////////////////////////////////////////////////////
    // Metadata
    ///////////////////////////////////////////////////////////////////////////

    function renderSVG(uint256 _tokenId) external view returns (string memory) {
        ConceptStruct.Concept memory concept = _getConceptFromTokenId(_tokenId);
        return Render.renderSVG(_tokenId, concept, font);
    }

    function renderSVGBase64(uint256 _tokenId) external view returns (string memory) {
        ConceptStruct.Concept memory concept = _getConceptFromTokenId(_tokenId);
        return Render.renderSVGBase64(_tokenId, concept, font);
    }

    function tokenURI(uint256 _tokenId) public view override returns (string memory) {
        if (
            (_tokenId == PERMANENCE_I  && block.number % 2 == 0) ||
            (_tokenId == PERMANENCE_II && block.number % 2 == 1)
        ) {
            revert HalfOfTheTime();
        } else if (_tokenId == OPENING_HOURS) {
            if(!isOpenHours()) revert CurrentlyClosed();
        }
        require(_ownerOf[_tokenId] != address(0), "NOT_MINTED");
        ConceptStruct.Concept memory concept = _getConceptFromTokenId(_tokenId);
        return Render.tokenURI(_tokenId, concept, font);
    }

    function _getConceptFromTokenId(uint256 _tokenId) private view returns (ConceptStruct.Concept memory) {
        uint256 conceptId = tokenIdToConcept[_tokenId];
        ConceptStruct.Concept memory concept = concepts[conceptId];

        if (_tokenId == FAIR_PRICE) {

            bytes32[] memory statusText = new bytes32[](1);
            statusText[0] = bytes32(abi.encodePacked("Price: ", Util.uint256ToString(uint256(fairPrice / 10e17)), ".", Util.uint256ToString(uint256((fairPrice / 10e16) % 10)), (fairPrice / 10e15) % 10 == 0 ? "" : Util.uint256ToString(uint256((fairPrice / 10e15) % 10)), " ETH"));
            concept._statusText = statusText;

        } else if (_tokenId == LIMITED_USE) {

            bytes32[] memory statusText = new bytes32[](1);
            statusText[0] = bytes32(abi.encodePacked("Transfers Left: ", Util.uint256ToString(uint256(transfersLeft))));
            concept._statusText = statusText;

        } else if (_tokenId == INCREASE) {

            concept._title = bytes32(abi.encodePacked(Util.uint256ToString(uint256(increasable))));

        } else if (_tokenId == DECREASE) {

            concept._title = bytes32(abi.encodePacked(Util.uint256ToString(uint256(decreasable))));

        } else if (_tokenId == OPENING_HOURS) {

            bytes32[] memory statusText = new bytes32[](1);
            statusText[0] = bytes32(abi.encodePacked("Currently ", isOpenHours() ? "Open" : "Closed"));
            concept._statusText = statusText;

        } else if (_tokenId == LOCUS) {

            bytes32[] memory statusText = new bytes32[](3);
            uint256 x; uint256 y; uint256 z;
            (x,y,z) = whereIs(_ownerOf[_tokenId]);
            statusText[0] = bytes32(abi.encodePacked(
                Util.uint256ToString(x), ", ",
                Util.uint256ToString(y), ", ",
                Util.uint256ToString(z)
            ));
            concept._statusText = statusText;

        }

        return concept;
    }

    ///////////////////////////////////////////////////////////////////////////
    // Font
    ///////////////////////////////////////////////////////////////////////////

    string private font = "data:application/font-woff2;charset=utf-8;base64,d09GMgABAAAAABRUABIAAAAALMgAABPwAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP0ZGVE0cGh4bhzwcMAZgAIMyCDQJhGURCAq1KK5OC4EKAAE2AiQDghAEIAWGQAeCUwyCZRuoJwXcGKdh4wAD/+7DEdWhZcv+rxO4MQT7h1rCI0LVSZUog7oNa2Kt3pmxsVZfG8XXcc5iHMBWfJWLYRTw4RNn7VevmEXEXqttFIsosDXqeKqcDq9Kff+TeoQkszxUy2+ve2b39lIATXbBYVO2KFRUYBTZIvlCUngs5Q/Kp2jk9s/jZr4fg0JIoEChnkCQVPUmPZWMOu0pPTU4JlCZlJ7b5r0JlVlPlTknKp3YvNN+ySVt0qZJM9qkY9/g7q98UtafYCwKBxqhUQant/sai/A8AmDAnfEbWYP40ne2VbZ2Xzmmi8zWgM/xKaIyi1rlYjm1WdTgoaaqUYgOzxNJIJEEEkkgkQTi+wQmMvBDPO3X3iLW/iIiJ5aQlul55t2VTiiEskik8X86y/Z/jRWPHNxckBwo6fUHVIaLJk0jz8iSZkYySN4XwYHPPtLesY/IuwEfUJlwU6ZcBw8IurRcpk57dZoiVZeyD1Td6q9+f4nQOqZTBIrXmB3w5vrdwNpI1P1w+g8qPk89SxmB5IADr37Rf3kE4PNLbTHw6Qm6EvDjf9frAALWgINAQpBeEAJIIIAVGV6GXbpy+QDM47u2CsQgAFUQWDTj0UNT8+SdOIQ1XiCHWplQ7QT+v3B6U6NmK2yyxzd/gkI0SkDOmBbuWBSdcTYux824HPfjL3Q57Vga5shp2ZjL8rs8lrcbhtN4Fj4YYgQm8irKuVtWMhLZy8VaSUTJczckL4EYOhhFCStOCDOKKpDAjkBkreCWTNRRgyWGUkSYO85DvhwS1FwnUwmAIhYTUM8aW1AINsaUs1AhMv0ksAkHDsjCtljjKKabYmaxRbE3ZYcqtnntY5lYLZlUGpTQ9qpjIjPZ0MJLDwURrShXNlue43MYwraWrgHZMR3ihO4FcHfEdyYMSwAHMSuw4yjUlTtMD6uQaB9ADOlci4wwLNH1tgBir2bWCtvc7zh3n89XoBSvklDAxDGmI3AjO9YREc/XvqiHQpU9vUXNnOWu2Q5X52AoMgjCA3e/dHMgaVwtc+d8F+rsQCd5FldGD2u3QDjjaYIqj10virrFGfdwxfHgqHI2V3NuuqGfcK3GHKo2gB1Wd7zHtYs9qDikvoPHVsxrdQEyQM3dbJcS8DAdfqSGaJnQBKniLts3pkjLG3uBokO3timWwBFDNhECLDY/nh99zDrAMMLL1OGMbt/834BXccf/oepmFpag+/yHO3Kx8iEY0N4tXDHvVgpNUsISgZRDbC4vWZoiL6lSZ7otvjik4HRcOjfS8s//xR1IlZEveQC4rX+++lNn6nSdqnD9Uodrdy2uhp/DyymXIy9d+24D5GVmjNDGiBxfQvS0muyeqci+q6JqDe4s3t3TRxl+3PprvMksWKw2u5iUnAKDO0/6b57yUjjt3Tx7Dm5CbMAD/xCGCCRDchSBlIhFaqRBBtgl7D/CGjfHgBbFOi/AaZfIBIAAkrrQ3a/o3HAIuC4dVKnWuMkN33f0CjCpLD0EEvqGrzQEJl2D2sLOhsBlLZ3war9avOpCECLXx7Ld0T9z54ylqf/mQWmyBXn4KFo3nPm9+PQQpMRMjoeg5NAUOehX0IFz0gBcKmRyKHzO1y8tl8QEqohSK0JoX8G+b82dI+D5HUwgCjoRnB3yS36OaGe5sdYZXyODXJmnQBbFm/i1SW2l0LMtLl1OIQpZ6aQStXHr3DopLc7LMxGp0lpyNfI18DX2RZlVSe65jnpfd2bGfrk0KtkVo6VvzXu6tYbe/XlQ86IOAozgUrZNxAorZcXmuC/tGjIWyKkHUtDBp83oDvByjvIJX5svqY4BRqTGeIyML1L6gctuq1kn2CjSCsmBf8dnS3cuspeBmrjaXIoH1ckx1KP6xsZI10V8sAAVaxmUKukjKc8TgBuNA+Q6cF/d9zsKKGga23gUoQiuClpAxlKWnlgvEGIGWnewVEBQfSzApZH3arfi8BCM7728Zg2snAGMipGHbZzDdBxGPbwxEtGxEZk7BlcSR6AATqgTYT2OptW0JrNQEAy0hqMZA/2ybx1ukEeIjDwxJiVBFZugNvt90lq5gY6RZ+oTDDbOYIzbWHRfhNLLesaoIuiRyK9U4fEpZQAw1VPgU9BYh6IZ4XQzmzfNGctRyeis6gj/qZyFgfp+8/HJsb5HjGT+pgZeC80fG3t8n2J/5HV0lpP+r2zjcf8ub8neiZC7OZEJoz4FAAsYMGCsgwttgPD+FKqr3dNhu7Z+6w0HN9wEd6QUx3rX+3lrjW5VD1xf2Z5hem6O+QaRjc9aPHv010BAPFNN+rMnp58ZnSq6HMzjt5omkOHeoHA0J3rp5tZq3H+qHzp0EiFcjiRBKe7baY2H+rGFM+zLmLBm92mtsSM1dYW9lzygl2hfH9lcuXa5d71SFYj2bMRWTBVdARhNVtUegX84s+Zkza1jxxUcjxNbrqBsok8Zz3zSALDI7k3RXvzx6S8J/raAVpl8Mtdq5aje3Fqzhu6nRzZVRKFwnRPmCq+XKjw9XqZWKFehitxIj/D0VkSClDmep0/bYD7wI5j4mwPgTS6YZIJnbeuhmEkOzEdNUKxfQtprhmVrK97j3bzk6jIkU7g38JKEBQrKp/Tr0R6lTLkf88UOt14yTmTYaUW09b3R31Km4ShFt72yjoQNHTUJb9QqguD0YGd96FNOPuMYQhFevAOw0UeLlWUWYT2FndKLnqWVeVKX85q9Cr2rFPDggLLh04XFtJdPKeWIbzgvB96C+XKBdbHeSeuSMDO6sjoaak35smHiXbeN3agZeV6GbgKRIK+ws0+hi5Hp4+XUyFH7o/pZlqnPRjkMZci2iqNAyK4r3kdyIBqiJt5+C5qR1+vpDWQp1x7yXK81oTVprj17RDEYFMW9M9yj2mrQ1pRc9TsIevMqNrnsiNs5WcdlNS5duXLpzaGzm6/eL0nznqp9cPPTKFfvA/Yx7iyeA8rCatgwzwPJvMl+lO6yO+NmXLxJelurbYwkbeH4MM+dAdj34tWrllyLW/zo8PNLvl0ULzha9yBBYcdVcbIroVet5riBbbMkPcEx/4l9rdUyeDdanZijcdl7LQ+Xrl651F3Qf7ibcPcfVuA5Ps+HgeXLG13st9G3uGuOM+ZT0XcPcmZHfrcotovi04sYVF3zzl2DxXJXQglUTbr0Wn/+zbVJpiOi+J2uOFRyKy2TGVi+PNDduRWmAzDpfU2dO81hg7zp9/7tJytBznrMcUmaJUmp1QW/QrnmhxKx/hlgqYvcYvkNXf+X+JHtJquMLqunoP8wpPcOL3Bv5zp63lxPfVSSZkjSX4P1g9a19hn2tdZ/yGi11Ng1wcCyZS3dLWnFAJvWz9SxCw8O+MQy5gSK7jT2hg9PpVJjF++F2bxK0bI9C076xbxm0ve1VcfHxVf7E5NMZ2OchUlT8pOcMeeE93Ko+mNWV5I/i+PvI++4zyrj313TaV1MF+Kga3gB+asTPsoFjg/x3IeSNCmpj6vah/xuPqvYC0uU+uKblupA6NbK1UujciW7z0epdpxqO6QdaV9cJgviKc+FzDyse4c3HTfz72wC7YXIEM8/ZVBJ15LKION/NvhLm+f9CzPTL8pnyRpCwrABl/Mq1E5q6VZEWYhFsOe84aRm/jUt30K1cPyv5jrwy7CKDVCB3nz5hfp6whfA7ESXNeyU2mCjd5PTIBMXT61cmeuyK13pnfiCosYH3CnDXyurjxmyiz9QRJ8x70IjBy05SA+V5uJ4/gLPhzj+FkQFfZS7LcMKDUz2P/+oQWCRf3Z3Y591DN2xqVEYJzTyysw6Udwp9jHuG4/HvaedPZ4ebeYax2ObtR9MUozzEN7Zvhe7nRrG6Xy2eNXqJd1Et6ZmNt+ZXX/cuzMHYD97m3qP+GoUHhnWn+uz+q3tnlFHY++P6ItgB/hhxasthkZrON75rmwh4UUOSY7T40Pqp/jnj/ObJGmMJGmub5pZdC2U4dIzFoktx5vZWm0xNzeX5l1pFlbhYU8oH17E8w8hyodwid2HL7cgLAtklGa+5mCrLuARF0axE0uSbcOfKhXvLqRkidb9QoNqzkDVioENwn5rIiXTf6NrFE4IjYlUXTGOW2z77VYS36WgO/Y2CF6hgW7Yq4x67bLa99ksOK6kdFb7UaFR9dom1ewt9ULIbi3N+atJ10ub/7jpL2NI2Lbzxq4b28A1hqcLH+vGavf9q3nHgYf7H+4w/ypgJ/Ob7AZD9NX1Qb+f6SvLCYO9yTB78VuieEAU30rr/9fKxLDlE1bDhhIxzByjGJx4w7af545zWLzg4oCs4PmnHHZGBLX+ncvl2/6rDo6WQ9dT7JekBkm6UW2d9ojYhVIH1NqfwqcT5WSl3+8EPh43y0esLt5/pXvuwcu+hMC/JcEHv1Pj6HMy0MY80pAWzU8SH/47Ai+ExqNWUdZgIRu01Zu/a+xmL1FDKSJRodPXqJ7AQcMjpAVTGSYvVIZW4ED2sBfjSZB6EWzv5i3IOsCTxDbice5QpgD0xs7WaYV6LK3xtTVp1F5MGtL1laYhpSXsmRj1HlkE9okoGluIa5yngPsdBXYO8OoVXnUujlmw3lu13MFmuLRGSWtTkErH4TkA0LiMlgUW6R72iDZ43myCAc28z6WrjDecK4abMD2GKKOBzC9TI1/1DSRJ8gqSEtQX4TWw0Xr3h4V2H7SjMnIDMxJogWAKjgaz+BQyDchq3uJ+JUBVhXl+JlXygtcOmsub0AhoXF7px+GALJ56laGGCcmWPijL90nsCzvP9EQWbFUNdKGdaOuSnNo9nQCzez3bqaskNwGsznblZ6hAcbD54smaVwq1MOpS1Y7U7AUOI2t8NCazwopMDVabKgtIqCMmnyFl6NQ2pdQZcEkHe1lQdxd+pHNdhd0glUmQcv8miLVScCIu+z5xgRP10H2NMjNT3YYbKJ0MXMCEe1ixniWDd5lOIALfbMWelypuQn9ynfOo2F252TcY8xkUfvZZGDaiJ4YDoKAby9RF98BqOVY8HgWi+WWRqzlfZdkaoqwdY/I+UCckq+21YqPWkFfAYdUpKrqKxSmNInQwwDjIM6y5I/BgDDNoUrbhcnuYBE+hbALdDMehTDNj0fIPUEm6Q5oN10sNZ+4KGlOdpYVT31h65RQELkB7zy7hWAHVsjnEonBFAFWThkGdoNZhAcZM5iDYBWRkDAtzVSsUgBZ1DAkF5KCTNFZckkADwVwzDgdSnupt5eQ/6GAe0dYJXZB9B3vpYH3fe2lHgloTFRAYtQ7YWhjksWrHgeqaV7oamfPPOCMiwl1yzN97hXOB6TWNVIDqSCNpJTVFytsts3YvO0MCsyLIp6QOHcsIurbEPU+0eaasZqJkSwcTDNJbkVZMYNEoUfxMHuaFSYqT5wm2nwu9Wo00XybSSjfYOSFq9x/xHUOTXnYbhgawHRLKedMEeESr067bklkG661yGPZcHz83OgdmKFEybrCsL0PC0CXwNXtEk2DWEFnQQAMGe5CUcmC4NWiPadDoLV9qV5gUkisjQbBgUViKPZbungYSCeyBYAYDnpGqGS6JmyY/BBUEu5ynkazYoAQJLEkmB5SRJCXbUwkGtaHSWmBLwB4dVUzcJIBIdWbqeJa1AuZcszRMKO5iulVdxqyYzUoO2eR7+REZmefBzUlqSOBw3J9k01UONzrdVZoXxbs5SeVF1mkjOCAgWBrlrDIg490o16KxMxsclInkzTSTRZkkyUFltmypOSoh4D1SdmuOTbFOODbs9gacFd/7KC1TZb/LCNNedQqWGlZjP3x+j0XH0mMpDdSgN2h45QWysd5764bRHMvfXXz5Oxv9/CG//6O+sQD4V4GDQd2a6sY6YIIB4dFhyX8bYdoHqhQD6nqJLuX9+BJAvgUvGl6ryzE0ztAONLcaHRDDfTqk6TC26YFYfVgOY4IGlVmD7V/q20X8a3UYQNs9Y3Bifi+8+1HdxnzppVaFl8dmNoTQa3EGAwViDCvD2WrZAC7bG5pH6vGmzW3X7QNe9e6I2pT2EzgxNqNiwEAEZIEiuJEBqahTjWdeDrfhSzjUIwB8AA5FJNKeIobxSxFX4HKRYApjkeSOIkFJensxgjF+K9Ky4n7xCJsJxaOuM6d4jMhxzx0X56zzPtMgJt16mW4Gz2uaAsfbhQbVZLwLWxsgmZcWhpNOPBpQv3HhRCgCxIU/xbJlVWr3qsju9cZxT2DVhGCs2OYhfjEa0yDcfogu7AYciboRxeyEpipPTNmT7fSaHGZZzpEJvLWGvcFgtP6e/7f1chvdLiNxx1dQPzLdEpzt0jL0eBdq3QzBm1KbEq26k6w3H/hOhZAYvmBfmSyQPu1N3+PFeLWTS9wfKCEfPBmiPw4LOdD/TyfZNNhoF314J/GW02pUENl4NSFcWQ01YHTSDEtgM0nJ7m2R2vhtiE8LptmWIS/vWRz7S7gEREaDCDIcjcUTyVQ6k83lC5Vqrd5ottqdbq8/GCK6vMl0Nl8sV+vN9vjKDRGIRNSfy4XCL6KRCjF/Nj+lSKSFduhAOqRHUdT4KZ4ZEzLXG2fJ5k6bmJFRkjHSertZzs8geqaepWfrOXqunqfn6wV6Ya7kzsyMRqbif8xmjxs9e8LnRlZfkss1HyfW6zv0/4AWwqCgfHhFG0KLKtv6/uU7Cqorqa6TStNXGR9MozsrIIi4PkE8uXcwgtfrAoRmAJa8hJCf9ojLU2SSd0FJtgJS1DQIkSPBRZSACU+aCjVJmIaSNgXGFroq0aKDgip8od3tqnfDbcP7zvNELq3zGI0j81FbkwFrtRbG7KChU/dVb/3f6PqqdeoeRalXvMqgLhk=";

}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";

/// @notice Adopted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)
abstract contract BeefERC721 is Ownable {

    /*//////////////////////////////////////////////////////////////
                         ERC721 STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    mapping(uint256 => address) public getApproved;

    mapping(address => mapping(address => bool)) public isApprovedForAll;

    mapping(uint256 => address) internal _ownerOf;

    mapping(address => uint256) internal _balanceOf;

    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 indexed id);

    event Approval(address indexed owner, address indexed spender, uint256 indexed id);

    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /*//////////////////////////////////////////////////////////////
                                  VIEW
    //////////////////////////////////////////////////////////////*/

    function tokenURI(uint256 id) public view virtual returns (string memory);


    function ownerOf(uint256 id) public view virtual returns (address) {
        address owner = _ownerOf[id];
        require(owner != address(0), "NOT_MINTED");
        return owner;
    }

    function balanceOf(address owner) public view virtual returns (uint256) {
        require(owner != address(0), "ZERO_ADDRESS");
        return _balanceOf[owner];
    }

    /*//////////////////////////////////////////////////////////////
                                 VANITY
    //////////////////////////////////////////////////////////////*/

    function artist() public view returns (address) {
        return owner();
    }

    modifier onlyArtist {
        require(msg.sender == artist());
        _;
    }

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(string memory _name, string memory _symbol) {
        name = _name;
        symbol = _symbol;
    }

    /*//////////////////////////////////////////////////////////////
                              ERC721 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 id) public virtual {
        address owner = _ownerOf[id];
        require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED");

        getApproved[id] = spender;

        emit Approval(owner, spender, id);
    }

    function setApprovalForAll(address operator, bool approved) public virtual {
        isApprovedForAll[msg.sender][operator] = approved;

        emit ApprovalForAll(msg.sender, operator, approved);
    }

    function transferFrom(
        address from,
        address to,
        uint256 id
    ) public virtual payable {
        require(
            msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],
            "NOT_AUTHORIZED"
        );

        _transferFromInternal(from, to, id);
    }

    function _transferFromInternal(
        address from,
        address to,
        uint256 id
    ) internal virtual {
        require(to != address(0), "INVALID_RECIPIENT");
        require(from == _ownerOf[id], "WRONG_FROM");

        bool doTransfer = _beforeTokenTransfer(from, to, id);
        if (!doTransfer) return;

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        unchecked {
            _balanceOf[from]--;

            _balanceOf[to]++;
        }

        _ownerOf[id] = to;

        delete getApproved[id];

        emit Transfer(from, to, id);

        _afterTokenTransfer(from, to, id);
    }

    function _transferFromInternalNoHooksAndChecks(
        address from,
        address to,
        uint256 id
    ) internal virtual {
        require(to != address(0), "INVALID_RECIPIENT");

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        unchecked {
            _balanceOf[from]--;

            _balanceOf[to]++;
        }

        _ownerOf[id] = to;

        delete getApproved[id];

        emit Transfer(from, to, id);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id
    ) public virtual payable;

    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        bytes calldata data
    ) public virtual payable;

    /*//////////////////////////////////////////////////////////////
                              ERC165 LOGIC
    //////////////////////////////////////////////////////////////*/

    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return
            interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
            interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
            interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 id) internal virtual {
        require(to != address(0), "INVALID_RECIPIENT");
        require(_ownerOf[id] == address(0), "ALREADY_MINTED");

        bool doTransfer =_beforeTokenTransfer(address(0), to, id);
        if (!doTransfer) return;

        // Counter overflow is incredibly unrealistic.
        unchecked {
            _balanceOf[to]++;
        }

        _ownerOf[id] = to;

        emit Transfer(address(0), to, id);

        _afterTokenTransfer(address(0), to, id);
    }

    function _mintNoHooks(address to, uint256 id) internal virtual {
        require(to != address(0), "INVALID_RECIPIENT");
        require(_ownerOf[id] == address(0), "ALREADY_MINTED");

        // Counter overflow is incredibly unrealistic.
        unchecked {
            _balanceOf[to]++;
        }

        _ownerOf[id] = to;

        emit Transfer(address(0), to, id);
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual returns (bool) {}

    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}

    /*//////////////////////////////////////////////////////////////
                        INTERNAL SAFE MINT LOGIC
    //////////////////////////////////////////////////////////////*/

}

/// @notice A generic interface for a contract which properly accepts ERC721 tokens.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)
abstract contract ERC721TokenReceiver {
    function onERC721Received(
        address,
        address,
        uint256,
        bytes calldata
    ) external virtual returns (bytes4) {
        return ERC721TokenReceiver.onERC721Received.selector;
    }
}

// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.0;

import {SVG} from "./SVG.sol";
import {Util} from "./Util.sol";

library Background {
    /*//////////////////////////////////////////////////////////////
                                 RENDER
    //////////////////////////////////////////////////////////////*/

    function render(bool isBeef) internal pure returns (string memory) {
        return
            SVG.element(
                "rect",
                SVG.rectAttributes({
                    _width: "100%",
                    _height: "100%",
                    _fill: isBeef ? "#BA2219" : "#000",
                    _attributes: ""
                })
            );
    }
}

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

/// @title Base64
/// @author Brecht Devos - <[email protected]>
/// @notice Provides a function for encoding some bytes in base64
library Base64 {
    string internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    function encode(string memory _data) internal pure returns (string memory) {
        return encode(bytes(_data));
    }

    function encode(bytes memory _data) internal pure returns (string memory) {
        if (_data.length == 0) return "";

        // load the table into memory
        string memory table = TABLE;

        // multiply by 4/3 rounded up
        uint256 encodedLen = 4 * ((_data.length + 2) / 3);

        // add some extra buffer at the end required for the writing
        string memory result = new string(encodedLen + 32);

        assembly {
            // set the actual output length
            mstore(result, encodedLen)

            // prepare the lookup table
            let tablePtr := add(table, 1)

            // input ptr
            let dataPtr := _data
            let endPtr := add(dataPtr, mload(_data))

            // result ptr, jump over length
            let resultPtr := add(result, 32)

            // run over the input, 3 bytes at a time
            for {

            } lt(dataPtr, endPtr) {

            } {
                dataPtr := add(dataPtr, 3)

                // read 3 bytes
                let input := mload(dataPtr)

                // write 4 characters
                mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(18, input), 0x3F)))))
                resultPtr := add(resultPtr, 1)
                mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(12, input), 0x3F)))))
                resultPtr := add(resultPtr, 1)
                mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(6, input), 0x3F)))))
                resultPtr := add(resultPtr, 1)
                mstore(resultPtr, shl(248, mload(add(tablePtr, and(input, 0x3F)))))
                resultPtr := add(resultPtr, 1)
            }

            // padding with '='
            switch mod(mload(_data), 3)
            case 1 {
                mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
            }
            case 2 {
                mstore(sub(resultPtr, 1), shl(248, 0x3d))
            }
        }

        return result;
    }
}

File 7 of 16 : ConceptStruct.sol
// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.0;

library ConceptStruct {
    struct Concept {
        uint256 _editionTokenRangeStart;
        uint256 _editionSize;
        bytes32 _title;
        bytes32[] _bodyText;
        bytes32[] _smallPrintText;
        bytes32[] _statusText;
    }
}

// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.0;

import {Base64} from "./Base64.sol";
import {Util} from "./Util.sol";

library Metadata {
    string constant JSON_BASE64_HEADER = "data:application/json;base64,";
    string constant SVG_XML_BASE64_HEADER = "data:image/svg+xml;base64,";

    function encodeMetadata(
        uint256 _tokenId,
        string memory _name,
        string memory _description,
        // string memory _attributes,
        // string memory _backgroundColor,
        string memory _svg
    ) internal pure returns (string memory) {
        string memory metadata = string.concat(
            "{",
            Util.keyValue("tokenId", Util.uint256ToString(_tokenId)),
            ",",
            Util.keyValue("name", _name),
            ",",
            Util.keyValue("description", _description),
            // ",",
            // Util.keyValueNoQuotes("attributes", _attributes),
            // ",",
            // Util.keyValue("backgroundColor", _backgroundColor),
            ",",
            Util.keyValue("image", _encodeSVG(_svg)),
            "}"
        );

        return _encodeJSON(metadata);
    }

    /// @notice base64 encode json
    /// @param _json, stringified json
    /// @return string, bytes64 encoded json with prefix
    function _encodeJSON(string memory _json) internal pure returns (string memory) {
        return string.concat(JSON_BASE64_HEADER, Base64.encode(_json));
    }

    /// @notice base64 encode svg
    /// @param _svg, stringified json
    /// @return string, bytes64 encoded svg with prefix
    function _encodeSVG(string memory _svg) internal pure returns (string memory) {
        return string.concat(SVG_XML_BASE64_HEADER, Base64.encode(bytes(_svg)));
    }
}

// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.0;

import {Metadata} from "./Metadata.sol";
import {Util} from "./Util.sol";
import {Traits} from "./Traits.sol";
import {Background} from "./Background.sol";
import {TextBody} from "./TextBody.sol";
import {TextLine} from "./TextLine.sol";
import {TextEdition} from "./TextEdition.sol";
import {TextOf} from "./TextOf.sol";
import {Traits} from "./Traits.sol";
import {SVG} from "./SVG.sol";
import {ConceptStruct} from "./ConceptStruct.sol";

/// @notice Adopted from Bibos (0xf528e3381372c43f5e8a55b3e6c252e32f1a26e4)
library Render {
    string public constant description =
        "The BEEF series.";

    /*//////////////////////////////////////////////////////////////
                                TOKENURI
    //////////////////////////////////////////////////////////////*/

    function tokenURI(uint256 _tokenId, ConceptStruct.Concept memory concept, string memory base64font) internal pure returns (string memory) {
        bytes memory descriptionConcat;
        for (uint i = 0; i < concept._bodyText.length; i++) {
            descriptionConcat = abi.encodePacked(descriptionConcat, Util.bytes32ToBytes(concept._bodyText[i]));
        }
        return
            Metadata.encodeMetadata({
                _tokenId: _tokenId,
                _name: Util.bytes32ToString(concept._title),
                _description: string(abi.encodePacked(descriptionConcat)),
                _svg: _svg(_tokenId, concept, base64font)
            });
    }

    function renderSVG(uint256 _tokenId, ConceptStruct.Concept memory concept, string memory base64font) internal pure returns (string memory) {
        return _svg(_tokenId, concept, base64font);
    }

    function renderSVGBase64(uint256 _tokenId, ConceptStruct.Concept memory concept, string memory base64font) internal pure returns (string memory) {
        return Metadata._encodeSVG(_svg(_tokenId, concept, base64font));
    }

    /*//////////////////////////////////////////////////////////////
                                INTERNAL
    //////////////////////////////////////////////////////////////*/

    function _svg(
        uint256 _tokenId,
        ConceptStruct.Concept memory _concept,
        string memory base64font
    ) internal pure returns (string memory) {
        bool isBeef = _tokenId == 4 || _tokenId == 8 || _tokenId == 12 || _tokenId == 23 || _tokenId == 32 || _tokenId == 35 || _tokenId == 36 || _tokenId == 37;
        return
            SVG.element(
                "svg",
                SVG.svgAttributes(),
                string.concat(
                    '<defs><style>',
                    '@font-face {font-family: "Norw";src: url("',
                        base64font,
                    '");}',
                    'text {text-transform: uppercase;'
                    '}</style></defs>'
                ),
                Background.render(isBeef),
                _renderText(_tokenId, _concept)
            );
    }

    function _renderText(uint256 _tokenId, ConceptStruct.Concept memory _concept) internal pure returns (string memory) {
        // uint256 titleOffset = 155;
        // uint256 bodyOffset = 155 + 60;
        uint256 smallPrintOffset = 215 + _concept._bodyText.length * 30 + (_concept._bodyText.length > 0 ? 50 : 0);
        uint256 statusOffset = smallPrintOffset + _concept._smallPrintText.length * 20 + (_concept._smallPrintText.length > 0 ? 50 : 0);
        return SVG.element(
            "g",
            "",
            TextLine.render(_concept._title, 155, false),
            TextBody.render(_concept._bodyText, 215, false),
            TextBody.render(_concept._statusText, statusOffset, false),
            TextBody.render(_concept._smallPrintText, smallPrintOffset, true),
            TextEdition.render(bytes32(abi.encodePacked(Util.uint256ToString(_tokenId)))),
            TextOf.render(_editionTextConcat(_tokenId, _concept))
        );
    }

    function _editionTextConcat(uint256 _tokenId, ConceptStruct.Concept memory _concept) internal pure returns (bytes32) {
        uint256 editionCount = _tokenId - _concept._editionTokenRangeStart + 1;
        return bytes32(abi.encodePacked(Util.uint256ToString(editionCount), " of ", Util.uint256ToString(_concept._editionSize)));
    }

    function _name(uint256 _tokenId) internal pure returns (string memory) {
        return string.concat("Beef ", Util.uint256ToString(_tokenId, 4));
    }
}

// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.0;

import {Util} from "./Util.sol";

library SVG {
    /*//////////////////////////////////////////////////////////////
                                 ELEMENT
    //////////////////////////////////////////////////////////////*/

    function element(string memory _type, string memory _attributes) internal pure returns (string memory) {
        return string.concat("<", _type, " ", _attributes, "/>");
    }

    function element(
        string memory _type,
        string memory _attributes,
        string memory _children
    ) internal pure returns (string memory) {
        return string.concat("<", _type, " ", _attributes, ">", _children, "</", _type, ">");
    }

    function element(
        string memory _type,
        string memory _attributes,
        string memory _child1,
        string memory _child2
    ) internal pure returns (string memory) {
        return element(_type, _attributes, string.concat(_child1, _child2));
    }

    function element(
        string memory _type,
        string memory _attributes,
        string memory _child1,
        string memory _child2,
        string memory _child3
    ) internal pure returns (string memory) {
        return element(_type, _attributes, string.concat(_child1, _child2, _child3));
    }

    function element(
        string memory _type,
        string memory _attributes,
        string memory _child1,
        string memory _child2,
        string memory _child3,
        string memory _child4
    ) internal pure returns (string memory) {
        return element(_type, _attributes, string.concat(_child1, _child2, _child3, _child4));
    }

    function element(
        string memory _type,
        string memory _attributes,
        string memory _child1,
        string memory _child2,
        string memory _child3,
        string memory _child4,
        string memory _child5
    ) internal pure returns (string memory) {
        return element(_type, _attributes, string.concat(_child1, _child2, _child3, _child4, _child5));
    }

    function element(
        string memory _type,
        string memory _attributes,
        string memory _child1,
        string memory _child2,
        string memory _child3,
        string memory _child4,
        string memory _child5,
        string memory _child6
    ) internal pure returns (string memory) {
        return element(_type, _attributes, string.concat(_child1, _child2, _child3, _child4, _child5, _child6));
    }

    function element(
        string memory _type,
        string memory _attributes,
        string memory _child1,
        string memory _child2,
        string memory _child3,
        string memory _child4,
        string memory _child5,
        string memory _child6,
        string memory _child7
    ) internal pure returns (string memory) {
        return
            element(_type, _attributes, string.concat(_child1, _child2, _child3, _child4, _child5, _child6, _child7));
    }

    function element(
        string memory _type,
        string memory _attributes,
        string memory _child1,
        string memory _child2,
        string memory _child3,
        string memory _child4,
        string memory _child5,
        string memory _child6,
        string memory _child7,
        string memory _child8
    ) internal pure returns (string memory) {
        return
            element(_type, _attributes, string.concat(_child1, _child2, _child3, _child4, _child5, _child6, _child7, _child8));
    }

    /*//////////////////////////////////////////////////////////////
                               ATTRIBUTES
    //////////////////////////////////////////////////////////////*/

    function svgAttributes() internal pure returns (string memory) {
        return
            string.concat(
                'xmlns="http://www.w3.org/2000/svg" '
                'xmlns:xlink="http://www.w3.org/1999/xlink" '
                'width="100%" '
                'height="100%" '
                'viewBox="0 0 511 619" ',
                'preserveAspectRatio="xMidYMid meet" ',
                'fill="none" '
            );
    }

    function textAttributes(
        string[2] memory _coords,
        string memory _fontSize,
        string memory _fontFamily,
        string memory _fill,
        string memory _attributes
    ) internal pure returns (string memory) {
        return
            string.concat(
                "x=",
                Util.quote(_coords[0]),
                "y=",
                Util.quote(_coords[1]),
                "font-size=",
                Util.quote(string.concat(_fontSize, "px")),
                "font-family=",
                Util.quote(_fontFamily),
                "fill=",
                Util.quote(_fill),
                " ",
                _attributes,
                " "
            );
    }

    function rectAttributes(
        string memory _width,
        string memory _height,
        string memory _fill,
        string memory _attributes
    ) internal pure returns (string memory) {
        return
            string.concat(
                "width=",
                Util.quote(_width),
                "height=",
                Util.quote(_height),
                "fill=",
                Util.quote(_fill),
                " ",
                _attributes,
                " "
            );
    }

    function filterAttribute(string memory _id) internal pure returns (string memory) {
        return string.concat("filter=", '"', "url(#", _id, ")", '" ');
    }
}

// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.0;

import {Util} from "./Util.sol";
import {SVG} from "./SVG.sol";

library TextBody {
    /*//////////////////////////////////////////////////////////////
                                 RENDER
    //////////////////////////////////////////////////////////////*/

    function render(bytes32[] memory _text, uint256 yOffset, bool _small) internal pure returns (string memory) {
        string memory textLines = "";

        for (uint8 index = 0; index < _text.length; ++index) {
            textLines = string.concat(
                textLines,
                SVG.element(
                    "text",
                    SVG.textAttributes({
                        _fontSize: _small ? "14" : "26",
                        _fontFamily: "Norw, 'Courier New', monospace",
                        _coords: [
                            "60",
                            Util.uint256ToString(yOffset + index * (_small ? 20 : 30))
                        ],
                        _fill: "white",
                        _attributes: ""
                    }),
                    Util.bytes32ToString(_text[index])
                )
            );
        }

        return
            textLines;
    }
}

// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.0;

import {Util} from "./Util.sol";
import {SVG} from "./SVG.sol";

library TextEdition {
    /*//////////////////////////////////////////////////////////////
                                 RENDER
    //////////////////////////////////////////////////////////////*/

    function render(bytes32 _text) internal pure returns (string memory) {
        return
            SVG.element(
                "text",
                SVG.textAttributes({
                    _fontSize: "26",
                    _fontFamily: "Norw, 'Courier New', monospace",
                    _coords: ["12", "35"],
                    _fill: "white",
                    _attributes: ""
                }),
                Util.bytes32ToString(_text)
            );
    }
}

// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.0;

import {Util} from "./Util.sol";
import {SVG} from "./SVG.sol";

library TextLine {
    /*//////////////////////////////////////////////////////////////
                                 RENDER
    //////////////////////////////////////////////////////////////*/

    function render(bytes32 _text, uint256 yOffset, bool _small) internal pure returns (string memory) {
        return
            SVG.element(
                "text",
                SVG.textAttributes({
                    _fontSize: _small ? "14" : "26",
                    _fontFamily: "Norw, 'Courier New', monospace",
                    _coords: [
                        "60",
                        Util.uint256ToString(yOffset)
                    ],
                    _fill: "white",
                    _attributes: ""
                }),
                Util.bytes32ToString(_text)
            )
        ;
    }
}

// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.0;

import {Util} from "./Util.sol";
import {SVG} from "./SVG.sol";

library TextOf {
    /*//////////////////////////////////////////////////////////////
                                 RENDER
    //////////////////////////////////////////////////////////////*/

    function render(bytes32 _text) internal pure returns (string memory) {
        return
            SVG.element(
                "text",
                SVG.textAttributes({
                    _fontSize: "26",
                    _fontFamily: "Norw, 'Courier New', monospace",
                    _coords: ["499", "605"],
                    _fill: "white",
                    _attributes: 'text-anchor="end"'
                }),
                Util.bytes32ToString(_text)
            );
    }
}

// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.0;

import {Util} from "./Util.sol";

library Traits {
    /*//////////////////////////////////////////////////////////////
                                 TRAITS
    //////////////////////////////////////////////////////////////*/

    function attributes(bytes32[] memory _attributeLabels, bytes32[] memory _attributeValues) internal pure returns (string memory) {
        string memory result = "[";
        // result = string.concat(result, _attribute("Density", densityTrait(_seed, _tokenId)));
        for (uint i; i < _attributeValues.length; i++) {
            result = string.concat(result, _attribute(string(abi.encodePacked(_attributeLabels[i])), string(abi.encodePacked(_attributeValues[i]))));
        }
        return string.concat(result, "]");
    }

    /*//////////////////////////////////////////////////////////////
                                INTERNAL
    //////////////////////////////////////////////////////////////*/

    function _attribute(string memory _traitType, string memory _value) internal pure returns (string memory) {
        return string.concat("{", Util.keyValue("trait_type", _traitType), ",", Util.keyValue("value", _value), "}");
    }

    // function _rarity(bytes32 _seed, string memory _salt) internal pure returns (uint256) {
    //     return uint256(keccak256(abi.encodePacked(_seed, _salt))) % 100;
    // }
}

// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.0;

library Util {
    error NumberHasTooManyDigits();

    /// @notice wraps a string in quotes and adds a space after
    function quote(string memory value) internal pure returns (string memory) {
        return string.concat('"', value, '" ');
    }

    function keyValue(string memory _key, string memory _value) internal pure returns (string memory) {
        return string.concat('"', _key, '":"', _value, '"');
    }

    function keyValueNoQuotes(string memory _key, string memory _value) internal pure returns (string memory) {
        return string.concat('"', _key, '":', _value);
    }

    /// @notice converts a tokenId to string and pads to _digits digits
    /// @dev tokenId must be less than 10**_digits
    /// @param _tokenId, uint256, the tokenId
    /// @param _digits, uint8, the number of digits to pad to
    /// @return result the resulting string
    function uint256ToString(uint256 _tokenId, uint8 _digits) internal pure returns (string memory result) {
        uint256 max = 10**_digits;
        if (_tokenId >= max) revert NumberHasTooManyDigits();
        // add leading zeroes
        result = uint256ToString(_tokenId + max);
        assembly {
            // cut off one character
            result := add(result, 1)
            // store new length = _digits
            mstore(result, _digits)
        }
    }

    /// @notice converts a uint256 to ascii representation, without leading zeroes
    /// @param _value, uint256, the value to convert
    /// @return result the resulting string
    function uint256ToString(uint256 _value) internal pure returns (string memory result) {
        if (_value == 0) return "0";

        assembly {
            // largest uint = 2^256-1 has 78 digits
            // reserve 110 = 78 + 32 bytes of data in memory
            // (first 32 are for string length)

            // get 110 bytes of free memory
            result := add(mload(0x40), 110)
            mstore(0x40, result)

            // keep track of digits
            let digits := 0

            for {

            } gt(_value, 0) {

            } {
                // increment digits
                digits := add(digits, 1)
                // go back one byte
                result := sub(result, 1)
                // compute ascii char
                let c := add(mod(_value, 10), 48)
                // store byte
                mstore8(result, c)
                // advance to next digit
                _value := div(_value, 10)
            }
            // go back 32 bytes
            result := sub(result, 32)
            // store the length
            mstore(result, digits)
        }
    }

    function bytes1ToString(bytes1 _value) internal pure returns (string memory) {
        return uint256ToString(uint8(_value));
    }

    function uint8ToString(uint8 _value) internal pure returns (string memory) {
        return uint256ToString(_value);
    }

    /// @notice will revert in any characters are not in [0-9]
    function stringToUint256(string memory _value) internal pure returns (uint256 result) {
        // 0-9 are 48-57

        bytes memory value = bytes(_value);
        if (value.length == 0) return 0;
        uint256 multiplier = 10**(value.length - 1);
        uint256 i;
        while (multiplier != 0) {
            result += uint256((uint8(value[i]) - 48)) * multiplier;
            unchecked {
                multiplier /= 10;
                ++i;
            }
        }
    }

    function bytes1ToHex(bytes1 _value) internal pure returns (string memory) {
        bytes memory result = new bytes(2);
        uint8 x = uint8(_value);

        result[0] = getHexChar(x >> 4);
        result[1] = getHexChar(x % 16);

        return string(result);
    }

    function bytes32ToBytes(bytes32 x) internal pure returns (bytes memory) {
        bytes memory bytesString = new bytes(32);
        for (uint i = 0; i < 32; i++) {
            if (x[i] == 0) {
                bytesString[i] = bytes1(0x20);
            } else {
                bytesString[i] = x[i];
            }
        }
        return abi.encodePacked(bytesString);
    }

    function bytes32ToString(bytes32 x) internal pure returns (string memory) {
        return string(bytes32ToBytes(x));
    }

    function getHexChar(uint8 _value) internal pure returns (bytes1) {
        if (_value < 10) {
            return bytes1(_value + 48);
        }
        _value -= 10;
        return bytes1(_value + 97);
    }

    function stringToBytes1(string memory _value) internal pure returns (bytes1 result) {
        return bytes1(uint8(stringToUint256(_value)));
    }

    function getRGBString(bytes memory _palette, uint256 _pos) internal pure returns (string memory result) {
        return
            string.concat(
                "#",
                Util.bytes1ToHex(_palette[3 * _pos]),
                Util.bytes1ToHex(_palette[3 * _pos + 1]),
                Util.bytes1ToHex(_palette[3 * _pos + 2])
            );
    }

    function getRGBString(bytes3 _color) internal pure returns (string memory result) {
        return
            string.concat(
                "#",
                Util.bytes1ToHex(_color[0]),
                Util.bytes1ToHex(_color[1]),
                Util.bytes1ToHex(_color[2])
            );
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 2000000
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Codependent","type":"error"},{"inputs":[],"name":"CurrentlyClosed","type":"error"},{"inputs":[],"name":"HalfOfTheTime","type":"error"},{"inputs":[],"name":"MutuallyExclusive","type":"error"},{"inputs":[],"name":"NoBeef","type":"error"},{"inputs":[],"name":"NotChromatic","type":"error"},{"inputs":[],"name":"NotCoinbase","type":"error"},{"inputs":[],"name":"NotContinuous","type":"error"},{"inputs":[],"name":"NotContract","type":"error"},{"inputs":[],"name":"NotDark","type":"error"},{"inputs":[],"name":"NotFairPrice","type":"error"},{"inputs":[],"name":"NotLight","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"artist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyAtFairPrice","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"decreasable","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decrease","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"editionSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fairPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"increasable","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"increase","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOpenHours","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"renderSVG","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"renderSVGBase64","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"retract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"_editionTokenRangeStart","type":"uint256"},{"internalType":"uint256","name":"_editionSize","type":"uint256"},{"internalType":"bytes32","name":"_title","type":"bytes32"},{"internalType":"bytes32[]","name":"_bodyText","type":"bytes32[]"},{"internalType":"bytes32[]","name":"_smallPrintText","type":"bytes32[]"},{"internalType":"bytes32[]","name":"_statusText","type":"bytes32[]"}],"internalType":"struct ConceptStruct.Concept[]","name":"_concepts","type":"tuple[]"}],"name":"setConceptData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transfersLeft","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateTransitory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"whereIs","outputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"},{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address payable","name":"_to","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60006007908155602a60085567016345785d8a0000600d55600e80546001600160c01b03191677039716ee06e7aaee571c71c7000000000000000000000001179055600f55611c00604052611b4d608081815290620075d760a039601090620000699082620013c1565b503480156200007757600080fd5b50604051806040016040528060048152602001632122a2a360e11b815250604051806040016040528060048152602001632122a2a360e11b815250620000cc620000c66200011c60201b60201c565b62000120565b6001620000da8382620013c1565b506002620000e98282620013c1565b505050620000ff41602a6200017060201b60201c565b600780549060006200011183620014a3565b9190505550620015c9565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038216620001c05760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b60448201526064015b60405180910390fd5b6000818152600560205260409020546001600160a01b031615620002185760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b6044820152606401620001b7565b600062000227818484620002a3565b9050806200023457505050565b6001600160a01b038316600081815260066020908152604080832080546001019055858352600590915280822080546001600160a01b031916841790555184929190600080516020620075b7833981519152908290a46200029e600084846001600160e01b038416565b505050565b600060098203620002eb576000805b62026db8811015620002e35781620002ca81620014a3565b9250508080620002da90620014a3565b915050620002b2565b50506200111b565b60168214801562000306575062000304600243620014d5565b155b806200032a5750601f821480156200032a575062000326600243620014d5565b6001145b15620003495760405163184e367960e01b815260040160405180910390fd5b602a82036200036e576001600160a01b03831641146200036857600080fd5b6200111b565b600382036200039f576200038162001126565b620003685760405163e188e19f60e01b815260040160405180910390fd5b6004821480620003af5750601782145b80620003bb5750602582145b80620003c75750602082145b80620003d35750600c82145b80620003df5750602482145b80620003eb5750602382145b80620003f75750600882145b80620004035750602982145b806200040f5750601282145b806200041b5750601c82145b156200081c57606083901b6004831480156200047857507fdead00000000000000000000000000000000beef0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b80620004d15750601783148015620004d157507fbeef00000000000000000000000000000000beef0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b806200052a57506025831480156200052a57507ffeed00000000000000000000000000000000beef0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b806200058357506020831480156200058357507fdeaf00000000000000000000000000000000beef0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b80620005dc5750600c83148015620005dc57507fbad000000000000000000000000000000000beef0000000000000000000000007ffff000000000000000000000000000000000ffff0000000000000000000000008216145b806200063557506024831480156200063557507fbeef00000000000000000000000000000000face0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b806200068e57506023831480156200068e57507fbabe00000000000000000000000000000000beef0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b80620006e75750600883148015620006e757507fbeef00000000000000000000000000000000babe0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b806200074057506029831480156200074057507fbad000000000000000000000000000000000babe0000000000000000000000007ffff000000000000000000000000000000000ffff0000000000000000000000008216145b806200079957506012831480156200079957507fdeaf00000000000000000000000000000000babe0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b80620007f25750601c83148015620007f257507fdead00000000000000000000000000000000babe0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b15156000036200081557604051631a9e492760e01b815260040160405180910390fd5b506200111b565b600e82101580156200082f575060108211155b15620009e9576000600e83146200084857600e6200084b565b600f5b90506000600e84146200087157600f84146200086957600f62000874565b601062000874565b60105b6000838152600b602052604090205490915043148015620008a257506000818152600b602052604090205443145b15620009ac576000828152600560205260409020546001600160a01b0316156200090057600082815260056020908152604080832054600c90925290912054620008fa916001600160a01b0390811691168462001155565b62000924565b6000828152600c602052604090205462000924906001600160a01b0316836200121f565b6000818152600560205260409020546001600160a01b0316156200097c57600081815260056020908152604080832054600c9092529091205462000976916001600160a01b0390811691168362001155565b620009a0565b6000818152600c6020526040902054620009a0906001600160a01b0316826200121f565b6001925050506200111f565b5050506000818152600b60209081526040808320439055600c909152812080546001600160a01b0319166001600160a01b0385161790556200111f565b6018821480620009f95750601982145b1562000ae15760006018831462000a1257601862000a15565b60195b905061100062000a268186620014ec565b60008381526005602052604090205462000a4d90611000906001600160a01b0316620014ec565b62000a59919062001515565b6001600160a01b031610801562000abe575061100062000a8281610fff609488901c16620014ec565b60008381526005602052604090205462000aa7906110009060941c610fff16620014ec565b62000ab3919062001515565b6001600160a01b0316105b1515600003620008155760405163386e95a360e11b815260040160405180910390fd5b600582148062000af15750600682145b1562000be45760006005831462000b0a57600562000b0d565b60065b6000818152600560205260408120549192506001600160601b0319606092831b169186901b905b602881101562000bda57601062000b4d8260046200153f565b62000b6991906001600160601b03198516901c60601c620014ec565b6001600160a01b0316601062000b818360046200153f565b62000b9d91906001600160601b03198716901c60601c620014ec565b6001600160a01b03160362000bc55760405163a90de52960e01b815260040160405180910390fd5b8062000bd181620014a3565b91505062000b34565b505050506200111b565b601a820362000cd057606083901b6000805b602881101562000cb657601062000c0f8260046200153f565b62000c2b91906001600160601b03198616901c60601c620014ec565b6001600160a01b03161562000cb657601062000c498260046200153f565b62000c6591906001600160601b03198616901c60601c620014ec565b6001600160a01b0316600f0362000c86578162000c82816200155f565b9250505b600d8261ffff16111562000ca157600193505050506200111f565b8062000cad81620014a3565b91505062000bf6565b506040516374279ff760e01b815260040160405180910390fd5b600a820362000dbf57606083901b6000805b602881101562000da557601062000cfb8260046200153f565b62000d1791906001600160601b03198616901c60601c620014ec565b6001600160a01b0316600f031562000da557601062000d388260046200153f565b62000d5491906001600160601b03198616901c60601c620014ec565b6001600160a01b031660000362000d75578162000d71816200155f565b9250505b600d8261ffff16111562000d9057600193505050506200111f565b8062000d9c81620014a3565b91505062000ce2565b5060405163c274dea760e01b815260040160405180910390fd5b6027820362000e5d57606083901b6000805b602881101562000e4357601062000dea8260046200153f565b62000e0691906001600160601b03198616901c60601c620014ec565b6001600160a01b03166001901b821791508161ffff0362000e2e57600193505050506200111f565b8062000e3a81620014a3565b91505062000dd1565b50604051633b75083d60e11b815260040160405180910390fd5b6002820362000e8b57823b60008190036200081557604051636f7c43f160e01b815260040160405180910390fd5b600d820362000eaf57823b801562000ea257600080fd5b3233146200081557600080fd5b6011820362000f3057600f541562000ede57600f805490600062000ed38362001583565b91905055506200111b565b6011600081905260056020527fb4e18992ad424cdedc46668609f2bafcf665a8d99577618d5923c69264d9cf5f5462000f27916001600160a01b039091169061dead9062001155565b5060006200111f565b6028820362000fd757670de0b6b3a7640000341015801562000f6d575062000f6967016345785d8a0000670de0b6b3a76400006200159d565b3411155b62000f7757600080fd5b6040516000908190670de0b6b3a7640000908281818185825af1925050503d806000811462000fc3576040519150601f19603f3d011682016040523d82523d6000602084013e62000fc8565b606091505b50509050806200081557600080fd5b602282036200100a576001600160a01b0383164114620003685760405163c384d6a960e01b815260040160405180910390fd5b601d82036200111b57601d600090815260056020527f348e8fe0716b12afdd2e814ae0b8b1bb9b5c7a197ef418c73b8bdd93bee14de5546001600160601b0319606091821b16919085901b905b60038110156200111757601062001070826003620015b3565b6200107d906028620015b3565b6200108a9060046200153f565b620010a691906001600160601b03198516901c60601c620014ec565b6001600160a01b03166010620010be8360046200153f565b620010da91906001600160601b03198716901c60601c620014ec565b6001600160a01b03161462001102576040516326f3b96560e11b815260040160405180910390fd5b806200110e81620014a3565b91505062001057565b5050505b5060015b9392505050565b600080620011386201518042620014d5565b9050617e9081101580156200114f575061ef108111155b91505090565b6001600160a01b038216620011a15760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401620001b7565b6001600160a01b0380841660008181526006602090815260408083208054600019019055938616808352848320805460010190558583526005825284832080546001600160a01b0319908116831790915560039092528483208054909216909155925184939291600080516020620075b783398151915291a4505050565b6001600160a01b0382166200126b5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401620001b7565b6000818152600560205260409020546001600160a01b031615620012c35760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b6044820152606401620001b7565b6001600160a01b038216600081815260066020908152604080832080546001019055848352600590915280822080546001600160a01b031916841790555183929190600080516020620075b7833981519152908290a45050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200134857607f821691505b6020821081036200136957634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029e57600081815260208120601f850160051c81016020861015620013985750805b601f850160051c820191505b81811015620013b957828155600101620013a4565b505050505050565b81516001600160401b03811115620013dd57620013dd6200131d565b620013f581620013ee845462001333565b846200136f565b602080601f8311600181146200142d5760008415620014145750858301515b600019600386901b1c1916600185901b178555620013b9565b600085815260208120601f198616915b828110156200145e578886015182559484019460019091019084016200143d565b50858210156200147d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b600060018201620014b857620014b86200148d565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082620014e757620014e7620014bf565b500690565b60006001600160a01b0383811680620015095762001509620014bf565b92169190910692915050565b6001600160a01b038181168382160190808211156200153857620015386200148d565b5092915050565b80820281158282048414176200155957620015596200148d565b92915050565b600061ffff8083168181036200157957620015796200148d565b6001019392505050565b6000816200159557620015956200148d565b506000190190565b808201808211156200155957620015596200148d565b818103818111156200155957620015596200148d565b615fde80620015d96000396000f3fe60806040526004361061024f5760003560e01c8063944221d511610138578063d1db019a116100b0578063e8927fbc1161007f578063f2fde38b11610064578063f2fde38b14610671578063f4ed0f4614610691578063ff750ae3146106a757600080fd5b8063e8927fbc1461062e578063e985e9c51461063657600080fd5b8063d1db019a146105b5578063d732d955146105d5578063dc244a23146105dd578063dcb624bd146105f357600080fd5b8063a22cb46511610107578063b88d4fde116100ec578063b88d4fde14610562578063c87b56dd14610575578063d12a4c981461059557600080fd5b8063a22cb4651461052d578063a520e23c1461054d57600080fd5b8063944221d5146104b457806395d89b41146104e9578063a035b1fe146104fe578063a0712d681461051a57600080fd5b806347f57b32116101cb5780635ca2ddf11161019a57806370a082311161017f57806370a082311461047f578063715018a61461049f5780638da5cb5b1461039557600080fd5b80635ca2ddf11461043f5780636352211e1461045f57600080fd5b806347f57b32146103c05780634e67e779146103d55780634f4d61aa146103dd57806351cff8d91461041f57600080fd5b806318160ddd1161022257806323b872dd1161020757806323b872dd1461036f57806342842e0e1461038257806343bc16121461039557600080fd5b806318160ddd146103355780631a9ca8d21461035957600080fd5b806301ffc9a71461025457806306fdde0314610289578063081812fc146102ab578063095ea7b314610313575b600080fd5b34801561026057600080fd5b5061027461026f366004614bf4565b6106bc565b60405190151581526020015b60405180910390f35b34801561029557600080fd5b5061029e6107a1565b6040516102809190614c35565b3480156102b757600080fd5b506102ee6102c6366004614c86565b60036020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610280565b34801561031f57600080fd5b5061033361032e366004614cc1565b61082f565b005b34801561034157600080fd5b5061034b60075481565b604051908152602001610280565b34801561036557600080fd5b5061034b600f5481565b61033361037d366004614ced565b61097e565b610333610390366004614ced565b6109b4565b3480156103a157600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166102ee565b3480156103cc57600080fd5b50610333610b44565b610333610bd6565b3480156103e957600080fd5b50600e54610402906bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff9091168152602001610280565b34801561042b57600080fd5b5061033361043a366004614d2e565b610cf5565b34801561044b57600080fd5b5061029e61045a366004614c86565b610d8a565b34801561046b57600080fd5b506102ee61047a366004614c86565b610e35565b34801561048b57600080fd5b5061034b61049a366004614d2e565b610f04565b3480156104ab57600080fd5b50610333610f5d565b3480156104c057600080fd5b50600e54610402906c0100000000000000000000000090046bffffffffffffffffffffffff1681565b3480156104f557600080fd5b5061029e610f6f565b34801561050a57600080fd5b5061034b67016345785d8a000081565b610333610528366004614c86565b610f7c565b34801561053957600080fd5b50610333610548366004614d4b565b610ffa565b34801561055957600080fd5b50610274611091565b610333610570366004614d89565b6110bd565b34801561058157600080fd5b5061029e610590366004614c86565b611242565b3480156105a157600080fd5b5061029e6105b0366004614c86565b611426565b3480156105c157600080fd5b506103336105d0366004614f5e565b6114ca565b6103336115f4565b3480156105e957600080fd5b5061034b600d5481565b3480156105ff57600080fd5b5061061361060e366004614d2e565b611653565b60408051938452602084019290925290820152606001610280565b610333611701565b34801561064257600080fd5b506102746106513660046150d0565b600460209081526000928352604080842090915290825290205460ff1681565b34801561067d57600080fd5b5061033361068c366004614d2e565b61171f565b34801561069d57600080fd5b5061034b60085481565b3480156106b357600080fd5b506103336117d6565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061074f57507f80ac58cd000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b8061079b57507f5b5e139f000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b600180546107ae906150fe565b80601f01602080910402602001604051908101604052809291908181526020018280546107da906150fe565b80156108275780601f106107fc57610100808354040283529160200191610827565b820191906000526020600020905b81548152906001019060200180831161080a57829003601f168201915b505050505081565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1633811480610892575073ffffffffffffffffffffffffffffffffffffffff8116600090815260046020908152604080832033845290915290205460ff165b6108fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008281526003602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff87811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6001810361099657610991838383611824565b505050565b602a81036109a957610991838383611824565b610991838383611a1e565b600181036109cc576109c7838383611824565b6109ea565b602a81036109df576109c7838383611824565b6109ea838383611a1e565b73ffffffffffffffffffffffffffffffffffffffff82163b1580610ade57506040517f150b7a020000000000000000000000000000000000000000000000000000000080825233600483015273ffffffffffffffffffffffffffffffffffffffff858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af1158015610a96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aba9190615151565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e540000000000000000000000000000000060448201526064016108f4565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b6857600080fd5b600b60005260056020527f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed554610bd49073ffffffffffffffffffffffffffffffffffffffff16610bcd60005473ffffffffffffffffffffffffffffffffffffffff1690565b600b611b11565b565b600760005260056020527feddb6698d7c569ff62ff64f1f1492bf14a54594835ba0faac91f84b4f5d814605473ffffffffffffffffffffffffffffffffffffffff16610c6357600d54341015610c58576040517f5dbd9b4100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd4336007611c60565b600d54341115610cc35734600d556007600081905260056020527feddb6698d7c569ff62ff64f1f1492bf14a54594835ba0faac91f84b4f5d8146054610bd49173ffffffffffffffffffffffffffffffffffffffff909116903390611824565b6040517f5dbd9b4100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314610d1957600080fd5b60008173ffffffffffffffffffffffffffffffffffffffff164760405160006040518083038185875af1925050503d8060008114610d73576040519150601f19603f3d011682016040523d82523d6000602084013e610d78565b606091505b5050905080610d8657600080fd5b5050565b60606000610d9783611e14565b9050610e2e838260108054610dab906150fe565b80601f0160208091040260200160405190810160405280929190818152602001828054610dd7906150fe565b8015610e245780601f10610df957610100808354040283529160200191610e24565b820191906000526020600020905b815481529060010190602001808311610e0757829003601f168201915b5050505050612305565b9392505050565b6000602a8203610e46575041919050565b601682148015610e5e5750610e5c60024361519d565b155b80610e7e5750601f82148015610e7e5750610e7a60024361519d565b6001145b15610eb5576040517f184e367900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60038203610efb57610ec5611091565b610efb576040517fe188e19f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61079b82612322565b60004173ffffffffffffffffffffffffffffffffffffffff831603610f545773ffffffffffffffffffffffffffffffffffffffff821660009081526006602052604090205461079b9060016151e0565b61079b826123ae565b610f65612456565b610bd460006124d7565b600280546107ae906150fe565b600081118015610f8e57506008548111155b610f9757600080fd5b600060288214610faf5767016345785d8a0000610fc9565b610fc967016345785d8a0000670de0b6b3a76400006151e0565b9050803414610fd757600080fd5b610fe13383611c60565b60078054906000610ff1836151f3565b91905055505050565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6000806110a1620151804261519d565b9050617e9081101580156110b7575061ef108111155b91505090565b600183036110d5576110d0858585611824565b6110f3565b602a83036110e8576110d0858585611824565b6110f3858585611a1e565b73ffffffffffffffffffffffffffffffffffffffff84163b15806111d557506040517f150b7a02000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff86169063150b7a029061116e9033908a9089908990899060040161522b565b6020604051808303816000875af115801561118d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111b19190615151565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b61123b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e540000000000000000000000000000000060448201526064016108f4565b5050505050565b606060168214801561125c575061125a60024361519d565b155b8061127c5750601f8214801561127c575061127860024361519d565b6001145b156112b3576040517f184e367900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600382036112f9576112c3611091565b6112f9576040517fe188e19f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526005602052604090205473ffffffffffffffffffffffffffffffffffffffff16611384576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e4f545f4d494e5445440000000000000000000000000000000000000000000060448201526064016108f4565b600061138f83611e14565b9050610e2e8382601080546113a3906150fe565b80601f01602080910402602001604051908101604052809291908181526020018280546113cf906150fe565b801561141c5780601f106113f15761010080835404028352916020019161141c565b820191906000526020600020905b8154815290600101906020018083116113ff57829003601f168201915b505050505061254c565b6060600061143383611e14565b9050610e2e838260108054611447906150fe565b80601f0160208091040260200160405190810160405280929190818152602001828054611473906150fe565b80156114c05780601f10611495576101008083540402835291602001916114c0565b820191906000526020600020905b8154815290600101906020018083116114a357829003601f168201915b5050505050612606565b60005473ffffffffffffffffffffffffffffffffffffffff1633146114ee57600080fd5b60005b8151811015610d8657600082828151811061150e5761150e6152aa565b602090810291909101810151805160008181526009845260409081902083518155838501516001820155908301516002820155606083015180519395509193859391926115649260038501929190910190614b66565b5060808201518051611580916004840191602090910190614b66565b5060a0820151805161159c916005840191602090910190614b66565b5050825190505b602083015183516115b491906151e0565b8110156115de576000818152600a60205260409020829055806115d6816151f3565b9150506115a3565b50505080806115ec906151f3565b9150506114f1565b600e80546c0100000000000000000000000090046bffffffffffffffffffffffff1690600c611622836152d9565b91906101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606083901b166020820152600090819081908190603401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012090506116d3620186a08261519d565b93506116e6620186a0600883901c61519d565b92506116f8612710601083901c61519d565b93959294505050565b600e80546bffffffffffffffffffffffff169060006116228361531f565b611727612456565b73ffffffffffffffffffffffffffffffffffffffff81166117ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016108f4565b6117d3816124d7565b50565b602a600081905260056020527fd3e7a847b0e4be9f2ff1f88564b0a771bb9789c2c82f98679296a6042483791d54610bd49173ffffffffffffffffffffffffffffffffffffffff9091169041905b73ffffffffffffffffffffffffffffffffffffffff82166118a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f494e56414c49445f524543495049454e5400000000000000000000000000000060448201526064016108f4565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff848116911614611931576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f57524f4e475f46524f4d0000000000000000000000000000000000000000000060448201526064016108f4565b600061193e848484612613565b90508061194b5750505050565b73ffffffffffffffffffffffffffffffffffffffff808516600081815260066020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019055938716808352848320805460010190558683526005825284832080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081168317909155600390925284832080549092169091559251859392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a450505050565b3373ffffffffffffffffffffffffffffffffffffffff84161480611a72575073ffffffffffffffffffffffffffffffffffffffff8316600090815260046020908152604080832033845290915290205460ff165b80611aa0575060008181526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1633145b611b06576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016108f4565b610991838383611824565b73ffffffffffffffffffffffffffffffffffffffff8216611b8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f494e56414c49445f524543495049454e5400000000000000000000000000000060448201526064016108f4565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260066020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019055938616808352848320805460010190558583526005825284832080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081168317909155600390925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b73ffffffffffffffffffffffffffffffffffffffff8216611cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f494e56414c49445f524543495049454e5400000000000000000000000000000060448201526064016108f4565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611d69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f414c52454144595f4d494e54454400000000000000000000000000000000000060448201526064016108f4565b6000611d7760008484612613565b905080611d8357505050565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260066020908152604080832080546001019055858352600590915280822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905551849291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4505050565b611e506040518060c001604052806000815260200160008152602001600080191681526020016060815260200160608152602001606081525090565b6000828152600a602090815260408083205480845260098352818420825160c0810184528154815260018201548186015260028201548185015260038201805485518188028101880190965280865293969591949293606086019392830182828015611edb57602002820191906000526020600020905b815481526020019060010190808311611ec7575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020018280548015611f3357602002820191906000526020600020905b815481526020019060010190808311611f1f575b5050505050815260200160058201805480602002602001604051908101604052809291908181526020018280548015611f8b57602002820191906000526020600020905b815481526020019060010190808311611f77575b5050505050815250509050600784036120ab5760408051600180825281830190925260009160208083019080368337019050509050611fde670de0b6b3a7640000600d54611fd9919061534a565b613717565b612003600a67016345785d8a0000600d54611ff9919061534a565b611fd9919061519d565b600a662386f26fc10000600d5461201a919061534a565b612024919061519d565b1561204857612043600a662386f26fc10000600d54611ff9919061534a565b612059565b604051806020016040528060008152505b60405160200161206b9392919061537a565b6040516020818303038152906040526120839061543c565b81600081518110612096576120966152aa565b602090810291909101015260a0820152610e2e565b601184036120f057604080516001808252818301909252600091602080830190803683370190505090506120e0600f54613717565b60405160200161206b919061547e565b601b840361214457600e54612112906bffffffffffffffffffffffff16613717565b60405160200161212291906154c3565b60405160208183030381529060405261213a9061543c565b6040820152610e2e565b6013840361217657600e54612112906c0100000000000000000000000090046bffffffffffffffffffffffff16613717565b6003840361222e57604080516001808252818301909252600091602080830190803683370190505090506121a8611091565b6121e7576040518060400160405280600681526020017f436c6f736564000000000000000000000000000000000000000000000000000081525061221e565b6040518060400160405280600481526020017f4f70656e000000000000000000000000000000000000000000000000000000008152505b60405160200161206b91906154df565b60158403610e2e576040805160038082526080820190925260009160208201606080368337505050600086815260056020526040812054919250908190819061228c9073ffffffffffffffffffffffffffffffffffffffff16611653565b9194509250905061229c83613717565b6122a583613717565b6122ae83613717565b6040516020016122c093929190615524565b6040516020818303038152906040526122d89061543c565b846000815181106122eb576122eb6152aa565b602090810291909101015250505060a08201529392505050565b606061231a6123158585856137d9565b6138a9565b949350505050565b60008181526005602052604081205473ffffffffffffffffffffffffffffffffffffffff168061079b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e4f545f4d494e5445440000000000000000000000000000000000000000000060448201526064016108f4565b600073ffffffffffffffffffffffffffffffffffffffff821661242d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f5a45524f5f41444452455353000000000000000000000000000000000000000060448201526064016108f4565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604090205490565b60005473ffffffffffffffffffffffffffffffffffffffff163314610bd4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108f4565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60608060005b8460600151518110156125bb578161258686606001518381518110612579576125796152aa565b6020026020010151613911565b60405160200161259792919061559a565b604051602081830303815290604052915080806125b3906151f3565b915050612552565b506125fd856125cd8660400151613a5f565b836040516020016125de91906154c3565b6040516020818303038152906040526125f88989896137d9565b613a6a565b95945050505050565b606061231a8484846137d9565b600060098203612653576000805b62026db881101561264c5781612636816151f3565b9250508080612644906151f3565b915050612621565b505061370d565b60168214801561266b575061266960024361519d565b155b8061268b5750601f8214801561268b575061268760024361519d565b6001145b156126c2576040517f184e367900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602a82036126f15773ffffffffffffffffffffffffffffffffffffffff831641146126ec57600080fd5b61370d565b6003820361273757612701611091565b6126ec576040517fe188e19f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60048214806127465750601782145b806127515750602582145b8061275c5750602082145b806127675750600c82145b806127725750602482145b8061277d5750602382145b806127885750600882145b806127935750602982145b8061279e5750601282145b806127a95750601c82145b15612bab57606083901b60048314801561280457507fdead00000000000000000000000000000000beef0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b8061285b575060178314801561285b57507fbeef00000000000000000000000000000000beef0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b806128b257506025831480156128b257507ffeed00000000000000000000000000000000beef0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b80612909575060208314801561290957507fdeaf00000000000000000000000000000000beef0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b806129605750600c8314801561296057507fbad000000000000000000000000000000000beef0000000000000000000000007ffff000000000000000000000000000000000ffff0000000000000000000000008216145b806129b757506024831480156129b757507fbeef00000000000000000000000000000000face0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b80612a0e5750602383148015612a0e57507fbabe00000000000000000000000000000000beef0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b80612a655750600883148015612a6557507fbeef00000000000000000000000000000000babe0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b80612abc5750602983148015612abc57507fbad000000000000000000000000000000000babe0000000000000000000000007ffff000000000000000000000000000000000ffff0000000000000000000000008216145b80612b135750601283148015612b1357507fdeaf00000000000000000000000000000000babe0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b80612b6a5750601c83148015612b6a57507fdead00000000000000000000000000000000babe0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b1515600003612ba5576040517f1a9e492700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061370d565b600e8210158015612bbd575060108211155b15612dd3576000600e8314612bd357600e612bd6565b600f5b90506000600e8414612bf857600f8414612bf157600f612bfb565b6010612bfb565b60105b6000838152600b602052604090205490915043148015612c2857506000818152600b602052604090205443145b15612d725760008281526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1615612c9b57600082815260056020908152604080832054600c90925290912054612c969173ffffffffffffffffffffffffffffffffffffffff908116911684611b11565b612cca565b6000828152600c6020526040902054612cca9073ffffffffffffffffffffffffffffffffffffffff1683613bac565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1615612d3857600081815260056020908152604080832054600c90925290912054612d339173ffffffffffffffffffffffffffffffffffffffff908116911683611b11565b612d67565b6000818152600c6020526040902054612d679073ffffffffffffffffffffffffffffffffffffffff1682613bac565b600192505050610e2e565b5050506000818152600b60209081526040808320439055600c909152812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8516179055610e2e565b6018821480612de25750601982145b15612ef957600060188314612df8576018612dfb565b60195b9050611000612e0a81866155c9565b600083815260056020526040902054612e3c906110009073ffffffffffffffffffffffffffffffffffffffff166155c9565b612e4691906155fc565b73ffffffffffffffffffffffffffffffffffffffff16108015612ebe5750611000612e7981610fff609488901c166155c9565b600083815260056020526040902054612e9c906110009060941c610fff166155c9565b612ea691906155fc565b73ffffffffffffffffffffffffffffffffffffffff16105b1515600003612ba5576040517f70dd2b4600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005821480612f085750600682145b1561306557600060058314612f1e576005612f21565b60065b6000818152600560205260408120549192507fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606092831b169186901b905b602881101561305c576010612f76826004615630565b612fa891907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008516901c60601c6155c9565b73ffffffffffffffffffffffffffffffffffffffff166010612fcb836004615630565b612ffd91907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008716901c60601c6155c9565b73ffffffffffffffffffffffffffffffffffffffff160361304a576040517fa90de52900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80613054816151f3565b915050612f60565b5050505061370d565b601a82036131a157606083901b6000805b602881101561316e57601061308c826004615630565b6130be91907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008616901c60601c6155c9565b73ffffffffffffffffffffffffffffffffffffffff161561316e5760106130e6826004615630565b61311891907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008616901c60601c6155c9565b73ffffffffffffffffffffffffffffffffffffffff16600f03613143578161313f81615647565b9250505b600d8261ffff16111561315c5760019350505050610e2e565b80613166816151f3565b915050613076565b506040517f74279ff700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a82036132e057606083901b6000805b60288110156132ad5760106131c8826004615630565b6131fa91907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008616901c60601c6155c9565b73ffffffffffffffffffffffffffffffffffffffff16600f03156132ad576010613225826004615630565b61325791907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008616901c60601c6155c9565b73ffffffffffffffffffffffffffffffffffffffff16600003613282578161327e81615647565b9250505b600d8261ffff16111561329b5760019350505050610e2e565b806132a5816151f3565b9150506131b2565b506040517fc274dea700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602782036133b157606083901b6000805b602881101561337e576010613307826004615630565b61333991907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008616901c60601c6155c9565b73ffffffffffffffffffffffffffffffffffffffff166001901b821791508161ffff0361336c5760019350505050610e2e565b80613376816151f3565b9150506132f1565b506040517f76ea107a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600282036133f657823b6000819003612ba5576040517f6f7c43f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d820361341757823b801561340b57600080fd5b323314612ba557600080fd5b6011820361349d57600f541561344157600f80549060006134378361565e565b919050555061370d565b6011600081905260056020527fb4e18992ad424cdedc46668609f2bafcf665a8d99577618d5923c69264d9cf5f546134959173ffffffffffffffffffffffffffffffffffffffff9091169061dead90611b11565b506000610e2e565b6028820361353c57670de0b6b3a764000034101580156134d657506134d267016345785d8a0000670de0b6b3a76400006151e0565b3411155b6134df57600080fd5b6040516000908190670de0b6b3a7640000908281818185825af1925050503d8060008114613529576040519150601f19603f3d011682016040523d82523d6000602084013e61352e565b606091505b5050905080612ba557600080fd5b602282036135935773ffffffffffffffffffffffffffffffffffffffff831641146126ec576040517fc384d6a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601d820361370d57601d600090815260056020527f348e8fe0716b12afdd2e814ae0b8b1bb9b5c7a197ef418c73b8bdd93bee14de5547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606091821b16919085901b905b600381101561370957601061360d826003615693565b613618906028615693565b613623906004615630565b61365591907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008516901c60601c6155c9565b73ffffffffffffffffffffffffffffffffffffffff166010613678836004615630565b6136aa91907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008716901c60601c6155c9565b73ffffffffffffffffffffffffffffffffffffffff16146136f7576040517f4de772ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80613701816151f3565b9150506135f7565b5050505b5060019392505050565b60608160000361375a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b606e6040510190508060405260005b82156137ad577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90910190600101600a830660300180835350600a83049250613769565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909101908152919050565b6060600084600414806137ec5750846008145b806137f7575084600c145b806138025750846017145b8061380d5750846020145b806138185750846023145b806138235750846024145b8061382e5750846025145b90506125fd6040518060400160405280600381526020017f7376670000000000000000000000000000000000000000000000000000000000815250613871613d45565b8560405160200161388291906156a6565b60405160208183030381529060405261389a85613e72565b6138a48a8a613fad565b614111565b60606040518060400160405280601a81526020017f646174613a696d6167652f7376672b786d6c3b6261736536342c0000000000008152506138ea83614141565b6040516020016138fb92919061559a565b6040516020818303038152906040529050919050565b6040805160208082528183019092526060916000919060208201818036833701905050905060005b6020811015613a3657838160208110613954576139546152aa565b1a60f81b7fff00000000000000000000000000000000000000000000000000000000000000166000036139cc57602060f81b828281518110613998576139986152aa565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350613a24565b8381602081106139de576139de6152aa565b1a60f81b8282815181106139f4576139f46152aa565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b80613a2e816151f3565b915050613939565b5080604051602001613a4891906154c3565b604051602081830303815290604052915050919050565b606061079b82613911565b60606000613ab56040518060400160405280600781526020017f746f6b656e496400000000000000000000000000000000000000000000000000815250613ab088613717565b61431b565b613af46040518060400160405280600481526020017f6e616d65000000000000000000000000000000000000000000000000000000008152508761431b565b613b336040518060400160405280600b81526020017f6465736372697074696f6e0000000000000000000000000000000000000000008152508761431b565b613b756040518060400160405280600581526020017f696d616765000000000000000000000000000000000000000000000000000000815250613ab0886138a9565b604051602001613b8894939291906157aa565b6040516020818303038152906040529050613ba281614347565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8216613c29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f494e56414c49445f524543495049454e5400000000000000000000000000000060448201526064016108f4565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1615613cb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f414c52454144595f4d494e54454400000000000000000000000000000000000060448201526064016108f4565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260066020908152604080832080546001019055848352600590915280822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6060604051602001613e5e907f786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737681527f672220786d6c6e733a786c696e6b3d22687474703a2f2f7777772e77332e6f7260208201527f672f313939392f786c696e6b222077696474683d22313030252220686569676860408201527f743d2231303025222076696577426f783d22302030203531312036313922200060608201527f7072657365727665417370656374526174696f3d22784d6964594d6964206d65607f8201527f6574222000000000000000000000000000000000000000000000000000000000609f8201527f66696c6c3d226e6f6e652220000000000000000000000000000000000000000060a382015260af0190565b604051602081830303815290604052905090565b606061079b6040518060400160405280600481526020017f7265637400000000000000000000000000000000000000000000000000000000815250613fa86040518060400160405280600481526020017f31303025000000000000000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f313030250000000000000000000000000000000000000000000000000000000081525086613f5c576040518060400160405280600481526020017f2330303000000000000000000000000000000000000000000000000000000000815250613f93565b6040518060400160405280600781526020017f23424132323139000000000000000000000000000000000000000000000000008152505b60405180602001604052806000815250614388565b6143d2565b606060008083606001515111613fc4576000613fc7565b60325b60ff16836060015151601e613fdc9190615630565b613fe79060d76151e0565b613ff191906151e0565b90506000808460800151511161400857600061400b565b60325b60ff1684608001515160146140209190615630565b61402a90846151e0565b61403491906151e0565b90506125fd6040518060400160405280600181526020017f6700000000000000000000000000000000000000000000000000000000000000815250604051806020016040528060008152506140908760400151609b60006143e7565b6140a1886060015160d7600061457c565b6140b18960a0015187600061457c565b6140c18a6080015189600161457c565b6140fa6140cd8d613717565b6040516020016140dd91906154c3565b6040516020818303038152906040526140f59061543c565b6146ec565b61410c6141078e8e614869565b6148c6565b614a60565b6060613ba2868686868660405160200161412d93929190615891565b604051602081830303815290604052614a8f565b6060815160000361416057505060408051602081019091526000815290565b6000604051806060016040528060408152602001615f69604091399050600060038451600261418f91906151e0565b614199919061534a565b6141a4906004615630565b905060006141b38260206151e0565b67ffffffffffffffff8111156141cb576141cb614e28565b6040519080825280601f01601f1916602001820160405280156141f5576020820181803683370190505b509050818152600183018586518101602084015b818310156142635760039283018051603f601282901c811687015160f890811b8552600c83901c8216880151811b6001860152600683901c8216880151811b60028601529116860151901b93820193909352600401614209565b60038951066001811461427d57600281146142c75761430d565b7f3d3d0000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe83015261430d565b7f3d000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8301525b509398975050505050505050565b606082826040516020016143309291906158d4565b604051602081830303815290604052905092915050565b60606040518060400160405280601d81526020017f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000008152506138ea83614ac0565b606061439385614acb565b61439c85614acb565b6143a585614acb565b846040516020016143b9949392919061595e565b6040516020818303038152906040529050949350505050565b60608282604051602001614330929190615a66565b606061231a6040518060400160405280600481526020017f746578740000000000000000000000000000000000000000000000000000000081525061456e60405180604001604052806040518060400160405280600281526020017f3630000000000000000000000000000000000000000000000000000000000000815250815260200161447488613717565b9052856144b6576040518060400160405280600281526020017f32360000000000000000000000000000000000000000000000000000000000008152506144ed565b6040518060400160405280600281526020017f31340000000000000000000000000000000000000000000000000000000000008152505b6040518060400160405280601e81526020017f4e6f72772c2027436f7572696572204e6577272c206d6f6e6f737061636500008152506040518060400160405280600581526020017f776869746500000000000000000000000000000000000000000000000000000081525060405180602001604052806000815250614ade565b61457787613a5f565b614a8f565b60408051602081019091526000808252606091905b85518160ff1610156146e357816146b06040518060400160405280600481526020017f746578740000000000000000000000000000000000000000000000000000000081525061468b60405180604001604052806040518060400160405280600281526020017f363000000000000000000000000000000000000000000000000000000000000081525081526020016146498a61462f57601e614632565b60145b61463c9089615b11565b611fd99060ff168d6151e0565b9052886144b6576040518060400160405280600281526020017f32360000000000000000000000000000000000000000000000000000000000008152506144ed565b6145778a8660ff16815181106146a3576146a36152aa565b6020026020010151613a5f565b6040516020016146c192919061559a565b6040516020818303038152906040529150806146dc90615b2d565b9050614591565b50949350505050565b606061079b6040518060400160405280600481526020017f746578740000000000000000000000000000000000000000000000000000000081525061486060405180604001604052806040518060400160405280600281526020017f313200000000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600281526020017f33350000000000000000000000000000000000000000000000000000000000008152508152506040518060400160405280600281526020017f32360000000000000000000000000000000000000000000000000000000000008152506040518060400160405280601e81526020017f4e6f72772c2027436f7572696572204e6577272c206d6f6e6f737061636500008152506040518060400160405280600581526020017f776869746500000000000000000000000000000000000000000000000000000081525060405180602001604052806000815250614ade565b61457785613a5f565b8051600090819061487a9085615693565b6148859060016151e0565b905061489081613717565b61489d8460200151613717565b6040516020016148ae929190615b4c565b60405160208183030381529060405261231a9061543c565b606061079b6040518060400160405280600481526020017f746578740000000000000000000000000000000000000000000000000000000081525061486060405180604001604052806040518060400160405280600381526020017f343939000000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600381526020017f36303500000000000000000000000000000000000000000000000000000000008152508152506040518060400160405280600281526020017f32360000000000000000000000000000000000000000000000000000000000008152506040518060400160405280601e81526020017f4e6f72772c2027436f7572696572204e6577272c206d6f6e6f737061636500008152506040518060400160405280600581526020017f77686974650000000000000000000000000000000000000000000000000000008152506040518060400160405280601181526020017f746578742d616e63686f723d22656e6422000000000000000000000000000000815250614ade565b6060614a82898989898989898960405160200161412d96959493929190615ba4565b9998505050505050505050565b606083838386604051602001614aa89493929190615c23565b60405160208183030381529060405290509392505050565b606061079b82614141565b6060816040516020016138fb9190615d2b565b6060614af18660005b6020020151614acb565b614afc876001614ae7565b614b2487604051602001614b109190615d97565b604051602081830303815290604052614acb565b614b2d87614acb565b614b3687614acb565b86604051602001614b4c96959493929190615dd8565b604051602081830303815290604052905095945050505050565b828054828255906000526020600020908101928215614ba1579160200282015b82811115614ba1578251825591602001919060010190614b86565b50614bad929150614bb1565b5090565b5b80821115614bad5760008155600101614bb2565b7fffffffff00000000000000000000000000000000000000000000000000000000811681146117d357600080fd5b600060208284031215614c0657600080fd5b8135610e2e81614bc6565b60005b83811015614c2c578181015183820152602001614c14565b50506000910152565b6020815260008251806020840152614c54816040850160208701614c11565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600060208284031215614c9857600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146117d357600080fd5b60008060408385031215614cd457600080fd5b8235614cdf81614c9f565b946020939093013593505050565b600080600060608486031215614d0257600080fd5b8335614d0d81614c9f565b92506020840135614d1d81614c9f565b929592945050506040919091013590565b600060208284031215614d4057600080fd5b8135610e2e81614c9f565b60008060408385031215614d5e57600080fd5b8235614d6981614c9f565b915060208301358015158114614d7e57600080fd5b809150509250929050565b600080600080600060808688031215614da157600080fd5b8535614dac81614c9f565b94506020860135614dbc81614c9f565b935060408601359250606086013567ffffffffffffffff80821115614de057600080fd5b818801915088601f830112614df457600080fd5b813581811115614e0357600080fd5b896020828501011115614e1557600080fd5b9699959850939650602001949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715614e7a57614e7a614e28565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614ec757614ec7614e28565b604052919050565b600067ffffffffffffffff821115614ee957614ee9614e28565b5060051b60200190565b600082601f830112614f0457600080fd5b81356020614f19614f1483614ecf565b614e80565b82815260059290921b84018101918181019086841115614f3857600080fd5b8286015b84811015614f535780358352918301918301614f3c565b509695505050505050565b60006020808385031215614f7157600080fd5b823567ffffffffffffffff80821115614f8957600080fd5b818501915085601f830112614f9d57600080fd5b8135614fab614f1482614ecf565b81815260059190911b83018401908481019088831115614fca57600080fd5b8585015b838110156150c357803585811115614fe557600080fd5b860160c0818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001121561501a5760008081fd5b615022614e57565b8882013581526040808301358a830152606080840135828401526080915081840135898111156150525760008081fd5b6150608f8d83880101614ef3565b82850152505060a0808401358981111561507a5760008081fd5b6150888f8d83880101614ef3565b838501525060c08401359150888211156150a25760008081fd5b6150b08e8c84870101614ef3565b9083015250845250918601918601614fce565b5098975050505050505050565b600080604083850312156150e357600080fd5b82356150ee81614c9f565b91506020830135614d7e81614c9f565b600181811c9082168061511257607f821691505b60208210810361514b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561516357600080fd5b8151610e2e81614bc6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826151ac576151ac61516e565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561079b5761079b6151b1565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615224576152246151b1565b5060010190565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525084604083015260806060830152826080830152828460a0840137600060a0848401015260a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011683010190509695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006bffffffffffffffffffffffff8216806152f7576152f76151b1565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b60006bffffffffffffffffffffffff808316818103615340576153406151b1565b6001019392505050565b6000826153595761535961516e565b500490565b60008151615370818560208601614c11565b9290920192915050565b7f50726963653a20000000000000000000000000000000000000000000000000008152600084516153b2816007850160208901614c11565b7f2e0000000000000000000000000000000000000000000000000000000000000060079184019182015284516153ef816008840160208901614c11565b8451910190615405816008840160208801614c11565b7f204554480000000000000000000000000000000000000000000000000000000060089290910191820152600c0195945050505050565b8051602080830151919081101561514b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b7f5472616e7366657273204c6566743a20000000000000000000000000000000008152600082516154b6816010850160208701614c11565b9190910160100192915050565b600082516154d5818460208701614c11565b9190910192915050565b7f43757272656e746c79200000000000000000000000000000000000000000000081526000825161551781600a850160208701614c11565b91909101600a0192915050565b60008451615536818460208901614c11565b80830190507f2c200000000000000000000000000000000000000000000000000000000000008082528551615572816002850160208a01614c11565b6002920191820152835161558d816004840160208801614c11565b0160040195945050505050565b600083516155ac818460208801614c11565b8351908301906155c0818360208801614c11565b01949350505050565b600073ffffffffffffffffffffffffffffffffffffffff808416806155f0576155f061516e565b92169190910692915050565b73ffffffffffffffffffffffffffffffffffffffff818116838216019080821115615629576156296151b1565b5092915050565b808202811582820484141761079b5761079b6151b1565b600061ffff808316818103615340576153406151b1565b60008161566d5761566d6151b1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8181038181111561079b5761079b6151b1565b7f3c646566733e3c7374796c653e0000000000000000000000000000000000000081527f40666f6e742d66616365207b666f6e742d66616d696c793a20224e6f7277223b600d8201527f7372633a2075726c282200000000000000000000000000000000000000000000602d8201526000825161572a816037850160208701614c11565b7f22293b7d0000000000000000000000000000000000000000000000000000000060379390910192830152507f74657874207b746578742d7472616e73666f726d3a207570706572636173653b603b8201527f7d3c2f7374796c653e3c2f646566733e00000000000000000000000000000000605b820152606b01919050565b7f7b000000000000000000000000000000000000000000000000000000000000008152600085516157e2816001850160208a01614c11565b80830190507f2c000000000000000000000000000000000000000000000000000000000000008060018301528651615821816002850160208b01614c11565b60029201918201819052855161583e816003850160208a01614c11565b60039201918201528351615859816004840160208801614c11565b7f7d00000000000000000000000000000000000000000000000000000000000000600492909101918201526005019695505050505050565b600084516158a3818460208901614c11565b8451908301906158b7818360208901614c11565b84519101906158ca818360208801614c11565b0195945050505050565b60007f2200000000000000000000000000000000000000000000000000000000000000808352845161590d816001860160208901614c11565b7f223a220000000000000000000000000000000000000000000000000000000000600191850191820152845161594a816004840160208901614c11565b016004810191909152600501949350505050565b7f77696474683d0000000000000000000000000000000000000000000000000000815260008551615996816006850160208a01614c11565b7f6865696768743d0000000000000000000000000000000000000000000000000060069184019182015285516159d381600d840160208a01614c11565b7f66696c6c3d000000000000000000000000000000000000000000000000000000600d92909101918201528451615a11816012840160208901614c11565b8082019150507f20000000000000000000000000000000000000000000000000000000000000008060128301528451615a51816013850160208901614c11565b60139201918201526014019695505050505050565b7f3c00000000000000000000000000000000000000000000000000000000000000815260008351615a9e816001850160208801614c11565b7f20000000000000000000000000000000000000000000000000000000000000006001918401918201528351615adb816002840160208801614c11565b7f2f3e00000000000000000000000000000000000000000000000000000000000060029290910191820152600401949350505050565b60ff8181168382160290811690818114615629576156296151b1565b600060ff821660ff8103615b4357615b436151b1565b60010192915050565b60008351615b5e818460208801614c11565b7f206f6620000000000000000000000000000000000000000000000000000000009083019081528351615b98816004840160208801614c11565b01600401949350505050565b600087516020615bb78285838d01614c11565b885191840191615bca8184848d01614c11565b8851920191615bdc8184848c01614c11565b8751920191615bee8184848b01614c11565b8651920191615c008184848a01614c11565b8551920191615c128184848901614c11565b919091019998505050505050505050565b7f3c00000000000000000000000000000000000000000000000000000000000000815260008551615c5b816001850160208a01614c11565b7f20000000000000000000000000000000000000000000000000000000000000006001918401918201528551615c98816002840160208a01614c11565b8082019150507f3e000000000000000000000000000000000000000000000000000000000000008060028301528551615cd8816003850160208a01614c11565b7f3c2f000000000000000000000000000000000000000000000000000000000000600393909101928301528451615d16816005850160208901614c11565b60059201918201526006019695505050505050565b7f2200000000000000000000000000000000000000000000000000000000000000815260008251615d63816001850160208701614c11565b7f22200000000000000000000000000000000000000000000000000000000000006001939091019283015250600301919050565b60008251615da9818460208701614c11565b7f7078000000000000000000000000000000000000000000000000000000000000920191825250600201919050565b7f783d000000000000000000000000000000000000000000000000000000000000815260008751615e10816002850160208c01614c11565b7f793d0000000000000000000000000000000000000000000000000000000000006002918401918201528751615e4d816004840160208c01614c11565b7f666f6e742d73697a653d00000000000000000000000000000000000000000000600492909101918201528651615e8b81600e840160208b01614c11565b7f666f6e742d66616d696c793d0000000000000000000000000000000000000000600e92909101918201528551615ec981601a840160208a01614c11565b01615ef6601a82017f66696c6c3d0000000000000000000000000000000000000000000000000000009052565b615f03601f82018661535e565b7f200000000000000000000000000000000000000000000000000000000000000081529050615f35600182018561535e565b7f20000000000000000000000000000000000000000000000000000000000000008152600101999850505050505050505056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa264697066735822122070f18396ebf9b3bdc664dd05e66b332952b27e097d156a1e9455993b1ec7b70064736f6c63430008120033ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef646174613a6170706c69636174696f6e2f666f6e742d776f6666323b636861727365743d7574662d383b6261736536342c643039474d674142414141414142525541424941414141414c4d674141425077414145414141414141414141414141414141414141414141414141414141414150305a475645306347683462687a77634d415a6741494d794344514a68475552434171314b4b354f4334454b4141453241695144676841454941574751416543557779435a52756f4a775863474b6468347741442f2b3744456457685a63762b72784f344d5154376831724349304c56535a556f67376f4e61324b7433706d7873565a664738585863633569484d4257664a574c5952547734524e6e375665766d455845587174744649736f73445871654b71634471394b66662b54656f516b737a785579322b7665326233396c49415458624259564f324b4652555942545a49766c43556e677335512f4b70326a6b39732f6a5a72346667304a496f4543686e6b43515650556d505a574d4f753070505455344a6c435a6c4a37623572304a6c566c506c546b6e4b703359764e4e2b7953567430715a4a4d39716b59392f6737713938557461665943774b427871685551616e742f7361692f4138416d44416e66456257595034306e653256625a32587a6d6d69387a57674d2f784b6149796931726c596a6d31576454676f6161715559674f7a784e4a494a4545456b6b676b5154692b77516d4d764244504f335833694c572f6949694a3561516c756c353574325654696945736b696b38583836792f5a2f6a525750484e78636b42776f366655485649614c4a6b306a7a3869535a6b5979534e34587759485050744c6573592f4975774566554a6c7755365a634277384975725263706b3537645a6f69565a6579443154643671392b66346e514f715a54424972586d42337735767264774e7049315031772b673871506b383953786d42354941447233375266336b4534504e4c6254487736516d364576446a6639667241414c5767494e415170426545414a494949415647563647586270792b51444d3437753243735167414655515744546a30554e54382b53644f4951315869434857706c513751542b7633423655364e6d4b327979787a642f676b4930536b444f6d4262755742536463545975783832344850666a4c3351353756676135736870325a6a4c387273386c72636268744e34466a34595967516d3869724b755674574d684c5a793856615355544a637a636b4c3445594f6868464353744f43444f4b4b7044416a6b426b72654357544e525267795747556b53594f383544766877533146776e55776d4149685954554d3861573141494e736155733141684d76306b73416b4844736a43746c6a6a4b4b6162596d6178526245335a596371746e6e7459356c594c5a6c55477054513971706a496a505a304d4a4c44775552725368584e6c756534334d59777261577267485a4d523369684f3446634866456479594d537741484d53757734796a556c54744d4436755161423941444f6c63693477774c4e4831746742697232625743747663377a68336e3839586f4253766b6c44417844476d4933416a4f39595245632f5876716948517055397655584e6e4f5775325135583532416f4d676a434133652f64484d6761567774632b6438462b727351436435466c64474432753351446a6a615949716a3130766972724647666477786648677148493256334e7575714766634b3347484b6f326742315764377a48745973397144696b766f50485673787264514579514d3364624a63533844416466715347614a6e51424b6e694c747333706b6a4c473375426f6b4f3374696d57774246444e6845434c44592f6e6839397a4472414d4d4c4c314f474d62742f38333442586363662f6f65706d467061672b2f79484f334b7838694559304e3474584448765667704e55734953675a524462433476575a6f694c366c535a376f74766a696b344852634f6a665338732f2f785231496c5a45766551433472582b2b2b6c4e6e366e5364716e4439556f64726479327568702f4479796d58497939642b3234443547566d6a4e444769427866517653306d7579657163692b71364a71446534733374335452786c2b33507072764d6b73574b7732753569556e414b444f302f3662353779556a6a7433547837446d3543624d41442f78434743435244636853426c496846617152424274676c37442f43476a6648674262464f692f41615a6649424941416b72725133612f6f3348414975433464564b6e57754d6b4e33336630436a43704c44304545767147727a51454a6c324432734c4f6873426c4c5a337761723961764f704345434c5878374c643054397a3534796c71662f6d51576d7942586e344b466f336e506d392b505151704d524d6a6f6567354e41554f6568583049467a306742634b6d52794b487a4f317938746c385145716f68534b304a6f5838472b62383264492b443548557767436a6f526e4233795333364f614765357364595a58794f44584a6d6e514262466d2f69315357326c304c4d744c6c314f4951705a366151537458487233446f704c63374c4d784770306c70794e66493138445832525a6c56536536356a6e70666432624766726b304b746b566f3656767a587536745962652f586c513836494f416f7a6755725a4e78416f725a63586d75432f74476a4957794b6b48557444427038336f447642796a76494a5835737671593442527154476549794d4c314c366763747571316b6e32436a5343736d426638646e53336375737065426d726a6158496f4831636b78314b503678735a49313056387341415661786d554b756b6a4b6338546742754e412b513663462f64397a734b4b476761323367556f516975436c7041786c4b576e6c677645474947576e65775645425166537a41705a4833617266693842434d373732385a6732736e41474d69704748625a7a44644278475062777845744778455a6b37426c635352364141547167545954324f707457304a724e514541793068714d5a412f3279627831756b4565496a4477784a695642465a75674e767439306c7135675936525a2b6f544444624f59497a6257485266684e4c4c6573616f49756952794b3955346645705a51417731565067553942596836495a3458517a6d7a664e476374527965697336676a2f715a79466766702b382f484a736235486a47542b70675a6543383066473374386e324a2f354856306c70502b72327a6a6366387562386e65695a43374f5a454a6f7a3446414173594d474373677774746750442b464b717233644e6875375a2b367730484e39774564365155783372582b336c726a57355644317866325a3568656d364f2b5161526a633961504876303130424150464e4e2b724d6e7035385a6e537136484d7a6a74356f6d6b4f48656f4841304a33727035745a7133482b71487a7030456946636a6952424b653762615932482b7247464d2b7a4c6d4c426d39326d7473534d31645957396c7a79676c32686648396c63755861356437315346596a32624d5257544256644152684e5674556567583834732b5a6b7a61316a787855636a784e62727142736f6b385a7a337a53414c4449376b335258767a783653384a2f72614156706c384d74647135616a653346717a6875366e527a5a56524b46776e52506d43712b584b6a773958715a574b466568697478496a2f4430566b53436c446d6570302f625944377749356a346d775067545336595a494a6e626575686d456b4f7a45644e554b786651747072686d56724b39376a33627a6b366a496b55376733384a4b454251724b702f54723052366c544c6b663838554f74313479546d5459615557303962335233314b6d34536846743732796a6f514e4854554a62395171677544305947643936464e4f50754d595168466576414f773055654c6c575557595432466e644b4c6e71575665564b58383571394372327246504467674c4c6830345846744a64504b655749627a6776423936432b584b4264624865536575534d444f36736a6f61616b3335736d48695862654e3361675a6556364762674b52494b2b7773302b6869354870342b5855794648376f2f705a6c716e50526a6b4d5a63693269714e41794b3472336b6479494271694a74352b43357152312b76704457517031783779584b38316f545670726a313752444559464d57394d39796a326d7251317052633954734965764d714e726e73694e73355763646c4e53356475584c707a61477a6d362f654c306e7a6e717039635050544b466676412f59783769796541387243617467777a77504a764d6c2b6c4f36794f2b4e6d584c784a656c75726259776b626548344d4d2b6441646a33347457726c6c794c572f7a6f38504e4c766c30554c7a68613979424259636456636249726f5665743572694262624d6b506345782f346c3972645579654464616e5a696a63646c374c512b58726c36353146335166376962635063665675413550732b486765584c47313373743947337547754f4d2b5a5430586350636d5a486672636f746f7669303473595646337a7a6c324478584a5851676c5554627230576e2f2b7a62564a70694f692b4a32754f4652794b7932544756692b504e44647552576d417a4470665532644f38316867377a70392f37744a7974427a6e724d63556d614a556d703151572f51726e6d68784b782f686c677159766359766b4e58662b582b4a48744a71754d4c71756e6f5038777050634f4c334276357a7036336c7850665653535a6b6a53583450316739613139686e3274645a2f79476931314e6731776343795a5333644c576e46414a76577a3953784377384f2b4d51793567534b376a54326867395070564a6a462b2b463262784b30624939433037367862786d30766531566366487856663745354e4d5a324f6368556c5438704f634d65654539334b6f2b6d4e575635492f692b5076492b2b347a79726a333133546156314d462b4b67613367422b61735450736f466a672f78334965534e436d706a367661682f787550717659433075552b754b626c757041364e624b3155756a636957377a306570647078714f365164615639634a6776694b632b467a447973653463334854667a3732774337595849454d382f5a56424a31354c4b494f4e2f4e76684c6d2b6639437a50544c38706e79527043777241426c2f4d713145357136565a4557596846734f65383461526d2f6a557433304b3163507976356a72777937434b44564342336e7a356866703677686641374553584e657955326d436a6435505449424d58543631636d6575794b3133706e6669436f73594833436e44587975726a786d79697a3951524a38783730496a4279303553412b5635754a342f674c50687a6a2b466b5146665a53374c634d4b44557a32502f2b6f5157435266335a3359353931444e3278715645594a7a54797973773655647770396a487547342f4876616564505a34656265596178324f627452394d556f7a7a454e375a766865376e52724736587932654e58714a64314574365a6d4e742b5a58582f63757a4d48594439376d3371502b476f5548686e576e2b757a2b7133746e6c4648592b2b5036497467422f686878617374686b5a724f4e3735726d77683455554f5359375434305071702f6a6e6a2f4f624a476d4d4a476d756235705a644332553464497a466f6b747835765a576d30784e7a6558356c3170466c62685955386f4831374538773868796f6477696432484c3763674c41746b6c47612b356d43724c754152463061784530755362634f664b6858764c71526b69646239516f4e717a6b4456696f454e776e35724969585466364e72464534496a596c555854474f57327a3737565953333657674f2f593243463668675737597134783637624c6139396b734f4b366b644662375561465239646f6d3165777439554c496269334e2b61744a313075622f376a704c324e49324c627a78713462323841316871634c482b76476176663971336e4867596637482b34772f7970674a2f4f6237415a44394e583151622b663653764c43594f39795442373856756965454155333072722f39664b784c446c45316244686849787a42796a474a7834773761663534357a574c7a67346f437334506d6e48485a47424c582b6e63766c322f3672446f365751396454374a656b426b6d3655573264396f6a5968564948314e7166777163543557536c332b384550683433793065734c74352f705876757763752b684d432f4a6345487631506a36484d79304d5938307041577a553853482f343741692b4578714e5755645a6749527530315a752f612b786d4c3146444b534a526f645058714a374151634d6a704156544753597656495a57344544327342666a535a423645577a76356933494f73435478446269636535517067443078733757615956364c4b3378745456703146354d47744c316c615968705358736d526a31486c6b45396f6b6f476c75496135796e675073644258594f384f6f56586e55756a6c6d77336c7531334d466d754c5247535774546b45724834546b41304c694d6c6755573652373269445a34336d7943416332387a3657726a4465634b3461624d4432474b4b4f427a43395449312f314453524a38677153457451583454577730587233683456324837536a4d6e49444d784a6f6757414b6a67617a2b4251794463687133754a2b4a55425668586c2b4a6c58796774634f6d7375623041686f58463770782b47414c4a35366c61474743636d5750696a4c39306e73437a7650394551576246554e644b4764614f75536e4e6f396e51437a657a33627161736b4e7747737a6e626c5a3668416362443534736d61567771314d4f7053315937553741554f493274384e43617a776f704d445661624b67744971434d6d6e79466c364e51327064515a63456b4865316c516478642b70484e64686430676c556d516376386d694c5653634349752b7a3578675250313048324e4d6a4e54335959624b4a304d584d4345653169786e69574464356c4f49414c66624d57656c797075516e39796e664f6f324632353254635938786b5566765a5a474461694a3459446f4b416279395246393842714f565938486757692b575752717a6c665a646b616f717764592f492b5543636b712b3231597150576b466641596455704b72714b78536d4e496e517777446a494d367935492f426744444e6f55726268636e755942452b6862414c64444d656854444e6a3066495055456d3651356f4e3130734e5a2b344b476c4f647059565433316836355251454c6b42377a79376857414856736a6e456f6e424641465754686b47646f4e5a6841635a4d356944594257526b4441747a5653735567425a3144416b46354b43544e465a636b6b41447756777a446764536e7570743565512f364741653064594a585a4239423376705948336665326c48676c6f54465241597451375957686a6b735772486765716156376f616d6650504f434d69776c31797a4e393768584f423654574e5649447153434e704a54564679747374733359764f304d4373794c497036514f486373497572624550552b30656161735a714a6b53776354444e4a626b565a4d594e456f5566784d487561465359715435776d326e777539576f303058796253536a66594f53467139782f7848554f54586e59626867617748524c4b65644d4565455372303637626b6c6b473636317947505a63487a38334f67646d4b464579627243734c305043304358774e5874456b32445745466e5151414d4765354355636d43344e5769506164446f4c563971563567556b69736a516242675556694b505a62756e67595343657942594159446e7047714753364a6d79592f424255457535796e6b617a596f41514a4c456b6d423553524a43586255776b4774614853576d424c7742346456557a634a49424964576271654a613141755a63737a524d4b4f3569756c5664787179597a556f4f326552372b52455a6d6566427a556c71534f4277334a396b3031554f4e7a7264565a6f587862733553655646316d6b6a4f4341675742726c724449673439306f31364b784d7873636c496e6b7a545354525a6b6b7955466c746d79704f536f6834443153646d754f5462464f4f4462733967616346642f374b4331545a622f4c434e4e6564517157476c5a6a5033782b6a305848306d4d70446453674e326834355157797364353736346252484d766658587a354f7876392f43472f2f364f2b7351443456344744516432613673593659494942346446687958386259646f4871685144366e714a4c7558392b424a4176675576476c3672797a45307a74414f4e4c6361485244446654716b36544332365946596656674f593449476c566d4437562f713230583861335559514e73395933426966692b382b314864786e7a70705661466c38646d4e6f54516133454741775669444376443257725a41433762473570483676476d7a57335837514e653965364932705432457a67784e714e69774541455a494569754a4542716168546a57646544726668537a6a5549774238414135464a4e4b65496f62785378465834484b525941706a6b65534f496b464a656e7378676a462b4b394b79346e3778434a734a78614f754d3664346a4d68787a78305835367a7a50744d674a7431366d5734477a32756141736662685162565a4c774c577873676d5a635768704e4f5042705176334868524367437849552f78624a6c5657723371736a7539635a785432445668474373324f5968666a456130794463666f67753741596369626f527865794570697050544e6d543766536148475a5a7a70454a764c574776634667745036652f376631636876644c694e7878316451507a4c6445707a74306a4c306542647133517a426d314b62457132366b367733482f684f685a4159766d42666d5379515075314e332b5046654c5754533977664b43456650426d695077344c4f64442f5479665a4e4e686f463331344a2f475730327055454e6c344e5346635751303159485453444574674d306e4a376d3252327668746945384c70746d5749532f7657527a375337674552456144434449636a635554795651366b38336c433556717264356f747471646271382f47434b36764d6c304e6c3873562b764e39766a4b44524749524e5366793458434c364b52436a462f4e6a2b6c534b5346647568414f715248556454344b5a345a457a4c584732664a356b36626d4a46526b6a48536572745a7a73386765716165705766724f5871756e71666e367756365961376b7a73794d527162696638786d6a78733965384c6e526c5a666b73733148796657367a76302f344157777143676648684647304b4c4b7476362f75553743716f727161365453744e584752394d6f7a737249496934506b45387558637767746672416f526d414a6138684a4366396f6a4c553253536430464a74674a53314451496b535042525a534143552b61436a564a6d4961534e67584746726f7130614b44676970386f643374716e6644626350377a764e454c71337a4749306a383146626b77467274526247374b4368552f6456622f33663650717164656f6552616c58764d71674c686b3d

Deployed Bytecode

0x60806040526004361061024f5760003560e01c8063944221d511610138578063d1db019a116100b0578063e8927fbc1161007f578063f2fde38b11610064578063f2fde38b14610671578063f4ed0f4614610691578063ff750ae3146106a757600080fd5b8063e8927fbc1461062e578063e985e9c51461063657600080fd5b8063d1db019a146105b5578063d732d955146105d5578063dc244a23146105dd578063dcb624bd146105f357600080fd5b8063a22cb46511610107578063b88d4fde116100ec578063b88d4fde14610562578063c87b56dd14610575578063d12a4c981461059557600080fd5b8063a22cb4651461052d578063a520e23c1461054d57600080fd5b8063944221d5146104b457806395d89b41146104e9578063a035b1fe146104fe578063a0712d681461051a57600080fd5b806347f57b32116101cb5780635ca2ddf11161019a57806370a082311161017f57806370a082311461047f578063715018a61461049f5780638da5cb5b1461039557600080fd5b80635ca2ddf11461043f5780636352211e1461045f57600080fd5b806347f57b32146103c05780634e67e779146103d55780634f4d61aa146103dd57806351cff8d91461041f57600080fd5b806318160ddd1161022257806323b872dd1161020757806323b872dd1461036f57806342842e0e1461038257806343bc16121461039557600080fd5b806318160ddd146103355780631a9ca8d21461035957600080fd5b806301ffc9a71461025457806306fdde0314610289578063081812fc146102ab578063095ea7b314610313575b600080fd5b34801561026057600080fd5b5061027461026f366004614bf4565b6106bc565b60405190151581526020015b60405180910390f35b34801561029557600080fd5b5061029e6107a1565b6040516102809190614c35565b3480156102b757600080fd5b506102ee6102c6366004614c86565b60036020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610280565b34801561031f57600080fd5b5061033361032e366004614cc1565b61082f565b005b34801561034157600080fd5b5061034b60075481565b604051908152602001610280565b34801561036557600080fd5b5061034b600f5481565b61033361037d366004614ced565b61097e565b610333610390366004614ced565b6109b4565b3480156103a157600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166102ee565b3480156103cc57600080fd5b50610333610b44565b610333610bd6565b3480156103e957600080fd5b50600e54610402906bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff9091168152602001610280565b34801561042b57600080fd5b5061033361043a366004614d2e565b610cf5565b34801561044b57600080fd5b5061029e61045a366004614c86565b610d8a565b34801561046b57600080fd5b506102ee61047a366004614c86565b610e35565b34801561048b57600080fd5b5061034b61049a366004614d2e565b610f04565b3480156104ab57600080fd5b50610333610f5d565b3480156104c057600080fd5b50600e54610402906c0100000000000000000000000090046bffffffffffffffffffffffff1681565b3480156104f557600080fd5b5061029e610f6f565b34801561050a57600080fd5b5061034b67016345785d8a000081565b610333610528366004614c86565b610f7c565b34801561053957600080fd5b50610333610548366004614d4b565b610ffa565b34801561055957600080fd5b50610274611091565b610333610570366004614d89565b6110bd565b34801561058157600080fd5b5061029e610590366004614c86565b611242565b3480156105a157600080fd5b5061029e6105b0366004614c86565b611426565b3480156105c157600080fd5b506103336105d0366004614f5e565b6114ca565b6103336115f4565b3480156105e957600080fd5b5061034b600d5481565b3480156105ff57600080fd5b5061061361060e366004614d2e565b611653565b60408051938452602084019290925290820152606001610280565b610333611701565b34801561064257600080fd5b506102746106513660046150d0565b600460209081526000928352604080842090915290825290205460ff1681565b34801561067d57600080fd5b5061033361068c366004614d2e565b61171f565b34801561069d57600080fd5b5061034b60085481565b3480156106b357600080fd5b506103336117d6565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061074f57507f80ac58cd000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b8061079b57507f5b5e139f000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b600180546107ae906150fe565b80601f01602080910402602001604051908101604052809291908181526020018280546107da906150fe565b80156108275780601f106107fc57610100808354040283529160200191610827565b820191906000526020600020905b81548152906001019060200180831161080a57829003601f168201915b505050505081565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1633811480610892575073ffffffffffffffffffffffffffffffffffffffff8116600090815260046020908152604080832033845290915290205460ff165b6108fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064015b60405180910390fd5b60008281526003602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff87811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6001810361099657610991838383611824565b505050565b602a81036109a957610991838383611824565b610991838383611a1e565b600181036109cc576109c7838383611824565b6109ea565b602a81036109df576109c7838383611824565b6109ea838383611a1e565b73ffffffffffffffffffffffffffffffffffffffff82163b1580610ade57506040517f150b7a020000000000000000000000000000000000000000000000000000000080825233600483015273ffffffffffffffffffffffffffffffffffffffff858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af1158015610a96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aba9190615151565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e540000000000000000000000000000000060448201526064016108f4565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b6857600080fd5b600b60005260056020527f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed554610bd49073ffffffffffffffffffffffffffffffffffffffff16610bcd60005473ffffffffffffffffffffffffffffffffffffffff1690565b600b611b11565b565b600760005260056020527feddb6698d7c569ff62ff64f1f1492bf14a54594835ba0faac91f84b4f5d814605473ffffffffffffffffffffffffffffffffffffffff16610c6357600d54341015610c58576040517f5dbd9b4100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bd4336007611c60565b600d54341115610cc35734600d556007600081905260056020527feddb6698d7c569ff62ff64f1f1492bf14a54594835ba0faac91f84b4f5d8146054610bd49173ffffffffffffffffffffffffffffffffffffffff909116903390611824565b6040517f5dbd9b4100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314610d1957600080fd5b60008173ffffffffffffffffffffffffffffffffffffffff164760405160006040518083038185875af1925050503d8060008114610d73576040519150601f19603f3d011682016040523d82523d6000602084013e610d78565b606091505b5050905080610d8657600080fd5b5050565b60606000610d9783611e14565b9050610e2e838260108054610dab906150fe565b80601f0160208091040260200160405190810160405280929190818152602001828054610dd7906150fe565b8015610e245780601f10610df957610100808354040283529160200191610e24565b820191906000526020600020905b815481529060010190602001808311610e0757829003601f168201915b5050505050612305565b9392505050565b6000602a8203610e46575041919050565b601682148015610e5e5750610e5c60024361519d565b155b80610e7e5750601f82148015610e7e5750610e7a60024361519d565b6001145b15610eb5576040517f184e367900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60038203610efb57610ec5611091565b610efb576040517fe188e19f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61079b82612322565b60004173ffffffffffffffffffffffffffffffffffffffff831603610f545773ffffffffffffffffffffffffffffffffffffffff821660009081526006602052604090205461079b9060016151e0565b61079b826123ae565b610f65612456565b610bd460006124d7565b600280546107ae906150fe565b600081118015610f8e57506008548111155b610f9757600080fd5b600060288214610faf5767016345785d8a0000610fc9565b610fc967016345785d8a0000670de0b6b3a76400006151e0565b9050803414610fd757600080fd5b610fe13383611c60565b60078054906000610ff1836151f3565b91905055505050565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6000806110a1620151804261519d565b9050617e9081101580156110b7575061ef108111155b91505090565b600183036110d5576110d0858585611824565b6110f3565b602a83036110e8576110d0858585611824565b6110f3858585611a1e565b73ffffffffffffffffffffffffffffffffffffffff84163b15806111d557506040517f150b7a02000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff86169063150b7a029061116e9033908a9089908990899060040161522b565b6020604051808303816000875af115801561118d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111b19190615151565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b61123b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f554e534146455f524543495049454e540000000000000000000000000000000060448201526064016108f4565b5050505050565b606060168214801561125c575061125a60024361519d565b155b8061127c5750601f8214801561127c575061127860024361519d565b6001145b156112b3576040517f184e367900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600382036112f9576112c3611091565b6112f9576040517fe188e19f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526005602052604090205473ffffffffffffffffffffffffffffffffffffffff16611384576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e4f545f4d494e5445440000000000000000000000000000000000000000000060448201526064016108f4565b600061138f83611e14565b9050610e2e8382601080546113a3906150fe565b80601f01602080910402602001604051908101604052809291908181526020018280546113cf906150fe565b801561141c5780601f106113f15761010080835404028352916020019161141c565b820191906000526020600020905b8154815290600101906020018083116113ff57829003601f168201915b505050505061254c565b6060600061143383611e14565b9050610e2e838260108054611447906150fe565b80601f0160208091040260200160405190810160405280929190818152602001828054611473906150fe565b80156114c05780601f10611495576101008083540402835291602001916114c0565b820191906000526020600020905b8154815290600101906020018083116114a357829003601f168201915b5050505050612606565b60005473ffffffffffffffffffffffffffffffffffffffff1633146114ee57600080fd5b60005b8151811015610d8657600082828151811061150e5761150e6152aa565b602090810291909101810151805160008181526009845260409081902083518155838501516001820155908301516002820155606083015180519395509193859391926115649260038501929190910190614b66565b5060808201518051611580916004840191602090910190614b66565b5060a0820151805161159c916005840191602090910190614b66565b5050825190505b602083015183516115b491906151e0565b8110156115de576000818152600a60205260409020829055806115d6816151f3565b9150506115a3565b50505080806115ec906151f3565b9150506114f1565b600e80546c0100000000000000000000000090046bffffffffffffffffffffffff1690600c611622836152d9565b91906101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606083901b166020820152600090819081908190603401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012090506116d3620186a08261519d565b93506116e6620186a0600883901c61519d565b92506116f8612710601083901c61519d565b93959294505050565b600e80546bffffffffffffffffffffffff169060006116228361531f565b611727612456565b73ffffffffffffffffffffffffffffffffffffffff81166117ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016108f4565b6117d3816124d7565b50565b602a600081905260056020527fd3e7a847b0e4be9f2ff1f88564b0a771bb9789c2c82f98679296a6042483791d54610bd49173ffffffffffffffffffffffffffffffffffffffff9091169041905b73ffffffffffffffffffffffffffffffffffffffff82166118a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f494e56414c49445f524543495049454e5400000000000000000000000000000060448201526064016108f4565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff848116911614611931576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f57524f4e475f46524f4d0000000000000000000000000000000000000000000060448201526064016108f4565b600061193e848484612613565b90508061194b5750505050565b73ffffffffffffffffffffffffffffffffffffffff808516600081815260066020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019055938716808352848320805460010190558683526005825284832080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081168317909155600390925284832080549092169091559251859392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a450505050565b3373ffffffffffffffffffffffffffffffffffffffff84161480611a72575073ffffffffffffffffffffffffffffffffffffffff8316600090815260046020908152604080832033845290915290205460ff165b80611aa0575060008181526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1633145b611b06576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016108f4565b610991838383611824565b73ffffffffffffffffffffffffffffffffffffffff8216611b8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f494e56414c49445f524543495049454e5400000000000000000000000000000060448201526064016108f4565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260066020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019055938616808352848320805460010190558583526005825284832080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081168317909155600390925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b73ffffffffffffffffffffffffffffffffffffffff8216611cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f494e56414c49445f524543495049454e5400000000000000000000000000000060448201526064016108f4565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1615611d69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f414c52454144595f4d494e54454400000000000000000000000000000000000060448201526064016108f4565b6000611d7760008484612613565b905080611d8357505050565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260066020908152604080832080546001019055858352600590915280822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905551849291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4505050565b611e506040518060c001604052806000815260200160008152602001600080191681526020016060815260200160608152602001606081525090565b6000828152600a602090815260408083205480845260098352818420825160c0810184528154815260018201548186015260028201548185015260038201805485518188028101880190965280865293969591949293606086019392830182828015611edb57602002820191906000526020600020905b815481526020019060010190808311611ec7575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020018280548015611f3357602002820191906000526020600020905b815481526020019060010190808311611f1f575b5050505050815260200160058201805480602002602001604051908101604052809291908181526020018280548015611f8b57602002820191906000526020600020905b815481526020019060010190808311611f77575b5050505050815250509050600784036120ab5760408051600180825281830190925260009160208083019080368337019050509050611fde670de0b6b3a7640000600d54611fd9919061534a565b613717565b612003600a67016345785d8a0000600d54611ff9919061534a565b611fd9919061519d565b600a662386f26fc10000600d5461201a919061534a565b612024919061519d565b1561204857612043600a662386f26fc10000600d54611ff9919061534a565b612059565b604051806020016040528060008152505b60405160200161206b9392919061537a565b6040516020818303038152906040526120839061543c565b81600081518110612096576120966152aa565b602090810291909101015260a0820152610e2e565b601184036120f057604080516001808252818301909252600091602080830190803683370190505090506120e0600f54613717565b60405160200161206b919061547e565b601b840361214457600e54612112906bffffffffffffffffffffffff16613717565b60405160200161212291906154c3565b60405160208183030381529060405261213a9061543c565b6040820152610e2e565b6013840361217657600e54612112906c0100000000000000000000000090046bffffffffffffffffffffffff16613717565b6003840361222e57604080516001808252818301909252600091602080830190803683370190505090506121a8611091565b6121e7576040518060400160405280600681526020017f436c6f736564000000000000000000000000000000000000000000000000000081525061221e565b6040518060400160405280600481526020017f4f70656e000000000000000000000000000000000000000000000000000000008152505b60405160200161206b91906154df565b60158403610e2e576040805160038082526080820190925260009160208201606080368337505050600086815260056020526040812054919250908190819061228c9073ffffffffffffffffffffffffffffffffffffffff16611653565b9194509250905061229c83613717565b6122a583613717565b6122ae83613717565b6040516020016122c093929190615524565b6040516020818303038152906040526122d89061543c565b846000815181106122eb576122eb6152aa565b602090810291909101015250505060a08201529392505050565b606061231a6123158585856137d9565b6138a9565b949350505050565b60008181526005602052604081205473ffffffffffffffffffffffffffffffffffffffff168061079b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e4f545f4d494e5445440000000000000000000000000000000000000000000060448201526064016108f4565b600073ffffffffffffffffffffffffffffffffffffffff821661242d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f5a45524f5f41444452455353000000000000000000000000000000000000000060448201526064016108f4565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604090205490565b60005473ffffffffffffffffffffffffffffffffffffffff163314610bd4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108f4565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60608060005b8460600151518110156125bb578161258686606001518381518110612579576125796152aa565b6020026020010151613911565b60405160200161259792919061559a565b604051602081830303815290604052915080806125b3906151f3565b915050612552565b506125fd856125cd8660400151613a5f565b836040516020016125de91906154c3565b6040516020818303038152906040526125f88989896137d9565b613a6a565b95945050505050565b606061231a8484846137d9565b600060098203612653576000805b62026db881101561264c5781612636816151f3565b9250508080612644906151f3565b915050612621565b505061370d565b60168214801561266b575061266960024361519d565b155b8061268b5750601f8214801561268b575061268760024361519d565b6001145b156126c2576040517f184e367900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602a82036126f15773ffffffffffffffffffffffffffffffffffffffff831641146126ec57600080fd5b61370d565b6003820361273757612701611091565b6126ec576040517fe188e19f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60048214806127465750601782145b806127515750602582145b8061275c5750602082145b806127675750600c82145b806127725750602482145b8061277d5750602382145b806127885750600882145b806127935750602982145b8061279e5750601282145b806127a95750601c82145b15612bab57606083901b60048314801561280457507fdead00000000000000000000000000000000beef0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b8061285b575060178314801561285b57507fbeef00000000000000000000000000000000beef0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b806128b257506025831480156128b257507ffeed00000000000000000000000000000000beef0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b80612909575060208314801561290957507fdeaf00000000000000000000000000000000beef0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b806129605750600c8314801561296057507fbad000000000000000000000000000000000beef0000000000000000000000007ffff000000000000000000000000000000000ffff0000000000000000000000008216145b806129b757506024831480156129b757507fbeef00000000000000000000000000000000face0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b80612a0e5750602383148015612a0e57507fbabe00000000000000000000000000000000beef0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b80612a655750600883148015612a6557507fbeef00000000000000000000000000000000babe0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b80612abc5750602983148015612abc57507fbad000000000000000000000000000000000babe0000000000000000000000007ffff000000000000000000000000000000000ffff0000000000000000000000008216145b80612b135750601283148015612b1357507fdeaf00000000000000000000000000000000babe0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b80612b6a5750601c83148015612b6a57507fdead00000000000000000000000000000000babe0000000000000000000000007fffff00000000000000000000000000000000ffff0000000000000000000000008216145b1515600003612ba5576040517f1a9e492700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5061370d565b600e8210158015612bbd575060108211155b15612dd3576000600e8314612bd357600e612bd6565b600f5b90506000600e8414612bf857600f8414612bf157600f612bfb565b6010612bfb565b60105b6000838152600b602052604090205490915043148015612c2857506000818152600b602052604090205443145b15612d725760008281526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1615612c9b57600082815260056020908152604080832054600c90925290912054612c969173ffffffffffffffffffffffffffffffffffffffff908116911684611b11565b612cca565b6000828152600c6020526040902054612cca9073ffffffffffffffffffffffffffffffffffffffff1683613bac565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1615612d3857600081815260056020908152604080832054600c90925290912054612d339173ffffffffffffffffffffffffffffffffffffffff908116911683611b11565b612d67565b6000818152600c6020526040902054612d679073ffffffffffffffffffffffffffffffffffffffff1682613bac565b600192505050610e2e565b5050506000818152600b60209081526040808320439055600c909152812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8516179055610e2e565b6018821480612de25750601982145b15612ef957600060188314612df8576018612dfb565b60195b9050611000612e0a81866155c9565b600083815260056020526040902054612e3c906110009073ffffffffffffffffffffffffffffffffffffffff166155c9565b612e4691906155fc565b73ffffffffffffffffffffffffffffffffffffffff16108015612ebe5750611000612e7981610fff609488901c166155c9565b600083815260056020526040902054612e9c906110009060941c610fff166155c9565b612ea691906155fc565b73ffffffffffffffffffffffffffffffffffffffff16105b1515600003612ba5576040517f70dd2b4600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005821480612f085750600682145b1561306557600060058314612f1e576005612f21565b60065b6000818152600560205260408120549192507fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606092831b169186901b905b602881101561305c576010612f76826004615630565b612fa891907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008516901c60601c6155c9565b73ffffffffffffffffffffffffffffffffffffffff166010612fcb836004615630565b612ffd91907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008716901c60601c6155c9565b73ffffffffffffffffffffffffffffffffffffffff160361304a576040517fa90de52900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80613054816151f3565b915050612f60565b5050505061370d565b601a82036131a157606083901b6000805b602881101561316e57601061308c826004615630565b6130be91907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008616901c60601c6155c9565b73ffffffffffffffffffffffffffffffffffffffff161561316e5760106130e6826004615630565b61311891907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008616901c60601c6155c9565b73ffffffffffffffffffffffffffffffffffffffff16600f03613143578161313f81615647565b9250505b600d8261ffff16111561315c5760019350505050610e2e565b80613166816151f3565b915050613076565b506040517f74279ff700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a82036132e057606083901b6000805b60288110156132ad5760106131c8826004615630565b6131fa91907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008616901c60601c6155c9565b73ffffffffffffffffffffffffffffffffffffffff16600f03156132ad576010613225826004615630565b61325791907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008616901c60601c6155c9565b73ffffffffffffffffffffffffffffffffffffffff16600003613282578161327e81615647565b9250505b600d8261ffff16111561329b5760019350505050610e2e565b806132a5816151f3565b9150506131b2565b506040517fc274dea700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602782036133b157606083901b6000805b602881101561337e576010613307826004615630565b61333991907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008616901c60601c6155c9565b73ffffffffffffffffffffffffffffffffffffffff166001901b821791508161ffff0361336c5760019350505050610e2e565b80613376816151f3565b9150506132f1565b506040517f76ea107a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600282036133f657823b6000819003612ba5576040517f6f7c43f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d820361341757823b801561340b57600080fd5b323314612ba557600080fd5b6011820361349d57600f541561344157600f80549060006134378361565e565b919050555061370d565b6011600081905260056020527fb4e18992ad424cdedc46668609f2bafcf665a8d99577618d5923c69264d9cf5f546134959173ffffffffffffffffffffffffffffffffffffffff9091169061dead90611b11565b506000610e2e565b6028820361353c57670de0b6b3a764000034101580156134d657506134d267016345785d8a0000670de0b6b3a76400006151e0565b3411155b6134df57600080fd5b6040516000908190670de0b6b3a7640000908281818185825af1925050503d8060008114613529576040519150601f19603f3d011682016040523d82523d6000602084013e61352e565b606091505b5050905080612ba557600080fd5b602282036135935773ffffffffffffffffffffffffffffffffffffffff831641146126ec576040517fc384d6a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601d820361370d57601d600090815260056020527f348e8fe0716b12afdd2e814ae0b8b1bb9b5c7a197ef418c73b8bdd93bee14de5547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606091821b16919085901b905b600381101561370957601061360d826003615693565b613618906028615693565b613623906004615630565b61365591907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008516901c60601c6155c9565b73ffffffffffffffffffffffffffffffffffffffff166010613678836004615630565b6136aa91907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008716901c60601c6155c9565b73ffffffffffffffffffffffffffffffffffffffff16146136f7576040517f4de772ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80613701816151f3565b9150506135f7565b5050505b5060019392505050565b60608160000361375a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b606e6040510190508060405260005b82156137ad577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90910190600101600a830660300180835350600a83049250613769565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909101908152919050565b6060600084600414806137ec5750846008145b806137f7575084600c145b806138025750846017145b8061380d5750846020145b806138185750846023145b806138235750846024145b8061382e5750846025145b90506125fd6040518060400160405280600381526020017f7376670000000000000000000000000000000000000000000000000000000000815250613871613d45565b8560405160200161388291906156a6565b60405160208183030381529060405261389a85613e72565b6138a48a8a613fad565b614111565b60606040518060400160405280601a81526020017f646174613a696d6167652f7376672b786d6c3b6261736536342c0000000000008152506138ea83614141565b6040516020016138fb92919061559a565b6040516020818303038152906040529050919050565b6040805160208082528183019092526060916000919060208201818036833701905050905060005b6020811015613a3657838160208110613954576139546152aa565b1a60f81b7fff00000000000000000000000000000000000000000000000000000000000000166000036139cc57602060f81b828281518110613998576139986152aa565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350613a24565b8381602081106139de576139de6152aa565b1a60f81b8282815181106139f4576139f46152aa565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b80613a2e816151f3565b915050613939565b5080604051602001613a4891906154c3565b604051602081830303815290604052915050919050565b606061079b82613911565b60606000613ab56040518060400160405280600781526020017f746f6b656e496400000000000000000000000000000000000000000000000000815250613ab088613717565b61431b565b613af46040518060400160405280600481526020017f6e616d65000000000000000000000000000000000000000000000000000000008152508761431b565b613b336040518060400160405280600b81526020017f6465736372697074696f6e0000000000000000000000000000000000000000008152508761431b565b613b756040518060400160405280600581526020017f696d616765000000000000000000000000000000000000000000000000000000815250613ab0886138a9565b604051602001613b8894939291906157aa565b6040516020818303038152906040529050613ba281614347565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8216613c29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f494e56414c49445f524543495049454e5400000000000000000000000000000060448201526064016108f4565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1615613cb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f414c52454144595f4d494e54454400000000000000000000000000000000000060448201526064016108f4565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260066020908152604080832080546001019055848352600590915280822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6060604051602001613e5e907f786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737681527f672220786d6c6e733a786c696e6b3d22687474703a2f2f7777772e77332e6f7260208201527f672f313939392f786c696e6b222077696474683d22313030252220686569676860408201527f743d2231303025222076696577426f783d22302030203531312036313922200060608201527f7072657365727665417370656374526174696f3d22784d6964594d6964206d65607f8201527f6574222000000000000000000000000000000000000000000000000000000000609f8201527f66696c6c3d226e6f6e652220000000000000000000000000000000000000000060a382015260af0190565b604051602081830303815290604052905090565b606061079b6040518060400160405280600481526020017f7265637400000000000000000000000000000000000000000000000000000000815250613fa86040518060400160405280600481526020017f31303025000000000000000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f313030250000000000000000000000000000000000000000000000000000000081525086613f5c576040518060400160405280600481526020017f2330303000000000000000000000000000000000000000000000000000000000815250613f93565b6040518060400160405280600781526020017f23424132323139000000000000000000000000000000000000000000000000008152505b60405180602001604052806000815250614388565b6143d2565b606060008083606001515111613fc4576000613fc7565b60325b60ff16836060015151601e613fdc9190615630565b613fe79060d76151e0565b613ff191906151e0565b90506000808460800151511161400857600061400b565b60325b60ff1684608001515160146140209190615630565b61402a90846151e0565b61403491906151e0565b90506125fd6040518060400160405280600181526020017f6700000000000000000000000000000000000000000000000000000000000000815250604051806020016040528060008152506140908760400151609b60006143e7565b6140a1886060015160d7600061457c565b6140b18960a0015187600061457c565b6140c18a6080015189600161457c565b6140fa6140cd8d613717565b6040516020016140dd91906154c3565b6040516020818303038152906040526140f59061543c565b6146ec565b61410c6141078e8e614869565b6148c6565b614a60565b6060613ba2868686868660405160200161412d93929190615891565b604051602081830303815290604052614a8f565b6060815160000361416057505060408051602081019091526000815290565b6000604051806060016040528060408152602001615f69604091399050600060038451600261418f91906151e0565b614199919061534a565b6141a4906004615630565b905060006141b38260206151e0565b67ffffffffffffffff8111156141cb576141cb614e28565b6040519080825280601f01601f1916602001820160405280156141f5576020820181803683370190505b509050818152600183018586518101602084015b818310156142635760039283018051603f601282901c811687015160f890811b8552600c83901c8216880151811b6001860152600683901c8216880151811b60028601529116860151901b93820193909352600401614209565b60038951066001811461427d57600281146142c75761430d565b7f3d3d0000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe83015261430d565b7f3d000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8301525b509398975050505050505050565b606082826040516020016143309291906158d4565b604051602081830303815290604052905092915050565b60606040518060400160405280601d81526020017f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000008152506138ea83614ac0565b606061439385614acb565b61439c85614acb565b6143a585614acb565b846040516020016143b9949392919061595e565b6040516020818303038152906040529050949350505050565b60608282604051602001614330929190615a66565b606061231a6040518060400160405280600481526020017f746578740000000000000000000000000000000000000000000000000000000081525061456e60405180604001604052806040518060400160405280600281526020017f3630000000000000000000000000000000000000000000000000000000000000815250815260200161447488613717565b9052856144b6576040518060400160405280600281526020017f32360000000000000000000000000000000000000000000000000000000000008152506144ed565b6040518060400160405280600281526020017f31340000000000000000000000000000000000000000000000000000000000008152505b6040518060400160405280601e81526020017f4e6f72772c2027436f7572696572204e6577272c206d6f6e6f737061636500008152506040518060400160405280600581526020017f776869746500000000000000000000000000000000000000000000000000000081525060405180602001604052806000815250614ade565b61457787613a5f565b614a8f565b60408051602081019091526000808252606091905b85518160ff1610156146e357816146b06040518060400160405280600481526020017f746578740000000000000000000000000000000000000000000000000000000081525061468b60405180604001604052806040518060400160405280600281526020017f363000000000000000000000000000000000000000000000000000000000000081525081526020016146498a61462f57601e614632565b60145b61463c9089615b11565b611fd99060ff168d6151e0565b9052886144b6576040518060400160405280600281526020017f32360000000000000000000000000000000000000000000000000000000000008152506144ed565b6145778a8660ff16815181106146a3576146a36152aa565b6020026020010151613a5f565b6040516020016146c192919061559a565b6040516020818303038152906040529150806146dc90615b2d565b9050614591565b50949350505050565b606061079b6040518060400160405280600481526020017f746578740000000000000000000000000000000000000000000000000000000081525061486060405180604001604052806040518060400160405280600281526020017f313200000000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600281526020017f33350000000000000000000000000000000000000000000000000000000000008152508152506040518060400160405280600281526020017f32360000000000000000000000000000000000000000000000000000000000008152506040518060400160405280601e81526020017f4e6f72772c2027436f7572696572204e6577272c206d6f6e6f737061636500008152506040518060400160405280600581526020017f776869746500000000000000000000000000000000000000000000000000000081525060405180602001604052806000815250614ade565b61457785613a5f565b8051600090819061487a9085615693565b6148859060016151e0565b905061489081613717565b61489d8460200151613717565b6040516020016148ae929190615b4c565b60405160208183030381529060405261231a9061543c565b606061079b6040518060400160405280600481526020017f746578740000000000000000000000000000000000000000000000000000000081525061486060405180604001604052806040518060400160405280600381526020017f343939000000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600381526020017f36303500000000000000000000000000000000000000000000000000000000008152508152506040518060400160405280600281526020017f32360000000000000000000000000000000000000000000000000000000000008152506040518060400160405280601e81526020017f4e6f72772c2027436f7572696572204e6577272c206d6f6e6f737061636500008152506040518060400160405280600581526020017f77686974650000000000000000000000000000000000000000000000000000008152506040518060400160405280601181526020017f746578742d616e63686f723d22656e6422000000000000000000000000000000815250614ade565b6060614a82898989898989898960405160200161412d96959493929190615ba4565b9998505050505050505050565b606083838386604051602001614aa89493929190615c23565b60405160208183030381529060405290509392505050565b606061079b82614141565b6060816040516020016138fb9190615d2b565b6060614af18660005b6020020151614acb565b614afc876001614ae7565b614b2487604051602001614b109190615d97565b604051602081830303815290604052614acb565b614b2d87614acb565b614b3687614acb565b86604051602001614b4c96959493929190615dd8565b604051602081830303815290604052905095945050505050565b828054828255906000526020600020908101928215614ba1579160200282015b82811115614ba1578251825591602001919060010190614b86565b50614bad929150614bb1565b5090565b5b80821115614bad5760008155600101614bb2565b7fffffffff00000000000000000000000000000000000000000000000000000000811681146117d357600080fd5b600060208284031215614c0657600080fd5b8135610e2e81614bc6565b60005b83811015614c2c578181015183820152602001614c14565b50506000910152565b6020815260008251806020840152614c54816040850160208701614c11565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600060208284031215614c9857600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146117d357600080fd5b60008060408385031215614cd457600080fd5b8235614cdf81614c9f565b946020939093013593505050565b600080600060608486031215614d0257600080fd5b8335614d0d81614c9f565b92506020840135614d1d81614c9f565b929592945050506040919091013590565b600060208284031215614d4057600080fd5b8135610e2e81614c9f565b60008060408385031215614d5e57600080fd5b8235614d6981614c9f565b915060208301358015158114614d7e57600080fd5b809150509250929050565b600080600080600060808688031215614da157600080fd5b8535614dac81614c9f565b94506020860135614dbc81614c9f565b935060408601359250606086013567ffffffffffffffff80821115614de057600080fd5b818801915088601f830112614df457600080fd5b813581811115614e0357600080fd5b896020828501011115614e1557600080fd5b9699959850939650602001949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715614e7a57614e7a614e28565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614ec757614ec7614e28565b604052919050565b600067ffffffffffffffff821115614ee957614ee9614e28565b5060051b60200190565b600082601f830112614f0457600080fd5b81356020614f19614f1483614ecf565b614e80565b82815260059290921b84018101918181019086841115614f3857600080fd5b8286015b84811015614f535780358352918301918301614f3c565b509695505050505050565b60006020808385031215614f7157600080fd5b823567ffffffffffffffff80821115614f8957600080fd5b818501915085601f830112614f9d57600080fd5b8135614fab614f1482614ecf565b81815260059190911b83018401908481019088831115614fca57600080fd5b8585015b838110156150c357803585811115614fe557600080fd5b860160c0818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001121561501a5760008081fd5b615022614e57565b8882013581526040808301358a830152606080840135828401526080915081840135898111156150525760008081fd5b6150608f8d83880101614ef3565b82850152505060a0808401358981111561507a5760008081fd5b6150888f8d83880101614ef3565b838501525060c08401359150888211156150a25760008081fd5b6150b08e8c84870101614ef3565b9083015250845250918601918601614fce565b5098975050505050505050565b600080604083850312156150e357600080fd5b82356150ee81614c9f565b91506020830135614d7e81614c9f565b600181811c9082168061511257607f821691505b60208210810361514b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561516357600080fd5b8151610e2e81614bc6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826151ac576151ac61516e565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561079b5761079b6151b1565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615224576152246151b1565b5060010190565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525084604083015260806060830152826080830152828460a0840137600060a0848401015260a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011683010190509695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006bffffffffffffffffffffffff8216806152f7576152f76151b1565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b60006bffffffffffffffffffffffff808316818103615340576153406151b1565b6001019392505050565b6000826153595761535961516e565b500490565b60008151615370818560208601614c11565b9290920192915050565b7f50726963653a20000000000000000000000000000000000000000000000000008152600084516153b2816007850160208901614c11565b7f2e0000000000000000000000000000000000000000000000000000000000000060079184019182015284516153ef816008840160208901614c11565b8451910190615405816008840160208801614c11565b7f204554480000000000000000000000000000000000000000000000000000000060089290910191820152600c0195945050505050565b8051602080830151919081101561514b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b7f5472616e7366657273204c6566743a20000000000000000000000000000000008152600082516154b6816010850160208701614c11565b9190910160100192915050565b600082516154d5818460208701614c11565b9190910192915050565b7f43757272656e746c79200000000000000000000000000000000000000000000081526000825161551781600a850160208701614c11565b91909101600a0192915050565b60008451615536818460208901614c11565b80830190507f2c200000000000000000000000000000000000000000000000000000000000008082528551615572816002850160208a01614c11565b6002920191820152835161558d816004840160208801614c11565b0160040195945050505050565b600083516155ac818460208801614c11565b8351908301906155c0818360208801614c11565b01949350505050565b600073ffffffffffffffffffffffffffffffffffffffff808416806155f0576155f061516e565b92169190910692915050565b73ffffffffffffffffffffffffffffffffffffffff818116838216019080821115615629576156296151b1565b5092915050565b808202811582820484141761079b5761079b6151b1565b600061ffff808316818103615340576153406151b1565b60008161566d5761566d6151b1565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b8181038181111561079b5761079b6151b1565b7f3c646566733e3c7374796c653e0000000000000000000000000000000000000081527f40666f6e742d66616365207b666f6e742d66616d696c793a20224e6f7277223b600d8201527f7372633a2075726c282200000000000000000000000000000000000000000000602d8201526000825161572a816037850160208701614c11565b7f22293b7d0000000000000000000000000000000000000000000000000000000060379390910192830152507f74657874207b746578742d7472616e73666f726d3a207570706572636173653b603b8201527f7d3c2f7374796c653e3c2f646566733e00000000000000000000000000000000605b820152606b01919050565b7f7b000000000000000000000000000000000000000000000000000000000000008152600085516157e2816001850160208a01614c11565b80830190507f2c000000000000000000000000000000000000000000000000000000000000008060018301528651615821816002850160208b01614c11565b60029201918201819052855161583e816003850160208a01614c11565b60039201918201528351615859816004840160208801614c11565b7f7d00000000000000000000000000000000000000000000000000000000000000600492909101918201526005019695505050505050565b600084516158a3818460208901614c11565b8451908301906158b7818360208901614c11565b84519101906158ca818360208801614c11565b0195945050505050565b60007f2200000000000000000000000000000000000000000000000000000000000000808352845161590d816001860160208901614c11565b7f223a220000000000000000000000000000000000000000000000000000000000600191850191820152845161594a816004840160208901614c11565b016004810191909152600501949350505050565b7f77696474683d0000000000000000000000000000000000000000000000000000815260008551615996816006850160208a01614c11565b7f6865696768743d0000000000000000000000000000000000000000000000000060069184019182015285516159d381600d840160208a01614c11565b7f66696c6c3d000000000000000000000000000000000000000000000000000000600d92909101918201528451615a11816012840160208901614c11565b8082019150507f20000000000000000000000000000000000000000000000000000000000000008060128301528451615a51816013850160208901614c11565b60139201918201526014019695505050505050565b7f3c00000000000000000000000000000000000000000000000000000000000000815260008351615a9e816001850160208801614c11565b7f20000000000000000000000000000000000000000000000000000000000000006001918401918201528351615adb816002840160208801614c11565b7f2f3e00000000000000000000000000000000000000000000000000000000000060029290910191820152600401949350505050565b60ff8181168382160290811690818114615629576156296151b1565b600060ff821660ff8103615b4357615b436151b1565b60010192915050565b60008351615b5e818460208801614c11565b7f206f6620000000000000000000000000000000000000000000000000000000009083019081528351615b98816004840160208801614c11565b01600401949350505050565b600087516020615bb78285838d01614c11565b885191840191615bca8184848d01614c11565b8851920191615bdc8184848c01614c11565b8751920191615bee8184848b01614c11565b8651920191615c008184848a01614c11565b8551920191615c128184848901614c11565b919091019998505050505050505050565b7f3c00000000000000000000000000000000000000000000000000000000000000815260008551615c5b816001850160208a01614c11565b7f20000000000000000000000000000000000000000000000000000000000000006001918401918201528551615c98816002840160208a01614c11565b8082019150507f3e000000000000000000000000000000000000000000000000000000000000008060028301528551615cd8816003850160208a01614c11565b7f3c2f000000000000000000000000000000000000000000000000000000000000600393909101928301528451615d16816005850160208901614c11565b60059201918201526006019695505050505050565b7f2200000000000000000000000000000000000000000000000000000000000000815260008251615d63816001850160208701614c11565b7f22200000000000000000000000000000000000000000000000000000000000006001939091019283015250600301919050565b60008251615da9818460208701614c11565b7f7078000000000000000000000000000000000000000000000000000000000000920191825250600201919050565b7f783d000000000000000000000000000000000000000000000000000000000000815260008751615e10816002850160208c01614c11565b7f793d0000000000000000000000000000000000000000000000000000000000006002918401918201528751615e4d816004840160208c01614c11565b7f666f6e742d73697a653d00000000000000000000000000000000000000000000600492909101918201528651615e8b81600e840160208b01614c11565b7f666f6e742d66616d696c793d0000000000000000000000000000000000000000600e92909101918201528551615ec981601a840160208a01614c11565b01615ef6601a82017f66696c6c3d0000000000000000000000000000000000000000000000000000009052565b615f03601f82018661535e565b7f200000000000000000000000000000000000000000000000000000000000000081529050615f35600182018561535e565b7f20000000000000000000000000000000000000000000000000000000000000008152600101999850505050505050505056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa264697066735822122070f18396ebf9b3bdc664dd05e66b332952b27e097d156a1e9455993b1ec7b70064736f6c63430008120033

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ 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.