ETH Price: $3,381.18 (+4.52%)
Gas: 3 Gwei

Contract

0x5DcE0bB0778694Ef3Ba79Bb702b88CAC1879cc7D
 

Overview

ETH Balance

0.883225 ETH

Eth Value

$2,986.34 (@ $3,381.18/ETH)

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Approval For...180971662023-09-09 6:50:59324 days ago1694242259IN
0x5DcE0bB0...C1879cc7D
0 ETH0.00055519.35827187
Water180971472023-09-09 6:47:11324 days ago1694242031IN
0x5DcE0bB0...C1879cc7D
0 ETH0.00036529.12363248
Set Approval For...177812362023-07-27 1:49:35368 days ago1690422575IN
0x5DcE0bB0...C1879cc7D
0 ETH0.001127119.00141741
Set Approval For...175864812023-06-29 17:36:11395 days ago1688060171IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0037755263.65000758
Set Approval For...175497982023-06-24 13:52:59400 days ago1687614779IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0007260612.24038056
Water173383152023-05-25 19:44:47430 days ago1685043887IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0014485633.46199893
Water173013382023-05-20 14:49:59435 days ago1684594199IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0014546133.60156666
Water172885632023-05-18 19:38:11437 days ago1684438691IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0032661275.44744819
Water172846202023-05-18 6:20:47438 days ago1684390847IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0015946536.83645658
Water172712122023-05-16 8:54:11440 days ago1684227251IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0018056641.71571325
Water172479232023-05-13 1:51:35443 days ago1683942695IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0020959348.42168718
Water172330212023-05-10 22:40:35445 days ago1683758435IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0033772278.02300619
Water172291692023-05-10 9:39:23446 days ago1683711563IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0025324658.50686315
Water171940852023-05-05 11:18:47450 days ago1683285527IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0030299570
Water171827942023-05-03 21:15:23452 days ago1683148523IN
0x5DcE0bB0...C1879cc7D
0 ETH0.003222974.45773882
Water171827912023-05-03 21:14:47452 days ago1683148487IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0028385865.57889591
Water171769912023-05-03 1:38:11453 days ago1683077891IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0034503379.71213854
Water171758132023-05-02 21:40:11453 days ago1683063611IN
0x5DcE0bB0...C1879cc7D
0 ETH0.00433073100.0517462
Water171724862023-05-02 10:26:35453 days ago1683023195IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0027076262.5533723
Water171494432023-04-29 4:41:23457 days ago1682743283IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0011977830
Water171493842023-04-29 4:29:35457 days ago1682742575IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0011977830
Water171343602023-04-27 1:49:35459 days ago1682560175IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0015455935.70738361
Water171263942023-04-25 22:58:47460 days ago1682463527IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0016545838.22534131
Water171263912023-04-25 22:58:11460 days ago1682463491IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0016735838.66423081
Water171248542023-04-25 17:47:35460 days ago1682444855IN
0x5DcE0bB0...C1879cc7D
0 ETH0.0016313637.68891023
View all transactions

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To
162350862022-12-21 19:12:23585 days ago1671649943
0x5DcE0bB0...C1879cc7D
 Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
BonsaiMaker

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-12-21
*/

// SPDX-License-Identifier: VPL - VIRAL PUBLIC LICENSE
pragma solidity ^0.8.13;

/*
*  bbbbbbbb                                                                              
*  b::::::b                                                  
*  b::::::b                                                
*  b::::::b                                               
*   b:::::b                                               
*   b:::::bbbbbbbbb       ooooooooooo   nnnn  nnnnnnnn      
*   b::::::::::::::bb   oo:::::::::::oo n:::nn::::::::nn    
*   b::::::::::::::::b o:::::::::::::::on::::::::::::::nn    
*   b:::::bbbbb:::::::bo:::::ooooo:::::onn:::::::::::::::n    
*   b:::::b    b::::::bo::::o     o::::o  n:::::nnnn:::::n      
*   b:::::b     b:::::bo::::o     o::::o  n::::n    n::::n  
*   b:::::b     b:::::bo::::o     o::::o  n::::n    n::::n  
*   b:::::b     b:::::bo::::o     o::::o  n::::n    n::::n
*   b:::::bbbbbb::::::bo:::::ooooo:::::o  n::::n    n::::n
*   b::::::::::::::::b o:::::::::::::::o  n::::n    n::::n
*   b:::::::::::::::b   oo:::::::::::oo   n::::n    n::::n
*   bbbbbbbbbbbbbbbb      ooooooooooo     nnnnnn    nnnnnn
*                         SSSSSSSSSSSSSSS              AAA               IIIIIIIIII
*                       SS:::::::::::::::S            A:::A              I::::::::I
*                      S:::::SSSSSS::::::S           A:::::A             I::::::::I
*                      S:::::S     SSSSSSS          A:::::::A            II::::::II
*                      S:::::S                     A:::::::::A             I::::I  
*                      S:::::S                    A:::::A:::::A            I::::I  
*                       S::::SSSS                A:::::A A:::::A           I::::I  
*                        SS::::::SSSSS          A:::::A   A:::::A          I::::I  
*                          SSS::::::::SS       A:::::A     A:::::A         I::::I  
*                             SSSSSS::::S     A:::::AAAAAAAAA:::::A        I::::I  
*                                  S:::::S   A:::::::::::::::::::::A       I::::I  
*                                  S:::::S  A:::::AAAAAAAAAAAAA:::::A      I::::I  
*                      SSSSSSS     S:::::S A:::::A             A:::::A   II::::::II
*                      S::::::SSSSSS:::::SA:::::A               A:::::A  I::::::::I
*                      S:::::::::::::::SSA:::::A                 A:::::A I::::::::I
*                       SSSSSSSSSSSSSSS AAAAAAA                   AAAAAAAIIIIIIIIII
*
*
*   Living Collectibles
*
*   The first dispatch from NO_SIDE
*    
*    
*                                            @@@@                                    
*                                       ,@@@@@@@@%,@@@@@                             
*                                     /@@@@@@@@@@@@@@@@@@@.                          
*                                    @@@@@@@@@@@@@@@@@@@@@@&                         
*                                   @@@@@@@@@@@@@@@@@@@@@@@@*                        
*                                  @@@@@@@@@@@@@@@@@@@@@@@@@@                        
*                                  @@@@@@@@@@@@@@@@@@@@@@@@@@                        
*         *%@@@@@@@@@@@@%          @@@@@@@@@@@@@@@@@@@@@@@@@@                        
*       @@@@@@@@@@@@@@@@@@@@@*     @@@@@@@@@@@@@@@@@@@@@@@@@*                        
*         @@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@@@@@@@@@@@@@@@@@&                         
*    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@(@@@@@@@@@@@@@@@@@@@@@@@       ((%@@@(((          
*    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&%@@@@@@@@@@@@@@@@@@@@@%    
*    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 
*     &@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&    &@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@. 
*       @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@(  .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@(
*         (@@@@@@@@@@@@@@@@@@@@@@@@.   /@@@@@@@@.    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
*             *@@@@@@@@@@@@@@@@@@@@/   @@@@@@@@@@  ,@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 
*                       %%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@(  
*                   .&@@@@@@@@@@@@@@@     @@@@    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*    
*               ,@@@@@@@@@@@@@@@@@@@@@%*@@@@@@.  ,@@@@@@@@@@@@@@@@@@@@@@@@@@,        
*             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                      
*           @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@,                   
*         ,@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@/                 
*         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                
*        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@@@@@@@@@@@@@@@@@@@@@               
*        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   @@@@@@@@@@@@@@@@@@@@@@@@@@@@#              
*        @@@@@@@@@@@@@@@@@@@@@@@@@@@@      @@@@@@@@@@@@@@@@@@@@@@@@@@@@              
*         ,,, &@@@@@@@@@@@@@@@@@@@@         @@@@@@@@@@@@@@@@@@@@@@@@@@@              
*            &@@@@@@@@@@@@@@@@@/              @@@@@@@@@@@@@@@@@@@@@@@@(              
*               ,%@@@@@@@%                      @@@@@@@@@@@@@@@@@@@@@@               
*                                                 *@@@@@@@@@@@@@/(@@%                
*                                                     .@@@@@@@@@                     
*    
*    
*        
* bonSAI Living Collectibles is a limited, generative art collection living entirely "in-chain". 
* Each piece requires a prescribed amount of care to reach its full potential. 
*
* Mint your bonSAI via the payable external
*
*     `mint(address to)` 
*
* function including ETH value as a multiple of PRICE_PER_TOKEN = 0.0721 ether. This multiple
* determines the quantity minted and is capped by MAX_QTY.
* 
* Both bots and humans can mint these pieces, however the humans have access to a greater 
* range of plants with rarer qualities.
*
* There is a `freeMint` available for a limited run. Read the smart contract for details.
*
* The bonSAI is best viewed on https://www.nftviewer.xyz/ or https://opensea.io.
* Note: The bonSAI's appearance changes as it grows, with about 36 new sprouts per day. 
*   At this rate, changes are noticeable after about a day. To view changes from 
*   this growth, you may need to click "refresh metadata" on the OpenSea 
*   profile of your bonsai.
* 
* Once minted, the bonSAI must be watered weekly until about 6 weeks when it reaches 
* maturity, otherwise it will dry out and die.
* 
*   - To water a bonSAI call the `water(uint256 tokenId)` external function.
*     The caller only pays for gas. See etherscan history for idea of watering gas cost.
* 
* The form, ratio, and growth steps, are unique to each bonSAI where some may even grow blossoms. 
* At any point, a bonSAI owner can influence their piece by pruning to varying degrees.
* Of course, pruning is not necessary if you are satisfied with the original growth pattern 
* of your plant.
* Pruning changes the growth steps which can give more aesthetic branching, body, and may 
* even induce blossoming. Note that pruning extends the watering and maturation period 
* proportionally. Also pruning is restricted to the range above and cannot affect the 
* trunk or first layer of branching. These caveats aside, a plain bonSAI can be sculpted 
* to a striking beauty with just a few clips.
*
* The PRUNE_COST_PER_DEGREE is PRICE_PER_TOKEN/4, aka 0.018025 ether.  
*   - To prune a bonSAI call the `prune(uint256 tokenId)` payable external function with eth value
*       1 * PRUNE_COST_PER_DEGREE for LOW
*       2 * PRUNE_COST_PER_DEGREE for MEDIUM
*       3 * PRUNE_COST_PER_DEGREE for HIGH PruningDegrees
* 
* Your bonSAI's latest growth is rendered "in-chain" in real-time via the standard 
* 
*     `tokenURI(uint256 tokenId)` 
* 
* external view function returning a JSON array with latest attributes and svg image. 
* 
* Be sure to call this `tokenURI` view function using `callStatic`.
* 
* Keep posted for other upcoming projects from our group.
* 
*     - NO_SIDE
* 
**/

/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)
abstract contract ERC721 {
    /*//////////////////////////////////////////////////////////////
                                 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);

    /*//////////////////////////////////////////////////////////////
                         METADATA STORAGE/LOGIC
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

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

    /*//////////////////////////////////////////////////////////////
                      ERC721 BALANCE/OWNER STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(uint256 => address) internal _ownerOf;

    mapping(address => uint256) internal _balanceOf;

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

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

        return _balanceOf[owner];
    }

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

    mapping(uint256 => address) public getApproved;

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

    /*//////////////////////////////////////////////////////////////
                               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 {
        require(from == _ownerOf[id], "WRONG_FROM");

        require(to != address(0), "INVALID_RECIPIENT");

        require(
            msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],
            "NOT_AUTHORIZED"
        );

        // 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 {
        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 virtual {
        transferFrom(from, to, id);

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

    /*//////////////////////////////////////////////////////////////
                              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");

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

        _ownerOf[id] = to;

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

    function _burn(uint256 id) internal virtual {
        address owner = _ownerOf[id];

        require(owner != address(0), "NOT_MINTED");

        // Ownership check above ensures no underflow.
        unchecked {
            _balanceOf[owner]--;
        }

        delete _ownerOf[id];

        delete getApproved[id];

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

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

    function _safeMint(address to, uint256 id) internal virtual {
        _mint(to, id);

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

    function _safeMint(
        address to,
        uint256 id,
        bytes memory data
    ) internal virtual {
        _mint(to, id);

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

/// @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;
    }
}

interface IOperatorFilterRegistry {
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);
    function register(address registrant) external;
    function registerAndSubscribe(address registrant, address subscription) external;
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;
    function unregister(address addr) external;
    function updateOperator(address registrant, address operator, bool filtered) external;
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
    function subscribe(address registrant, address registrantToSubscribe) external;
    function unsubscribe(address registrant, bool copyExistingEntries) external;
    function subscriptionOf(address addr) external returns (address registrant);
    function subscribers(address registrant) external returns (address[] memory);
    function subscriberAt(address registrant, uint256 index) external returns (address);
    function copyEntriesOf(address registrant, address registrantToCopy) external;
    function isOperatorFiltered(address registrant, address operator) external returns (bool);
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
    function filteredOperators(address addr) external returns (address[] memory);
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
    function isRegistered(address addr) external returns (bool);
    function codeHashOf(address addr) external returns (bytes32);
}

/**
 * @title  OperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 */
abstract contract OperatorFilterer {
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

    constructor(address subscriptionOrRegistrantToCopy, bool subscribe) {
        // If an inheriting token contract is deployed to a network without the registry deployed, the modifier
        // will not revert, but the contract will need to be registered with the registry once it is deployed in
        // order for the modifier to filter addresses.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (subscribe) {
                OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
                } else {
                    OPERATOR_FILTER_REGISTRY.register(address(this));
                }
            }
        }
    }

    modifier onlyAllowedOperator(address from) virtual {
        // Allow spending tokens from addresses with balance
        // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
        // from an EOA.
        if (from != msg.sender) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    function _checkFilterOperator(address operator) internal view virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}

/**
 * @title  DefaultOperatorFilterer
 * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription.
 */
abstract contract DefaultOperatorFilterer is OperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {}
}

abstract contract OperatorFilteredERC721 is ERC721, DefaultOperatorFilterer {

    constructor(
        string memory name_,
        string memory symbol_
    ) ERC721(name_, symbol_) {}

    // overrides for DefaultOperatorFilterer, which enables creator fees on opensea

    function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {
        super.setApprovalForAll(operator, approved);
    }

    function approve(address operator, uint256 tokenId) public override onlyAllowedOperatorApproval(operator) {
        super.approve(operator, tokenId);
    }

    function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) {
        super.transferFrom(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) {
        super.safeTransferFrom(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data)
        public
        override
        onlyAllowedOperator(from)
    {
        super.safeTransferFrom(from, to, tokenId, data);
    }
}

enum PruneDegrees {NONE, LOW, MEDIUM, HIGH}

enum HealthStatus {OK, DRY, DEAD}

struct BonsaiProfile {
    uint256 modifiedSteps;

    uint64 adjustedStartTime;
    uint64 ratio;
    uint32 seed;
    uint8 trunkSVGNumber;

    uint64 lastWatered;
}

struct WateringStatus {
    uint64 lastWatered; 
    HealthStatus healthStatus;
    string status;
}

struct Vars {
    uint256 layer;
    uint256 strokeWidth;
    bytes32[12] gradients;
}

struct RawAttributes {
    bytes32 backgroundColor;
    bytes32 blossomColor;
    bytes32 wateringStatus;

    uint32 seed;
    uint64 ratio;
    uint64 adjustedStartTime;
    uint64 lastWatered;
    uint8 trunkSVGNumber;
    HealthStatus healthStatus;

    uint256[] modifiedSteps;
}

interface IBonsaiRenderer {
    function numTrunks() external view returns(uint256);
    function renderForHumans(uint256 tokenId) external view returns(string memory);
    function renderForRobots(uint256 tokenId) external view returns(RawAttributes memory);
}

interface IBonsaiState {
    function getBonsaiProfile(uint256 tokenId) external view returns(BonsaiProfile memory);
    function initializeBonsai(uint256 tokenId, bool mayBeBot) external;
    function water(uint256 tokenId) external returns(WateringStatus memory);
    function wateringStatus(uint256 tokenId) external view returns(WateringStatus memory);
    function wateringStatusForRender(uint64 lastWatered, uint64 adjustedStartTime, bool watering) external view returns(WateringStatus memory ws);
    function prune(uint256 tokenId, PruneDegrees degree) external;
}

/// @notice Library to encode strings in Base64.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/Base64.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Base64.sol)
/// @author Modified from (https://github.com/Brechtpd/base64/blob/main/base64.sol) by Brecht Devos - <[email protected]>.
library Base64 {
    /// @dev Encodes `data` using the base64 encoding described in RFC 4648.
    /// See: https://datatracker.ietf.org/doc/html/rfc4648
    /// @param fileSafe  Whether to replace '+' with '-' and '/' with '_'.
    /// @param noPadding Whether to strip away the padding.
    function encode(bytes memory data, bool fileSafe, bool noPadding)
        internal
        pure
        returns (string memory result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let dataLength := mload(data)

            if dataLength {
                // Multiply by 4/3 rounded up.
                // The `shl(2, ...)` is equivalent to multiplying by 4.
                let encodedLength := shl(2, div(add(dataLength, 2), 3))

                // Set `result` to point to the start of the free memory.
                result := mload(0x40)

                // Store the table into the scratch space.
                // Offsetted by -1 byte so that the `mload` will load the character.
                // We will rewrite the free memory pointer at `0x40` later with
                // the allocated size.
                // The magic constant 0x0230 will translate "-_" + "+/".
                mstore(0x1f, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef")
                mstore(0x3f, sub("ghijklmnopqrstuvwxyz0123456789-_", mul(iszero(fileSafe), 0x0230)))

                // Skip the first slot, which stores the length.
                let ptr := add(result, 0x20)
                let end := add(ptr, encodedLength)

                // Run over the input, 3 bytes at a time.
                for {} 1 {} {
                    data := add(data, 3) // Advance 3 bytes.
                    let input := mload(data)

                    // Write 4 bytes. Optimized for fewer stack operations.
                    mstore8(ptr, mload(and(shr(18, input), 0x3F)))
                    mstore8(add(ptr, 1), mload(and(shr(12, input), 0x3F)))
                    mstore8(add(ptr, 2), mload(and(shr(6, input), 0x3F)))
                    mstore8(add(ptr, 3), mload(and(input, 0x3F)))

                    ptr := add(ptr, 4) // Advance 4 bytes.

                    if iszero(lt(ptr, end)) { break }
                }

                let r := mod(dataLength, 3)

                switch noPadding
                case 0 {
                    // Offset `ptr` and pad with '='. We can simply write over the end.
                    mstore8(sub(ptr, iszero(iszero(r))), 0x3d) // Pad at `ptr - 1` if `r > 0`.
                    mstore8(sub(ptr, shl(1, eq(r, 1))), 0x3d) // Pad at `ptr - 2` if `r == 1`.
                    // Write the length of the string.
                    mstore(result, encodedLength)
                }
                default {
                    // Write the length of the string.
                    mstore(result, sub(encodedLength, add(iszero(iszero(r)), eq(r, 1))))
                }

                // Allocate the memory for the string.
                // Add 31 and mask with `not(31)` to round the
                // free memory pointer up the next multiple of 32.
                mstore(0x40, and(add(end, 31), not(31)))
            }
        }
    }

    /// @dev Encodes `data` using the base64 encoding described in RFC 4648.
    /// Equivalent to `encode(data, false, false)`.
    function encode(bytes memory data) internal pure returns (string memory result) {
        result = encode(data, false, false);
    }

    /// @dev Encodes `data` using the base64 encoding described in RFC 4648.
    /// Equivalent to `encode(data, fileSafe, false)`.
    function encode(bytes memory data, bool fileSafe)
        internal
        pure
        returns (string memory result)
    {
        result = encode(data, fileSafe, false);
    }

    /// @dev Encodes base64 encoded `data`.
    ///
    /// Supports:
    /// - RFC 4648 (both standard and file-safe mode).
    /// - RFC 3501 (63: ',').
    ///
    /// Does not support:
    /// - Line breaks.
    ///
    /// Note: For performance reasons,
    /// this function will NOT revert on invalid `data` inputs.
    /// Outputs for invalid inputs will simply be undefined behaviour.
    /// It is the user's responsibility to ensure that the `data`
    /// is a valid base64 encoded string.
    function decode(string memory data) internal pure returns (bytes memory result) {
        /// @solidity memory-safe-assembly
        assembly {
            let dataLength := mload(data)

            if dataLength {
                let end := add(data, dataLength)
                let decodedLength := mul(shr(2, dataLength), 3)

                switch and(dataLength, 3)
                case 0 {
                    // If padded.
                    // forgefmt: disable-next-item
                    decodedLength := sub(
                        decodedLength,
                        add(eq(and(mload(end), 0xFF), 0x3d), eq(and(mload(end), 0xFFFF), 0x3d3d))
                    )
                }
                default {
                    // If non-padded.
                    decodedLength := add(decodedLength, sub(and(dataLength, 3), 1))
                }

                result := mload(0x40)

                // Write the length of the string.
                mstore(result, decodedLength)

                // Skip the first slot, which stores the length.
                let ptr := add(result, 0x20)

                // Load the table into the scratch space.
                // Constants are optimized for smaller bytecode with zero gas overhead.
                // `m` also doubles as the mask of the upper 6 bits.
                let m := 0xfc000000fc00686c7074787c8084888c9094989ca0a4a8acb0b4b8bcc0c4c8cc
                mstore(0x5b, m)
                mstore(0x3b, 0x04080c1014181c2024282c3034383c4044484c5054585c6064)
                mstore(0x1a, 0xf8fcf800fcd0d4d8dce0e4e8ecf0f4)

                for {} 1 {} {
                    // Read 4 bytes.
                    data := add(data, 4)
                    let input := mload(data)

                    // Write 3 bytes.
                    // forgefmt: disable-next-item
                    mstore(ptr, or(
                        and(m, mload(byte(28, input))),
                        shr(6, or(
                            and(m, mload(byte(29, input))),
                            shr(6, or(
                                and(m, mload(byte(30, input))),
                                shr(6, mload(byte(31, input)))
                            ))
                        ))
                    ))

                    ptr := add(ptr, 3)

                    if iszero(lt(data, end)) { break }
                }

                // Allocate the memory for the string.
                // Add 32 + 31 and mask with `not(31)` to round the
                // free memory pointer up the next multiple of 32.
                mstore(0x40, and(add(add(result, decodedLength), 63), not(31)))

                // Restore the zero slot.
                mstore(0x60, 0)
            }
        }
    }
}

// OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol)

// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)

// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 *
 * _Available since v4.5._
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}

// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

/**
 * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
 *
 * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
 * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
 *
 * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
 * fee is specified in basis points by default.
 *
 * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
 * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
 * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
 *
 * _Available since v4.5._
 */
abstract contract ERC2981 is IERC2981, ERC165 {
    struct RoyaltyInfo {
        address receiver;
        uint96 royaltyFraction;
    }

    RoyaltyInfo private _defaultRoyaltyInfo;
    mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
        return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @inheritdoc IERC2981
     */
    function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) {
        RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId];

        if (royalty.receiver == address(0)) {
            royalty = _defaultRoyaltyInfo;
        }

        uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator();

        return (royalty.receiver, royaltyAmount);
    }

    /**
     * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
     * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
     * override.
     */
    function _feeDenominator() internal pure virtual returns (uint96) {
        return 10000;
    }

    /**
     * @dev Sets the royalty information that all ids in this contract will default to.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: invalid receiver");

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Removes default royalty information.
     */
    function _deleteDefaultRoyalty() internal virtual {
        delete _defaultRoyaltyInfo;
    }

    /**
     * @dev Sets the royalty information for a specific token id, overriding the global default.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setTokenRoyalty(
        uint256 tokenId,
        address receiver,
        uint96 feeNumerator
    ) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: Invalid parameters");

        _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Resets royalty information for the token id back to the global default.
     */
    function _resetTokenRoyalty(uint256 tokenId) internal virtual {
        delete _tokenRoyaltyInfo[tokenId];
    }
}

// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10**64) {
                value /= 10**64;
                result += 64;
            }
            if (value >= 10**32) {
                value /= 10**32;
                result += 32;
            }
            if (value >= 10**16) {
                value /= 10**16;
                result += 16;
            }
            if (value >= 10**8) {
                value /= 10**8;
                result += 8;
            }
            if (value >= 10**4) {
                value /= 10**4;
                result += 4;
            }
            if (value >= 10**2) {
                value /= 10**2;
                result += 2;
            }
            if (value >= 10**1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

/// @notice Read and write to persistent storage at a fraction of the cost.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SSTORE2.sol)
/// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol)
library SSTORE2 {
    uint256 internal constant DATA_OFFSET = 1; // We skip the first byte as it's a STOP opcode to ensure the contract can't be called.

    /*//////////////////////////////////////////////////////////////
                               WRITE LOGIC
    //////////////////////////////////////////////////////////////*/

    function write(bytes memory data) internal returns (address pointer) {
        // Prefix the bytecode with a STOP opcode to ensure it cannot be called.
        bytes memory runtimeCode = abi.encodePacked(hex"00", data);

        bytes memory creationCode = abi.encodePacked(
            //---------------------------------------------------------------------------------------------------------------//
            // Opcode  | Opcode + Arguments  | Description  | Stack View                                                     //
            //---------------------------------------------------------------------------------------------------------------//
            // 0x60    |  0x600B             | PUSH1 11     | codeOffset                                                     //
            // 0x59    |  0x59               | MSIZE        | 0 codeOffset                                                   //
            // 0x81    |  0x81               | DUP2         | codeOffset 0 codeOffset                                        //
            // 0x38    |  0x38               | CODESIZE     | codeSize codeOffset 0 codeOffset                               //
            // 0x03    |  0x03               | SUB          | (codeSize - codeOffset) 0 codeOffset                           //
            // 0x80    |  0x80               | DUP          | (codeSize - codeOffset) (codeSize - codeOffset) 0 codeOffset   //
            // 0x92    |  0x92               | SWAP3        | codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset)   //
            // 0x59    |  0x59               | MSIZE        | 0 codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //
            // 0x39    |  0x39               | CODECOPY     | 0 (codeSize - codeOffset)                                      //
            // 0xf3    |  0xf3               | RETURN       |                                                                //
            //---------------------------------------------------------------------------------------------------------------//
            hex"60_0B_59_81_38_03_80_92_59_39_F3", // Returns all code in the contract except for the first 11 (0B in hex) bytes.
            runtimeCode // The bytecode we want the contract to have after deployment. Capped at 1 byte less than the code size limit.
        );

        /// @solidity memory-safe-assembly
        assembly {
            // Deploy a new contract with the generated creation code.
            // We start 32 bytes into the code to avoid copying the byte length.
            pointer := create(0, add(creationCode, 32), mload(creationCode))
        }

        require(pointer != address(0), "DEPLOYMENT_FAILED");
    }

    /*//////////////////////////////////////////////////////////////
                               READ LOGIC
    //////////////////////////////////////////////////////////////*/

    function read(address pointer) internal view returns (bytes memory) {
        return readBytecode(pointer, DATA_OFFSET, pointer.code.length - DATA_OFFSET);
    }

    function read(address pointer, uint256 start) internal view returns (bytes memory) {
        start += DATA_OFFSET;

        return readBytecode(pointer, start, pointer.code.length - start);
    }

    function read(
        address pointer,
        uint256 start,
        uint256 end
    ) internal view returns (bytes memory) {
        start += DATA_OFFSET;
        end += DATA_OFFSET;

        require(pointer.code.length >= end, "OUT_OF_BOUNDS");

        return readBytecode(pointer, start, end - start);
    }

    /*//////////////////////////////////////////////////////////////
                          INTERNAL HELPER LOGIC
    //////////////////////////////////////////////////////////////*/

    function readBytecode(
        address pointer,
        uint256 start,
        uint256 size
    ) private view returns (bytes memory data) {
        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            data := mload(0x40)

            // Update the free memory pointer to prevent overriding our data.
            // We use and(x, not(31)) as a cheaper equivalent to sub(x, mod(x, 32)).
            // Adding 31 to size and running the result through the logic above ensures
            // the memory pointer remains word-aligned, following the Solidity convention.
            mstore(0x40, add(data, and(add(add(size, 32), 31), not(31))))

            // Store the size of the data in the first 32 byte chunk of free memory.
            mstore(data, size)

            // Copy the code into memory right after the 32 bytes we used to store the size.
            extcodecopy(pointer, add(data, 32), start, size)
        }
    }
}

abstract contract MarketWares is ERC2981 {

    address public immutable OWNER;
    address public immutable SECURITY_ADVISOR;

    address private _logoPointer;

    constructor(address owner_, address securityAdvisor_) {
        // assumption: admin addresses are auditted contracts or verified to be EOA's
        OWNER = owner_;
        SECURITY_ADVISOR = securityAdvisor_;

        _setDefaultRoyalty(OWNER, 100); // ERC2981 1% royalty on secondary sales
    }
      
    // needed for opensea
    function contractURI() public view returns(string memory) {
        return string(abi.encodePacked(
                  "data:application/json;base64,", 
                  Base64.encode(abi.encodePacked("{\"name\": \"bonSAI\","
                       " \"description\": \"Limited, generative art collection living entirely 'in-chain'.\","
                       " \"image\": \"", 
                       "data:image/svg+xml;base64,",
                       Base64.encode(SSTORE2.read(_logoPointer)), 
                       "\",",
                       " \"seller_fee_basis_points:\": \"100\","
                       " \"fee_recipient\": \"", Strings.toHexString(OWNER) ,"\"}"))));
    }

    function sendETH() external {
        // assumption: admin addresses are auditted contracts or verified to be EOA's
        (bool success,) = SECURITY_ADVISOR.call{value: address(this).balance/10}("");
        require(success, "call0: breaks EOA assumption.");
        (success,) = OWNER.call{value: address(this).balance}("");
        require(success, "call1: breaks EOA assumption.");
    }

    function setLogo(string memory logo) external {
        require(msg.sender == OWNER, "not owner.");
        _logoPointer = SSTORE2.write(bytes(logo));
    }
}

contract BonsaiMaker is OperatorFilteredERC721, MarketWares {

    uint256 constant public PRICE_PER_TOKEN = 0.0721 ether;
    uint256 constant public MAX_TOKENS = 10_000;
    uint256 constant public MAX_QTY = 70;
    uint256 constant public FREE_MINT = 100;

    uint256 constant public PRUNE_COST_PER_DEGREE = PRICE_PER_TOKEN / 4; 

    uint256 public totalSupply;

    IBonsaiState public bonsaiState;
    IBonsaiRenderer public bonsaiRenderer;

    mapping(address => uint256) private _freeMintedTime;
    mapping(address => uint256) private _numMinted;

    constructor(
        address owner_, 
        // security advisement was provided by Nomoi Web3 Hacker Collective, nomoi.xyz
        address securityAdvisor_, 
        address bonsaiState_,
        address bonsaiRenderer_
    ) OperatorFilteredERC721("BonSAIMaker", "bMKR") MarketWares(owner_, securityAdvisor_) { // see `MarketWares` for royalty stuffs

        bonsaiState = IBonsaiState(bonsaiState_);
        bonsaiRenderer = IBonsaiRenderer(bonsaiRenderer_);
    }

    function _mayBeBot() internal view returns(bool) {
        return tx.origin != msg.sender;
    }

    // minting

    function mintFree(address to) external returns(uint256 tokenId) {
        unchecked{
        if (msg.sender != OWNER) {
            require(!_mayBeBot(), "no freebies for bots.");
            require(totalSupply < FREE_MINT, "no more free mints.");
            require(block.timestamp > _freeMintedTime[tx.origin] + 1 days, "1 free mint /EOA /day.");
            _freeMintedTime[msg.sender] = block.timestamp; // since !_mayBeBot
        }
        tokenId = ++totalSupply;
        _mint(to, tokenId);
        bonsaiState.initializeBonsai({tokenId: tokenId, mayBeBot: false});
        }//uc
    }

    function mint(address to) external payable returns(uint256 lastTokenId) {
        unchecked{
        require(msg.value % PRICE_PER_TOKEN == 0, "msg.value != n * price.");
        uint256 qty = msg.value / PRICE_PER_TOKEN;
        require(qty > 0, "call mint with n * PRICE_PER_TOKEN.");
        require(_numMinted[msg.sender] + qty <= MAX_QTY, "minting too many.");
        _numMinted[msg.sender] += qty;
        uint256 tokenId = totalSupply;
        require(tokenId + qty <= MAX_TOKENS, "new tokens exceed max.");

        bool mayBeBot = _mayBeBot(); // bots ok but they get limited options
        for (uint256 i; i < qty; ++i) {
            _mint(to, ++tokenId); 
            bonsaiState.initializeBonsai(tokenId, mayBeBot);
        }
        lastTokenId = tokenId;
        totalSupply = lastTokenId;
        }//uc
    }

    // enjoyment

    // viewing

    function tokenURI(uint256 tokenId) public view override returns(string memory) {
        require(_ownerOf[tokenId] != address(0), "Bonsai dne.");
        return bonsaiRenderer.renderForHumans(tokenId);
    }

    function tokenURIForRobots(uint256 tokenId) public view returns(RawAttributes memory) {
        require(_ownerOf[tokenId] != address(0), "Bonsai dne.");
        return bonsaiRenderer.renderForRobots(tokenId);
    }

    // bonsai care

    // watering

    event Watered(uint256 indexed tokenId, string indexed status);

    // anyone can water :)
    function water(uint256 tokenId) external returns(WateringStatus memory ws) {
        require(_ownerOf[tokenId] != address(0), "Bonsai dne.");
        ws = bonsaiState.water(tokenId);    
        emit Watered(tokenId, ws.status);
    }

    function wateringStatus(uint256 tokenId) external view returns(WateringStatus memory) {
        require(_ownerOf[tokenId] != address(0), "Bonsai dne.");
        return bonsaiState.wateringStatus(tokenId);
    }

    // pruning

    event Pruned(uint256 indexed tokenId, PruneDegrees indexed degree);

    function prune(uint256 tokenId) external payable {
        require(msg.sender == _ownerOf[tokenId], "you don't mow another man's lawn.");
        require(msg.value % PRUNE_COST_PER_DEGREE == 0, "incongruent pruning payment.");
        uint256 degreeNumber = (msg.value / PRUNE_COST_PER_DEGREE);
        require(degreeNumber > 0, "call prune with value n * PRUNE_COST_PER_DEGREE.");
        require(degreeNumber < 4, "max prune degree is 3 (HIGH)");
        PruneDegrees degree = PruneDegrees(degreeNumber);
        bonsaiState.prune(tokenId, degree);
        emit Pruned(tokenId, degree);
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC2981) returns (bool) {
        return interfaceId == type(IERC2981).interfaceId || 
               interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
               interfaceId == 0x5b5e139f || // ERC165 Interface ID for ERC721Metadata
               super.supportsInterface(interfaceId);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"securityAdvisor_","type":"address"},{"internalType":"address","name":"bonsaiState_","type":"address"},{"internalType":"address","name":"bonsaiRenderer_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","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":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"enum PruneDegrees","name":"degree","type":"uint8"}],"name":"Pruned","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"string","name":"status","type":"string"}],"name":"Watered","type":"event"},{"inputs":[],"name":"FREE_MINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_QTY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OWNER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE_PER_TOKEN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRUNE_COST_PER_DEGREE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SECURITY_ADVISOR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bonsaiRenderer","outputs":[{"internalType":"contract IBonsaiRenderer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bonsaiState","outputs":[{"internalType":"contract IBonsaiState","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":[{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"lastTokenId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mintFree","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"prune","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sendETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"logo","type":"string"}],"name":"setLogo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURIForRobots","outputs":[{"components":[{"internalType":"bytes32","name":"backgroundColor","type":"bytes32"},{"internalType":"bytes32","name":"blossomColor","type":"bytes32"},{"internalType":"bytes32","name":"wateringStatus","type":"bytes32"},{"internalType":"uint32","name":"seed","type":"uint32"},{"internalType":"uint64","name":"ratio","type":"uint64"},{"internalType":"uint64","name":"adjustedStartTime","type":"uint64"},{"internalType":"uint64","name":"lastWatered","type":"uint64"},{"internalType":"uint8","name":"trunkSVGNumber","type":"uint8"},{"internalType":"enum HealthStatus","name":"healthStatus","type":"uint8"},{"internalType":"uint256[]","name":"modifiedSteps","type":"uint256[]"}],"internalType":"struct RawAttributes","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"water","outputs":[{"components":[{"internalType":"uint64","name":"lastWatered","type":"uint64"},{"internalType":"enum HealthStatus","name":"healthStatus","type":"uint8"},{"internalType":"string","name":"status","type":"string"}],"internalType":"struct WateringStatus","name":"ws","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"wateringStatus","outputs":[{"components":[{"internalType":"uint64","name":"lastWatered","type":"uint64"},{"internalType":"enum HealthStatus","name":"healthStatus","type":"uint8"},{"internalType":"string","name":"status","type":"string"}],"internalType":"struct WateringStatus","name":"","type":"tuple"}],"stateMutability":"view","type":"function"}]

60c06040523480156200001157600080fd5b506040516200322138038062003221833981016040819052620000349162000378565b83836040518060400160405280600b81526020016a2137b729a0a4a6b0b5b2b960a91b815250604051806040016040528060048152602001633126a5a960e11b815250733cc6cdda760b79bafa08df41ecfa224f810dceb6600183838160009081620000a191906200047a565b506001620000b082826200047a565b5050506daaeb6d7670e522a718067333cd4e3b15620001f85780156200014657604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b1580156200012757600080fd5b505af11580156200013c573d6000803e3d6000fd5b50505050620001f8565b6001600160a01b03821615620001975760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af2903906044016200010c565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b158015620001de57600080fd5b505af1158015620001f3573d6000803e3d6000fd5b505050505b5050506001600160a01b03808416608081905290831660a0526200021f9150606462000256565b5050600a80546001600160a01b039384166001600160a01b031991821617909155600b805492909316911617905550620005469050565b6127106001600160601b0382161115620002ca5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b60648201526084015b60405180910390fd5b6001600160a01b038216620003225760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401620002c1565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600655565b80516001600160a01b03811681146200037357600080fd5b919050565b600080600080608085870312156200038f57600080fd5b6200039a856200035b565b9350620003aa602086016200035b565b9250620003ba604086016200035b565b9150620003ca606086016200035b565b905092959194509250565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200040057607f821691505b6020821081036200042157634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200047557600081815260208120601f850160051c81016020861015620004505750805b601f850160051c820191505b8181101562000471578281556001016200045c565b5050505b505050565b81516001600160401b03811115620004965762000496620003d5565b620004ae81620004a78454620003eb565b8462000427565b602080601f831160018114620004e65760008415620004cd5750858301515b600019600386901b1c1916600185901b17855562000471565b600085815260208120601f198616915b828110156200051757888601518255948401946001909101908401620004f6565b5085821015620005365787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051612c926200058f6000396000818161056001526108670152600081816103240152818161093101528181610aca0152818161137801526115450152612c926000f3fe6080604052600436106101f95760003560e01c80635e2893dd1161010d578063a22cb465116100a0578063db065b1d1161006f578063db065b1d14610602578063e55fcf2d14610617578063e8a3d48514610637578063e985e9c51461064c578063f47c84c51461068757600080fd5b8063a22cb46514610582578063a7eec44b146105a2578063b88d4fde146105c2578063c87b56dd146105e257600080fd5b8063784eb67d116100dc578063784eb67d146104f0578063833b94991461051d57806395d89b41146105395780639621026e1461054e57600080fd5b80635e2893dd1461048a5780636352211e1461049d5780636a627842146104bd57806370a08231146104d057600080fd5b80631c96cae9116101905780632fe319621161015f5780632fe31962146103f357806333043dbf1461041357806341f434341461043357806342842e0e1461045557806347bf8d311461047557600080fd5b80631c96cae91461036a5780631d16d9a01461037f57806323b872dd146103945780632a55205a146103b457600080fd5b806309a1f9c6116101cc57806309a1f9c6146102c557806310414d6d146102e5578063117803e31461031257806318160ddd1461034657600080fd5b806301ffc9a7146101fe57806306fdde0314610233578063081812fc14610255578063095ea7b3146102a3575b600080fd5b34801561020a57600080fd5b5061021e6102193660046120ce565b61069d565b60405190151581526020015b60405180910390f35b34801561023f57600080fd5b506102486106fe565b60405161022a919061213b565b34801561026157600080fd5b5061028b61027036600461214e565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161022a565b3480156102af57600080fd5b506102c36102be36600461217e565b61078c565b005b3480156102d157600080fd5b50600a5461028b906001600160a01b031681565b3480156102f157600080fd5b5061030561030036600461214e565b6107a5565b60405161022a919061220d565b34801561031e57600080fd5b5061028b7f000000000000000000000000000000000000000000000000000000000000000081565b34801561035257600080fd5b5061035c60095481565b60405190815260200161022a565b34801561037657600080fd5b5061035c604681565b34801561038b57600080fd5b506102c361085b565b3480156103a057600080fd5b506102c36103af3660046122d1565b6109e8565b3480156103c057600080fd5b506103d46103cf36600461230d565b610a13565b604080516001600160a01b03909316835260208301919091520161022a565b3480156103ff57600080fd5b506102c361040e3660046123c5565b610abf565b34801561041f57600080fd5b50600b5461028b906001600160a01b031681565b34801561043f57600080fd5b5061028b6daaeb6d7670e522a718067333cd4e81565b34801561046157600080fd5b506102c36104703660046122d1565b610b50565b34801561048157600080fd5b5061035c610b75565b6102c361049836600461214e565b610b8b565b3480156104a957600080fd5b5061028b6104b836600461214e565b610dfa565b61035c6104cb366004612444565b610e51565b3480156104dc57600080fd5b5061035c6104eb366004612444565b611069565b3480156104fc57600080fd5b5061051061050b36600461214e565b6110cc565b60405161022a919061245f565b34801561052957600080fd5b5061035c6701002691684e400081565b34801561054557600080fd5b50610248611179565b34801561055a57600080fd5b5061028b7f000000000000000000000000000000000000000000000000000000000000000081565b34801561058e57600080fd5b506102c361059d3660046124ae565b611186565b3480156105ae57600080fd5b506105106105bd36600461214e565b61119a565b3480156105ce57600080fd5b506102c36105dd3660046124e5565b611294565b3480156105ee57600080fd5b506102486105fd36600461214e565b6112c3565b34801561060e57600080fd5b5061035c606481565b34801561062357600080fd5b5061035c610632366004612444565b61136b565b34801561064357600080fd5b5061024861151b565b34801561065857600080fd5b5061021e61066736600461257f565b600560209081526000928352604080842090915290825290205460ff1681565b34801561069357600080fd5b5061035c61271081565b60006001600160e01b0319821663152a902d60e11b14806106ce57506380ac58cd60e01b6001600160e01b03198316145b806106e95750635b5e139f60e01b6001600160e01b03198316145b806106f857506106f8826115b2565b92915050565b6000805461070b906125b2565b80601f0160208091040260200160405190810160405280929190818152602001828054610737906125b2565b80156107845780601f1061075957610100808354040283529160200191610784565b820191906000526020600020905b81548152906001019060200180831161076757829003601f168201915b505050505081565b81610796816115e7565b6107a083836116a0565b505050565b6107ad612049565b6000828152600260205260409020546001600160a01b03166107ea5760405162461bcd60e51b81526004016107e1906125ec565b60405180910390fd5b600b5460405163aaf1e61160e01b8152600481018490526001600160a01b039091169063aaf1e61190602401600060405180830381865afa158015610833573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106f891908101906126db565b60006001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016610892600a476127fd565b604051600081818185875af1925050503d80600081146108ce576040519150601f19603f3d011682016040523d82523d6000602084013e6108d3565b606091505b50509050806109245760405162461bcd60e51b815260206004820152601d60248201527f63616c6c303a20627265616b7320454f4120617373756d7074696f6e2e00000060448201526064016107e1565b6040516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016904790600081818185875af1925050503d806000811461098d576040519150601f19603f3d011682016040523d82523d6000602084013e610992565b606091505b505080915050806109e55760405162461bcd60e51b815260206004820152601d60248201527f63616c6c313a20627265616b7320454f4120617373756d7074696f6e2e00000060448201526064016107e1565b50565b826001600160a01b0381163314610a0257610a02336115e7565b610a0d848484611782565b50505050565b60008281526007602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610a885750604080518082019091526006546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090610aa7906001600160601b031687612811565b610ab191906127fd565b915196919550909350505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b245760405162461bcd60e51b815260206004820152600a6024820152693737ba1037bbb732b91760b11b60448201526064016107e1565b610b2d81611949565b600880546001600160a01b0319166001600160a01b039290921691909117905550565b826001600160a01b0381163314610b6a57610b6a336115e7565b610a0d8484846119ee565b610b8860046701002691684e40006127fd565b81565b6000818152600260205260409020546001600160a01b03163314610bfb5760405162461bcd60e51b815260206004820152602160248201527f796f7520646f6e2774206d6f7720616e6f74686572206d616e2773206c61776e6044820152601760f91b60648201526084016107e1565b610c0e60046701002691684e40006127fd565b610c189034612828565b15610c655760405162461bcd60e51b815260206004820152601c60248201527f696e636f6e677275656e74207072756e696e67207061796d656e742e0000000060448201526064016107e1565b6000610c7a60046701002691684e40006127fd565b610c8490346127fd565b905060008111610cef5760405162461bcd60e51b815260206004820152603060248201527f63616c6c207072756e6520776974682076616c7565206e202a205052554e455f60448201526f21a7a9aa2fa822a92fa222a3a922a29760811b60648201526084016107e1565b60048110610d3f5760405162461bcd60e51b815260206004820152601c60248201527f6d6178207072756e65206465677265652069732033202848494748290000000060448201526064016107e1565b6000816003811115610d5357610d536121a8565b600a54604051630320f0dd60e61b81529192506001600160a01b03169063c83c374090610d86908690859060040161283c565b600060405180830381600087803b158015610da057600080fd5b505af1158015610db4573d6000803e3d6000fd5b50505050806003811115610dca57610dca6121a8565b60405184907fbb9360aa013e49a3091c9b89863774bc1ba5d5b25bc14fc6d17c8a27b0e021de90600090a3505050565b6000818152600260205260409020546001600160a01b031680610e4c5760405162461bcd60e51b815260206004820152600a6024820152691393d517d3525395115160b21b60448201526064016107e1565b919050565b60006701002691684e4000340615610eab5760405162461bcd60e51b815260206004820152601760248201527f6d73672e76616c756520213d206e202a2070726963652e00000000000000000060448201526064016107e1565b6701002691684e4000340480610f0f5760405162461bcd60e51b815260206004820152602360248201527f63616c6c206d696e742077697468206e202a2050524943455f5045525f544f4b60448201526222a71760e91b60648201526084016107e1565b336000908152600d602052604090205460469082011115610f665760405162461bcd60e51b815260206004820152601160248201527036b4b73a34b733903a37b79036b0b73c9760791b60448201526064016107e1565b336000908152600d602052604090208054820190556009546127108183011115610fcb5760405162461bcd60e51b81526020600482015260166024820152753732bb903a37b5b2b7399032bc31b2b2b21036b0bc1760511b60448201526064016107e1565b3233141560005b8381101561105b57610fea8684600101945084611ae1565b600a5460405163d1aa8c6560e01b81526004810185905283151560248201526001600160a01b039091169063d1aa8c6590604401600060405180830381600087803b15801561103857600080fd5b505af115801561104c573d6000803e3d6000fd5b50505050806001019050610fd2565b505060098190559392505050565b60006001600160a01b0382166110b05760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b60448201526064016107e1565b506001600160a01b031660009081526003602052604090205490565b6110d461209e565b6000828152600260205260409020546001600160a01b03166111085760405162461bcd60e51b81526004016107e1906125ec565b600a5460405163784eb67d60e01b8152600481018490526001600160a01b039091169063784eb67d90602401600060405180830381865afa158015611151573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106f891908101906128a5565b6001805461070b906125b2565b81611190816115e7565b6107a08383611bec565b6111a261209e565b6000828152600260205260409020546001600160a01b03166111d65760405162461bcd60e51b81526004016107e1906125ec565b600a5460405163a7eec44b60e01b8152600481018490526001600160a01b039091169063a7eec44b906024016000604051808303816000875af1158015611221573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261124991908101906128a5565b9050806040015160405161125d9190612949565b6040519081900381209083907f45f022ebaef0359458bda97ad02c7e8c572b5705a168151dee77f29fecb2d37690600090a3919050565b846001600160a01b03811633146112ae576112ae336115e7565b6112bb8686868686611c58565b505050505050565b6000818152600260205260409020546060906001600160a01b03166112fa5760405162461bcd60e51b81526004016107e1906125ec565b600b546040516379f2b5cf60e11b8152600481018490526001600160a01b039091169063f3e56b9e90602401600060405180830381865afa158015611343573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106f89190810190612965565b6000336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461149b573332146113e45760405162461bcd60e51b8152602060048201526015602482015274373790333932b2b134b2b9903337b9103137ba399760591b60448201526064016107e1565b60646009541061142c5760405162461bcd60e51b815260206004820152601360248201527237379036b7b93290333932b29036b4b73a399760691b60448201526064016107e1565b326000908152600c6020526040902054620151800142116114885760405162461bcd60e51b81526020600482015260166024820152751890333932b29036b4b73a1017a2a7a09017b230bc9760511b60448201526064016107e1565b336000908152600c602052604090204290555b5060098054600101908190556114b18282611ae1565b600a5460405163d1aa8c6560e01b815260048101839052600060248201526001600160a01b039091169063d1aa8c6590604401600060405180830381600087803b1580156114fe57600080fd5b505af1158015611512573d6000803e3d6000fd5b50505050919050565b60085460609061158e906115409061153b906001600160a01b0316611d40565b611d61565b6115697f0000000000000000000000000000000000000000000000000000000000000000611d6f565b60405160200161157a929190612999565b604051602081830303815290604052611d61565b60405160200161159e9190612adc565b604051602081830303815290604052905090565b60006001600160e01b0319821663152a902d60e11b14806106f857506301ffc9a760e01b6001600160e01b03198316146106f8565b6daaeb6d7670e522a718067333cd4e3b156109e557604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611654573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116789190612b21565b6109e557604051633b79c77360e21b81526001600160a01b03821660048201526024016107e1565b6000818152600260205260409020546001600160a01b0316338114806116e957506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b6117265760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064016107e1565b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000818152600260205260409020546001600160a01b038481169116146117d85760405162461bcd60e51b815260206004820152600a60248201526957524f4e475f46524f4d60b01b60448201526064016107e1565b6001600160a01b0382166118225760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b60448201526064016107e1565b336001600160a01b038416148061185c57506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b8061187d57506000818152600460205260409020546001600160a01b031633145b6118ba5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064016107e1565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000808260405160200161195d9190612b3e565b60405160208183030381529060405290506000816040516020016119819190612b64565b60405160208183030381529060405290508051602082016000f092506001600160a01b0383166119e75760405162461bcd60e51b81526020600482015260116024820152701111541313d65351539517d19052531151607a1b60448201526064016107e1565b5050919050565b6119f98383836109e8565b6001600160a01b0382163b1580611aa25750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af1158015611a72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a969190612b98565b6001600160e01b031916145b6107a05760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b60448201526064016107e1565b6001600160a01b038216611b2b5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b60448201526064016107e1565b6000818152600260205260409020546001600160a01b031615611b815760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b60448201526064016107e1565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611c638585856109e8565b6001600160a01b0384163b1580611cfa5750604051630a85bd0160e11b808252906001600160a01b0386169063150b7a0290611cab9033908a90899089908990600401612bb5565b6020604051808303816000875af1158015611cca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cee9190612b98565b6001600160e01b031916145b611d395760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b60448201526064016107e1565b5050505050565b60606106f8826001611d5c816001600160a01b0384163b612c09565b611d85565b60606106f882600080611da8565b60606106f86001600160a01b0383166014611ea7565b60408051603f8301601f19168101909152818152818360208301863c9392505050565b606083518015611e9f576003600282010460021b60405192507f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566601f526102308515027f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5f03603f52602083018181015b6003880197508751603f8160121c16518353603f81600c1c16516001840153603f8160061c16516002840153603f811651600384015350600482019150808210611e185760038406868015611e7857600182148215150185038752611e90565b603d821515850353603d6001831460011b8503538487525b5050601f01601f191660405250505b509392505050565b60606000611eb6836002612811565b611ec1906002612c1c565b6001600160401b03811115611ed857611ed861232f565b6040519080825280601f01601f191660200182016040528015611f02576020820181803683370190505b509050600360fc1b81600081518110611f1d57611f1d612c2f565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110611f4c57611f4c612c2f565b60200101906001600160f81b031916908160001a9053506000611f70846002612811565b611f7b906001612c1c565b90505b6001811115611ff3576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110611faf57611faf612c2f565b1a60f81b828281518110611fc557611fc5612c2f565b60200101906001600160f81b031916908160001a90535060049490941c93611fec81612c45565b9050611f7e565b5083156120425760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016107e1565b9392505050565b6040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052906101008201905b8152602001606081525090565b604080516060810190915260008082526020820190612091565b6001600160e01b0319811681146109e557600080fd5b6000602082840312156120e057600080fd5b8135612042816120b8565b60005b838110156121065781810151838201526020016120ee565b50506000910152565b600081518084526121278160208601602086016120eb565b601f01601f19169290920160200192915050565b602081526000612042602083018461210f565b60006020828403121561216057600080fd5b5035919050565b80356001600160a01b0381168114610e4c57600080fd5b6000806040838503121561219157600080fd5b61219a83612167565b946020939093013593505050565b634e487b7160e01b600052602160045260246000fd5b600381106121ce576121ce6121a8565b9052565b600081518084526020808501945080840160005b83811015612202578151875295820195908201906001016121e6565b509495945050505050565b6020815281516020820152602082015160408201526040820151606082015260006060830151612245608084018263ffffffff169052565b5060808301516001600160401b03811660a08401525060a08301516001600160401b03811660c08401525060c08301516001600160401b03811660e08401525060e083015161010061229b8185018360ff169052565b84015190506101206122af848201836121be565b8401516101408481015290506122c96101608401826121d2565b949350505050565b6000806000606084860312156122e657600080fd5b6122ef84612167565b92506122fd60208501612167565b9150604084013590509250925092565b6000806040838503121561232057600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b60405161014081016001600160401b03811182821017156123685761236861232f565b60405290565b604051601f8201601f191681016001600160401b03811182821017156123965761239661232f565b604052919050565b60006001600160401b038211156123b7576123b761232f565b50601f01601f191660200190565b6000602082840312156123d757600080fd5b81356001600160401b038111156123ed57600080fd5b8201601f810184136123fe57600080fd5b803561241161240c8261239e565b61236e565b81815285602083850101111561242657600080fd5b81602084016020830137600091810160200191909152949350505050565b60006020828403121561245657600080fd5b61204282612167565b602081526001600160401b0382511660208201526000602083015161248760408401826121be565b5060408301516060808401526122c9608084018261210f565b80151581146109e557600080fd5b600080604083850312156124c157600080fd5b6124ca83612167565b915060208301356124da816124a0565b809150509250929050565b6000806000806000608086880312156124fd57600080fd5b61250686612167565b945061251460208701612167565b93506040860135925060608601356001600160401b038082111561253757600080fd5b818801915088601f83011261254b57600080fd5b81358181111561255a57600080fd5b89602082850101111561256c57600080fd5b9699959850939650602001949392505050565b6000806040838503121561259257600080fd5b61259b83612167565b91506125a960208401612167565b90509250929050565b600181811c908216806125c657607f821691505b6020821081036125e657634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600b908201526a2137b739b0b4903237329760a91b604082015260600190565b805163ffffffff81168114610e4c57600080fd5b80516001600160401b0381168114610e4c57600080fd5b805160ff81168114610e4c57600080fd5b805160038110610e4c57600080fd5b600082601f83011261266d57600080fd5b815160206001600160401b038211156126885761268861232f565b8160051b61269782820161236e565b92835284810182019282810190878511156126b157600080fd5b83870192505b848310156126d0578251825291830191908301906126b7565b979650505050505050565b6000602082840312156126ed57600080fd5b81516001600160401b038082111561270457600080fd5b90830190610140828603121561271957600080fd5b612721612345565b82518152602083015160208201526040830151604082015261274560608401612611565b606082015261275660808401612625565b608082015261276760a08401612625565b60a082015261277860c08401612625565b60c082015261278960e0840161263c565b60e082015261010061279c81850161264d565b9082015261012083810151838111156127b457600080fd5b6127c08882870161265c565b918301919091525095945050505050565b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60008261280c5761280c6127d1565b500490565b80820281158282048414176106f8576106f86127e7565b600082612837576128376127d1565b500690565b8281526040810160048310612853576128536121a8565b8260208301529392505050565b600082601f83011261287157600080fd5b815161287f61240c8261239e565b81815284602083860101111561289457600080fd5b6122c98260208301602087016120eb565b6000602082840312156128b757600080fd5b81516001600160401b03808211156128ce57600080fd5b90830190606082860312156128e257600080fd5b6040516060810181811083821117156128fd576128fd61232f565b60405261290983612625565b81526129176020840161264d565b602082015260408301518281111561292e57600080fd5b61293a87828601612860565b60408301525095945050505050565b6000825161295b8184602087016120eb565b9190910192915050565b60006020828403121561297757600080fd5b81516001600160401b0381111561298d57600080fd5b6122c984828501612860565b7f7b226e616d65223a2022626f6e534149222c20226465736372697074696f6e2281527f3a20224c696d697465642c2067656e657261746976652061727420636f6c6c6560208201527f6374696f6e206c6976696e6720656e746972656c792027696e2d636861696e2760408201526d171116101134b6b0b3b2911d101160911b60608201527f646174613a696d6167652f7376672b786d6c3b6261736536342c000000000000606e82015260008351612a5a8160888501602088016120eb565b61088b60f21b6088918401918201527f202273656c6c65725f6665655f62617369735f706f696e74733a223a20223130608a8201527518111610113332b2afb932b1b4b834b2b73a111d101160511b60aa8201528351612ac18160c08401602088016120eb565b61227d60f01b60c0929091019182015260c201949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251612b1481601d8501602087016120eb565b91909101601d0192915050565b600060208284031215612b3357600080fd5b8151612042816124a0565b6000815260008251612b578160018501602087016120eb565b9190910160010192915050565b6a600b5981380380925939f360a81b81528151600090612b8b81600b8501602087016120eb565b91909101600b0192915050565b600060208284031215612baa57600080fd5b8151612042816120b8565b6001600160a01b038681168252851660208201526040810184905260806060820181905281018290526000828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b818103818111156106f8576106f86127e7565b808201808211156106f8576106f86127e7565b634e487b7160e01b600052603260045260246000fd5b600081612c5457612c546127e7565b50600019019056fea26469706673582212200a818f8f65358f192c7cceb0f2f6dd2e30cf8e48298a42d5f485a088c7ee977964736f6c63430008110033000000000000000000000000d64e3c25b0cc9afb535157cbb96eb601a47650fa000000000000000000000000ec4a325e273f031c136def19c5920065055d912b000000000000000000000000c2ddd87ef19b10ab491b9af808b039d98914f2e50000000000000000000000004feaf4cd57f111345b5ce82241f5b9d7c7f2bc96

Deployed Bytecode

0x6080604052600436106101f95760003560e01c80635e2893dd1161010d578063a22cb465116100a0578063db065b1d1161006f578063db065b1d14610602578063e55fcf2d14610617578063e8a3d48514610637578063e985e9c51461064c578063f47c84c51461068757600080fd5b8063a22cb46514610582578063a7eec44b146105a2578063b88d4fde146105c2578063c87b56dd146105e257600080fd5b8063784eb67d116100dc578063784eb67d146104f0578063833b94991461051d57806395d89b41146105395780639621026e1461054e57600080fd5b80635e2893dd1461048a5780636352211e1461049d5780636a627842146104bd57806370a08231146104d057600080fd5b80631c96cae9116101905780632fe319621161015f5780632fe31962146103f357806333043dbf1461041357806341f434341461043357806342842e0e1461045557806347bf8d311461047557600080fd5b80631c96cae91461036a5780631d16d9a01461037f57806323b872dd146103945780632a55205a146103b457600080fd5b806309a1f9c6116101cc57806309a1f9c6146102c557806310414d6d146102e5578063117803e31461031257806318160ddd1461034657600080fd5b806301ffc9a7146101fe57806306fdde0314610233578063081812fc14610255578063095ea7b3146102a3575b600080fd5b34801561020a57600080fd5b5061021e6102193660046120ce565b61069d565b60405190151581526020015b60405180910390f35b34801561023f57600080fd5b506102486106fe565b60405161022a919061213b565b34801561026157600080fd5b5061028b61027036600461214e565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161022a565b3480156102af57600080fd5b506102c36102be36600461217e565b61078c565b005b3480156102d157600080fd5b50600a5461028b906001600160a01b031681565b3480156102f157600080fd5b5061030561030036600461214e565b6107a5565b60405161022a919061220d565b34801561031e57600080fd5b5061028b7f000000000000000000000000d64e3c25b0cc9afb535157cbb96eb601a47650fa81565b34801561035257600080fd5b5061035c60095481565b60405190815260200161022a565b34801561037657600080fd5b5061035c604681565b34801561038b57600080fd5b506102c361085b565b3480156103a057600080fd5b506102c36103af3660046122d1565b6109e8565b3480156103c057600080fd5b506103d46103cf36600461230d565b610a13565b604080516001600160a01b03909316835260208301919091520161022a565b3480156103ff57600080fd5b506102c361040e3660046123c5565b610abf565b34801561041f57600080fd5b50600b5461028b906001600160a01b031681565b34801561043f57600080fd5b5061028b6daaeb6d7670e522a718067333cd4e81565b34801561046157600080fd5b506102c36104703660046122d1565b610b50565b34801561048157600080fd5b5061035c610b75565b6102c361049836600461214e565b610b8b565b3480156104a957600080fd5b5061028b6104b836600461214e565b610dfa565b61035c6104cb366004612444565b610e51565b3480156104dc57600080fd5b5061035c6104eb366004612444565b611069565b3480156104fc57600080fd5b5061051061050b36600461214e565b6110cc565b60405161022a919061245f565b34801561052957600080fd5b5061035c6701002691684e400081565b34801561054557600080fd5b50610248611179565b34801561055a57600080fd5b5061028b7f000000000000000000000000ec4a325e273f031c136def19c5920065055d912b81565b34801561058e57600080fd5b506102c361059d3660046124ae565b611186565b3480156105ae57600080fd5b506105106105bd36600461214e565b61119a565b3480156105ce57600080fd5b506102c36105dd3660046124e5565b611294565b3480156105ee57600080fd5b506102486105fd36600461214e565b6112c3565b34801561060e57600080fd5b5061035c606481565b34801561062357600080fd5b5061035c610632366004612444565b61136b565b34801561064357600080fd5b5061024861151b565b34801561065857600080fd5b5061021e61066736600461257f565b600560209081526000928352604080842090915290825290205460ff1681565b34801561069357600080fd5b5061035c61271081565b60006001600160e01b0319821663152a902d60e11b14806106ce57506380ac58cd60e01b6001600160e01b03198316145b806106e95750635b5e139f60e01b6001600160e01b03198316145b806106f857506106f8826115b2565b92915050565b6000805461070b906125b2565b80601f0160208091040260200160405190810160405280929190818152602001828054610737906125b2565b80156107845780601f1061075957610100808354040283529160200191610784565b820191906000526020600020905b81548152906001019060200180831161076757829003601f168201915b505050505081565b81610796816115e7565b6107a083836116a0565b505050565b6107ad612049565b6000828152600260205260409020546001600160a01b03166107ea5760405162461bcd60e51b81526004016107e1906125ec565b60405180910390fd5b600b5460405163aaf1e61160e01b8152600481018490526001600160a01b039091169063aaf1e61190602401600060405180830381865afa158015610833573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106f891908101906126db565b60006001600160a01b037f000000000000000000000000ec4a325e273f031c136def19c5920065055d912b16610892600a476127fd565b604051600081818185875af1925050503d80600081146108ce576040519150601f19603f3d011682016040523d82523d6000602084013e6108d3565b606091505b50509050806109245760405162461bcd60e51b815260206004820152601d60248201527f63616c6c303a20627265616b7320454f4120617373756d7074696f6e2e00000060448201526064016107e1565b6040516001600160a01b037f000000000000000000000000d64e3c25b0cc9afb535157cbb96eb601a47650fa16904790600081818185875af1925050503d806000811461098d576040519150601f19603f3d011682016040523d82523d6000602084013e610992565b606091505b505080915050806109e55760405162461bcd60e51b815260206004820152601d60248201527f63616c6c313a20627265616b7320454f4120617373756d7074696f6e2e00000060448201526064016107e1565b50565b826001600160a01b0381163314610a0257610a02336115e7565b610a0d848484611782565b50505050565b60008281526007602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610a885750604080518082019091526006546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090610aa7906001600160601b031687612811565b610ab191906127fd565b915196919550909350505050565b336001600160a01b037f000000000000000000000000d64e3c25b0cc9afb535157cbb96eb601a47650fa1614610b245760405162461bcd60e51b815260206004820152600a6024820152693737ba1037bbb732b91760b11b60448201526064016107e1565b610b2d81611949565b600880546001600160a01b0319166001600160a01b039290921691909117905550565b826001600160a01b0381163314610b6a57610b6a336115e7565b610a0d8484846119ee565b610b8860046701002691684e40006127fd565b81565b6000818152600260205260409020546001600160a01b03163314610bfb5760405162461bcd60e51b815260206004820152602160248201527f796f7520646f6e2774206d6f7720616e6f74686572206d616e2773206c61776e6044820152601760f91b60648201526084016107e1565b610c0e60046701002691684e40006127fd565b610c189034612828565b15610c655760405162461bcd60e51b815260206004820152601c60248201527f696e636f6e677275656e74207072756e696e67207061796d656e742e0000000060448201526064016107e1565b6000610c7a60046701002691684e40006127fd565b610c8490346127fd565b905060008111610cef5760405162461bcd60e51b815260206004820152603060248201527f63616c6c207072756e6520776974682076616c7565206e202a205052554e455f60448201526f21a7a9aa2fa822a92fa222a3a922a29760811b60648201526084016107e1565b60048110610d3f5760405162461bcd60e51b815260206004820152601c60248201527f6d6178207072756e65206465677265652069732033202848494748290000000060448201526064016107e1565b6000816003811115610d5357610d536121a8565b600a54604051630320f0dd60e61b81529192506001600160a01b03169063c83c374090610d86908690859060040161283c565b600060405180830381600087803b158015610da057600080fd5b505af1158015610db4573d6000803e3d6000fd5b50505050806003811115610dca57610dca6121a8565b60405184907fbb9360aa013e49a3091c9b89863774bc1ba5d5b25bc14fc6d17c8a27b0e021de90600090a3505050565b6000818152600260205260409020546001600160a01b031680610e4c5760405162461bcd60e51b815260206004820152600a6024820152691393d517d3525395115160b21b60448201526064016107e1565b919050565b60006701002691684e4000340615610eab5760405162461bcd60e51b815260206004820152601760248201527f6d73672e76616c756520213d206e202a2070726963652e00000000000000000060448201526064016107e1565b6701002691684e4000340480610f0f5760405162461bcd60e51b815260206004820152602360248201527f63616c6c206d696e742077697468206e202a2050524943455f5045525f544f4b60448201526222a71760e91b60648201526084016107e1565b336000908152600d602052604090205460469082011115610f665760405162461bcd60e51b815260206004820152601160248201527036b4b73a34b733903a37b79036b0b73c9760791b60448201526064016107e1565b336000908152600d602052604090208054820190556009546127108183011115610fcb5760405162461bcd60e51b81526020600482015260166024820152753732bb903a37b5b2b7399032bc31b2b2b21036b0bc1760511b60448201526064016107e1565b3233141560005b8381101561105b57610fea8684600101945084611ae1565b600a5460405163d1aa8c6560e01b81526004810185905283151560248201526001600160a01b039091169063d1aa8c6590604401600060405180830381600087803b15801561103857600080fd5b505af115801561104c573d6000803e3d6000fd5b50505050806001019050610fd2565b505060098190559392505050565b60006001600160a01b0382166110b05760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b60448201526064016107e1565b506001600160a01b031660009081526003602052604090205490565b6110d461209e565b6000828152600260205260409020546001600160a01b03166111085760405162461bcd60e51b81526004016107e1906125ec565b600a5460405163784eb67d60e01b8152600481018490526001600160a01b039091169063784eb67d90602401600060405180830381865afa158015611151573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106f891908101906128a5565b6001805461070b906125b2565b81611190816115e7565b6107a08383611bec565b6111a261209e565b6000828152600260205260409020546001600160a01b03166111d65760405162461bcd60e51b81526004016107e1906125ec565b600a5460405163a7eec44b60e01b8152600481018490526001600160a01b039091169063a7eec44b906024016000604051808303816000875af1158015611221573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261124991908101906128a5565b9050806040015160405161125d9190612949565b6040519081900381209083907f45f022ebaef0359458bda97ad02c7e8c572b5705a168151dee77f29fecb2d37690600090a3919050565b846001600160a01b03811633146112ae576112ae336115e7565b6112bb8686868686611c58565b505050505050565b6000818152600260205260409020546060906001600160a01b03166112fa5760405162461bcd60e51b81526004016107e1906125ec565b600b546040516379f2b5cf60e11b8152600481018490526001600160a01b039091169063f3e56b9e90602401600060405180830381865afa158015611343573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106f89190810190612965565b6000336001600160a01b037f000000000000000000000000d64e3c25b0cc9afb535157cbb96eb601a47650fa161461149b573332146113e45760405162461bcd60e51b8152602060048201526015602482015274373790333932b2b134b2b9903337b9103137ba399760591b60448201526064016107e1565b60646009541061142c5760405162461bcd60e51b815260206004820152601360248201527237379036b7b93290333932b29036b4b73a399760691b60448201526064016107e1565b326000908152600c6020526040902054620151800142116114885760405162461bcd60e51b81526020600482015260166024820152751890333932b29036b4b73a1017a2a7a09017b230bc9760511b60448201526064016107e1565b336000908152600c602052604090204290555b5060098054600101908190556114b18282611ae1565b600a5460405163d1aa8c6560e01b815260048101839052600060248201526001600160a01b039091169063d1aa8c6590604401600060405180830381600087803b1580156114fe57600080fd5b505af1158015611512573d6000803e3d6000fd5b50505050919050565b60085460609061158e906115409061153b906001600160a01b0316611d40565b611d61565b6115697f000000000000000000000000d64e3c25b0cc9afb535157cbb96eb601a47650fa611d6f565b60405160200161157a929190612999565b604051602081830303815290604052611d61565b60405160200161159e9190612adc565b604051602081830303815290604052905090565b60006001600160e01b0319821663152a902d60e11b14806106f857506301ffc9a760e01b6001600160e01b03198316146106f8565b6daaeb6d7670e522a718067333cd4e3b156109e557604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611654573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116789190612b21565b6109e557604051633b79c77360e21b81526001600160a01b03821660048201526024016107e1565b6000818152600260205260409020546001600160a01b0316338114806116e957506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b6117265760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064016107e1565b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000818152600260205260409020546001600160a01b038481169116146117d85760405162461bcd60e51b815260206004820152600a60248201526957524f4e475f46524f4d60b01b60448201526064016107e1565b6001600160a01b0382166118225760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b60448201526064016107e1565b336001600160a01b038416148061185c57506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b8061187d57506000818152600460205260409020546001600160a01b031633145b6118ba5760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064016107e1565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000808260405160200161195d9190612b3e565b60405160208183030381529060405290506000816040516020016119819190612b64565b60405160208183030381529060405290508051602082016000f092506001600160a01b0383166119e75760405162461bcd60e51b81526020600482015260116024820152701111541313d65351539517d19052531151607a1b60448201526064016107e1565b5050919050565b6119f98383836109e8565b6001600160a01b0382163b1580611aa25750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af1158015611a72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a969190612b98565b6001600160e01b031916145b6107a05760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b60448201526064016107e1565b6001600160a01b038216611b2b5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b60448201526064016107e1565b6000818152600260205260409020546001600160a01b031615611b815760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b60448201526064016107e1565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611c638585856109e8565b6001600160a01b0384163b1580611cfa5750604051630a85bd0160e11b808252906001600160a01b0386169063150b7a0290611cab9033908a90899089908990600401612bb5565b6020604051808303816000875af1158015611cca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cee9190612b98565b6001600160e01b031916145b611d395760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b60448201526064016107e1565b5050505050565b60606106f8826001611d5c816001600160a01b0384163b612c09565b611d85565b60606106f882600080611da8565b60606106f86001600160a01b0383166014611ea7565b60408051603f8301601f19168101909152818152818360208301863c9392505050565b606083518015611e9f576003600282010460021b60405192507f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566601f526102308515027f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5f03603f52602083018181015b6003880197508751603f8160121c16518353603f81600c1c16516001840153603f8160061c16516002840153603f811651600384015350600482019150808210611e185760038406868015611e7857600182148215150185038752611e90565b603d821515850353603d6001831460011b8503538487525b5050601f01601f191660405250505b509392505050565b60606000611eb6836002612811565b611ec1906002612c1c565b6001600160401b03811115611ed857611ed861232f565b6040519080825280601f01601f191660200182016040528015611f02576020820181803683370190505b509050600360fc1b81600081518110611f1d57611f1d612c2f565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110611f4c57611f4c612c2f565b60200101906001600160f81b031916908160001a9053506000611f70846002612811565b611f7b906001612c1c565b90505b6001811115611ff3576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110611faf57611faf612c2f565b1a60f81b828281518110611fc557611fc5612c2f565b60200101906001600160f81b031916908160001a90535060049490941c93611fec81612c45565b9050611f7e565b5083156120425760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016107e1565b9392505050565b6040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052906101008201905b8152602001606081525090565b604080516060810190915260008082526020820190612091565b6001600160e01b0319811681146109e557600080fd5b6000602082840312156120e057600080fd5b8135612042816120b8565b60005b838110156121065781810151838201526020016120ee565b50506000910152565b600081518084526121278160208601602086016120eb565b601f01601f19169290920160200192915050565b602081526000612042602083018461210f565b60006020828403121561216057600080fd5b5035919050565b80356001600160a01b0381168114610e4c57600080fd5b6000806040838503121561219157600080fd5b61219a83612167565b946020939093013593505050565b634e487b7160e01b600052602160045260246000fd5b600381106121ce576121ce6121a8565b9052565b600081518084526020808501945080840160005b83811015612202578151875295820195908201906001016121e6565b509495945050505050565b6020815281516020820152602082015160408201526040820151606082015260006060830151612245608084018263ffffffff169052565b5060808301516001600160401b03811660a08401525060a08301516001600160401b03811660c08401525060c08301516001600160401b03811660e08401525060e083015161010061229b8185018360ff169052565b84015190506101206122af848201836121be565b8401516101408481015290506122c96101608401826121d2565b949350505050565b6000806000606084860312156122e657600080fd5b6122ef84612167565b92506122fd60208501612167565b9150604084013590509250925092565b6000806040838503121561232057600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b60405161014081016001600160401b03811182821017156123685761236861232f565b60405290565b604051601f8201601f191681016001600160401b03811182821017156123965761239661232f565b604052919050565b60006001600160401b038211156123b7576123b761232f565b50601f01601f191660200190565b6000602082840312156123d757600080fd5b81356001600160401b038111156123ed57600080fd5b8201601f810184136123fe57600080fd5b803561241161240c8261239e565b61236e565b81815285602083850101111561242657600080fd5b81602084016020830137600091810160200191909152949350505050565b60006020828403121561245657600080fd5b61204282612167565b602081526001600160401b0382511660208201526000602083015161248760408401826121be565b5060408301516060808401526122c9608084018261210f565b80151581146109e557600080fd5b600080604083850312156124c157600080fd5b6124ca83612167565b915060208301356124da816124a0565b809150509250929050565b6000806000806000608086880312156124fd57600080fd5b61250686612167565b945061251460208701612167565b93506040860135925060608601356001600160401b038082111561253757600080fd5b818801915088601f83011261254b57600080fd5b81358181111561255a57600080fd5b89602082850101111561256c57600080fd5b9699959850939650602001949392505050565b6000806040838503121561259257600080fd5b61259b83612167565b91506125a960208401612167565b90509250929050565b600181811c908216806125c657607f821691505b6020821081036125e657634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600b908201526a2137b739b0b4903237329760a91b604082015260600190565b805163ffffffff81168114610e4c57600080fd5b80516001600160401b0381168114610e4c57600080fd5b805160ff81168114610e4c57600080fd5b805160038110610e4c57600080fd5b600082601f83011261266d57600080fd5b815160206001600160401b038211156126885761268861232f565b8160051b61269782820161236e565b92835284810182019282810190878511156126b157600080fd5b83870192505b848310156126d0578251825291830191908301906126b7565b979650505050505050565b6000602082840312156126ed57600080fd5b81516001600160401b038082111561270457600080fd5b90830190610140828603121561271957600080fd5b612721612345565b82518152602083015160208201526040830151604082015261274560608401612611565b606082015261275660808401612625565b608082015261276760a08401612625565b60a082015261277860c08401612625565b60c082015261278960e0840161263c565b60e082015261010061279c81850161264d565b9082015261012083810151838111156127b457600080fd5b6127c08882870161265c565b918301919091525095945050505050565b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60008261280c5761280c6127d1565b500490565b80820281158282048414176106f8576106f86127e7565b600082612837576128376127d1565b500690565b8281526040810160048310612853576128536121a8565b8260208301529392505050565b600082601f83011261287157600080fd5b815161287f61240c8261239e565b81815284602083860101111561289457600080fd5b6122c98260208301602087016120eb565b6000602082840312156128b757600080fd5b81516001600160401b03808211156128ce57600080fd5b90830190606082860312156128e257600080fd5b6040516060810181811083821117156128fd576128fd61232f565b60405261290983612625565b81526129176020840161264d565b602082015260408301518281111561292e57600080fd5b61293a87828601612860565b60408301525095945050505050565b6000825161295b8184602087016120eb565b9190910192915050565b60006020828403121561297757600080fd5b81516001600160401b0381111561298d57600080fd5b6122c984828501612860565b7f7b226e616d65223a2022626f6e534149222c20226465736372697074696f6e2281527f3a20224c696d697465642c2067656e657261746976652061727420636f6c6c6560208201527f6374696f6e206c6976696e6720656e746972656c792027696e2d636861696e2760408201526d171116101134b6b0b3b2911d101160911b60608201527f646174613a696d6167652f7376672b786d6c3b6261736536342c000000000000606e82015260008351612a5a8160888501602088016120eb565b61088b60f21b6088918401918201527f202273656c6c65725f6665655f62617369735f706f696e74733a223a20223130608a8201527518111610113332b2afb932b1b4b834b2b73a111d101160511b60aa8201528351612ac18160c08401602088016120eb565b61227d60f01b60c0929091019182015260c201949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251612b1481601d8501602087016120eb565b91909101601d0192915050565b600060208284031215612b3357600080fd5b8151612042816124a0565b6000815260008251612b578160018501602087016120eb565b9190910160010192915050565b6a600b5981380380925939f360a81b81528151600090612b8b81600b8501602087016120eb565b91909101600b0192915050565b600060208284031215612baa57600080fd5b8151612042816120b8565b6001600160a01b038681168252851660208201526040810184905260806060820181905281018290526000828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b818103818111156106f8576106f86127e7565b808201808211156106f8576106f86127e7565b634e487b7160e01b600052603260045260246000fd5b600081612c5457612c546127e7565b50600019019056fea26469706673582212200a818f8f65358f192c7cceb0f2f6dd2e30cf8e48298a42d5f485a088c7ee977964736f6c63430008110033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000d64e3c25b0cc9afb535157cbb96eb601a47650fa000000000000000000000000ec4a325e273f031c136def19c5920065055d912b000000000000000000000000c2ddd87ef19b10ab491b9af808b039d98914f2e50000000000000000000000004feaf4cd57f111345b5ce82241f5b9d7c7f2bc96

-----Decoded View---------------
Arg [0] : owner_ (address): 0xd64e3c25B0cC9AFb535157cBB96eb601a47650fa
Arg [1] : securityAdvisor_ (address): 0xEC4A325E273f031c136Def19c5920065055D912B
Arg [2] : bonsaiState_ (address): 0xC2ddd87ef19B10AB491b9aF808b039D98914f2E5
Arg [3] : bonsaiRenderer_ (address): 0x4FeAF4Cd57f111345B5CE82241f5B9D7C7F2bc96

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000d64e3c25b0cc9afb535157cbb96eb601a47650fa
Arg [1] : 000000000000000000000000ec4a325e273f031c136def19c5920065055d912b
Arg [2] : 000000000000000000000000c2ddd87ef19b10ab491b9af808b039d98914f2e5
Arg [3] : 0000000000000000000000004feaf4cd57f111345b5ce82241f5b9d7c7f2bc96


Deployed Bytecode Sourcemap

60199:4849:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64647:398;;;;;;;;;;-1:-1:-1;64647:398:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;64647:398:0;;;;;;;;9011:18;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;9984:46::-;;;;;;;;;;-1:-1:-1;9984:46:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;9984:46:0;;;;;;-1:-1:-1;;;;;1697:32:1;;;1679:51;;1667:2;1652:18;9984:46:0;1533:203:1;21291:157:0;;;;;;;;;;-1:-1:-1;21291:157:0;;;;;:::i;:::-;;:::i;:::-;;60582:31;;;;;;;;;;-1:-1:-1;60582:31:0;;;;-1:-1:-1;;;;;60582:31:0;;;63112:217;;;;;;;;;;-1:-1:-1;63112:217:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;58452:30::-;;;;;;;;;;;;;;;60547:26;;;;;;;;;;;;;;;;;;;4879:25:1;;;4867:2;4852:18;60547:26:0;4733:177:1;60379:36:0;;;;;;;;;;;;60413:2;60379:36;;59627:398;;;;;;;;;;;;;:::i;21456:163::-;;;;;;;;;;-1:-1:-1;21456:163:0;;;;;:::i;:::-;;:::i;35386:442::-;;;;;;;;;;-1:-1:-1;35386:442:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;5693:32:1;;;5675:51;;5757:2;5742:18;;5735:34;;;;5648:18;35386:442:0;5501:274:1;60033:159:0;;;;;;;;;;-1:-1:-1;60033:159:0;;;;;:::i;:::-;;:::i;60620:37::-;;;;;;;;;;-1:-1:-1;60620:37:0;;;;-1:-1:-1;;;;;60620:37:0;;;18424:143;;;;;;;;;;;;18524:42;18424:143;;21627:171;;;;;;;;;;-1:-1:-1;21627:171:0;;;;;:::i;:::-;;:::i;60470:67::-;;;;;;;;;;;;;:::i;64036:603::-;;;;;;:::i;:::-;;:::i;9453:151::-;;;;;;;;;;-1:-1:-1;9453:151:0;;;;;:::i;:::-;;:::i;62005:843::-;;;;;;:::i;:::-;;:::i;9612:172::-;;;;;;;;;;-1:-1:-1;9612:172:0;;;;;:::i;:::-;;:::i;63722:213::-;;;;;;;;;;-1:-1:-1;63722:213:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;60268:54::-;;;;;;;;;;;;60310:12;60268:54;;9038:20;;;;;;;;;;;;;:::i;58489:41::-;;;;;;;;;;;;;;;21107:176;;;;;;;;;;-1:-1:-1;21107:176:0;;;;;:::i;:::-;;:::i;63476:238::-;;;;;;;;;;-1:-1:-1;63476:238:0;;;;;:::i;:::-;;:::i;21806:230::-;;;;;;;;;;-1:-1:-1;21806:230:0;;;;;:::i;:::-;;:::i;62894:210::-;;;;;;;;;;-1:-1:-1;62894:210:0;;;;;:::i;:::-;;:::i;60422:39::-;;;;;;;;;;;;60458:3;60422:39;;61390:607;;;;;;;;;;-1:-1:-1;61390:607:0;;;;;:::i;:::-;;:::i;58921:698::-;;;;;;;;;;;;;:::i;10039:68::-;;;;;;;;;;-1:-1:-1;10039:68:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;60329:43;;;;;;;;;;;;60366:6;60329:43;;64647:398;64749:4;-1:-1:-1;;;;;;64773:41:0;;-1:-1:-1;;;64773:41:0;;:87;;-1:-1:-1;;;;;;;;;;64835:25:0;;;64773:87;:166;;;-1:-1:-1;;;;;;;;;;64914:25:0;;;64773:166;:264;;;;65001:36;65025:11;65001:23;:36::i;:::-;64766:271;64647:398;-1:-1:-1;;64647:398:0:o;9011:18::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;21291:157::-;21387:8;19945:30;19966:8;19945:20;:30::i;:::-;21408:32:::1;21422:8;21432:7;21408:13;:32::i;:::-;21291:157:::0;;;:::o;63112:217::-;63176:20;;:::i;:::-;63246:1;63217:17;;;:8;:17;;;;;;-1:-1:-1;;;;;63217:17:0;63209:55;;;;-1:-1:-1;;;63209:55:0;;;;;;;:::i;:::-;;;;;;;;;63282:14;;:39;;-1:-1:-1;;;63282:39:0;;;;;4879:25:1;;;-1:-1:-1;;;;;63282:14:0;;;;:30;;4852:18:1;;63282:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;63282:39:0;;;;;;;;;;;;:::i;59627:398::-;59754:12;-1:-1:-1;;;;;59771:16:0;:21;59800:24;59822:2;59800:21;:24;:::i;:::-;59771:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59753:76;;;59848:7;59840:49;;;;-1:-1:-1;;;59840:49:0;;14295:2:1;59840:49:0;;;14277:21:1;14334:2;14314:18;;;14307:30;14373:31;14353:18;;;14346:59;14422:18;;59840:49:0;14093:353:1;59840:49:0;59913:44;;-1:-1:-1;;;;;59913:5:0;:10;;59931:21;;59913:44;;;;59931:21;59913:10;:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59900:57;;;;;59976:7;59968:49;;;;-1:-1:-1;;;59968:49:0;;14653:2:1;59968:49:0;;;14635:21:1;14692:2;14672:18;;;14665:30;14731:31;14711:18;;;14704:59;14780:18;;59968:49:0;14451:353:1;59968:49:0;59655:370;59627:398::o;21456:163::-;21557:4;-1:-1:-1;;;;;19765:18:0;;19773:10;19765:18;19761:83;;19800:32;19821:10;19800:20;:32::i;:::-;21574:37:::1;21593:4;21599:2;21603:7;21574:18;:37::i;:::-;21456:163:::0;;;;:::o;35386:442::-;35483:7;35541:27;;;:17;:27;;;;;;;;35512:56;;;;;;;;;-1:-1:-1;;;;;35512:56:0;;;;;-1:-1:-1;;;35512:56:0;;;-1:-1:-1;;;;;35512:56:0;;;;;;;;35483:7;;35581:92;;-1:-1:-1;35632:29:0;;;;;;;;;35642:19;35632:29;-1:-1:-1;;;;;35632:29:0;;;;-1:-1:-1;;;35632:29:0;;-1:-1:-1;;;;;35632:29:0;;;;;35581:92;35723:23;;;;35685:21;;36194:5;;35710:36;;-1:-1:-1;;;;;35710:36:0;:10;:36;:::i;:::-;35709:58;;;;:::i;:::-;35788:16;;;;;-1:-1:-1;35386:442:0;;-1:-1:-1;;;;35386:442:0:o;60033:159::-;60098:10;-1:-1:-1;;;;;60112:5:0;60098:19;;60090:42;;;;-1:-1:-1;;;60090:42:0;;15184:2:1;60090:42:0;;;15166:21:1;15223:2;15203:18;;;15196:30;-1:-1:-1;;;15242:18:1;;;15235:40;15292:18;;60090:42:0;14982:334:1;60090:42:0;60158:26;60178:4;60158:13;:26::i;:::-;60143:12;:41;;-1:-1:-1;;;;;;60143:41:0;-1:-1:-1;;;;;60143:41:0;;;;;;;;;;-1:-1:-1;60033:159:0:o;21627:171::-;21732:4;-1:-1:-1;;;;;19765:18:0;;19773:10;19765:18;19761:83;;19800:32;19821:10;19800:20;:32::i;:::-;21749:41:::1;21772:4;21778:2;21782:7;21749:22;:41::i;60470:67::-:0;60518:19;60536:1;60310:12;60518:19;:::i;:::-;60470:67;:::o;64036:603::-;64118:17;;;;:8;:17;;;;;;-1:-1:-1;;;;;64118:17:0;64104:10;:31;64096:77;;;;-1:-1:-1;;;64096:77:0;;15523:2:1;64096:77:0;;;15505:21:1;15562:2;15542:18;;;15535:30;15601:34;15581:18;;;15574:62;-1:-1:-1;;;15652:18:1;;;15645:31;15693:19;;64096:77:0;15321:397:1;64096:77:0;60518:19;60536:1;60310:12;60518:19;:::i;:::-;64192:33;;:9;:33;:::i;:::-;:38;64184:79;;;;-1:-1:-1;;;64184:79:0;;16042:2:1;64184:79:0;;;16024:21:1;16081:2;16061:18;;;16054:30;16120;16100:18;;;16093:58;16168:18;;64184:79:0;15840:352:1;64184:79:0;64274:20;60518:19;60536:1;60310:12;60518:19;:::i;:::-;64298:33;;:9;:33;:::i;:::-;64274:58;;64366:1;64351:12;:16;64343:77;;;;-1:-1:-1;;;64343:77:0;;16399:2:1;64343:77:0;;;16381:21:1;16438:2;16418:18;;;16411:30;16477:34;16457:18;;;16450:62;-1:-1:-1;;;16528:18:1;;;16521:46;16584:19;;64343:77:0;16197:412:1;64343:77:0;64454:1;64439:12;:16;64431:57;;;;-1:-1:-1;;;64431:57:0;;16816:2:1;64431:57:0;;;16798:21:1;16855:2;16835:18;;;16828:30;16894;16874:18;;;16867:58;16942:18;;64431:57:0;16614:352:1;64431:57:0;64499:19;64534:12;64521:26;;;;;;;;:::i;:::-;64558:11;;:34;;-1:-1:-1;;;64558:34:0;;64499:48;;-1:-1:-1;;;;;;64558:11:0;;:17;;:34;;64576:7;;64499:48;;64558:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64624:6;64608:23;;;;;;;;:::i;:::-;;;64615:7;;64608:23;;;;;64085:554;;64036:603;:::o;9453:151::-;9511:13;9554:12;;;:8;:12;;;;;;-1:-1:-1;;;;;9554:12:0;;9537:59;;;;-1:-1:-1;;;9537:59:0;;17497:2:1;9537:59:0;;;17479:21:1;17536:2;17516:18;;;17509:30;-1:-1:-1;;;17555:18:1;;;17548:40;17605:18;;9537:59:0;17295:334:1;9537:59:0;9453:151;;;:::o;62005:843::-;62056:19;60310:12;62116:9;:27;:32;62108:68;;;;-1:-1:-1;;;62108:68:0;;17836:2:1;62108:68:0;;;17818:21:1;17875:2;17855:18;;;17848:30;17914:25;17894:18;;;17887:53;17957:18;;62108:68:0;17634:347:1;62108:68:0;60310:12;62201:9;:27;62247:7;62239:55;;;;-1:-1:-1;;;62239:55:0;;18188:2:1;62239:55:0;;;18170:21:1;18227:2;18207:18;;;18200:30;18266:34;18246:18;;;18239:62;-1:-1:-1;;;18317:18:1;;;18310:33;18360:19;;62239:55:0;17986:399:1;62239:55:0;62324:10;62313:22;;;;:10;:22;;;;;;60413:2;62313:28;;;:39;;62305:69;;;;-1:-1:-1;;;62305:69:0;;18592:2:1;62305:69:0;;;18574:21:1;18631:2;18611:18;;;18604:30;-1:-1:-1;;;18650:18:1;;;18643:47;18707:18;;62305:69:0;18390:341:1;62305:69:0;62396:10;62385:22;;;;:10;:22;;;;;:29;;;;;;62443:11;;60366:6;62473:13;;;:27;;62465:62;;;;-1:-1:-1;;;62465:62:0;;18938:2:1;62465:62:0;;;18920:21:1;18977:2;18957:18;;;18950:30;-1:-1:-1;;;18996:18:1;;;18989:52;19058:18;;62465:62:0;18736:346:1;62465:62:0;61333:9;61346:10;61333:23;;62540:13;62618:140;62638:3;62634:1;:7;62618:140;;;62663:20;62669:2;62673:9;;;;;;62663:5;:20::i;:::-;62699:11;;:47;;-1:-1:-1;;;62699:47:0;;;;;19255:25:1;;;19323:14;;19316:22;19296:18;;;19289:50;-1:-1:-1;;;;;62699:11:0;;;;:28;;19228:18:1;;62699:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62643:3;;;;;62618:140;;;-1:-1:-1;;62800:11:0;:25;;;62782:7;62005:843;-1:-1:-1;;;62005:843:0:o;9612:172::-;9675:7;-1:-1:-1;;;;;9703:19:0;;9695:44;;;;-1:-1:-1;;;9695:44:0;;19552:2:1;9695:44:0;;;19534:21:1;19591:2;19571:18;;;19564:30;-1:-1:-1;;;19610:18:1;;;19603:42;19662:18;;9695:44:0;19350:336:1;9695:44:0;-1:-1:-1;;;;;;9759:17:0;;;;;:10;:17;;;;;;;9612:172::o;63722:213::-;63785:21;;:::i;:::-;63856:1;63827:17;;;:8;:17;;;;;;-1:-1:-1;;;;;63827:17:0;63819:55;;;;-1:-1:-1;;;63819:55:0;;;;;;;:::i;:::-;63892:11;;:35;;-1:-1:-1;;;63892:35:0;;;;;4879:25:1;;;-1:-1:-1;;;;;63892:11:0;;;;:26;;4852:18:1;;63892:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;63892:35:0;;;;;;;;;;;;:::i;9038:20::-;;;;;;;:::i;21107:176::-;21211:8;19945:30;19966:8;19945:20;:30::i;:::-;21232:43:::1;21256:8;21266;21232:23;:43::i;63476:238::-:0;63525:24;;:::i;:::-;63599:1;63570:17;;;:8;:17;;;;;;-1:-1:-1;;;;;63570:17:0;63562:55;;;;-1:-1:-1;;;63562:55:0;;;;;;;:::i;:::-;63633:11;;:26;;-1:-1:-1;;;63633:26:0;;;;;4879:25:1;;;-1:-1:-1;;;;;63633:11:0;;;;:17;;4852:18:1;;63633:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;63633:26:0;;;;;;;;;;;;:::i;:::-;63628:31;;63696:2;:9;;;63679:27;;;;;;:::i;:::-;;;;;;;;;;63687:7;;63679:27;;;;;63476:238;;;:::o;21806:230::-;21959:4;-1:-1:-1;;;;;19765:18:0;;19773:10;19765:18;19761:83;;19800:32;19821:10;19800:20;:32::i;:::-;21981:47:::1;22004:4;22010:2;22014:7;22023:4;;21981:22;:47::i;:::-;21806:230:::0;;;;;;:::o;62894:210::-;63021:1;62992:17;;;:8;:17;;;;;;62958:13;;-1:-1:-1;;;;;62992:17:0;62984:55;;;;-1:-1:-1;;;62984:55:0;;;;;;;:::i;:::-;63057:14;;:39;;-1:-1:-1;;;63057:39:0;;;;;4879:25:1;;;-1:-1:-1;;;;;63057:14:0;;;;:30;;4852:18:1;;63057:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;63057:39:0;;;;;;;;;;;;:::i;61390:607::-;61437:15;61489:10;-1:-1:-1;;;;;61503:5:0;61489:19;;61485:351;;61346:10;61333:9;:23;61525:46;;;;-1:-1:-1;;;61525:46:0;;21913:2:1;61525:46:0;;;21895:21:1;21952:2;21932:18;;;21925:30;-1:-1:-1;;;21971:18:1;;;21964:51;22032:18;;61525:46:0;21711:345:1;61525:46:0;60458:3;61594:11;;:23;61586:55;;;;-1:-1:-1;;;61586:55:0;;22263:2:1;61586:55:0;;;22245:21:1;22302:2;22282:18;;;22275:30;-1:-1:-1;;;22321:18:1;;;22314:49;22380:18;;61586:55:0;22061:343:1;61586:55:0;61698:9;61682:26;;;;:15;:26;;;;;;61711:6;61682:35;61664:15;:53;61656:88;;;;-1:-1:-1;;;61656:88:0;;22611:2:1;61656:88:0;;;22593:21:1;22650:2;22630:18;;;22623:30;-1:-1:-1;;;22669:18:1;;;22662:52;22731:18;;61656:88:0;22409:346:1;61656:88:0;61775:10;61759:27;;;;:15;:27;;;;;61789:15;61759:45;;61485:351;-1:-1:-1;61858:11:0;61856:13;;;;;;;;61880:18;61886:2;61856:13;61880:5;:18::i;:::-;61909:11;;:65;;-1:-1:-1;;;61909:65:0;;;;;19255:25:1;;;61909:11:0;19296:18:1;;;19289:50;-1:-1:-1;;;;;61909:11:0;;;;:28;;19228:18:1;;61909:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61390:607;;;:::o;58921:698::-;59410:12;;58964:13;;59094:515;;59383:41;;59397:26;;-1:-1:-1;;;;;59410:12:0;59397;:26::i;:::-;59383:13;:41::i;:::-;59574:26;59594:5;59574:19;:26::i;:::-;59108:500;;;;;;;;;:::i;:::-;;;;;;;;;;;;;59094:13;:515::i;:::-;59004:606;;;;;;;;:::i;:::-;;;;;;;;;;;;;58990:621;;58921:698;:::o;35116:215::-;35218:4;-1:-1:-1;;;;;;35242:41:0;;-1:-1:-1;;;35242:41:0;;:81;;-1:-1:-1;;;;;;;;;;33847:40:0;;;35287:36;33738:157;20003:419;18524:42;20194:45;:49;20190:225;;20265:67;;-1:-1:-1;;;20265:67:0;;20316:4;20265:67;;;25136:34:1;-1:-1:-1;;;;;25206:15:1;;25186:18;;;25179:43;18524:42:0;;20265;;25071:18:1;;20265:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20260:144;;20360:28;;-1:-1:-1;;;20360:28:0;;-1:-1:-1;;;;;1697:32:1;;20360:28:0;;;1679:51:1;1652:18;;20360:28:0;1533:203:1;10610:290:0;10682:13;10698:12;;;:8;:12;;;;;;-1:-1:-1;;;;;10698:12:0;10731:10;:19;;;:58;;-1:-1:-1;;;;;;10754:23:0;;;;;;:16;:23;;;;;;;;10778:10;10754:35;;;;;;;;;;10731:58;10723:85;;;;-1:-1:-1;;;10723:85:0;;25685:2:1;10723:85:0;;;25667:21:1;25724:2;25704:18;;;25697:30;-1:-1:-1;;;25743:18:1;;;25736:44;25797:18;;10723:85:0;25483:338:1;10723:85:0;10821:15;;;;:11;:15;;;;;;:25;;-1:-1:-1;;;;;;10821:25:0;-1:-1:-1;;;;;10821:25:0;;;;;;;;;10864:28;;10821:15;;10864:28;;;;;;;10671:229;10610:290;;:::o;11123:768::-;11259:12;;;;:8;:12;;;;;;-1:-1:-1;;;;;11251:20:0;;;11259:12;;11251:20;11243:43;;;;-1:-1:-1;;;11243:43:0;;26028:2:1;11243:43:0;;;26010:21:1;26067:2;26047:18;;;26040:30;-1:-1:-1;;;26086:18:1;;;26079:40;26136:18;;11243:43:0;25826:334:1;11243:43:0;-1:-1:-1;;;;;11307:16:0;;11299:46;;;;-1:-1:-1;;;11299:46:0;;26367:2:1;11299:46:0;;;26349:21:1;26406:2;26386:18;;;26379:30;-1:-1:-1;;;26425:18:1;;;26418:47;26482:18;;11299:46:0;26165:341:1;11299:46:0;11380:10;-1:-1:-1;;;;;11380:18:0;;;;:56;;-1:-1:-1;;;;;;11402:22:0;;;;;;:16;:22;;;;;;;;11425:10;11402:34;;;;;;;;;;11380:56;:89;;;-1:-1:-1;11454:15:0;;;;:11;:15;;;;;;-1:-1:-1;;;;;11454:15:0;11440:10;:29;11380:89;11358:153;;;;-1:-1:-1;;;11358:153:0;;25685:2:1;11358:153:0;;;25667:21:1;25724:2;25704:18;;;25697:30;-1:-1:-1;;;25743:18:1;;;25736:44;25797:18;;11358:153:0;25483:338:1;11358:153:0;-1:-1:-1;;;;;11716:16:0;;;;;;;:10;:16;;;;;;;;:18;;-1:-1:-1;;11716:18:0;;;11751:14;;;;;;;;;:16;;11716:18;11751:16;;;11791:12;;;:8;:12;;;;;:17;;-1:-1:-1;;;;;;11791:17:0;;;;;;;;11828:11;:15;;;;;;11821:22;;;;;;;;11861;;11800:2;;11751:14;11716:16;11861:22;;;11123:768;;;:::o;53547:2743::-;53599:15;53709:24;53762:4;53736:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;53709:58;;53780:25;55776:11;53808:2101;;;;;;;;:::i;:::-;;;;;;;;;;;;;53780:2129;;56194:12;56188:19;56183:2;56169:12;56165:21;56162:1;56155:53;56144:64;-1:-1:-1;;;;;;56239:21:0;;56231:51;;;;-1:-1:-1;;;56231:51:0;;27612:2:1;56231:51:0;;;27594:21:1;27651:2;27631:18;;;27624:30;-1:-1:-1;;;27670:18:1;;;27663:47;27727:18;;56231:51:0;27410:341:1;56231:51:0;53616:2674;;53547:2743;;;:::o;11899:409::-;12023:26;12036:4;12042:2;12046;12023:12;:26::i;:::-;-1:-1:-1;;;;;12084:14:0;;;:19;;:172;;-1:-1:-1;12124:66:0;;-1:-1:-1;;;12124:66:0;;;12165:10;12124:66;;;28061:34:1;-1:-1:-1;;;;;28131:15:1;;;28111:18;;;28104:43;28163:18;;;28156:34;;;28226:3;28206:18;;;28199:31;-1:-1:-1;28246:19:1;;;28239:30;12211:45:0;;12124:40;;;;12211:45;;28286:19:1;;12124:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;12124:132:0;;12084:172;12062:238;;;;-1:-1:-1;;;12062:238:0;;28772:2:1;12062:238:0;;;28754:21:1;28811:2;28791:18;;;28784:30;-1:-1:-1;;;28830:18:1;;;28823:46;28886:18;;12062:238:0;28570:340:1;13491:384:0;-1:-1:-1;;;;;13566:16:0;;13558:46;;;;-1:-1:-1;;;13558:46:0;;26367:2:1;13558:46:0;;;26349:21:1;26406:2;26386:18;;;26379:30;-1:-1:-1;;;26425:18:1;;;26418:47;26482:18;;13558:46:0;26165:341:1;13558:46:0;13649:1;13625:12;;;:8;:12;;;;;;-1:-1:-1;;;;;13625:12:0;:26;13617:53;;;;-1:-1:-1;;;13617:53:0;;29117:2:1;13617:53:0;;;29099:21:1;29156:2;29136:18;;;29129:30;-1:-1:-1;;;29175:18:1;;;29168:44;29229:18;;13617:53:0;28915:338:1;13617:53:0;-1:-1:-1;;;;;13764:14:0;;;;;;:10;:14;;;;;;;;:16;;;;;;13804:12;;;:8;:12;;;;;;:17;;-1:-1:-1;;;;;;13804:17:0;;;;;13839:28;13813:2;;13764:14;;13839:28;;13764:14;;13839:28;13491:384;;:::o;10908:207::-;11011:10;10994:28;;;;:16;:28;;;;;;;;-1:-1:-1;;;;;10994:38:0;;;;;;;;;;;;:49;;-1:-1:-1;;10994:49:0;;;;;;;;;;11061:46;;540:41:1;;;10994:38:0;;11011:10;11061:46;;513:18:1;11061:46:0;;;;;;;10908:207;;:::o;12316:441::-;12470:26;12483:4;12489:2;12493;12470:12;:26::i;:::-;-1:-1:-1;;;;;12531:14:0;;;:19;;:174;;-1:-1:-1;12571:68:0;;-1:-1:-1;;;12571:68:0;;;12660:45;-1:-1:-1;;;;;12571:40:0;;;12660:45;;12571:68;;12612:10;;12624:4;;12630:2;;12634:4;;;;12571:68;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;12571:134:0;;12531:174;12509:240;;;;-1:-1:-1;;;12509:240:0;;28772:2:1;12509:240:0;;;28754:21:1;28811:2;28791:18;;;28784:30;-1:-1:-1;;;28830:18:1;;;28823:46;28886:18;;12509:240:0;28570:340:1;12509:240:0;12316:441;;;;;:::o;56483:163::-;56537:12;56569:69;56582:7;53263:1;56604:33;53263:1;-1:-1:-1;;;;;56604:19:0;;;:33;:::i;:::-;56569:12;:69::i;27437:134::-;27495:20;27537:26;27544:4;27550:5;27557;27537:6;:26::i;52755:151::-;52813:13;52846:52;-1:-1:-1;;;;;52858:22:0;;50910:2;52846:11;:52::i;57384:1011::-;57671:4;57665:11;;58065:22;;;-1:-1:-1;;58061:36:0;58051:47;;58038:61;;;58201:18;;;58073:4;58365:5;58079:2;58350:13;;58341:7;58329:48;57384:1011;;;;;:::o;24337:2961::-;24453:20;24583:4;24577:11;24607:10;24604:2676;;;24810:1;24806;24794:10;24790:18;24786:26;24783:1;24779:34;24924:4;24918:11;24908:21;;25303:34;25297:4;25290:48;25431:6;25420:8;25413:16;25409:29;25373:34;25369:70;25363:4;25356:84;25549:4;25541:6;25537:17;25592:13;25587:3;25583:23;25685:624;25738:1;25732:4;25728:12;25720:20;;25801:4;25795:11;25946:4;25938:5;25934:2;25930:14;25926:25;25920:32;25915:3;25907:46;26022:4;26014:5;26010:2;26006:14;26002:25;25996:32;25992:1;25987:3;25983:11;25975:54;26097:4;26089:5;26086:1;26082:13;26078:24;26072:31;26068:1;26063:3;26059:11;26051:53;26164:4;26157:5;26153:16;26147:23;26143:1;26138:3;26134:11;26126:45;;26211:1;26206:3;26202:11;26195:18;;26275:3;26270;26267:12;25685:624;26257:33;26354:1;26338:18;;26383:9;26410:415;;;;26993:1;26990;26987:8;26982:1;26975:9;26968:17;26964:32;26949:13;26945:52;26937:6;26930:68;26376:641;;26410:415;26566:4;26560:1;26553:9;26546:17;26541:3;26537:27;26529:42;26661:4;26655:1;26652;26649:8;26646:1;26642:16;26637:3;26633:26;26625:41;26792:13;26784:6;26777:29;26376:641;-1:-1:-1;;27260:2:0;27242:12;-1:-1:-1;;27238:26:0;27232:4;27225:40;-1:-1:-1;;24604:2676:0;;24337:2961;;;;;:::o;52151:447::-;52226:13;52252:19;52284:10;52288:6;52284:1;:10;:::i;:::-;:14;;52297:1;52284:14;:::i;:::-;-1:-1:-1;;;;;52274:25:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;52274:25:0;;52252:47;;-1:-1:-1;;;52310:6:0;52317:1;52310:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;52310:15:0;;;;;;;;;-1:-1:-1;;;52336:6:0;52343:1;52336:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;52336:15:0;;;;;;;;-1:-1:-1;52367:9:0;52379:10;52383:6;52379:1;:10;:::i;:::-;:14;;52392:1;52379:14;:::i;:::-;52367:26;;52362:131;52399:1;52395;:5;52362:131;;;-1:-1:-1;;;52443:5:0;52451:3;52443:11;52434:21;;;;;;;:::i;:::-;;;;52422:6;52429:1;52422:9;;;;;;;;:::i;:::-;;;;:33;-1:-1:-1;;;;;52422:33:0;;;;;;;;-1:-1:-1;52480:1:0;52470:11;;;;;52402:3;;;:::i;:::-;;;52362:131;;;-1:-1:-1;52511:10:0;;52503:55;;;;-1:-1:-1;;;52503:55:0;;30663:2:1;52503:55:0;;;30645:21:1;;;30682:18;;;30675:30;30741:34;30721:18;;;30714:62;30793:18;;52503:55:0;30461:356:1;52503:55:0;52583:6;52151:447;-1:-1:-1;;;52151:447:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:250::-;677:1;687:113;701:6;698:1;695:13;687:113;;;777:11;;;771:18;758:11;;;751:39;723:2;716:10;687:113;;;-1:-1:-1;;834:1:1;816:16;;809:27;592:250::o;847:271::-;889:3;927:5;921:12;954:6;949:3;942:19;970:76;1039:6;1032:4;1027:3;1023:14;1016:4;1009:5;1005:16;970:76;:::i;:::-;1100:2;1079:15;-1:-1:-1;;1075:29:1;1066:39;;;;1107:4;1062:50;;847:271;-1:-1:-1;;847:271:1:o;1123:220::-;1272:2;1261:9;1254:21;1235:4;1292:45;1333:2;1322:9;1318:18;1310:6;1292:45;:::i;1348:180::-;1407:6;1460:2;1448:9;1439:7;1435:23;1431:32;1428:52;;;1476:1;1473;1466:12;1428:52;-1:-1:-1;1499:23:1;;1348:180;-1:-1:-1;1348:180:1:o;1741:173::-;1809:20;;-1:-1:-1;;;;;1858:31:1;;1848:42;;1838:70;;1904:1;1901;1894:12;1919:254;1987:6;1995;2048:2;2036:9;2027:7;2023:23;2019:32;2016:52;;;2064:1;2061;2054:12;2016:52;2087:29;2106:9;2087:29;:::i;:::-;2077:39;2163:2;2148:18;;;;2135:32;;-1:-1:-1;;;1919:254:1:o;2693:127::-;2754:10;2749:3;2745:20;2742:1;2735:31;2785:4;2782:1;2775:15;2809:4;2806:1;2799:15;2825:143;2909:1;2902:5;2899:12;2889:46;;2915:18;;:::i;:::-;2944;;2825:143::o;2973:435::-;3026:3;3064:5;3058:12;3091:6;3086:3;3079:19;3117:4;3146:2;3141:3;3137:12;3130:19;;3183:2;3176:5;3172:14;3204:1;3214:169;3228:6;3225:1;3222:13;3214:169;;;3289:13;;3277:26;;3323:12;;;;3358:15;;;;3250:1;3243:9;3214:169;;;-1:-1:-1;3399:3:1;;2973:435;-1:-1:-1;;;;;2973:435:1:o;3413:1315::-;3604:2;3593:9;3586:21;3649:6;3643:13;3638:2;3627:9;3623:18;3616:41;3711:2;3703:6;3699:15;3693:22;3688:2;3677:9;3673:18;3666:50;3770:2;3762:6;3758:15;3752:22;3747:2;3736:9;3732:18;3725:50;3567:4;3822:2;3814:6;3810:15;3804:22;3835:52;3882:3;3871:9;3867:19;3853:12;2483:10;2472:22;2460:35;;2407:94;3835:52;-1:-1:-1;3936:3:1;3924:16;;3918:23;-1:-1:-1;;;;;2571:30:1;;3999:3;3984:19;;2559:43;-1:-1:-1;4053:3:1;4041:16;;4035:23;-1:-1:-1;;;;;2571:30:1;;4116:3;4101:19;;2559:43;-1:-1:-1;4170:3:1;4158:16;;4152:23;-1:-1:-1;;;;;2571:30:1;;4233:3;4218:19;;2559:43;4184:54;4287:3;4279:6;4275:16;4269:23;4311:3;4323:52;4371:2;4360:9;4356:18;4340:14;2680:4;2669:16;2657:29;;2613:75;4323:52;4412:15;;4406:22;;-1:-1:-1;4447:3:1;4459:64;4504:18;;;4406:22;4459:64;:::i;:::-;4560:15;;4554:22;4595:6;4617:18;;;4610:30;4554:22;-1:-1:-1;4657:65:1;4717:3;4702:19;;4554:22;4657:65;:::i;:::-;4649:73;3413:1315;-1:-1:-1;;;;3413:1315:1:o;4915:328::-;4992:6;5000;5008;5061:2;5049:9;5040:7;5036:23;5032:32;5029:52;;;5077:1;5074;5067:12;5029:52;5100:29;5119:9;5100:29;:::i;:::-;5090:39;;5148:38;5182:2;5171:9;5167:18;5148:38;:::i;:::-;5138:48;;5233:2;5222:9;5218:18;5205:32;5195:42;;4915:328;;;;;:::o;5248:248::-;5316:6;5324;5377:2;5365:9;5356:7;5352:23;5348:32;5345:52;;;5393:1;5390;5383:12;5345:52;-1:-1:-1;;5416:23:1;;;5486:2;5471:18;;;5458:32;;-1:-1:-1;5248:248:1:o;5780:127::-;5841:10;5836:3;5832:20;5829:1;5822:31;5872:4;5869:1;5862:15;5896:4;5893:1;5886:15;5912:255;5984:2;5978:9;6026:6;6014:19;;-1:-1:-1;;;;;6048:34:1;;6084:22;;;6045:62;6042:88;;;6110:18;;:::i;:::-;6146:2;6139:22;5912:255;:::o;6172:275::-;6243:2;6237:9;6308:2;6289:13;;-1:-1:-1;;6285:27:1;6273:40;;-1:-1:-1;;;;;6328:34:1;;6364:22;;;6325:62;6322:88;;;6390:18;;:::i;:::-;6426:2;6419:22;6172:275;;-1:-1:-1;6172:275:1:o;6452:187::-;6501:4;-1:-1:-1;;;;;6526:6:1;6523:30;6520:56;;;6556:18;;:::i;:::-;-1:-1:-1;6622:2:1;6601:15;-1:-1:-1;;6597:29:1;6628:4;6593:40;;6452:187::o;6644:673::-;6713:6;6766:2;6754:9;6745:7;6741:23;6737:32;6734:52;;;6782:1;6779;6772:12;6734:52;6822:9;6809:23;-1:-1:-1;;;;;6847:6:1;6844:30;6841:50;;;6887:1;6884;6877:12;6841:50;6910:22;;6963:4;6955:13;;6951:27;-1:-1:-1;6941:55:1;;6992:1;6989;6982:12;6941:55;7028:2;7015:16;7053:49;7069:32;7098:2;7069:32;:::i;:::-;7053:49;:::i;:::-;7125:2;7118:5;7111:17;7165:7;7160:2;7155;7151;7147:11;7143:20;7140:33;7137:53;;;7186:1;7183;7176:12;7137:53;7241:2;7236;7232;7228:11;7223:2;7216:5;7212:14;7199:45;7285:1;7264:14;;;7280:2;7260:23;7253:34;;;;7268:5;6644:673;-1:-1:-1;;;;6644:673:1:o;7793:186::-;7852:6;7905:2;7893:9;7884:7;7880:23;7876:32;7873:52;;;7921:1;7918;7911:12;7873:52;7944:29;7963:9;7944:29;:::i;7984:566::-;8177:2;8166:9;8159:21;-1:-1:-1;;;;;8226:6:1;8220:13;8216:38;8211:2;8200:9;8196:18;8189:66;8140:4;8302:2;8294:6;8290:15;8284:22;8315:62;8373:2;8362:9;8358:18;8344:12;8315:62;:::i;:::-;;8426:2;8418:6;8414:15;8408:22;8468:4;8461;8450:9;8446:20;8439:34;8490:54;8539:3;8528:9;8524:19;8508:14;8490:54;:::i;8555:118::-;8641:5;8634:13;8627:21;8620:5;8617:32;8607:60;;8663:1;8660;8653:12;8678:315;8743:6;8751;8804:2;8792:9;8783:7;8779:23;8775:32;8772:52;;;8820:1;8817;8810:12;8772:52;8843:29;8862:9;8843:29;:::i;:::-;8833:39;;8922:2;8911:9;8907:18;8894:32;8935:28;8957:5;8935:28;:::i;:::-;8982:5;8972:15;;;8678:315;;;;;:::o;8998:808::-;9095:6;9103;9111;9119;9127;9180:3;9168:9;9159:7;9155:23;9151:33;9148:53;;;9197:1;9194;9187:12;9148:53;9220:29;9239:9;9220:29;:::i;:::-;9210:39;;9268:38;9302:2;9291:9;9287:18;9268:38;:::i;:::-;9258:48;;9353:2;9342:9;9338:18;9325:32;9315:42;;9408:2;9397:9;9393:18;9380:32;-1:-1:-1;;;;;9472:2:1;9464:6;9461:14;9458:34;;;9488:1;9485;9478:12;9458:34;9526:6;9515:9;9511:22;9501:32;;9571:7;9564:4;9560:2;9556:13;9552:27;9542:55;;9593:1;9590;9583:12;9542:55;9633:2;9620:16;9659:2;9651:6;9648:14;9645:34;;;9675:1;9672;9665:12;9645:34;9720:7;9715:2;9706:6;9702:2;9698:15;9694:24;9691:37;9688:57;;;9741:1;9738;9731:12;9688:57;8998:808;;;;-1:-1:-1;8998:808:1;;-1:-1:-1;9772:2:1;9764:11;;9794:6;8998:808;-1:-1:-1;;;8998:808:1:o;9811:260::-;9879:6;9887;9940:2;9928:9;9919:7;9915:23;9911:32;9908:52;;;9956:1;9953;9946:12;9908:52;9979:29;9998:9;9979:29;:::i;:::-;9969:39;;10027:38;10061:2;10050:9;10046:18;10027:38;:::i;:::-;10017:48;;9811:260;;;;;:::o;10076:380::-;10155:1;10151:12;;;;10198;;;10219:61;;10273:4;10265:6;10261:17;10251:27;;10219:61;10326:2;10318:6;10315:14;10295:18;10292:38;10289:161;;10372:10;10367:3;10363:20;10360:1;10353:31;10407:4;10404:1;10397:15;10435:4;10432:1;10425:15;10289:161;;10076:380;;;:::o;10461:335::-;10663:2;10645:21;;;10702:2;10682:18;;;10675:30;-1:-1:-1;;;10736:2:1;10721:18;;10714:41;10787:2;10772:18;;10461:335::o;10801:167::-;10879:13;;10932:10;10921:22;;10911:33;;10901:61;;10958:1;10955;10948:12;10973:175;11051:13;;-1:-1:-1;;;;;11093:30:1;;11083:41;;11073:69;;11138:1;11135;11128:12;11153:160;11230:13;;11283:4;11272:16;;11262:27;;11252:55;;11303:1;11300;11293:12;11318:157;11407:13;;11449:1;11439:12;;11429:40;;11465:1;11462;11455:12;11480:709;11545:5;11598:3;11591:4;11583:6;11579:17;11575:27;11565:55;;11616:1;11613;11606:12;11565:55;11645:6;11639:13;11671:4;-1:-1:-1;;;;;11690:2:1;11687:26;11684:52;;;11716:18;;:::i;:::-;11762:2;11759:1;11755:10;11785:28;11809:2;11805;11801:11;11785:28;:::i;:::-;11847:15;;;11917;;;11913:24;;;11878:12;;;;11949:15;;;11946:35;;;11977:1;11974;11967:12;11946:35;12013:2;12005:6;12001:15;11990:26;;12025:135;12041:6;12036:3;12033:15;12025:135;;;12107:10;;12095:23;;12058:12;;;;12138;;;;12025:135;;;12178:5;11480:709;-1:-1:-1;;;;;;;11480:709:1:o;12194:1295::-;12295:6;12348:2;12336:9;12327:7;12323:23;12319:32;12316:52;;;12364:1;12361;12354:12;12316:52;12397:9;12391:16;-1:-1:-1;;;;;12467:2:1;12459:6;12456:14;12453:34;;;12483:1;12480;12473:12;12453:34;12506:22;;;;12562:6;12544:16;;;12540:29;12537:49;;;12582:1;12579;12572:12;12537:49;12608:22;;:::i;:::-;12659:2;12653:9;12646:5;12639:24;12709:2;12705;12701:11;12695:18;12690:2;12683:5;12679:14;12672:42;12760:2;12756;12752:11;12746:18;12741:2;12734:5;12730:14;12723:42;12797:41;12834:2;12830;12826:11;12797:41;:::i;:::-;12792:2;12785:5;12781:14;12774:65;12872:42;12909:3;12905:2;12901:12;12872:42;:::i;:::-;12866:3;12859:5;12855:15;12848:67;12948:42;12985:3;12981:2;12977:12;12948:42;:::i;:::-;12942:3;12935:5;12931:15;12924:67;13024:42;13061:3;13057:2;13053:12;13024:42;:::i;:::-;13018:3;13011:5;13007:15;13000:67;13100:41;13136:3;13132:2;13128:12;13100:41;:::i;:::-;13094:3;13087:5;13083:15;13076:66;13161:3;13196:52;13244:2;13240;13236:11;13196:52;:::i;:::-;13180:14;;;13173:76;13268:3;13302:11;;;13296:18;13326:16;;;13323:36;;;13355:1;13352;13345:12;13323:36;13391:67;13450:7;13439:8;13435:2;13431:17;13391:67;:::i;:::-;13375:14;;;13368:91;;;;-1:-1:-1;13379:5:1;12194:1295;-1:-1:-1;;;;;12194:1295:1:o;13494:127::-;13555:10;13550:3;13546:20;13543:1;13536:31;13586:4;13583:1;13576:15;13610:4;13607:1;13600:15;13626:127;13687:10;13682:3;13678:20;13675:1;13668:31;13718:4;13715:1;13708:15;13742:4;13739:1;13732:15;13758:120;13798:1;13824;13814:35;;13829:18;;:::i;:::-;-1:-1:-1;13863:9:1;;13758:120::o;14809:168::-;14882:9;;;14913;;14930:15;;;14924:22;;14910:37;14900:71;;14951:18;;:::i;15723:112::-;15755:1;15781;15771:35;;15786:18;;:::i;:::-;-1:-1:-1;15820:9:1;;15723:112::o;16971:319::-;17160:25;;;17148:2;17133:18;;17215:1;17204:13;;17194:47;;17221:18;;:::i;:::-;17277:6;17272:2;17261:9;17257:18;17250:34;16971:319;;;;;:::o;19691:443::-;19745:5;19798:3;19791:4;19783:6;19779:17;19775:27;19765:55;;19816:1;19813;19806:12;19765:55;19845:6;19839:13;19876:49;19892:32;19921:2;19892:32;:::i;19876:49::-;19950:2;19941:7;19934:19;19996:3;19989:4;19984:2;19976:6;19972:15;19968:26;19965:35;19962:55;;;20013:1;20010;20003:12;19962:55;20026:77;20100:2;20093:4;20084:7;20080:18;20073:4;20065:6;20061:17;20026:77;:::i;20139:931::-;20241:6;20294:2;20282:9;20273:7;20269:23;20265:32;20262:52;;;20310:1;20307;20300:12;20262:52;20343:9;20337:16;-1:-1:-1;;;;;20413:2:1;20405:6;20402:14;20399:34;;;20429:1;20426;20419:12;20399:34;20452:22;;;;20508:4;20490:16;;;20486:27;20483:47;;;20526:1;20523;20516:12;20483:47;20559:2;20553:9;20601:4;20593:6;20589:17;20656:6;20644:10;20641:22;20636:2;20624:10;20621:18;20618:46;20615:72;;;20667:18;;:::i;:::-;20703:2;20696:22;20742:32;20771:2;20742:32;:::i;:::-;20734:6;20727:48;20808:52;20856:2;20852;20848:11;20808:52;:::i;:::-;20803:2;20795:6;20791:15;20784:77;20900:2;20896;20892:11;20886:18;20929:2;20919:8;20916:16;20913:36;;;20945:1;20942;20935:12;20913:36;20982:56;21030:7;21019:8;21015:2;21011:17;20982:56;:::i;:::-;20977:2;20965:15;;20958:81;-1:-1:-1;20969:6:1;20139:931;-1:-1:-1;;;;;20139:931:1:o;21075:289::-;21206:3;21244:6;21238:13;21260:66;21319:6;21314:3;21307:4;21299:6;21295:17;21260:66;:::i;:::-;21342:16;;;;;21075:289;-1:-1:-1;;21075:289:1:o;21369:337::-;21449:6;21502:2;21490:9;21481:7;21477:23;21473:32;21470:52;;;21518:1;21515;21508:12;21470:52;21551:9;21545:16;-1:-1:-1;;;;;21576:6:1;21573:30;21570:50;;;21616:1;21613;21606:12;21570:50;21639:61;21692:7;21683:6;21672:9;21668:22;21639:61;:::i;22760:1693::-;23474:66;23469:3;23462:79;23571:66;23566:2;23561:3;23557:12;23550:88;23668:34;23663:2;23658:3;23654:12;23647:56;23742:30;23737:3;23733:40;23728:2;23723:3;23719:12;23712:62;23805:28;23799:3;23794;23790:13;23783:51;23444:3;23863:6;23857:13;23879:74;23946:6;23940:3;23935;23931:13;23926:2;23918:6;23914:15;23879:74;:::i;:::-;-1:-1:-1;;;24012:3:1;23972:16;;;24004:12;;;23997:36;24063:66;24057:3;24049:12;;24042:88;-1:-1:-1;;;24154:3:1;24146:12;;24139:77;24241:13;;24263:75;24241:13;24323:3;24315:12;;24310:2;24298:15;;24263:75;:::i;:::-;-1:-1:-1;;;24398:3:1;24357:17;;;;24390:12;;;24383:36;24443:3;24435:12;;22760:1693;-1:-1:-1;;;;22760:1693:1:o;24458:461::-;24720:31;24715:3;24708:44;24690:3;24781:6;24775:13;24797:75;24865:6;24860:2;24855:3;24851:12;24844:4;24836:6;24832:17;24797:75;:::i;:::-;24892:16;;;;24910:2;24888:25;;24458:461;-1:-1:-1;;24458:461:1:o;25233:245::-;25300:6;25353:2;25341:9;25332:7;25328:23;25324:32;25321:52;;;25369:1;25366;25359:12;25321:52;25401:9;25395:16;25420:28;25442:5;25420:28;:::i;26511:427::-;26771:1;26766:3;26759:14;26741:3;26802:6;26796:13;26818:74;26885:6;26881:1;26876:3;26872:11;26865:4;26857:6;26853:17;26818:74;:::i;:::-;26912:16;;;;26930:1;26908:24;;26511:427;-1:-1:-1;;26511:427:1:o;26943:462::-;-1:-1:-1;;;27191:47:1;;27261:13;;27173:3;;27283:75;27261:13;27346:2;27337:12;;27330:4;27318:17;;27283:75;:::i;:::-;27378:16;;;;27396:2;27374:25;;26943:462;-1:-1:-1;;26943:462:1:o;28316:249::-;28385:6;28438:2;28426:9;28417:7;28413:23;28409:32;28406:52;;;28454:1;28451;28444:12;28406:52;28486:9;28480:16;28505:30;28529:5;28505:30;:::i;29258:662::-;-1:-1:-1;;;;;29537:15:1;;;29519:34;;29589:15;;29584:2;29569:18;;29562:43;29636:2;29621:18;;29614:34;;;29684:3;29679:2;29664:18;;29657:31;;;29704:19;;29697:35;;;29462:4;29725:6;29775;29499:3;29754:19;;29741:49;29840:1;29834:3;29825:6;29814:9;29810:22;29806:32;29799:43;29910:3;29903:2;29899:7;29894:2;29886:6;29882:15;29878:29;29867:9;29863:45;29859:55;29851:63;;29258:662;;;;;;;;:::o;29925:128::-;29992:9;;;30013:11;;;30010:37;;;30027:18;;:::i;30058:125::-;30123:9;;;30144:10;;;30141:36;;;30157:18;;:::i;30188:127::-;30249:10;30244:3;30240:20;30237:1;30230:31;30280:4;30277:1;30270:15;30304:4;30301:1;30294:15;30320:136;30359:3;30387:5;30377:39;;30396:18;;:::i;:::-;-1:-1:-1;;;30432:18:1;;30320:136::o

Swarm Source

ipfs://0a818f8f65358f192c7cceb0f2f6dd2e30cf8e48298a42d5f485a088c7ee9779

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
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.