ETH Price: $2,433.80 (+1.54%)
 

Overview

ETH Balance

0.00400701426 ETH

Eth Value

$9.75 (@ $2,433.80/ETH)
Transaction Hash
Method
Block
From
To
Safe Transfer Fr...188534892023-12-24 5:15:47317 days ago1703394947IN
0x8bb765AE...CE4970DA5
0 ETH0.0016057224.5159534
Set Approval For...177515192023-07-22 22:02:59472 days ago1690063379IN
0x8bb765AE...CE4970DA5
0 ETH0.0004371618
Set Approval For...162784122022-12-27 20:16:35679 days ago1672172195IN
0x8bb765AE...CE4970DA5
0 ETH0.0009740321.08336713
Set Approval For...162290472022-12-20 22:59:11686 days ago1671577151IN
0x8bb765AE...CE4970DA5
0 ETH0.0006681814.46316474
Traverse Chains162090252022-12-18 3:55:35688 days ago1671335735IN
0x8bb765AE...CE4970DA5
0.00001289 ETH0.002992415.66260966
Traverse Chains162090102022-12-18 3:52:35688 days ago1671335555IN
0x8bb765AE...CE4970DA5
0.00001289 ETH0.002304512.06207294
Traverse Chains162042192022-12-17 11:48:47689 days ago1671277727IN
0x8bb765AE...CE4970DA5
0.0000131 ETH0.0027189514.23136788
Traverse Chains162042182022-12-17 11:48:35689 days ago1671277715IN
0x8bb765AE...CE4970DA5
0.0000131 ETH0.0029249115.30934935
Traverse Chains162040732022-12-17 11:19:23689 days ago1671275963IN
0x8bb765AE...CE4970DA5
0.0000131 ETH0.0027236714.25605498
Traverse Chains162040712022-12-17 11:18:59689 days ago1671275939IN
0x8bb765AE...CE4970DA5
0.0000131 ETH0.003592715.94957411
Set Presale161939762022-12-16 1:28:47690 days ago1671154127IN
0x8bb765AE...CE4970DA5
0 ETH0.0004108514.73924604
Set Approval For...161613592022-12-11 12:06:47695 days ago1670760407IN
0x8bb765AE...CE4970DA5
0 ETH0.0008200517.75046832
Set Approval For...158702272022-10-31 19:47:59736 days ago1667245679IN
0x8bb765AE...CE4970DA5
0 ETH0.0004414818.17777008
Set Approval For...157257332022-10-11 15:22:11756 days ago1665501731IN
0x8bb765AE...CE4970DA5
0 ETH0.0006962928.5705093
Set Trusted Remo...155840782022-09-21 20:19:11776 days ago1663791551IN
0x8bb765AE...CE4970DA5
0 ETH0.0013954818.01852624
Set Trusted Remo...155840772022-09-21 20:18:59776 days ago1663791539IN
0x8bb765AE...CE4970DA5
0 ETH0.0014181518.31132564
Set Trusted Remo...155840772022-09-21 20:18:59776 days ago1663791539IN
0x8bb765AE...CE4970DA5
0 ETH0.0014181518.31132564
Set Trusted Remo...155840772022-09-21 20:18:59776 days ago1663791539IN
0x8bb765AE...CE4970DA5
0 ETH0.0014181518.31132564
Set Trusted Remo...155840762022-09-21 20:18:47776 days ago1663791527IN
0x8bb765AE...CE4970DA5
0 ETH0.0014810319.12321933
Set Trusted Remo...155840762022-09-21 20:18:47776 days ago1663791527IN
0x8bb765AE...CE4970DA5
0 ETH0.0014810319.12321933
Set Trusted Remo...155778132022-09-20 22:58:23777 days ago1663714703IN
0x8bb765AE...CE4970DA5
0 ETH0.000223286.87722048
Set Trusted Remo...155778132022-09-20 22:58:23777 days ago1663714703IN
0x8bb765AE...CE4970DA5
0 ETH0.000223286.87722048
Set Trusted Remo...155778122022-09-20 22:58:11777 days ago1663714691IN
0x8bb765AE...CE4970DA5
0 ETH0.000228697.04358502
Set Trusted Remo...155778122022-09-20 22:58:11777 days ago1663714691IN
0x8bb765AE...CE4970DA5
0 ETH0.000228697.04358502
Set Trusted Remo...155778122022-09-20 22:58:11777 days ago1663714691IN
0x8bb765AE...CE4970DA5
0 ETH0.000228697.04358502
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
162090252022-12-18 3:55:35688 days ago1671335735
0x8bb765AE...CE4970DA5
0.00001289 ETH
162090102022-12-18 3:52:35688 days ago1671335555
0x8bb765AE...CE4970DA5
0.00001289 ETH
162042192022-12-17 11:48:47689 days ago1671277727
0x8bb765AE...CE4970DA5
0.0000131 ETH
162042182022-12-17 11:48:35689 days ago1671277715
0x8bb765AE...CE4970DA5
0.0000131 ETH
162040732022-12-17 11:19:23689 days ago1671275963
0x8bb765AE...CE4970DA5
0.0000131 ETH
162040712022-12-17 11:18:59689 days ago1671275939
0x8bb765AE...CE4970DA5
0.0000131 ETH
158721352022-11-01 2:11:47735 days ago1667268707
0x8bb765AE...CE4970DA5
0.0003 ETH
154479102022-08-31 17:21:13797 days ago1661966473
0x8bb765AE...CE4970DA5
0.01246923 ETH
153098022022-08-09 19:24:25819 days ago1660073065
0x8bb765AE...CE4970DA5
0.0001125 ETH
153095272022-08-09 18:23:36819 days ago1660069416
0x8bb765AE...CE4970DA5
0.00015 ETH
153090272022-08-09 16:23:20819 days ago1660062200
0x8bb765AE...CE4970DA5
0.01237736 ETH
153029982022-08-08 17:51:45820 days ago1659981105
0x8bb765AE...CE4970DA5
0.00707277 ETH
152941772022-08-07 8:49:03821 days ago1659862143
0x8bb765AE...CE4970DA5
0.00007124 ETH
152899242022-08-06 16:58:33822 days ago1659805113
0x8bb765AE...CE4970DA5
0.00006 ETH
152892022022-08-06 14:12:05822 days ago1659795125
0x8bb765AE...CE4970DA5
0.00006 ETH
152891972022-08-06 14:08:51822 days ago1659794931
0x8bb765AE...CE4970DA5
0.00006 ETH
152891242022-08-06 13:53:37822 days ago1659794017
0x8bb765AE...CE4970DA5
0.00006 ETH
152854642022-08-06 0:02:48822 days ago1659744168
0x8bb765AE...CE4970DA5
0.0001125 ETH
152854582022-08-06 0:01:40822 days ago1659744100
0x8bb765AE...CE4970DA5
0.000075 ETH
152854532022-08-06 0:01:03822 days ago1659744063
0x8bb765AE...CE4970DA5
0.00003375 ETH
152853692022-08-05 23:45:11822 days ago1659743111
0x8bb765AE...CE4970DA5
0.0000375 ETH
152845382022-08-05 20:43:59823 days ago1659732239
0x8bb765AE...CE4970DA5
0.00036 ETH
152837422022-08-05 17:48:03823 days ago1659721683
0x8bb765AE...CE4970DA5
0.0001875 ETH
152837392022-08-05 17:47:34823 days ago1659721654
0x8bb765AE...CE4970DA5
0.000135 ETH
152821232022-08-05 11:47:30823 days ago1659700050
0x8bb765AE...CE4970DA5
0.00036 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TinyDaemons

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 100 runs

Other Settings:
default evmVersion
File 1 of 40 : TinyDaemons.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: TinyDaemons.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: TinyDaemons an LZ ERC 721
 */

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

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "./access/MaxAccess.sol";
import "./modules/TimeCop.sol";
import "./modules/NonblockingReceiver.sol";
import "./modules/ContractURI.sol";
import "./modules/PaymentSplitterV2.sol";
import "./modules/lzLlamas.sol";
import "./eip/2981/ERC2981Collection.sol";

contract TinyDaemons is MaxAccess
                      , TimeCop
                      , ContractURI
                      , PaymentSplitterV2
                      , ERC2981Collection
                      , lzLlamas
                      , ERC721
                      , ERC721Burnable
                      , NonblockingReceiver {

  using Strings for uint256;

  uint private gasForDestinationLzReceive = 350000;
  string base;

  event UpdatedBaseURI(string _old, string _new);
  event ThankYou(address user, uint amount);

  constructor() ERC721("TinyDaemons", "TINYDMN") {}

  modifier presaleChecks() {
    if (balanceOf(msg.sender) >= 4) {
      revert MaxSplaining({
        reason: string(
                  abi.encodePacked(
                    "Token: Ok ",
                    Strings.toHexString(uint160(msg.sender), 20),
                    " you have ",
                    Strings.toString(balanceOf(msg.sender)),
                    " maximum at this time is 4."
                  )
                )
      });
    }
    _;
  }

  modifier saleChecks() {
    if (balanceOf(msg.sender) >= 10) {
      revert MaxSplaining({
        reason: string(
                  abi.encodePacked(
                    "Token: Ok ",
                    Strings.toHexString(uint160(msg.sender), 20),
                    " you have ",
                    Strings.toString(balanceOf(msg.sender)),
                    " maximum at this time is 10."
                  )
                )
      });
    }
    _;
  }

  function presaleMint(
    uint quant
  ) external
    onlyPresale()
    presaleChecks() {
    if (quant > 2) {
      revert MaxSplaining({
        reason: string(
                  abi.encodePacked(
                    "Token: Ok ",
                    Strings.toHexString(uint160(msg.sender), 20),
                    " you wanted to mint ",
                    Strings.toString(quant),
                    " 2 or less please."
                  )
                )
      });
    }
    for (uint x = 0; x < quant;) {
      // this is a little sneaky to ensure you can't mint 1-2-2
      if (balanceOf(msg.sender) >= 4) {
        revert MaxSplaining({
        reason: string(
                  abi.encodePacked(
                    "Token: Ok ",
                    Strings.toHexString(uint160(msg.sender), 20),
                    " you wanted to mint ",
                    Strings.toString(quant),
                    " that puts you at ",
                    Strings.toString(quant + balanceOf(msg.sender)),
                    " maximum at this time is 4."
                  )
                )
        });
      }
      // mint it
      _safeMint(msg.sender, _nextUp());
      _oneRegularMint();
      unchecked { ++x; }
    }
  }

  function publicMint()
    external 
    onlySale()
    saleChecks() {
    _safeMint(msg.sender, _nextUp());
    _oneRegularMint();
  }

  function teamMint()
    external
    onlyDev() {
    uint quant = this.minterTeamMintsRemaining();
    for (uint x = 0; x < quant;) {
      // mint it
      _safeMint(this.owner(), _nextUp());
      _oneTeamMint();
      unchecked { ++x; }
    }
  }
    
  function donate()
    external
    payable {
    // thank you
    emit ThankYou(msg.sender, msg.value);
  }

  // @notice: Function to receive ether, msg.data must be empty
  receive() 
    external
    payable {
    // From PaymentSplitter.sol
    emit PaymentReceived(msg.sender, msg.value);
  }

  // @notice: Function to receive ether, msg.data is not empty
  fallback()
    external
    payable {
    // From PaymentSplitter.sol
    emit PaymentReceived(msg.sender, msg.value);
  }

  // @notice this is a public getter for ETH blance on contract
  function getBalance()
    external
    view
    returns (uint) {
    return address(this).balance;
  }

  // @notice: This sets the data for LZ minting
  // @param startNumber: What tokenID number to start with
  // @param authMint: How many to mint on this chain
  // @param teamMints: How many for team mint on this chain
  // @param string memory img: Provenance Hash of images in sequence
  // @param string memory json: Provenance Hash of metadata in sequence
  // @param newAddress: The address for the LZ Endpoint (see LZ docs)
  function setMinter (
    uint startNumber
  , uint authMint
  , uint teamMints
  , string memory img
  , string memory json
  , address newAddress
  ) external
    onlyDev {
    _setLZLlamasEngine( startNumber
                      , authMint
                      , teamMints);
    _setProvenance( img
                  , json);
    endpoint = ILayerZeroEndpoint(newAddress);
  }

  /*
   *     #@+                                             .                                     
   *    -@@#                                             =#*+=---+**-                          
   *    %@@.                                               .==*@@@@+-                          
   *   =@@*                                                  -@@@*                             
   *  .@@@                                                 .#@@#:                              
   *  *@@+        :                          ::   -:    +**@%@*=*-            .:   --    .:    
   *  @@%      =%@@@#@@. -@@*   +*:  .*##+.  @@- *@@=   =%@@**++*+    .+##*.  @@= *@@= .%@@%   
   * +@@=     #@@#--@@@. #@@*  =@@+ =@@@%@+ +@@:#--*#- -#%%.         -@@@#@* =@@:#-:*%*%@#-%= .
   * @@@    :#@@+.=@@@: .@@@ :*@@% =@@@%%= .@@#@-     .#@*          :@@@#%+ .%@#%=    %@##*@#*@
   * @@#  .*@@@%#%-@@* +@@@#*@#@@#%@@+: .-#*@@@*      *%%     ....  +@*: .-#*@@@*    =@% :%%-: 
   * =@@.=@@=-%#-  +@%@#:-*#+.@@@*:.%++%%=.%@@+       @@%#%**#@%@@@@*@*+%%+.%@@*     .%##@#    
   *   -==:         .-:     =%@@.    ::.   =%:        =%##+-.      .::::.   -#-        :-.     
   *                      +@@@@=                                                               
   *                    .%@-*@#                                                                
   *                    %@.=@@.                                                                
   *                    =@%@%:                                                                 
   *
   * @dev: This is the LayerZero functions for NonblockingReceiver.sol and more
   */

  // @notice: This function transfers the nft from your address on the 
  //          source chain to the same address on the destination chain
  // @param _chainId: the uint16 of desination chain (see LZ docs)
  // @param tokenId: tokenID to be sent
  function traverseChains(
    uint16 _chainId
  , uint tokenId
  ) public
    payable {
    if (msg.sender != ownerOf(tokenId)) {
      revert Unauthorized();
    }
    if (trustedRemoteLookup[_chainId].length == 0) {
      revert MaxSplaining({
        reason: "Token: Ok the Dev didn't set this paramater, contact MaxFlowO2.eth."
      });
    }

    // burn NFT, eliminating it from circulation on src chain
    _burn(tokenId);
    // fixes totalSupply()
    _subOne();

    // abi.encode() the payload with the values to send
    bytes memory payload = abi.encode(
                             msg.sender
                           , tokenId);

    // encode adapterParams to specify more gas for the destination
    uint16 version = 1;
    bytes memory adapterParams = abi.encodePacked(
                                   version
                                 , gasForDestinationLzReceive);

    // get the fees we need to pay to LayerZero + Relayer to cover message delivery
    // you will be refunded for extra gas paid
    (uint messageFee, ) = endpoint.estimateFees(
                            _chainId
                          , address(this)
                          , payload
                          , false
                          , adapterParams);

    // revert this transaction if the fees are not met
    if (messageFee > msg.value) {
      revert MaxSplaining({
        reason: string(
                  abi.encodePacked(
                    "Token: ",
                    Strings.toHexString(uint160(msg.sender), 20),
                    " sent ",
                    Strings.toString(msg.value),
                    " instead of ",
                    Strings.toString(messageFee)
                  )
                )
      });
    }

    // send the transaction to the endpoint
    endpoint.send{value: msg.value}(
      _chainId,                           // destination chainId
      trustedRemoteLookup[_chainId],      // destination address of nft contract
      payload,                            // abi.encoded()'ed bytes
      payable(msg.sender),                // refund address
      address(0x0),                       // 'zroPaymentAddress' unused for this
      adapterParams                       // txParameters 
    );
  }

  // @notice: just in case this fixed variable limits us from future integrations
  // @param newVal: new value for gas amount
  function setGasForDestinationLzReceive(
    uint newVal
  ) external onlyOwner {
    gasForDestinationLzReceive = newVal;
  }

  // @notice internal function to mint NFT from migration
  // @param _srcChainId - the source endpoint identifier
  // @param _srcAddress - the source sending contract address from the source chain
  // @param _nonce - the ordered message nonce
  // @param _payload - the signed payload is the UA bytes has encoded to be sent
  function _LzReceive(
    uint16 _srcChainId
  , bytes memory _srcAddress
  , uint64 _nonce
  , bytes memory _payload
  ) override
    internal {
    // decode
    (address toAddr, uint tokenId) = abi.decode(_payload, (address, uint));

    // mint the tokens back into existence on destination chain
    _safeMint(toAddr, tokenId);
    // fixes totalSupply()
    _addOne();
  }

  // @notice: will return gas value for LZ
  // @return: uint for gas value
  function currentLZGas()
    external
    view
    returns (uint256) {
    return gasForDestinationLzReceive;
  }  

  /*
   *       .=*#%@@@@%+                                     .:.                                 
   * .-+*%@@@@@@@-:::-*+                         =-=+**#%%@@@@%:     -*%@@@@%*-            #@@%
   * :*@%*=:-@@@*                                +%@@%##*+@@@@#    =@@@@#=.   =@:        +@@@@@
   *       .@@@#                                        =@@@%-   -#@@@#:       @@:     +@@@@@@=
   *      .@@@#                                        *@@@*   .#@@@%:        =@@-   =@@@@@@@% 
   *     :@@@*                                   -*##%@@@@@#:  :*##+         :@@#      --@%@@= 
   *    .@@@@===-     .    ..                     *@@@@@+++.                -@@%        #%%@#  
   * -#%@@@@@%##*=   @@@  =@@@   -+*+-             =@@@-                   =@@*.       :@#@@.  
   *  +%@@@:        =@@# #++@@:-*@@@@@=           -@@@:                  .=%*          =#@@#   
   *   %@@=      =+ #@@:#=: .++*@@*.%@: .:       :@@%.                  -*#-           %#@@-   
   *  .@@@     -#%=.@@%%#.    :@@*    :---       @@@.                  :#+            .%@@@    
   *  =@@+  .+%@%- *@@%%-     *@@   =%%++       :@@*                .-*+....:-*.      -#@@#:   
   *   #@*.+@@@=  :@@@@-      +@%=#@@%-         .%@-               #%@@@@@@@@@@*.   .++@@@@@*  
   *    -*#*+:    -@@+.        =###*:             =-               -**++++=-::::    :+**+=-.   
   *
   * @dev: These are the ERC721 functions/overrides plus ERC165 at the end
   */

  // @notice will update _baseURI() by onlyDeveloper() role
  // @param _base: Base for NFT's
  function setBaseURI(
    string memory _base
    )
    public
    onlyDev() {
    string memory old = base;
    base = _base;
    emit UpdatedBaseURI(old, base);
  }

  // @notice: This override sets _base as the string for tokenURI(tokenId)
  function _baseURI()
    internal
    view
    override
    returns (string memory) {
    return base;
  }

  // @notice: This override is for making string/number now string/number.json
  // @param tokenId: tokenId to pull URI for
  function tokenURI(
    uint256 tokenId
  ) public
    view
    virtual
    override (ERC721)
    returns (string memory) {
    if (!_exists(tokenId)) {
      revert MaxSplaining({
        reason: string(
                  abi.encodePacked(
                    "ERC721Metadata: URI query for ",
                    Strings.toString(tokenId),
                    " returns nonexistent token"
                  )
                )
      });
    }
    string memory baseURI = _baseURI();
    string memory json = ".json";
    return bytes(baseURI).length > 0 ? string(
                                         abi.encodePacked(
                                           baseURI
                                         , tokenId.toString()
                                         , json)
                                       ) : "";
  }

  // @notice: This override is to correct totalSupply()
  // @param tokenId: tokenId to burn
  function burn(
    uint256 tokenId
  ) public
    virtual
    override(ERC721Burnable) {
    //solhint-disable-next-line max-line-length
    if (!_isApprovedOrOwner(_msgSender(), tokenId)) {
      revert MaxSplaining({
        reason: string(
                  abi.encodePacked(
                    "ERC721Burnable: ",
                    Strings.toHexString(uint160(msg.sender), 20),
                    " is not owner nor approved"
                  )
                )
      });
    }
    _burn(tokenId);
    // fixes totalSupply()
    _subOne();
  }

  // @notice: Standard override for ERC165
  // @param interfaceId: interfaceId to check for compliance
  // @return: bool if interfaceId is supported
  function supportsInterface(
    bytes4 interfaceId
  ) public
    view
    virtual
    override (
      ERC721
    , IERC165
    ) returns (bool) {
    return (
      interfaceId == type(IRole).interfaceId  ||
      interfaceId == type(IDeveloper).interfaceId  ||
      interfaceId == type(IDeveloperV2).interfaceId  ||
      interfaceId == type(IOwner).interfaceId  ||
      interfaceId == type(IOwnerV2).interfaceId  ||
      interfaceId == type(IERC2981).interfaceId  ||
      interfaceId == type(IMAX2981).interfaceId  ||
      interfaceId == type(IMAXPaymentSplitter).interfaceId  ||
      interfaceId == type(IPaymentSplitter).interfaceId  ||
      interfaceId == type(IMAX721).interfaceId  ||
      interfaceId == type(ILlamas).interfaceId  ||
      interfaceId == type(lzILlamas).interfaceId  ||
      interfaceId == type(ITimeCop).interfaceId  ||
      interfaceId == type(IContractURI).interfaceId  ||
      interfaceId == type(IMAXContractURI).interfaceId  ||
      interfaceId == type(ILayerZeroReceiver).interfaceId  ||
      super.supportsInterface(interfaceId)
    );
  }
}

File 2 of 40 : lzLlamas.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: lzLlamas.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Solidity for Llama/BAYC Mint engine, does Provenance for Metadata/Images, for lzModules
 * Source: https://etherscan.io/address/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d#code
 */

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

import "./lzILlamas.sol";
import "../lib/PsuedoRand.sol";
import "../lib/CountersV2.sol";

abstract contract lzLlamas is lzILlamas {

  using PsuedoRand for PsuedoRand.Engine;
  using CountersV2 for CountersV2.Counter;

  PsuedoRand.Engine private llamas;
  CountersV2.Counter private tokensOnChain;
  uint private tokenStartNumber;

  event SetStartNumbers(uint numberToMint, uint startingID, uint endingID);

  // @dev this is for any team mint that happens, must be included in mint...
  function _oneTeamMint()
    internal {
    llamas.battersUp();
    llamas.battersUpTeam();
    tokensOnChain.increment();
  }

  // @dev this is for any mint outside of a team mint, must be included in mint...
  function _oneRegularMint()
    internal {
    llamas.battersUp();
    tokensOnChain.increment();
  }

  // @dev this is to add one to on chain minted
  function _addOne()
    internal {
    tokensOnChain.increment();
  }

  // @dev this is to substract one to on chain minted
  function _subOne()
    internal {
    tokensOnChain.decrement();
  }

  // @dev this will set the boolean for minter status
  // @param toggle: bool for enabled or not
  function _setStatus(
    bool toggle
  ) internal {
    llamas.setStatus(toggle);
  }

  // @dev this will set the minter fees
  // @param number: uint for fees in wei.
  function _setMintFees(
    uint number
  ) internal {
    llamas.setFees(number);
  }

  // @dev this will set the mint engine
  // @param _startID: uint for startingID number (say 2000)
  // @param _mintingCap: uint for publicMint() capacity of this chain
  // @param _teamMints: uint for maximum teamMints() capacity on this chain
  function _setLZLlamasEngine(
    uint _startID
  , uint _mintingCap
  , uint _teamMints
  ) internal {
    tokenStartNumber = _startID;
    llamas.setMaxCap(_mintingCap);
    llamas.setMaxTeam(_teamMints);

    emit SetStartNumbers( _mintingCap
                        , _startID
                        , _mintingCap + _startID);
  }

  // @dev this will set the Provenance Hashes
  // @param string memory img - Provenance Hash of images in sequence
  // @param string memory json - Provenance Hash of metadata in sequence
  // @notice: This will set the start number as well, make sure to set MaxCap
  //  also can be a hyperlink... sha3... ipfs.. whatever.
  function _setProvenance(
    string memory img
  , string memory json
  ) internal {
    llamas.setProvJSON(json);
    llamas.setProvIMG(img);
    llamas.setStartNumber();
  }

  function _nextUp()
    internal
    view
    returns (uint) {
    return tokenStartNumber + llamas.mintID();
  }

  // @dev will return status of Minter
  // @return - bool of active or not
  function minterStatus()
    external
    view
    virtual
    override
    returns (bool) {
    return llamas.status;
  }

  // @dev will return minting fees
  // @return - uint of mint costs in wei
  function minterFees()
    external
    view
    virtual
    override
    returns (uint) {
    return llamas.mintFee;
  }

  // @dev will return maximum mint capacity
  // @return - uint of maximum mints allowed
  function minterMaximumCapacity()
    external
    view
    virtual
    override
    returns (uint) {
    return llamas.maxCapacity;
  }

  // @dev will return maximum mint capacity
  // @return - uint of maximum mints allowed
  function minterMintsRemaining()
    external
    view
    virtual
    returns (uint) {
    return llamas.maxCapacity - llamas.showMinted();
  }

  // @dev will return maximum mint capacity
  // @return - uint of maximum mints allowed
  function minterCurrentMints()
    external
    view
    virtual
    returns (uint) {
    return llamas.showMinted();
  }

  // @dev will return maximum "team minting" capacity
  // @return - uint of maximum airdrops or team mints allowed
  function minterMaximumTeamMints()
    external
    view
    virtual
    override
    returns (uint) {
    return llamas.maxTeamMints;
  }

  // @dev will return "team mints" left
  // @return - uint of remaing airdrops or team mints
  function minterTeamMintsRemaining()
    external
    view
    virtual
    override
    returns (uint) {
    return llamas.maxTeamMints - llamas.showTeam();
  }

  // @dev will return "team mints" count
  // @return - uint of airdrops or team mints done
  function minterTeamMintsCount()
    external
    view
    virtual
    override
    returns (uint) {
    return llamas.showTeam();
  }

  // @dev: will return total supply for mint
  // @return: uint for this mint
  function totalSupply()
    external
    view
    virtual
    override
    returns (uint256) {
    return tokensOnChain.current();
  }

  // @dev: will return Provenance hash of images
  // @return: string memory of the Images Hash (sha256)
  function RevealProvenanceImages() 
    external 
    view 
    virtual
    override 
    returns (string memory) {
    return llamas.ProvenanceIMG;
  }

  // @dev: will return Provenance hash of metadata
  // @return: string memory of the Metadata Hash (sha256)
  function RevealProvenanceJSON()
    external
    view
    virtual
    override
    returns (string memory) {
    return llamas.ProvenanceJSON;
  }

  // @dev: will return starting number for mint
  // @return: uint of the start number
  function RevealStartNumber()
    external
    view
    virtual
    override
    returns (uint256) {
    return llamas.startNumber;
  }

  // @dev: this is will show the start number for this chain's start number
  // @return: uint of start number
  function lzStartNumber()
    external
    view
    virtual
    override
    returns (uint256) {
    return tokenStartNumber;
  }
}

File 3 of 40 : lzILlamas.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: lzILlamas.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Interface for Llama/BAYC Mint engine, does Provenance for Metadata/Images
 * Source: https://etherscan.io/address/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d#code
 */

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

import "./ILlamas.sol";

///
/// @dev Interface for the ILlamas Standard v2.0 for LayerZero
///  this includes metadata with images
///

interface lzILlamas is ILlamas {

  // @dev: this is will show the start number for this chain's start number
  // @return: uint of start number
  function lzStartNumber()
    external
    view
    returns (uint256);

}

File 4 of 40 : TimeCop.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: TimeCop.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Time based mechanism for Solidity
 */

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

import "./ITimeCop.sol";
import "../access/MaxAccess.sol";

abstract contract TimeCop is MaxAccess
                           , ITimeCop {

   uint private startPresale;
   uint private presaleDuration;

   event PresaleSet(uint start, uint length);

  function setPresale(
    uint time
  , uint duration
  ) external
    onlyDev() {
    startPresale = time;
    presaleDuration = duration;
    emit PresaleSet(time, duration);
  }

  function showPresaleStart()
    external
    view
    virtual
    override (ITimeCop)
    returns (uint) {
    return startPresale;
  }

  function showStart()
    external
    view
    virtual
    override (ITimeCop)
    returns (uint) {
    return startPresale + presaleDuration;
  }

  function showPresaleTimes()
    external
    view
    virtual
    override (ITimeCop)
    returns (uint, uint) {
    return (
      startPresale
    , startPresale + presaleDuration
    );
  }

    modifier onlyPresale() {
    if (block.timestamp < startPresale) {
      revert TooSoonJunior({
        yourTime: block.timestamp
      , hitTime: startPresale
      });
    }
    if (block.timestamp >= startPresale + presaleDuration) {
      revert TooLateBoomer({
        yourTime: block.timestamp
      , hitTime: startPresale + presaleDuration
      });
    }
    _;
  }

    modifier onlySale() {
    if (block.timestamp < startPresale + presaleDuration) {
      revert TooSoonJunior({
        yourTime: block.timestamp
      , hitTime: startPresale + presaleDuration
      });
    }
    if (startPresale == 0) {
      revert MaxSplaining({
        reason: "TimeCop: You've been Time Copped. NGL onlyDev() hasn't set the time"
      });
    }
    _;
  }
}

File 5 of 40 : PaymentSplitterV2.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: PaymentSplitterV2.sol
 * @author: OG was OZ, rewritten by Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Updated to add/subtract payees
 */

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

import "./IMAXPaymentSplitter.sol";
import "../access/MaxAccess.sol";
import "@openzeppelin/contracts/utils/Address.sol";

// Removal of SafeMath due to ^0.8.0 standards, not needed

/**
 * @title PaymentSplitter
 * @dev This contract allows to split Ether payments among a group of accounts. The sender does not need to be aware
 * that the Ether will be split in this way, since it is handled transparently by the contract.
 *
 * The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each
 * account to a number of shares. Of all the Ether that this contract receives, each account will then be able to claim
 * an amount proportional to the percentage of total shares they were assigned.
 *
 * `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the
 * accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release}
 * function.
 */

abstract contract PaymentSplitterV2 is MaxAccess
                                     , IMAXPaymentSplitter {

  event PayeeAdded(address account, uint256 shares);
  event PaymentReleased(address to, uint256 amount);
  event PaymentReceived(address from, uint256 amount);
  event PayeeRemoved(address account, uint256 shares);
  event PayeesReset();

  uint256 private _totalShares;
  uint256 private _totalReleased;
  mapping(address => uint256) private _shares;
  mapping(address => uint256) private _released;
  address[] private _payees;

  /**
   * @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully
   * reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the
   * reliability of the events, and not the actual splitting of Ether.
   *
   * To learn more about this see the Solidity documentation for
   * https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback
   * functions].
   *
   *  receive() external payable virtual {
   *    emit PaymentReceived(msg.sender, msg.value);
   *  }
   *
   *  // Fallback function is called when msg.data is not empty
   *  // Added to PaymentSplitter.sol
   *  fallback() external payable {
   *    emit PaymentReceived(msg.sender, msg.value);
   *  }
   *
   * receive() and fallback() to be handled at final contract
   */

  /**
   * @dev Getter for the total shares held by payees.
   */
  function totalShares() 
    external
    view
    virtual
    override
    returns (uint256) {
    return _totalShares;
  }

  /**
   * @dev Getter for the total amount of Ether already released.
   */
  function totalReleased()
    external
    view
    virtual
    override
    returns (uint256) {
    return _totalReleased;
  }

  /**
   * @dev Getter for the amount of shares held by an account.
   */
  function shares(
    address account
  ) external
    view
    virtual
    override
    returns (uint256) {
    return _shares[account];
  }

  /**
   * @dev Getter for the amount of Ether already released to a payee.
   */
  function released(
    address account
  ) external
    view
    virtual
    override
    returns (uint256) {
    return _released[account];
  }

  /**
   * @dev Getter for the address of the payee number `index`.
   */
  function payee(
    uint256 index
  ) external
    view
    virtual
    override
    returns (address) {
    return _payees[index];
  }

  /**
   * @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the
   * total shares and their previous withdrawals.
   */
  // This function was updated from "account" to msg.sender
  function claim()
    external
    virtual
    override {
    address check = msg.sender;

    if (_shares[check] == 0) {
      revert MaxSplaining({
        reason: string(
                  abi.encodePacked(
                    "PaymentSplitter: ",
                    Strings.toHexString(uint160(msg.sender), 20),
                    " has no shares."
                  )
                )
      });
    }

    uint256 totalReceived = address(this).balance + _totalReleased;
    uint256 payment = (totalReceived * _shares[check]) / _totalShares - _released[check];

    if (payment == 0) {
      revert MaxSplaining({
        reason: string(
                  abi.encodePacked(
                    "PaymentSplitter: ",
                    Strings.toHexString(uint160(msg.sender), 20),
                    " is not due payment."
                  )
                )
      });
    }

    _released[check] = _released[check] + payment;
    _totalReleased = _totalReleased + payment;

    Address.sendValue(payable(check), payment);
    emit PaymentReleased(check, payment);
  }

  // now the internal logic of this contract

  /**
   * @dev Add a new payee to the contract.
   * @param account The address of the payee to add.
   * @param shares_ The number of shares owned by the payee.
   */
  // This function was updated to internal
  function _addPayee(
    address account
  , uint256 shares_
  ) internal {
    if (account == address(0)) {
      revert MaxSplaining({
        reason: "PaymentSplitter: account is the zero address"
      });
    } else if (shares_ == 0) {
      revert MaxSplaining({
        reason: "PaymentSplitter: shares are 0"
      });
    } else if (_shares[account] > 0) {
      revert MaxSplaining({
        reason: string(
                  abi.encodePacked(
                    "PaymentSplitter: ",
                    Strings.toHexString(uint160(account), 20),
                    " already has ",
                    Strings.toString(_shares[account]),
                    " shares."
                  )
                )
      });
    }

    _payees.push(account);
    _shares[account] = shares_;
    _totalShares = _totalShares + shares_;

    emit PayeeAdded(account, shares_);
  }

  /**
   * @dev finds index in array
   * @param account The address of the payee
   */
  function _findIndex(
    address account
  ) internal
    view
    returns (uint index) {
    uint max = _payees.length;
    for (uint i = 0; i < max;) {
      if (_payees[i] == account) {
        index = i;
      }
      unchecked { ++i; }
    }
  }

  /**
   * @dev Remove a payee to the contract.
   * @param account The address of the payee to remove.
   * leaves all payment data in the contract incase something was claimed
   */
  function _removePayee(
    address account
  ) internal {
    if (account == address(0)) {
      revert MaxSplaining({
        reason: "PaymentSplitter: account is the zero address"
      });
    } 

    // This finds the payee in the array _payees and removes it
    uint remove = _findIndex(account);
    address last = _payees[_payees.length - 1];
    _payees[remove] = last;
    _payees.pop();

    uint removeTwo = _shares[account];
    _shares[account] = 0;
    _totalShares = _totalShares - removeTwo;

    emit PayeeRemoved(account, removeTwo);
  }

  /**
   * @dev clears all data in PaymentSplitterV2
   * leaves all payment data in the contract incase something was claimed
   */
  function _clearAll()
    internal {
    uint max = _payees.length;
    for (uint i = 0; i < max;) {
      address account = _payees[i];
      _shares[account] = 0;
      unchecked { ++i; }
    }
    delete _totalShares;
    delete _payees;
    emit PayeesReset();
  }

  // @notice: This adds a payment split to PaymentSplitterV2.sol
  // @param newSplit: Address of payee
  // @param newShares: Shares to send user
  function addSplit (
    address newSplit
  , uint256 newShares
  ) external
    virtual
    override
    onlyDev() {
    _addPayee(newSplit, newShares);
  }

  // @notice: This removes a payment split on PaymentSplitterV2.sol
  // @param remSplit: Address of payee to remove
  function removeSplit (
    address remSplit
  ) external
    virtual
    override
    onlyDev() {
    _removePayee(remSplit);
  }

  // @notice: This removes all payment splits on PaymentSplitterV2.sol
  function clearSplits()
    external
    virtual
    override
    onlyDev() {
    _clearAll();
  }
}

File 6 of 40 : NonblockingReceiver.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: NonblockingReceiver.sol
 * @author: OG?? Rewrite: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: LZ non blocking reciever
 * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code
 * Remember to set all the trustedRemoteLookups with trustedRemoteLookup[chainID] = contract address
 */

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;

import "./ILayerZeroReceiver.sol";
import "./ILayerZeroEndpoint.sol";
import "../access/MaxAccess.sol";

abstract contract NonblockingReceiver is MaxAccess, ILayerZeroReceiver {

  ILayerZeroEndpoint internal endpoint;

  struct FailedMessages {
    uint payloadLength;
    bytes32 payloadHash;
  }

  mapping(uint16 => mapping(bytes => mapping(uint => FailedMessages))) public failedMessages;
  mapping(uint16 => bytes) public trustedRemoteLookup;

  event TrustedRemoteSet(
    uint16 _chainId
  , bytes _trustedRemote);

  event MessageFailed(
    uint16 _srcChainId
  , bytes _srcAddress
  , uint64 _nonce
  , bytes _payload);

  // @notice LayerZero endpoint will invoke this function to deliver the message on the destination
  // @param _srcChainId - the source endpoint identifier
  // @param _srcAddress - the source sending contract address from the source chain
  // @param _nonce - the ordered message nonce
  // @param _payload - the signed payload is the UA bytes has encoded to be sent
  function lzReceive(
    uint16 _srcChainId
  , bytes memory _srcAddress
  , uint64 _nonce
  , bytes memory _payload
  ) external
    override {
    if (msg.sender != address(endpoint)) {
      revert MaxSplaining({
        reason: "NonblockingReceiver: This message did not come from the endpoint, you failed, I won!"
      });
    }

    if (
      _srcAddress.length != trustedRemoteLookup[_srcChainId].length ||
      keccak256(_srcAddress) != keccak256(trustedRemoteLookup[_srcChainId])
    ) {
      revert MaxSplaining({
        reason: "NonblockingReceiver: This message did not come from a trusted contract, you failed, I won!"
      });
    }

    // try-catch all errors/exceptions
    // having failed messages does not block messages passing
    try this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {
      // do nothing
    } catch {
      // error or exception
      failedMessages[_srcChainId][_srcAddress][_nonce] = FailedMessages(_payload.length, keccak256(_payload));
      emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);
    }
  }

  // @notice this is the catch all above (should be an internal?)
  // @param _srcChainId - the source endpoint identifier
  // @param _srcAddress - the source sending contract address from the source chain
  // @param _nonce - the ordered message nonce
  // @param _payload - the signed payload is the UA bytes has encoded to be sent
  function onLzReceive(
    uint16 _srcChainId
  , bytes memory _srcAddress
  , uint64 _nonce
  , bytes memory _payload
  ) public {

    // only internal transaction
    if (msg.sender != address(this)) {
      revert MaxSplaining({
        reason: "NonblockingReceiver: This message did not come internally, you failed, I won!"
      });
    }

    // handle incoming message
    _LzReceive( _srcChainId, _srcAddress, _nonce, _payload);
  }

  // @notice internal function to do something in the main contract
  // @param _srcChainId - the source endpoint identifier
  // @param _srcAddress - the source sending contract address from the source chain
  // @param _nonce - the ordered message nonce
  // @param _payload - the signed payload is the UA bytes has encoded to be sent
  function _LzReceive(
    uint16 _srcChainId
  , bytes memory _srcAddress
  , uint64 _nonce
  , bytes memory _payload
  ) virtual
    internal;

  // @notice send a LayerZero message to the specified address at a LayerZero endpoint.
  // @param _dstChainId - the destination chain identifier
  // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains
  // @param _payload - a custom bytes payload to send to the destination contract
  // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address
  // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction
  // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination
  function _lzSend(
    uint16 _dstChainId
  , bytes memory _payload
  , address payable _refundAddress
  , address _zroPaymentAddress
  , bytes memory _txParam
  ) internal {
    endpoint.send{value: msg.value}(
      _dstChainId
    , trustedRemoteLookup[_dstChainId]
    , _payload, _refundAddress
    , _zroPaymentAddress
    , _txParam);
  }

  // @notice this is to retry a failed message on LayerZero
  // @param _srcChainId - the source chain identifier
  // @param _srcAddress - the source chain contract address
  // @param _nonce - the ordered message nonce
  // @param _payload - the payload to be retried
  function retryMessage(
    uint16 _srcChainId
  , bytes memory _srcAddress
  , uint64 _nonce
  , bytes calldata _payload
  ) external
    payable {
    // assert there is message to retry
    FailedMessages storage failedMsg = failedMessages[_srcChainId][_srcAddress][_nonce];
    if (failedMsg.payloadHash == bytes32(0)) {
      revert MaxSplaining({
        reason: "NonblockingReceiver: This message was already executed, you failed, I won!"
      });
    }
    if (
      _payload.length != failedMsg.payloadLength ||
      keccak256(_payload) != failedMsg.payloadHash
    ) {
      revert MaxSplaining({
        reason: "NonblockingReceiver: This message was not stored, you failed, I won!"
      });
    }

    // clear the stored message
    failedMsg.payloadLength = 0;
    failedMsg.payloadHash = bytes32(0);

    // execute the message. revert if it fails again
    this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
  }


  // @notice this is to set all valid incoming messages
  // @param _srcChainId - the source chain identifier
  // @param _trustedRemote - the source chain contract address
  function setTrustedRemote(
    uint16 _chainId
  , bytes calldata _trustedRemote
  ) external
    onlyDev() {
    trustedRemoteLookup[_chainId] = _trustedRemote;
    emit TrustedRemoteSet(_chainId, _trustedRemote);
  }
}

File 7 of 40 : ITimeCop.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: ITimeCop.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Time based interface for Solidity
 */

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

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

interface ITimeCop is IERC165 {

  function setPresale(
    uint time
  , uint duration
  ) external;

  function showPresaleStart()
    external
    view
    returns (uint);

  function showStart()
    external
    view
    returns (uint);

  function showPresaleTimes()
    external
    view
    returns (uint, uint);

}

File 8 of 40 : IPaymentSplitter.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: IPaymentSplitter.sol
 * @author: OG was OZ, rewritten by Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Interface for PaymentSplitter.sol
 */

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

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

///
/// @dev Interface for PaymentSplitter
///

interface IPaymentSplitter is IERC165 {

  /**
   * @dev Getter for the total shares held by payees.
   */
  function totalShares()
    external
    returns (uint256);

  /**
   * @dev Getter for the total amount of Ether already released.
   */
  function totalReleased()
    external
    returns (uint256);

  /**
   * @dev Getter for the amount of shares held by an account.
   */
  function shares(
    address account
  ) external
    view
    returns (uint256);

  /**
   * @dev Getter for the amount of Ether already released to a payee.
   */
  function released(
    address account
  ) external
    view
    returns (uint256);

  /**
   * @dev Getter for the address of the payee number `index`.
   */
  function payee(
    uint256 index
  ) external
    view
    returns (address);

  /**
   * @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the
   * total shares and their previous withdrawals.
   */
  // This function was updated from "account" to msg.sender
  function claim()
    external;
}

File 9 of 40 : IMAXPaymentSplitter.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: IMAXPaymentSplitter.sol
 * @author: OG was OZ, rewritten by Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Interface extension for PaymentSplitter.sol
 */

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

import "./IPaymentSplitter.sol";

///
/// @dev Interface extension for PaymentSplitter
///

interface IMAXPaymentSplitter is IPaymentSplitter {

  // @notice: This adds a payment split to PaymentSplitterV2.sol
  // @param newSplit: Address of payee
  // @param newShares: Shares to send user
  function addSplit (
    address newSplit
  , uint256 newShares
  ) external;

  // @notice: This removes a payment split on PaymentSplitterV2.sol
  // @param remSplit: Address of payee to remove
  function removeSplit (
    address remSplit
  ) external;

  // @notice: This removes all payment splits on PaymentSplitterV2.sol
  function clearSplits()
    external;

}

File 10 of 40 : IMAXContractURI.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: IMAXContractURI.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Extension for IContractURI
 */
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.9.0;

import "./IContractURI.sol";

interface IMAXContractURI is IContractURI {

  // @notice this sets the contractURI, set to internal
  // @param URI - string to URI of Contract Metadata
  // @notice: let the metadata be in this format
  // {
  //   "name": Project's name,
  //   "description": Project's Description,
  //   "image": pfp for project,
  //   "external_link": web url,
  //   "seller_fee_basis_points": 100 -> Indicates a 1% seller fee.
  //   "fee_recipient": checksum address
  // }
  function setContractURI(
    string memory URI
  ) external;
}

File 11 of 40 : IMAX721.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: IMAX721.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Interface for UX/UI
 */

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

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

///
/// @dev Interface for @MaxFlowO2's Contracts
///

interface IMAX721 is IERC165 {

  // @dev will return status of Minter
  // @return - bool of active or not
  function minterStatus() 
    external
    view
    returns (bool);

  // @dev will return minting fees
  // @return - uint of mint costs in wei
  function minterFees()
    external
    view
    returns (uint);

  // @dev will return maximum mint capacity
  // @return - uint of maximum mints allowed
  function minterMaximumCapacity()
    external
    view
    returns (uint);

  // @dev will return maximum "team minting" capacity
  // @return - uint of maximum airdrops or team mints allowed
  function minterMaximumTeamMints()
    external
    view
    returns (uint);

  // @dev will return "team mints" left
  // @return - uint of remaing airdrops or team mints
  function minterTeamMintsRemaining()
    external
    view
    returns (uint);

  // @dev will return "team mints" count
  // @return - uint of airdrops or team mints done
  function minterTeamMintsCount()
    external
    view
    returns (uint);

  // @dev: will return total supply for mint
  // @return: uint for this mint
  function totalSupply()
    external
    view
    returns (uint256);
}

File 12 of 40 : ILlamas.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: ILlamas.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Interface for Llama/BAYC Mint engine, does Provenance for Metadata/Images
 * Source: https://etherscan.io/address/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d#code
 */

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

import "./IMAX721.sol";

///
/// @dev Interface for the ILlamas Standard v2.0
///  this includes metadata with images
///

interface ILlamas is IMAX721{

  // @dev: will return Provenance hash of images
  // @return: string memory of the Images Hash (sha256)
  function RevealProvenanceImages()
    external
    view
    returns (string memory);

  // @dev: will return Provenance hash of metadata
  // @return: string memory of the Metadata Hash (sha256)
  function RevealProvenanceJSON()
    external
    view
    returns (string memory);

  // @dev: will return starting number for mint
  // @return: uint of the start number
  function RevealStartNumber()
    external
    view
    returns (uint256);

}

File 13 of 40 : ILayerZeroUserApplicationConfig.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: ILayerZeroUserApplicationConfig.sol
 * @author: OG?? Rewrite: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Interface for LayerZeroUserApplicationConfig
 * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code
 */

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

interface ILayerZeroUserApplicationConfig {
  // @notice set the configuration of the LayerZero messaging library of the specified version
  // @param _version - messaging library version
  // @param _chainId - the chainId for the pending config change
  // @param _configType - type of configuration. every messaging library has its own convention.
  // @param _config - configuration in the bytes. can encode arbitrary content.
  function setConfig(
    uint16 _version
  , uint16 _chainId
  , uint _configType
  , bytes calldata _config
  ) external;

  // @notice set the send() LayerZero messaging library version to _version
  // @param _version - new messaging library version
  function setSendVersion(
    uint16 _version
  ) external;

  // @notice set the lzReceive() LayerZero messaging library version to _version
  // @param _version - new messaging library version
  function setReceiveVersion(
    uint16 _version
  ) external;

  // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload
  // @param _srcChainId - the chainId of the source chain
  // @param _srcAddress - the contract address of the source contract at the source chain
  function forceResumeReceive(
    uint16 _srcChainId
  , bytes calldata _srcAddress
  ) external;
}

File 14 of 40 : ILayerZeroReceiver.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: ILayerZeroReceiver.sol
 * @author: OG?? Rewrite: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Interface for LayerZeroReceiver
 * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code
 */

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

interface ILayerZeroReceiver {

  // @notice LayerZero endpoint will invoke this function to deliver the message on the destination
  // @param _srcChainId - the source endpoint identifier
  // @param _srcAddress - the source sending contract address from the source chain
  // @param _nonce - the ordered message nonce
  // @param _payload - the signed payload is the UA bytes has encoded to be sent
  function lzReceive(
    uint16 _srcChainId
  , bytes calldata _srcAddress
  , uint64 _nonce
  , bytes calldata _payload
  ) external;

}

File 15 of 40 : ILayerZeroEndpoint.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: ILayerZeroEndpoint.sol
 * @author: OG?? Rewrite: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Interface for LayerZeroEndpoint
 * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code
 */

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

import "./ILayerZeroUserApplicationConfig.sol";

interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {
  // @notice send a LayerZero message to the specified address at a LayerZero endpoint.
  // @param _dstChainId - the destination chain identifier
  // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains
  // @param _payload - a custom bytes payload to send to the destination contract
  // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address
  // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction
  // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination
  function send(
    uint16 _dstChainId
  , bytes calldata _destination
  , bytes calldata _payload
  , address payable _refundAddress
  , address _zroPaymentAddress
  , bytes calldata _adapterParams
  ) external
    payable;

  // @notice used by the messaging library to publish verified payload
  // @param _srcChainId - the source chain identifier
  // @param _srcAddress - the source contract (as bytes) at the source chain
  // @param _dstAddress - the address on destination chain
  // @param _nonce - the unbound message ordering nonce
  // @param _gasLimit - the gas limit for external contract execution
  // @param _payload - verified payload to send to the destination contract
  function receivePayload(
    uint16 _srcChainId
  , bytes calldata _srcAddress
  , address _dstAddress
  , uint64 _nonce
  , uint _gasLimit
  , bytes calldata _payload
  ) external;

  // @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain
  // @param _srcChainId - the source chain identifier
  // @param _srcAddress - the source chain contract address
  function getInboundNonce(
    uint16 _srcChainId
  , bytes calldata _srcAddress
  ) external
    view
    returns (uint64);

  // @notice get the outboundNonce from this source chain which, consequently, is always an EVM
  // @param _srcAddress - the source chain contract address
  function getOutboundNonce(
    uint16 _dstChainId
  , address _srcAddress
  ) external
    view
    returns (uint64);

  // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery
  // @param _dstChainId - the destination chain identifier
  // @param _userApplication - the user app address on this EVM chain
  // @param _payload - the custom message to send over LayerZero
  // @param _payInZRO - if false, user app pays the protocol fee in native token
  // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain
  function estimateFees(
    uint16 _dstChainId
  , address _userApplication
  , bytes calldata _payload
  , bool _payInZRO
  , bytes calldata _adapterParam
  ) external
    view
    returns (
    uint nativeFee
  , uint zroFee);

  // @notice get this Endpoint's immutable source identifier
  function getChainId()
    external
    view
    returns (uint16);

  // @notice the interface to retry failed message on this Endpoint destination
  // @param _srcChainId - the source chain identifier
  // @param _srcAddress - the source chain contract address
  // @param _payload - the payload to be retried
  function retryPayload(
    uint16 _srcChainId
  , bytes calldata _srcAddress
  , bytes calldata _payload
  ) external;

  // @notice query if any STORED payload (message blocking) at the endpoint.
  // @param _srcChainId - the source chain identifier
  // @param _srcAddress - the source chain contract address
  function hasStoredPayload(
    uint16 _srcChainId
  , bytes calldata _srcAddress
  ) external
    view
    returns (bool);

  // @notice query if the _libraryAddress is valid for sending msgs.
  // @param _userApplication - the user app address on this EVM chain
  function getSendLibraryAddress(
    address _userApplication
  ) external
    view
    returns (address);

  // @notice query if the _libraryAddress is valid for receiving msgs.
  // @param _userApplication - the user app address on this EVM chain
  function getReceiveLibraryAddress(
    address _userApplication
  ) external
    view
    returns (address);

  // @notice query if the non-reentrancy guard for send() is on
  // @return true if the guard is on. false otherwise
  function isSendingPayload()
    external
    view
    returns (bool);

  // @notice query if the non-reentrancy guard for receive() is on
  // @return true if the guard is on. false otherwise
  function isReceivingPayload()
    external
    view
    returns (bool);

  // @notice get the configuration of the LayerZero messaging library of the specified version
  // @param _version - messaging library version
  // @param _chainId - the chainId for the pending config change
  // @param _userApplication - the contract address of the user application
  // @param _configType - type of configuration. every messaging library has its own convention.
  function getConfig(
    uint16 _version
  , uint16 _chainId
  , address _userApplication
  , uint _configType
  ) external
    view
    returns (bytes memory);

  // @notice get the send() LayerZero messaging library version
  // @param _userApplication - the contract address of the user application
  function getSendVersion(
    address _userApplication
  ) external
    view
    returns (uint16);

  // @notice get the lzReceive() LayerZero messaging library version
  // @param _userApplication - the contract address of the user application
  function getReceiveVersion(
    address _userApplication
  ) external
    view
    returns (uint16);
}

File 16 of 40 : IContractURI.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: IContractURI.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Purely for OpenSea compliance
 */
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.9.0;

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

///
/// @dev Interface for the OpenSea Standard
///

interface IContractURI is IERC165{

  // @notice contractURI() called for retreval of 
  //  OpenSea style collections pages
  // @return - the string URI of the contract, usually IPFS
  function contractURI()
    external
    view
    returns (string memory);
}

File 17 of 40 : ContractURI.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: ContractURI.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Purely for OpenSea compliance
 */

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

import "./IMAXContractURI.sol";
import "../access/MaxAccess.sol";

///
/// @dev Implementation of IMAXContractURI.sol
///

abstract contract ContractURI is MaxAccess
                               , IMAXContractURI {

  event ContractURIChange(
          string _old
        , string _new);

  string private thisContractURI;

  // @notice this sets the contractURI, set to internal
  // @param newURI - string to URI of Contract Metadata
  // @notice: let the metadata be in this format
  //{
  //  "name": Project's name,
  //  "description": Project's Description,
  //  "image": pfp for project,
  //  "external_link": web url,
  //  "seller_fee_basis_points": 100 -> Indicates a 1% seller fee.
  //  "fee_recipient": checksum address
  //}
  function _setContractURI(
    string memory newURI
  ) internal {
    string memory old = thisContractURI;
    thisContractURI = newURI;
    emit ContractURIChange(old, thisContractURI);
  }

  // @notice this clears the contractURI, set to internal
  function _clearContractURI() internal {
    string memory old = thisContractURI;
    delete thisContractURI;
    emit ContractURIChange(old, thisContractURI);
  }

  // @notice this sets the contractURI, set to internal
  // @param URI - string to URI of Contract Metadata
  // @notice: let the metadata be in this format
  // {
  //   "name": Project's name,
  //   "description": Project's Description,
  //   "image": pfp for project,
  //   "external_link": web url,
  //   "seller_fee_basis_points": 100 -> Indicates a 1% seller fee.
  //   "fee_recipient": checksum address
  // }
  function setContractURI(
    string memory URI
  ) external
    virtual
    override
    onlyDev() {
    _setContractURI(URI);
  }

  // @notice contractURI() called for retreval of
  //  OpenSea style collections pages
  // @return - string thisContractURI
  function contractURI() 
    external
    view
    virtual
    override(IContractURI)
    returns (string memory) {
    return thisContractURI;
  }
}

File 18 of 40 : Roles.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: Roles.sol
 * @author: OpenZeppelin, rewrite by Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Library for MaxAcess.sol
 * @dev: Rewritten for gas optimization, and from abstract -> library, added
 * multiple types instead of a solo role.
 * Original source:
 * https://github.com/hiddentao/openzeppelin-solidity/blob/master/contracts/access/Roles.sol
 *
 * Include with 'using Roles for Roles.Role;'
 */

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

import "@openzeppelin/contracts/utils/Strings.sol";

library Roles {

  // @dev: this is Unauthorized(), basically a catch all, zero description
  // @notice: 0x82b42900 bytes4 of this
  error Unauthorized();

  // @dev: this is MaxSplaining(), giving you a reason, aka require(param, "reason")
  // @param reason: Use the "Contract name: error"
  // @notice: 0x0661b792 bytes4 of this
  error MaxSplaining(
    string reason
  );

  event RoleChanged(bytes4 _type, address _user, bool _status); // 0x0baaa7ab

  struct Role {
    mapping(address => mapping(bytes4 => bool)) bearer;
  }

  /**
   * @dev give an account access to this role
   */
  function add(Role storage role, bytes4 _type, address account) internal {
    if (account == address(0)) {
      revert Unauthorized();
    } else if (has(role, _type, account)) {
      revert MaxSplaining({
        reason: string(
                  abi.encodePacked(
                    "Lib Roles: ",
                    Strings.toHexString(uint160(account), 20),
                    " already has role ",
                    Strings.toHexString(uint32(_type), 4)
                  )
                )
      });
    }
    role.bearer[account][_type] = true;
    emit RoleChanged(_type, account, true);
  }

  /**
   * @dev remove an account's access to this role
   */
  function remove(Role storage role, bytes4 _type, address account) internal {
    if (account == address(0)) {
      revert Unauthorized();
    } else if (!has(role, _type, account)) {
      revert MaxSplaining({
        reason: string(
                  abi.encodePacked(
                    "Lib Roles: ",
                    Strings.toHexString(uint160(account), 20),
                    " does not have role ",
                    Strings.toHexString(uint32(_type), 4)
                  )
                )
      });
    }
    role.bearer[account][_type] = false;
    emit RoleChanged(_type, account, false);
  }

  /**
   * @dev check if an account has this role
   * @return bool
   */
  function has(Role storage role, bytes4 _type, address account)
    internal
    view
    returns (bool)
  {
    if (account == address(0)) {
      revert Unauthorized();
    }
    return role.bearer[account][_type];
  }
}

File 19 of 40 : PsuedoRand.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: PsuedoRand.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Library for Llama/BAYC Mint engine...
 *  basically a random start point and a bookends mint to start
 *  i.e. 0-2999 start at 500 -> 2999, then 0 -> 499.
 *
 *  Covers IMAX721.sol and Illamas.sol
 *
 * Include with 'using PsuedoRand for PsuedoRand.Engine;'
 */

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

import "./CountersV2.sol";

library PsuedoRand {
  using CountersV2 for CountersV2.Counter;

  event SetProvenanceIMG(string _new, string _old);
  event SetProvenanceJSON(string _new, string _old);
  event SetStartNumber(uint _new);
  event SetMaxCapacity(uint _new, uint _old);
  event SetMaxTeamMint(uint _new, uint _old);
  event SetMintFees(uint _new, uint _old);
  event SetStatus(bool _new);

  // @dev: this is MaxSplaining(), giving you a reason, aka require(param, "reason")
  // @param reason: Use the "Contract name: error"
  // @notice: 0x0661b792 bytes4 of this
  error MaxSplaining(
    string reason
  );

  struct Engine {
    uint256 mintFee;
    uint256 startNumber;
    uint256 maxCapacity;
    uint256 maxTeamMints;
    string ProvenanceIMG;
    string ProvenanceJSON;
    CountersV2.Counter currentMinted;
    CountersV2.Counter currentTeam;
    bool status;
  }

  function setProvJSON(
    Engine storage engine
  , string memory provJSON
  ) internal {
    string memory old = engine.ProvenanceJSON;
    engine.ProvenanceJSON = provJSON;
    emit SetProvenanceJSON(provJSON, old);
  }
 
  function setProvIMG(
    Engine storage engine
  , string memory provIMG
  ) internal {
    string memory old = engine.ProvenanceIMG;
    engine.ProvenanceIMG = provIMG;
    emit SetProvenanceIMG(provIMG, old);
  }

  function setStartNumber(
    Engine storage engine
  ) internal {
    if (engine.maxCapacity == 0) {
      revert MaxSplaining({
        reason : "PsuedoRandom Lib: Maximum Capacity not set!"
      });
    }
    engine.startNumber = uint(
                           keccak256(
                             abi.encodePacked(
                               block.timestamp
                             , msg.sender
                             , engine.ProvenanceIMG
                             , engine.ProvenanceJSON
                             , block.difficulty))) 
                         % engine.maxCapacity;
    emit SetStartNumber(engine.startNumber);
  }

  function setMaxCap(
    Engine storage engine
  , uint256 max
  ) internal {
    uint old = engine.maxCapacity;
    engine.maxCapacity = max;
    emit SetMaxCapacity(max, old);
  }

  function setMaxTeam(
    Engine storage engine
  , uint256 max
  ) internal {
    uint old = engine.maxTeamMints;
    engine.maxTeamMints = max;
    emit SetMaxTeamMint(max, old);
  }

  function setFees(
    Engine storage engine
  , uint256 max
  ) internal {
    uint old = engine.mintFee;
    engine.mintFee = max;
    emit SetMintFees(max, old);
  }

  function setStatus(
    Engine storage engine
  , bool change
  ) internal {
    engine.status = change;
    emit SetStatus(change);
  }

  function mintID(
    Engine storage engine
  ) internal
    view
    returns (uint256) {
    return (engine.startNumber + engine.currentMinted.current()) % engine.maxCapacity;
  }

  function showTeam(
    Engine storage engine
  ) internal 
    view
    returns (uint256) {
    return engine.currentTeam.current();
  }

  function showMinted(
    Engine storage engine
  ) internal
    view
    returns (uint256) {
    return engine.currentMinted.current();
  }

  function battersUpTeam(
    Engine storage engine
  ) internal {
    engine.currentTeam.increment();
  }

  function battersUp(
    Engine storage engine
  ) internal {
    engine.currentMinted.increment();
  }
}

File 20 of 40 : CountersV2.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: CountersV2.sol
 * @author Matt Condon (@shrugs), Edits by Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @dev Provides counters that can only be incremented, decremented, reset or set. 
 * This can be used e.g. to track the number of elements in a mapping, issuing ERC721 ids
 * or counting request ids.
 *
 * Edited by @MaxFlowO2 for more NFT functionality on 13 Jan 2022
 * added .set(uint) so if projects need to start at say 1 or some random number they can
 * and an event log for numbers being reset or set.
 *
 * Include with `using CountersV2 for CountersV2.Counter;`
 */

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

library CountersV2 {

  // @dev: this is MaxSplaining(), giving you a reason, aka require(param, "reason")
  // @param reason: Use the "Contract name: error"
  // @notice: 0x0661b792 bytes4 of this
  error MaxSplaining(
    string reason
  );

  event CounterNumberChangedTo(uint _number);

  struct Counter {
    // This variable should never be directly accessed by users of the library: interactions must be restricted to
    // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
    // this feature: see https://github.com/ethereum/solidity/issues/4637
    uint256 _value; // default: 0
  }

  function current(
    Counter storage counter
  ) internal
    view
    returns (uint256) {
    return counter._value;
  }

  function increment(
    Counter storage counter
  ) internal {
    unchecked {
      ++counter._value;
    }
  }

  function decrement(
    Counter storage counter
  ) internal {
    uint256 value = counter._value;
    if (value == 0) {
      revert MaxSplaining({
        reason : "CountersV2: No negatives in uints"
      });
    }
    unchecked {
      --counter._value;
    }
  }

  function reset(
    Counter storage counter
  ) internal {
    counter._value = 0;
    emit CounterNumberChangedTo(counter._value);
  }

  function set(
    Counter storage counter
  , uint number
  ) internal {
    counter._value = number;
    emit CounterNumberChangedTo(counter._value);
  }  
}

File 21 of 40 : MaxErrors.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: MaxErrors.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Custom errors for all contracts, minus libraries
 */

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

abstract contract MaxErrors {

  // @dev: this is Unauthorized(), basically a catch all, zero description
  // @notice: 0x82b42900 bytes4 of this
  error Unauthorized();

  // @dev: this is MaxSplaining(), giving you a reason, aka require(param, "reason")
  // @param reason: Use the "Contract name: error"
  // @notice: 0x0661b792 bytes4 of this
  error MaxSplaining(
    string reason
  );

  // @dev: this is TooSoonJunior(), using times
  // @param yourTime: should almost always be block.timestamp
  // @param hitTime: the time you should have started
  // @notice: 0xf3f82ac5 bytes4 of this
  error TooSoonJunior(
    uint yourTime
  , uint hitTime
  );

  // @dev: this is TooLateBoomer(), using times
  // @param yourTime: should almost always be block.timestamp
  // @param hitTime: the time you should have ended
  // @notice: 0x43c540ef bytes4 of this
  error TooLateBoomer(
    uint yourTime
  , uint hitTime
  );

}

File 22 of 40 : IMAX2981.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: IMAX2981.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: IERC2981 Extension
 */

// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0 <0.9.0;

import "./IERC2981.sol";

interface IMAX2981 is IERC2981 {

  // @notice: This sets the contract as royalty reciever (useful with abstract PaymentSplitter)
  // @param permille: Percentage you want so 3.5% -> 35
  function setRoyaltiesThis (
    uint permille
  ) external;

  // @notice: This sets royalties per EIP-2981
  // @param newAddress: Sets the address for royalties
  // @param permille: Percentage you want so 3.5% -> 35
  function setRoyalties (
    address newAddress
  , uint256 permille
  ) external;

  // @notice: This clears all EIP-2981 royalties (address(0) and 0%)
  function clearRoyalties()
    external;

}

File 23 of 40 : IERC2981.sol
/***
 *    ███████╗██╗██████╗       ██████╗  █████╗  █████╗  ██╗
 *    ██╔════╝██║██╔══██╗      ╚════██╗██╔══██╗██╔══██╗███║
 *    █████╗  ██║██████╔╝█████╗ █████╔╝╚██████║╚█████╔╝╚██║
 *    ██╔══╝  ██║██╔═══╝ ╚════╝██╔═══╝  ╚═══██║██╔══██╗ ██║
 *    ███████╗██║██║           ███████╗ █████╔╝╚█████╔╝ ██║
 *    ╚══════╝╚═╝╚═╝           ╚══════╝ ╚════╝  ╚════╝  ╚═╝                                                        
 * Zach Burks, James Morgan, Blaine Malone, James Seibel,
 * "EIP-2981: NFT Royalty Standard,"
 * Ethereum Improvement Proposals, no. 2981, September 2020. [Online serial].
 * Available: https://eips.ethereum.org/EIPS/eip-2981.
 */

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

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

///
/// @dev Interface for the NFT Royalty Standard
///

interface IERC2981 is IERC165 {

  // @notice Called with the sale price to determine how much royalty
  //  is owed and to whom.
  // @param _tokenId - the NFT asset queried for royalty information
  // @param _salePrice - the sale price of the NFT asset specified by _tokenId
  // @return receiver - address of who should be sent the royalty payment
  // @return royaltyAmount - the royalty payment amount for _salePrice
  function royaltyInfo(
    uint256 _tokenId
  , uint256 _salePrice
  ) external
    view
    returns (
    address receiver
  , uint256 royaltyAmount
  );
}

File 24 of 40 : ERC2981Collection.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: ERC2981Collection.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Use case for EIP 2981, steered more towards NFT Collections as a whole
 */

// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0 <0.9.0;

import "./IMAX2981.sol";
import "../../access/MaxAccess.sol";

abstract contract ERC2981Collection is MaxAccess, IMAX2981 {

  address private royaltyAddress;
  uint256 private royaltyPermille;

  event royalatiesSet(
          uint value
        , address recipient
        );

  // the internals to do logic flows later

  // @dev to set roaylties on contract via EIP 2891
  // @param _receiver, address of recipient
  // @param _permille, permille xx.x -> xxx value
  function _setRoyalties(
    address _receiver
  , uint256 _permille
  ) internal {
  if (_permille >= 1000 || _permille == 0) {
    revert MaxSplaining({
      reason: string(
                abi.encodePacked(
                  "ERC2981Collection: ",
                  Strings.toHexString(uint160(msg.sender), 20),
                  " submitted ",
                  Strings.toString(_permille),
                  " and that is out of bounds!"
                )
              )
    });
  }
    royaltyAddress = _receiver;
    royaltyPermille = _permille;
    emit royalatiesSet(royaltyPermille, royaltyAddress);
  }

  // @dev to remove royalties from contract
  function _removeRoyalties()
    internal {
    delete royaltyAddress;
    delete royaltyPermille;
    emit royalatiesSet(royaltyPermille, royaltyAddress);
  }

  // Logic for this contract (abstract)

  // @notice: This sets the contract as royalty reciever (useful with abstract PaymentSplitter)
  // @param permille: Percentage you want so 3.5% -> 35
  function setRoyaltiesThis (
    uint permille
  ) external
    virtual
    override
    onlyOwner() {
    _setRoyalties(address(this), permille);
  }

  // @notice: This sets royalties per EIP-2981
  // @param newAddress: Sets the address for royalties
  // @param permille: Percentage you want so 3.5% -> 35
  function setRoyalties (
    address newAddress
  , uint256 permille
  ) external
    virtual
    override
    onlyOwner() {
    _setRoyalties(newAddress, permille);
  }

  // @notice: This clears all EIP-2981 royalties (address(0) and 0%)
  function clearRoyalties()
    external
    virtual
    override
    onlyOwner() {
    _removeRoyalties();
  }

  // @dev Override for royaltyInfo(uint256, uint256)
  // @param _tokenId, uint of token ID to be checked
  // @param _salePrice, uint of amount of sale
  // @return receiver, address of recipient
  // @return royaltyAmount, amount royalties recieved
  function royaltyInfo(
    uint256 _tokenId
  , uint256 _salePrice
  ) external
    view
    virtual
    override
    returns (
    address receiver
  , uint256 royaltyAmount
  ) {
    receiver = royaltyAddress;
    royaltyAmount = _salePrice * royaltyPermille / 1000;
  }
}

File 25 of 40 : MaxAccess.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: MaxAccess.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Access control based off EIP 173/roles from OZ
 */

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

import "./IOwnerV2.sol";
import "./IDeveloperV2.sol";
import "./IRole.sol";
import "../lib/Roles.sol";
import "../errors/MaxErrors.sol";
import "@openzeppelin/contracts/utils/Strings.sol";

abstract contract MaxAccess is MaxErrors
                             , IRole
                             , IOwnerV2
                             , IDeveloperV2 {
  using Roles for Roles.Role;

  Roles.Role private contractRoles;

  // bytes4 caluclated as follows
  // bytes4(keccak256(bytes(signature)))
  // developer() => 0xca4b208b
  // owner() => 0x8da5cb5b
  // admin() => 0xf851a440
  // was using trailing () for caluclations

  bytes4 constant private DEVS = 0xca4b208b;
  bytes4 constant private PENDING_DEVS = 0xca4b208a; // DEVS - 1
  bytes4 constant private OWNERS = 0x8da5cb5b;
  bytes4 constant private PENDING_OWNERS = 0x8da5cb5a; // OWNERS - 1
  bytes4 constant private ADMIN = 0xf851a440;

  // @dev you can sub your own address here... this is MaxFlowO2.eth
  // these are for displays anyways, and init().
  address private TheDev = address(0x4CE69fd760AD0c07490178f9a47863Dc0358cCCD);
  address private TheOwner = address(0x44f750eB065596c150B3479B1DF6957da300a332);

  constructor() {
    // supercedes all the logic below
    contractRoles.add(ADMIN, address(this));
    _grantRole(ADMIN, TheDev);
    _grantRole(OWNERS, TheOwner);
    _grantRole(DEVS, TheDev);
  }

  // modifiers
  modifier onlyRole(bytes4 role) {
    if (_checkRole(role, msg.sender) || _checkRole(ADMIN, msg.sender)) {
      _;
    } else {
      revert MaxSplaining({
        reason: string(
                  abi.encodePacked(
                    "MaxAccess: You are a not an ",
                    Strings.toHexString(uint32(role), 4),
                    " or ",
                    Strings.toHexString(uint32(ADMIN), 4),
                    " ",
                    Strings.toHexString(uint160(msg.sender), 20)
                  )
                )
      });
    }
  }

  modifier onlyDev() {
    if (!_checkRole(DEVS, msg.sender)) {
      revert Unauthorized();
    }
    _;
  }

  modifier onlyOwner() {
    if (!_checkRole(OWNERS, msg.sender)) {
      revert Unauthorized();
    }
    _;
  }

  // internal logic first 
  // (sets the tone later, and for later contracts)

  // @dev: this is the bool for checking if the account has a role via lib roles.sol
  // @param role: bytes4 of the role to check for
  // @param account: address of account to check
  // @return: bool true/false
  function _checkRole(
    bytes4 role
  , address account
  ) internal
    view
    virtual
    returns (bool) {
    return contractRoles.has(role, account);
  }

  // @dev: this is the internal to grant roles
  // @param role: bytes4 of the role
  // @param account: address of account to add
  function _grantRole(
    bytes4 role
  , address account
  ) internal
    virtual {
    contractRoles.add(role, account);
  }

  // @dev: this is the internal to revoke roles
  // @param role: bytes4 of the role
  // @param account: address of account to remove
  function _revokeRole(
    bytes4 role
  , address account
  ) internal
    virtual {
    contractRoles.remove(role, account);
  }

  // @dev: Returns `true` if `account` has been granted `role`.
  // @param role: Bytes4 of a role
  // @param account: Address to check
  // @return: bool true/false if account has role
  function hasRole(
    bytes4 role
  , address account
  ) external
    view
    virtual
    override
    returns (bool) {
    return _checkRole(role, account);
  }

  // @dev: Returns the admin role that controls a role
  // @param role: Role to check
  // @return: admin role
  function getRoleAdmin(
    bytes4 role
  ) external
    view
    virtual
    override
    returns (bytes4) {
    return ADMIN;
  }

  // @dev: Grants `role` to `account`
  // @param role: Bytes4 of a role
  // @param account: account to give role to
  function grantRole(
    bytes4 role
  , address account
  ) external
    virtual
    override 
    onlyRole(role) {

    if (role == PENDING_DEVS) {
      // locks out pending devs from mass swapping roles
      if (_checkRole(PENDING_DEVS, msg.sender)) {
        revert MaxSplaining({
          reason: string(
                    abi.encodePacked(
                      "MaxAccess: You are a pending developer() ",
                      Strings.toHexString(uint160(msg.sender), 20),
                      " you can not grant role ",
                      Strings.toHexString(uint32(role), 4),
                      " to ",
                      Strings.toHexString(uint160(account), 20)
                    )
                  )
        });
      }
    }

    if (role == PENDING_OWNERS) {
      // locks out pending owners from mass swapping roles
      if (_checkRole(PENDING_OWNERS, msg.sender)) {
        revert MaxSplaining({
          reason: string(
                    abi.encodePacked(
                      "MaxAccess: You are a pending owner() ",
                      Strings.toHexString(uint160(msg.sender), 20),
                      " you can not grant role ",
                      Strings.toHexString(uint32(role), 4),
                      " to ",
                      Strings.toHexString(uint160(account), 20)
                    )
                  )
        });
      }
    }

    _grantRole(role, account);
  }

  // @dev: Revokes `role` from `account`
  // @param role: Bytes4 of a role
  // @param account: account to revoke role from
  function revokeRole(
    bytes4 role
  , address account
  ) external
    virtual
    override
    onlyRole(role) {

    if (role == PENDING_DEVS) {
      // locks out pending devs from mass swapping roles
      if (account != msg.sender) {
        revert MaxSplaining({
          reason: string(
                    abi.encodePacked(
                      "MaxAccess: You are a pending developer() ",
                      Strings.toHexString(uint160(msg.sender), 20),
                      " you can not revoke role ",
                      Strings.toHexString(uint32(role), 4),
                      " to ",
                      Strings.toHexString(uint160(account), 20)
                    )
                  )
        });
      }
    }

    if (role == PENDING_OWNERS) {
      // locks out pending owners from mass swapping roles
      if (account != msg.sender) {
        revert MaxSplaining({
          reason: string(
                    abi.encodePacked(
                      "MaxAccess: You are a pending owner() ",
                      Strings.toHexString(uint160(msg.sender), 20),
                      " you can not revoke role ",
                      Strings.toHexString(uint32(role), 4),
                      " to ",
                      Strings.toHexString(uint160(account), 20)
                    )
                  )
        });
      }
    }
    _revokeRole(role, account);
  }

  // @dev: Renounces `role` from `account`
  // @param role: Bytes4 of a role
  // @param account: account to renounce role from
  function renounceRole(
    bytes4 role
  ) external
    virtual
    override 
    onlyRole(role) {
    address user = msg.sender;
    _revokeRole(role, user);
  }

  // Now the classic onlyDev() + "V2" suggested by auditors

  // @dev: Classic "EIP-173" but for onlyDev()
  // @return: Developer of contract
  function developer()
    external
    view
    virtual
    override
    returns (address) {
    return TheDev;
  }

  // @dev: This renounces your role as onlyDev()
  function renounceDeveloper()
    external
    virtual
    override 
    onlyRole(DEVS) {
    address user = msg.sender;
    _revokeRole(DEVS, user);
  }

  // @dev: Classic "EIP-173" but for onlyDev()
  // @param newDeveloper: addres of new pending Developer role
  function transferDeveloper(
    address newDeveloper
  ) external
    virtual
    override 
    onlyRole(DEVS) {
    address user = msg.sender;
    _grantRole(DEVS, newDeveloper);
    _revokeRole(DEVS, user);
  }

  // @dev: This accepts the push-pull method of onlyDev()
  function acceptDeveloper()
    external
    virtual
    override 
    onlyRole(PENDING_DEVS) {
    address user = msg.sender;
    _revokeRole(PENDING_DEVS, user);
    _grantRole(DEVS, user);
  }

  // @dev: This declines the push-pull method of onlyDev()
  function declineDeveloper()
    external
    virtual
    override 
    onlyRole(PENDING_DEVS) {
    address user = msg.sender;
    _revokeRole(PENDING_DEVS, user);
  }

  // @dev: This starts the push-pull method of onlyDev()
  // @param newDeveloper: addres of new pending developer role
  function pushDeveloper(
    address newDeveloper
  ) external
    virtual
    override
    onlyRole(DEVS) {
    _grantRole(PENDING_DEVS, newDeveloper);
  }

  // @dev: This changes the display of developer()
  // @param newDisplay: new display addrss for developer()
  function setDeveloper(
    address newDisplay
  ) external
    onlyDev() {
    if (!_checkRole(DEVS, newDisplay)) {
        revert MaxSplaining({
          reason: string(
                    abi.encodePacked(
                      "MaxAccess: The address ",
                      Strings.toHexString(uint160(newDisplay), 20),
                      " is not a developer and does not have the role ",
                      Strings.toHexString(uint32(DEVS), 4),
                      " there ",
                      Strings.toHexString(uint160(msg.sender), 20)
                    )
                  )
        });
    }
    TheDev = newDisplay;
  }

  // Now the classic onlyOwner() + "V2" suggested by auditors

  // @dev: Classic "EIP-173" getter for owner()
  // @return: owner of contract
  function owner()
    external
    view
    virtual
    override
    returns (address) {
    return TheOwner;
  }

   // @dev: This renounces your role as onlyOwner()
  function renounceOwnership()
    external
    virtual
    override
    onlyRole(OWNERS) {
    address user = msg.sender;
    _revokeRole(OWNERS, user);
  }

  // @dev: Classic "EIP-173" but for onlyOwner()
  // @param newOwner: addres of new pending Developer role
  function transferOwnership(
    address newOwner
  ) external
    virtual
    override
    onlyRole(OWNERS) {
    address user = msg.sender;
    _grantRole(OWNERS, newOwner);
    _revokeRole(OWNERS, user);
  }

  // @dev: This accepts the push-pull method of onlyOwner()
  function acceptOwnership()
    external
    virtual
    override
    onlyRole(PENDING_OWNERS) {
    address user = msg.sender;
    _revokeRole(PENDING_OWNERS, user);
    _grantRole(OWNERS, user);
  }

  // @dev: This declines the push-pull method of onlyOwner()
  function declineOwnership()
    external
    virtual
    override
    onlyRole(PENDING_OWNERS) {
    address user = msg.sender;
    _revokeRole(PENDING_OWNERS, user);
  }

  // @dev: This starts the push-pull method of onlyOwner()
  // @param newOwner: addres of new pending developer role
  function pushOwnership(
    address newOwner
  ) external
    virtual
    override
    onlyRole(OWNERS) {
    _grantRole(PENDING_OWNERS, newOwner);
  }

  // @dev: This changes the display of Ownership()
  // @param newDisplay: new display addrss for Ownership()
  function setOwner(
    address newDisplay
  ) external
    onlyOwner() {
    if (!_checkRole(OWNERS, newDisplay)) {
        revert MaxSplaining({
          reason: string(
                    abi.encodePacked(
                      "MaxAccess: The address ",
                      Strings.toHexString(uint160(newDisplay), 20),
                      " is not an owner and does not have the role ",
                      Strings.toHexString(uint32(OWNERS), 4),
                      " there ",
                      Strings.toHexString(uint160(msg.sender), 20)
                    )
                  )
        });
    }
    TheOwner = newDisplay;
  }
}

File 26 of 40 : IRole.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: IRole.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Interface for MaxAccess version of roles
 */

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

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

interface IRole is IERC165 {

  // @dev: Returns `true` if `account` has been granted `role`.
  // @param role: Bytes4 of a role
  // @param account: Address to check
  // @return: bool true/false if account has role
  function hasRole(
    bytes4 role
  , address account
  ) external
    view
    returns (bool);

  // @dev: Returns the admin role that controls a role
  // @param role: Role to check
  // @return: admin role
  function getRoleAdmin(
    bytes4 role
  ) external
    view 
    returns (bytes4);

  // @dev: Grants `role` to `account`
  // @param role: Bytes4 of a role
  // @param account: account to give role to
  function grantRole(
    bytes4 role
  , address account
  ) external;

  // @dev: Revokes `role` from `account`
  // @param role: Bytes4 of a role
  // @param account: account to revoke role from
  function revokeRole(
    bytes4 role
  , address account
  ) external;

  // @dev: Renounces `role` from `account`
  // @param role: Bytes4 of a role
  // @param account: account to renounce role from
  function renounceRole(
    bytes4 role
  ) external;
}

File 27 of 40 : IOwnerV2.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: IOwnerV2.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Interface V2 for onlyOwner() role, suggested by Auditors...
 */

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

import "./IOwner.sol";

interface IOwnerV2 is IOwner {

  // @dev: This accepts the push-pull method of onlyOwner()
  function acceptOwnership()
    external;

  // @dev: This declines the push-pull method of onlyOwner()
  function declineOwnership()
    external;

  // @dev: This starts the push-pull method of onlyOwner()
  // @param newOwner: addres of new pending owner role
  function pushOwnership(
    address newOwner
  ) external;
}

File 28 of 40 : IOwner.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#* 
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=: 
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%* 
 *
 * @title: IOwner.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Interface for onlyOwner() role
 */

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

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

interface IOwner is IERC165 {

  // @dev: Classic "EIP-173" getter for owner()
  // @return: owner of contract
  function owner()
    external
    view
    returns (address);

  // @dev: This is the classic "EIP-173" method of setting onlyOwner()  
  function renounceOwnership()
    external;


  // @dev: This is the classic "EIP-173" method of setting onlyOwner()
  // @param newOwner: addres of new pending owner role
  function transferOwnership(
    address newOwner
  ) external;
}

File 29 of 40 : IDeveloperV2.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#*
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=:
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%*
 *
 * @title: IDeveloperV2.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Interface V2 for onlyDev() role, suggested by Auditors...
 */

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

import "./IDeveloper.sol";

interface IDeveloperV2 is IDeveloper {

  // @dev: This accepts the push-pull method of onlyDev()
  function acceptDeveloper()
    external;

  // @dev: This declines the push-pull method of onlyDev()
  function declineDeveloper()
    external;

  // @dev: This starts the push-pull method of onlyDev()
  // @param newDeveloper: addres of new pending developer role
  function pushDeveloper(
    address newDeveloper
  ) external;
}

File 30 of 40 : IDeveloper.sol
/*     +%%#-                           ##.        =+.    .+#%#+:       *%%#:    .**+-      =+
 *   .%@@*#*:                          @@: *%-   #%*=  .*@@=.  =%.   .%@@*%*   +@@=+=%   .%##
 *  .%@@- -=+                         *@% :@@-  #@=#  -@@*     +@-  :@@@: ==* -%%. ***   #@=*
 *  %@@:  -.*  :.                    +@@-.#@#  =@%#.   :.     -@*  :@@@.  -:# .%. *@#   *@#* 
 * *%@-   +++ +@#.-- .*%*. .#@@*@#  %@@%*#@@: .@@=-.         -%-   #%@:   +*-   =*@*   -@%=: 
 * @@%   =##  +@@#-..%%:%.-@@=-@@+  ..   +@%  #@#*+@:      .*=     @@%   =#*   -*. +#. %@#+*@
 * @@#  +@*   #@#  +@@. -+@@+#*@% =#:    #@= :@@-.%#      -=.  :   @@# .*@*  =@=  :*@:=@@-:@+
 * -#%+@#-  :@#@@+%++@*@*:=%+..%%#=      *@  *@++##.    =%@%@%%#-  =#%+@#-   :*+**+=: %%++%* 
 *
 * @title: IDeveloper.sol
 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
 * @notice: Interface for onlyDev() role
 */

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

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

interface IDeveloper is IERC165 {


  // @dev: Classic "EIP-173" but for onlyDev()
  // @return: Developer of contract
  function developer()
    external
    view
    returns (address);

  // @dev: This renounces your role as onlyDev()
  function renounceDeveloper()
    external;

  // @dev: Classic "EIP-173" but for onlyDev()
  // @param newDeveloper: addres of new pending Developer role
  function transferDeveloper(
    address newDeveloper
  ) external;
}

File 31 of 40 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

File 32 of 40 : ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

File 33 of 40 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @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] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

File 34 of 40 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

File 35 of 40 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/Address.sol)

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 36 of 40 : IERC721Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

File 37 of 40 : ERC721Burnable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/ERC721Burnable.sol)

pragma solidity ^0.8.0;

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

/**
 * @title ERC721 Burnable Token
 * @dev ERC721 Token that can be irreversibly burned (destroyed).
 */
abstract contract ERC721Burnable is Context, ERC721 {
    /**
     * @dev Burns `tokenId`. See {ERC721-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved");
        _burn(tokenId);
    }
}

File 38 of 40 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

File 39 of 40 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}

File 40 of 40 : ERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;

import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

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

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

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

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits a {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

Settings
{
  "remappings": [],
  "optimizer": {
    "enabled": true,
    "runs": 100
  },
  "evmVersion": "london",
  "libraries": {},
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"MaxSplaining","type":"error"},{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"MaxSplaining","type":"error"},{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"MaxSplaining","type":"error"},{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"MaxSplaining","type":"error"},{"inputs":[{"internalType":"uint256","name":"yourTime","type":"uint256"},{"internalType":"uint256","name":"hitTime","type":"uint256"}],"name":"TooLateBoomer","type":"error"},{"inputs":[{"internalType":"uint256","name":"yourTime","type":"uint256"},{"internalType":"uint256","name":"hitTime","type":"uint256"}],"name":"TooSoonJunior","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_old","type":"string"},{"indexed":false,"internalType":"string","name":"_new","type":"string"}],"name":"ContractURIChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"MessageFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"PayeeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"PayeeRemoved","type":"event"},{"anonymous":false,"inputs":[],"name":"PayeesReset","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"start","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"length","type":"uint256"}],"name":"PresaleSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"numberToMint","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startingID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endingID","type":"uint256"}],"name":"SetStartNumbers","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ThankYou","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_chainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_trustedRemote","type":"bytes"}],"name":"TrustedRemoteSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_old","type":"string"},{"indexed":false,"internalType":"string","name":"_new","type":"string"}],"name":"UpdatedBaseURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"}],"name":"royalatiesSet","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"RevealProvenanceImages","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RevealProvenanceJSON","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RevealStartNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newSplit","type":"address"},{"internalType":"uint256","name":"newShares","type":"uint256"}],"name":"addSplit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"clearRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"clearSplits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentLZGas","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"declineDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"declineOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"developer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"donate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"failedMessages","outputs":[{"internalType":"uint256","name":"payloadLength","type":"uint256"},{"internalType":"bytes32","name":"payloadHash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lzStartNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterCurrentMints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterMaximumCapacity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterMaximumTeamMints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterMintsRemaining","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterTeamMintsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterTeamMintsRemaining","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"onLzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"payee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quant","type":"uint256"}],"name":"presaleMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"publicMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newDeveloper","type":"address"}],"name":"pushDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"pushOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"remSplit","type":"address"}],"name":"removeSplit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"retryMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_base","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"URI","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newDisplay","type":"address"}],"name":"setDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newVal","type":"uint256"}],"name":"setGasForDestinationLzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startNumber","type":"uint256"},{"internalType":"uint256","name":"authMint","type":"uint256"},{"internalType":"uint256","name":"teamMints","type":"uint256"},{"internalType":"string","name":"img","type":"string"},{"internalType":"string","name":"json","type":"string"},{"internalType":"address","name":"newAddress","type":"address"}],"name":"setMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newDisplay","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"setPresale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"},{"internalType":"uint256","name":"permille","type":"uint256"}],"name":"setRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"permille","type":"uint256"}],"name":"setRoyaltiesThis","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"bytes","name":"_trustedRemote","type":"bytes"}],"name":"setTrustedRemote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"shares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"showPresaleStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"showPresaleTimes","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"showStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[],"name":"teamMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newDeveloper","type":"address"}],"name":"transferDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"traverseChains","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"trustedRemoteLookup","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

6080604052600180546001600160a01b0319908116734ce69fd760ad0c07490178f9a47863dc0358cccd17909155600280549091167344f750eb065596c150b3479b1df6957da300a332179055620557306021553480156200006057600080fd5b506040518060400160405280600b81526020016a54696e794461656d6f6e7360a81b815250604051806040016040528060078152602001662a24a72ca226a760c91b815250620000c963f851a44060e01b3060006200014f60201b62002dd8179092919060201c565b600154620000e9906303e1469160e61b906001600160a01b03166200028e565b6002546200010990638da5cb5b60e01b906001600160a01b03166200028e565b600154620001299063ca4b208b60e01b906001600160a01b03166200028e565b601862000137838262000572565b50601962000146828262000572565b50505062000791565b6001600160a01b03811662000176576040516282b42960e81b815260040160405180910390fd5b62000183838383620002af565b156200021057620001aa816001600160a01b031660146200030d60201b62002eae1760201c565b620001cb8360e01c63ffffffff1660046200030d60201b62002eae1760201c565b604051602001620001de92919062000671565b60408051601f1981840301815290829052630330dbc960e11b82526200020791600401620006d9565b60405180910390fd5b6001600160a01b0381166000818152602085815260408083206001600160e01b03198716808552908352928190208054600160ff1990911681179091558151938452918301939093528183015290517fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f79181900360600190a1505050565b620002ab828260006200014f60201b62002dd8179092919060201c565b5050565b60006001600160a01b038216620002d8576040516282b42960e81b815260040160405180910390fd5b506001600160a01b03166000908152602092835260408082206001600160e01b03199390931682529190925290205460ff1690565b606060006200031e83600262000724565b6200032b90600262000746565b6001600160401b03811115620003455762000345620004cd565b6040519080825280601f01601f19166020018201604052801562000370576020820181803683370190505b509050600360fc1b816000815181106200038e576200038e62000761565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110620003c057620003c062000761565b60200101906001600160f81b031916908160001a9053506000620003e684600262000724565b620003f390600162000746565b90505b600181111562000475576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106200042b576200042b62000761565b1a60f81b82828151811062000444576200044462000761565b60200101906001600160f81b031916908160001a90535060049490941c936200046d8162000777565b9050620003f6565b508315620004c65760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640162000207565b9392505050565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620004f857607f821691505b6020821081036200051957634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200056d57600081815260208120601f850160051c81016020861015620005485750805b601f850160051c820191505b81811015620005695782815560010162000554565b5050505b505050565b81516001600160401b038111156200058e576200058e620004cd565b620005a6816200059f8454620004e3565b846200051f565b602080601f831160018114620005de5760008415620005c55750858301515b600019600386901b1c1916600185901b17855562000569565b600085815260208120601f198616915b828110156200060f57888601518255948401946001909101908401620005ee565b50858210156200062e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60005b838110156200065b57818101518382015260200162000641565b838111156200066b576000848401525b50505050565b6a02634b1102937b632b99d160ad1b8152600083516200069981600b8501602088016200063e565b7101030b63932b0b23c903430b9903937b632960751b600b918401918201528351620006cd81601d8401602088016200063e565b01601d01949350505050565b6020815260008251806020840152620006fa8160408501602087016200063e565b601f01601f19169190910160400192915050565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156200074157620007416200070e565b500290565b600082198211156200075c576200075c6200070e565b500190565b634e487b7160e01b600052603260045260246000fd5b6000816200078957620007896200070e565b506000190190565b615e4880620007a16000396000f3fe6080604052600436106104815760003560e01c80637544671611610255578063c87b56dd11610144578063de02cde7116100c1578063eb8d72b711610085578063eb8d72b714610db9578063ecc7afa914610dd9578063ed88c68e14610dee578063f2fde38b14610df6578063fd0198e814610e16578063ff70fa4914610e36576104c1565b8063de02cde714610d3a578063e33b7de314610d5a578063e68b796114610d6f578063e8a3d48514610d84578063e985e9c514610d99576104c1565b8063d1deba1f11610108578063d1deba1f14610cbd578063d39ce77c14610cd0578063d4d714be14610cf0578063d792d2a014610d10578063d95ae16214610d25576104c1565b8063c87b56dd14610c16578063c9b298f114610c36578063ca4b208b14610c56578063ce7c2ac214610c74578063cf89fa0314610caa576104c1565b806395d89b41116101d2578063aac3f28111610196578063aac3f28114610ba2578063ad6d9c1714610bb7578063ae47b2da14610bcc578063b88d4fde14610be1578063ba7a86b814610c01576104c1565b806395d89b4114610b0d5780639852595c14610b225780639c12b17f14610b58578063a22cb46514610b6d578063a86ff96014610b8d576104c1565b80638da5cb5b116102195780638da5cb5b14610a2f5780638ee7491214610a4d578063938e3d7b14610ab85780639435267614610ad8578063943fb87214610aed576104c1565b806375446716146109b057806378c5939b146109c557806379ba5097146109da5780638b83209b146109ef5780638c7ea24b14610a0f576104c1565b8063312744261161037157806355f804b3116102ee57806364cb4edb116102b257806364cb4edb1461091b57806366278a6c1461093b57806370a082311461095b578063715018a61461097b5780637533d78814610990576104c1565b806355f804b3146108665780635ba5e9f0146108865780635c17e370146108c65780636149d871146108db5780636352211e146108fb576104c1565b806342966c681161033557806342966c68146107e757806344faded014610807578063475de12e1461082757806348e3bab21461083c5780634e71d92d14610851576104c1565b8063312744261461075d57806331e26cfd1461077d5780633400ec63146107925780633a98ef39146107b257806342842e0e146107c7576104c1565b806313af4035116103ff57806323b872dd116103c357806323b872dd146106cd57806326092b83146106ed5780632a55205a146107025780632bfcf0f2146107305780632ecd28ab14610745576104c1565b806313af40351461064e57806318160ddd1461066e57806318a66a7e146106835780631c37a822146106985780631efb051a146106b8576104c1565b8063081812fc11610446578063081812fc146105a3578063095ea7b3146105db5780630f0efdbc146105fb57806310ab94321461061b57806312065fe01461063b576104c1565b80621d3567146104f2578063018f007e1461051457806301ffc9a71461053c578063049157bb1461056c57806306fdde0314610581576104c1565b366104c1577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033346040516104b7929190614559565b60405180910390a1005b7f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033346040516104b7929190614559565b3480156104fe57600080fd5b5061051261050d366004614642565b610e56565b005b34801561052057600080fd5b506105296110e3565b6040519081526020015b60405180910390f35b34801561054857600080fd5b5061055c6105573660046146dc565b6110f4565b6040519015158152602001610533565b34801561057857600080fd5b50601054610529565b34801561058d57600080fd5b506105966112b3565b6040516105339190614751565b3480156105af57600080fd5b506105c36105be366004614764565b611345565b6040516001600160a01b039091168152602001610533565b3480156105e757600080fd5b506105126105f6366004614792565b6113cd565b34801561060757600080fd5b50610512610616366004614792565b6114dd565b34801561062757600080fd5b5061055c6106363660046147be565b611518565b34801561064757600080fd5b5047610529565b34801561065a57600080fd5b506105126106693660046147f7565b61152b565b34801561067a57600080fd5b506105296115f6565b34801561068f57600080fd5b50610512611601565b3480156106a457600080fd5b506105126106b3366004614642565b611638565b3480156106c457600080fd5b50600e54610529565b3480156106d957600080fd5b506105126106e8366004614814565b6116be565b3480156106f957600080fd5b506105126116f0565b34801561070e57600080fd5b5061072261071d366004614855565b611815565b604051610533929190614559565b34801561073c57600080fd5b5061051261184b565b34801561075157600080fd5b5060155460ff1661055c565b34801561076957600080fd5b50610512610778366004614764565b6118da565b34801561078957600080fd5b50610512611911565b34801561079e57600080fd5b506105126107ad3660046147f7565b611951565b3480156107be57600080fd5b50600654610529565b3480156107d357600080fd5b506105126107e2366004614814565b611987565b3480156107f357600080fd5b50610512610802366004614764565b6119a2565b34801561081357600080fd5b506105126108223660046147be565b6119db565b34801561083357600080fd5b50602154610529565b34801561084857600080fd5b50601754610529565b34801561085d57600080fd5b50610512611adc565b34801561087257600080fd5b50610512610881366004614877565b611c23565b34801561089257600080fd5b506108ad6108a13660046146dc565b506303e1469160e61b90565b6040516001600160e01b03199091168152602001610533565b3480156108d257600080fd5b50610529611d2d565b3480156108e757600080fd5b506105126108f63660046147f7565b611d46565b34801561090757600080fd5b506105c3610916366004614764565b611d85565b34801561092757600080fd5b506105126109363660046147f7565b611dfc565b34801561094757600080fd5b506105126109563660046146dc565b611e4d565b34801561096757600080fd5b506105296109763660046147f7565b611e7f565b34801561098757600080fd5b50610512611f06565b34801561099c57600080fd5b506105966109ab3660046148ab565b611f46565b3480156109bc57600080fd5b50610529611fdf565b3480156109d157600080fd5b50600f54610529565b3480156109e657600080fd5b50610512611ff1565b3480156109fb57600080fd5b506105c3610a0a366004614764565b612042565b348015610a1b57600080fd5b50610512610a2a366004614792565b612072565b348015610a3b57600080fd5b506002546001600160a01b03166105c3565b348015610a5957600080fd5b50610aa3610a683660046148c6565b601f60209081526000938452604080852084518086018401805192815290840195840195909520945292905282529020805460019091015482565b60408051928352602083019190915201610533565b348015610ac457600080fd5b50610512610ad3366004614877565b6120a9565b348015610ae457600080fd5b506105966120df565b348015610af957600080fd5b50610512610b08366004614764565b6120f1565b348015610b1957600080fd5b50610596612123565b348015610b2e57600080fd5b50610529610b3d3660046147f7565b6001600160a01b031660009081526009602052604090205490565b348015610b6457600080fd5b50610aa3612132565b348015610b7957600080fd5b50610512610b8836600461491c565b612150565b348015610b9957600080fd5b5061051261215b565b348015610bae57600080fd5b50600354610529565b348015610bc357600080fd5b5061051261219b565b348015610bd857600080fd5b506105126121db565b348015610bed57600080fd5b50610512610bfc36600461494f565b612210565b348015610c0d57600080fd5b50610512612242565b348015610c2257600080fd5b50610596610c31366004614764565b61235d565b348015610c4257600080fd5b50610512610c51366004614764565b6123ff565b348015610c6257600080fd5b506001546001600160a01b03166105c3565b348015610c8057600080fd5b50610529610c8f3660046147f7565b6001600160a01b031660009081526008602052604090205490565b610512610cb83660046149ae565b612551565b610512610ccb366004614a12565b6127c9565b348015610cdc57600080fd5b50610512610ceb3660046147f7565b612994565b348015610cfc57600080fd5b50610512610d0b366004614855565b6129d3565b348015610d1c57600080fd5b50610596612a40565b348015610d3157600080fd5b50600d54610529565b348015610d4657600080fd5b50610512610d553660046147be565b612a52565b348015610d6657600080fd5b50600754610529565b348015610d7b57600080fd5b50610529612b5f565b348015610d9057600080fd5b50610596612b6b565b348015610da557600080fd5b5061055c610db4366004614a9d565b612b7a565b348015610dc557600080fd5b50610512610dd4366004614abb565b612ba8565b348015610de557600080fd5b50610529612c26565b610512612c3f565b348015610e0257600080fd5b50610512610e113660046147f7565b612c7a565b348015610e2257600080fd5b50610512610e31366004614b0d565b612ccb565b348015610e4257600080fd5b50610512610e513660046147f7565b612d34565b601e546001600160a01b03163314610ee757604051630330dbc960e11b81526020600482015260546024820152600080516020615dd383398151915260448201527f6520646964206e6f7420636f6d652066726f6d2074686520656e64706f696e746064820152732c20796f75206661696c65642c204920776f6e2160601b608482015260a4015b60405180910390fd5b61ffff8416600090815260208052604090208054610f0490614ba0565b90508351141580610f43575061ffff84166000908152602080526040908190209051610f309190614c4d565b6040518091039020838051906020012014155b15610fcb57604051630330dbc960e11b815260206004820152605a6024820152600080516020615dd383398151915260448201527f6520646964206e6f7420636f6d652066726f6d2061207472757374656420636f60648201527f6e74726163742c20796f75206661696c65642c204920776f6e21000000000000608482015260a401610ede565b604051630e1bd41160e11b81523090631c37a82290610ff4908790879087908790600401614c59565b600060405180830381600087803b15801561100e57600080fd5b505af192505050801561101f575060015b6110dd576040518060400160405280825181526020018280519060200120815250601f60008661ffff1661ffff168152602001908152602001600020846040516110699190614ca2565b9081526040805191829003602090810183206001600160401b038716600090815290825291909120835181559201516001909201919091557fe6f254030bcb01ffd20558175c13fcaed6d1520be7becee4c961b65f79243b0d906110d4908690869086908690614c59565b60405180910390a15b50505050565b60006110ef600d613049565b905090565b60006001600160e01b0319821663b7d1e49960e01b148061112557506001600160e01b031982166303edf24760e01b145b8061114057506001600160e01b03198216633daba23f60e11b145b8061115b57506001600160e01b03198216630704183b60e11b145b8061117657506001600160e01b031982166302494e8b60e01b145b8061119157506001600160e01b0319821663152a902d60e11b145b806111ac57506001600160e01b0319821663131e54b760e01b145b806111c757506001600160e01b031982166323a87ba160e01b145b806111e257506001600160e01b0319821663253f8c7960e11b145b806111fd57506001600160e01b031982166329499a2560e01b145b8061121857506001600160e01b031982166317573c7360e21b145b8061123357506001600160e01b03198216632471dd5960e11b145b8061124e57506001600160e01b03198216634ba1182b60e11b145b8061126957506001600160e01b0319821663e8a3d48560e01b145b8061128457506001600160e01b0319821663938e3d7b60e01b145b8061129e57506001600160e01b03198216621d356760e01b145b806112ad57506112ad82613056565b92915050565b6060601880546112c290614ba0565b80601f01602080910402602001604051908101604052809291908181526020018280546112ee90614ba0565b801561133b5780601f106113105761010080835404028352916020019161133b565b820191906000526020600020905b81548152906001019060200180831161131e57829003601f168201915b5050505050905090565b6000611350826130a6565b6113b15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ede565b506000908152601c60205260409020546001600160a01b031690565b60006113d882611d85565b9050806001600160a01b0316836001600160a01b0316036114455760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610ede565b336001600160a01b038216148061146157506114618133612b7a565b6114ce5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776044820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b6064820152608401610ede565b6114d883836130c3565b505050565b6114ee63ca4b208b60e01b33613131565b61150a576040516282b42960e81b815260040160405180910390fd5b611514828261313e565b5050565b60006115248383613131565b9392505050565b61153c638da5cb5b60e01b33613131565b611558576040516282b42960e81b815260040160405180910390fd5b611569638da5cb5b60e01b82613131565b6115d457611581816001600160a01b03166014612eae565b611590638da5cb5b6004612eae565b61159b336014612eae565b6040516020016115ad93929190614cbe565b60408051601f1981840301815290829052630330dbc960e11b8252610ede91600401614751565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60006110ef60165490565b61161263ca4b208b60e01b33613131565b61162e576040516282b42960e81b815260040160405180910390fd5b6116366132b8565b565b3330146116b257604051630330dbc960e11b815260206004820152604d6024820152600080516020615dd383398151915260448201527f6520646964206e6f7420636f6d6520696e7465726e616c6c792c20796f75206660648201526c61696c65642c204920776f6e2160981b608482015260a401610ede565b6110dd84848484613347565b6116c9335b8261337c565b6116e55760405162461bcd60e51b8152600401610ede90614d77565b6114d883838361343e565b6004546003546117009190614dde565b42101561173a57426004546003546117189190614dde565b60405163f3f82ac560e01b815260048101929092526024820152604401610ede565b6003546000036117bf57604051630330dbc960e11b815260206004820152604360248201527f54696d65436f703a20596f75277665206265656e2054696d6520436f7070656460448201527f2e204e474c206f6e6c794465762829206861736e277420736574207468652074606482015262696d6560e81b608482015260a401610ede565b600a6117ca33611e7f565b106117fc576117da336014612eae565b6117eb6117e633611e7f565b6135cc565b6040516020016115ad929190614df6565b61180d336118086136cc565b6136e5565b6116366136ff565b600b54600c546001600160a01b03909116906000906103e8906118389085614e7b565b6118429190614eb0565b90509250929050565b636525904560e11b61185d8133613131565b8061187457506118746303e1469160e61b33613131565b1561189c573361188b636525904560e11b82613717565b61151463ca4b208b60e01b82613723565b6118ab60e082901c6004612eae565b6118ba63f851a4406004612eae565b6118c5336014612eae565b6040516020016115ad93929190614ec4565b50565b6118eb638da5cb5b60e01b33613131565b611907576040516282b42960e81b815260040160405180910390fd5b6118d7308261372f565b636525904560e11b6119238133613131565b8061193a575061193a6303e1469160e61b33613131565b1561189c5733611514636525904560e11b82613717565b61196263ca4b208b60e01b33613131565b61197e576040516282b42960e81b815260040160405180910390fd5b6118d7816137c2565b6114d883838360405180602001604052806000815250612210565b6119ab336116c3565b6119ca576119ba336014612eae565b6040516020016115ad9190614f51565b6119d38161390a565b6118d7613993565b816119e68133613131565b806119fd57506119fd6303e1469160e61b33613131565b1561189c57631ada6fbb60e11b6001600160e01b0319841601611a6a576001600160a01b0382163314611a6a57611a35336014612eae565b611a4460e085901c6004612eae565b611a58846001600160a01b03166014612eae565b6040516020016115ad93929190614feb565b63392d1a5360e11b6001600160e01b0319841601611ad2576001600160a01b0382163314611ad257611a9d336014612eae565b611aac60e085901c6004612eae565b611ac0846001600160a01b03166014612eae565b6040516020016115ad939291906150a4565b6114d88383613717565b336000818152600860205260408120549003611b0d57611afd336014612eae565b6040516020016115ad91906150af565b600060075447611b1d9190614dde565b6001600160a01b0383166000908152600960209081526040808320546006546008909352908320549394509192611b549085614e7b565b611b5e9190614eb0565b611b689190615101565b905080600003611b8d57611b7d336014612eae565b6040516020016115ad9190615118565b6001600160a01b038316600090815260096020526040902054611bb1908290614dde565b6001600160a01b038416600090815260096020526040902055600754611bd8908290614dde565b600755611be5838261399d565b7fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b0568382604051611c16929190614559565b60405180910390a1505050565b611c3463ca4b208b60e01b33613131565b611c50576040516282b42960e81b815260040160405180910390fd5b600060228054611c5f90614ba0565b80601f0160208091040260200160405190810160405280929190818152602001828054611c8b90614ba0565b8015611cd85780601f10611cad57610100808354040283529160200191611cd8565b820191906000526020600020905b815481529060010190602001808311611cbb57829003601f168201915b505050505090508160229081611cee91906151ca565b507fd2877107a884510f506ed0bd833e6601f4344691e32a0ce4bcdedb1d9d9d28e1816022604051611d21929190615300565b60405180910390a15050565b6000611d39600d613ab6565b6010546110ef9190615101565b63ca4b208b60e01b611d588133613131565b80611d6f5750611d6f6303e1469160e61b33613131565b1561189c57611514636525904560e11b83613723565b6000818152601a60205260408120546001600160a01b0316806112ad5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610ede565b63ca4b208b60e01b611e0e8133613131565b80611e255750611e256303e1469160e61b33613131565b1561189c5733611e3c63ca4b208b60e01b84613723565b6114d863ca4b208b60e01b82613717565b80611e588133613131565b80611e6f5750611e6f6303e1469160e61b33613131565b1561189c57336114d88382613717565b60006001600160a01b038216611eea5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610ede565b506001600160a01b03166000908152601b602052604090205490565b638da5cb5b60e01b611f188133613131565b80611f2f5750611f2f6303e1469160e61b33613131565b1561189c5733611514638da5cb5b60e01b82613717565b602080526000908152604090208054611f5e90614ba0565b80601f0160208091040260200160405190810160405280929190818152602001828054611f8a90614ba0565b8015611fd75780601f10611fac57610100808354040283529160200191611fd7565b820191906000526020600020905b815481529060010190602001808311611fba57829003601f168201915b505050505081565b60006004546003546110ef9190614dde565b6346d2e5ad60e11b6120038133613131565b8061201a575061201a6303e1469160e61b33613131565b1561189c57336120316346d2e5ad60e11b82613717565b611514638da5cb5b60e01b82613723565b6000600a82815481106120575761205761532e565b6000918252602090912001546001600160a01b031692915050565b612083638da5cb5b60e01b33613131565b61209f576040516282b42960e81b815260040160405180910390fd5b611514828261372f565b6120ba63ca4b208b60e01b33613131565b6120d6576040516282b42960e81b815260040160405180910390fd5b6118d781613ac3565b6060600d60050180546112c290614ba0565b612102638da5cb5b60e01b33613131565b61211e576040516282b42960e81b815260040160405180910390fd5b602155565b6060601980546112c290614ba0565b6000806003546004546003546121489190614dde565b915091509091565b611514338383613b94565b6346d2e5ad60e11b61216d8133613131565b8061218457506121846303e1469160e61b33613131565b1561189c57336115146346d2e5ad60e11b82613717565b63ca4b208b60e01b6121ad8133613131565b806121c457506121c46303e1469160e61b33613131565b1561189c573361151463ca4b208b60e01b82613717565b6121ec638da5cb5b60e01b33613131565b612208576040516282b42960e81b815260040160405180910390fd5b611636613c5e565b61221a338361337c565b6122365760405162461bcd60e51b8152600401610ede90614d77565b6110dd84848484613cac565b61225363ca4b208b60e01b33613131565b61226f576040516282b42960e81b815260040160405180910390fd5b6000306001600160a01b0316635c17e3706040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d39190615344565b905060005b818110156115145761234d306001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612321573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612345919061535d565b6118086136cc565b612355613cdf565b6001016122d8565b6060612368826130a6565b61238557612375826135cc565b6040516020016115ad919061537a565b600061238f613cf3565b604080518082019091526005815264173539b7b760d91b60208201528151919250906123ca57604051806020016040528060008152506123f7565b816123d4856135cc565b826040516020016123e7939291906153e6565b6040516020818303038152906040525b949350505050565b60035442101561242f5760035460405163f3f82ac560e01b81524260048201526024810191909152604401610ede565b60045460035461243f9190614dde565b421061247857426004546003546124569190614dde565b6040516343c540ef60e01b815260048101929092526024820152604401610ede565b600461248333611e7f565b106124b057612493336014612eae565b61249f6117e633611e7f565b6040516020016115ad929190615429565b60028111156124de576124c4336014612eae565b6124cd826135cc565b6040516020016115ad9291906154ac565b60005b818110156115145760046124f433611e7f565b1061253557612504336014612eae565b61250d836135cc565b61252361251933611e7f565b6117e69086614dde565b6040516020016115ad93929190615530565b612541336118086136cc565b6125496136ff565b6001016124e1565b61255a81611d85565b6001600160a01b0316336001600160a01b03161461258a576040516282b42960e81b815260040160405180910390fd5b61ffff82166000908152602080526040902080546125a790614ba0565b905060000361262b57604051630330dbc960e11b815260206004820152604360248201527f546f6b656e3a204f6b2074686520446576206469646e2774207365742074686960448201527f7320706172616d617465722c20636f6e74616374204d6178466c6f774f322e656064820152623a341760e91b608482015260a401610ede565b6126348161390a565b61263c613993565b60003382604051602001612651929190614559565b60408051601f1981840301815290829052602154600160f01b60208401526022830152915060019060009060420160408051601f1981840301815290829052601e5463040a7bb160e41b83529092506000916001600160a01b03909116906340a7bb10906126cb90899030908990879089906004016155f1565b6040805180830381865afa1580156126e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061270b9190615645565b5090503481111561274557612721336014612eae565b61272a346135cc565b612733836135cc565b6040516020016115ad93929190615669565b601e5461ffff87166000908152602080526040808220905162c5803160e81b81526001600160a01b039093169263c580310092349261278f928c928b913391908b906004016156eb565b6000604051808303818588803b1580156127a857600080fd5b505af11580156127bc573d6000803e3d6000fd5b5050505050505050505050565b61ffff85166000908152601f602052604080822090516127ea908790614ca2565b90815260408051602092819003830190206001600160401b038716600090815292529020600181015490915061288a57604051630330dbc960e11b815260206004820152604a6024820152600080516020615dd383398151915260448201527f652077617320616c72656164792065786563757465642c20796f75206661696c60648201526965642c204920776f6e2160b01b608482015260a401610ede565b8054821415806128b55750806001015483836040516128aa929190615752565b604051809103902014155b1561292557604051630330dbc960e11b815260206004820152604460248201819052600080516020615dd3833981519152908201527f6520776173206e6f742073746f7265642c20796f75206661696c65642c204920606482015263776f6e2160e01b608482015260a401610ede565b60008082556001820155604051630e1bd41160e11b81523090631c37a8229061295a908990899089908990899060040161578b565b600060405180830381600087803b15801561297457600080fd5b505af1158015612988573d6000803e3d6000fd5b50505050505050505050565b638da5cb5b60e01b6129a68133613131565b806129bd57506129bd6303e1469160e61b33613131565b1561189c576115146346d2e5ad60e11b83613723565b6129e463ca4b208b60e01b33613131565b612a00576040516282b42960e81b815260040160405180910390fd5b6003829055600481905560408051838152602081018390527f5ef81ff0fe28d74938986521db9f3fb5637cae3d1cec04a94b4a0d3a3b0fc3c49101611d21565b6060600d60040180546112c290614ba0565b81612a5d8133613131565b80612a745750612a746303e1469160e61b33613131565b1561189c57631ada6fbb60e11b6001600160e01b0319841601612ae757612aa2636525904560e11b33613131565b15612ae757612ab2336014612eae565b612ac160e085901c6004612eae565b612ad5846001600160a01b03166014612eae565b6040516020016115ad939291906157ca565b63392d1a5360e11b6001600160e01b0319841601612b5557612b106346d2e5ad60e11b33613131565b15612b5557612b20336014612eae565b612b2f60e085901c6004612eae565b612b43846001600160a01b03166014612eae565b6040516020016115ad9392919061584b565b6114d88383613723565b60006110ef600d613ab6565b6060600580546112c290614ba0565b6001600160a01b039182166000908152601d6020908152604080832093909416825291909152205460ff1690565b612bb963ca4b208b60e01b33613131565b612bd5576040516282b42960e81b815260040160405180910390fd5b61ffff831660009081526020805260409020612bf2828483615856565b507f93c35c217d799290d33244ef8905b63167d13758ab18343cd8055ed1b8056748838383604051611c1693929190615910565b6000612c32600d613049565b600f546110ef9190615101565b7f9a064d674ddc42ac41b38566457161f1ded37e65a59162da003dd25bcb057b603334604051612c70929190614559565b60405180910390a1565b638da5cb5b60e01b612c8c8133613131565b80612ca35750612ca36303e1469160e61b33613131565b1561189c5733612cba638da5cb5b60e01b84613723565b6114d8638da5cb5b60e01b82613717565b612cdc63ca4b208b60e01b33613131565b612cf8576040516282b42960e81b815260040160405180910390fd5b612d03868686613d02565b612d0d8383613d65565b601e80546001600160a01b0319166001600160a01b03929092169190911790555050505050565b612d4563ca4b208b60e01b33613131565b612d61576040516282b42960e81b815260040160405180910390fd5b612d7263ca4b208b60e01b82613131565b612db657612d8a816001600160a01b03166014612eae565b612d9963ca4b208b6004612eae565b612da4336014612eae565b6040516020016115ad9392919061592e565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038116612dfe576040516282b42960e81b815260040160405180910390fd5b612e09838383613d85565b15612e4257612e22816001600160a01b03166014612eae565b612e3160e084901c6004612eae565b6040516020016115ad9291906159ea565b6001600160a01b0381166000908152602084815260408083206001600160e01b03198616845290915290819020805460ff1916600190811790915590517fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f791611c169185918591615a4e565b60606000612ebd836002614e7b565b612ec8906002614dde565b6001600160401b03811115612edf57612edf614589565b6040519080825280601f01601f191660200182016040528015612f09576020820181803683370190505b509050600360fc1b81600081518110612f2457612f2461532e565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612f5357612f5361532e565b60200101906001600160f81b031916908160001a9053506000612f77846002614e7b565b612f82906001614dde565b90505b6001811115612ffa576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612fb657612fb661532e565b1a60f81b828281518110612fcc57612fcc61532e565b60200101906001600160f81b031916908160001a90535060049490941c93612ff381615a7b565b9050612f85565b5083156115245760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610ede565b60006112ad826006015490565b60006001600160e01b031982166380ac58cd60e01b148061308757506001600160e01b03198216635b5e139f60e01b145b806112ad57506301ffc9a760e01b6001600160e01b03198316146112ad565b6000908152601a60205260409020546001600160a01b0316151590565b6000818152601c6020526040902080546001600160a01b0319166001600160a01b03841690811790915581906130f882611d85565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611524818484613d85565b6001600160a01b03821661316557604051630330dbc960e11b8152600401610ede90615a92565b806000036131b657604051630330dbc960e11b815260206004820152601d60248201527f5061796d656e7453706c69747465723a207368617265732061726520300000006044820152606401610ede565b6001600160a01b0382166000908152600860205260409020541561321b576131e8826001600160a01b03166014612eae565b6001600160a01b03831660009081526008602052604090205461320a906135cc565b6040516020016115ad929190615ade565b600a8054600181019091557fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a80180546001600160a01b0319166001600160a01b0384169081179091556000908152600860205260409020819055600654613283908290614dde565b6006556040517f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac90611d219084908490614559565b600a5460005b81811015613306576000600a82815481106132db576132db61532e565b60009182526020808320909101546001600160a01b03168252600890526040812055506001016132be565b50600660009055600a600061331b9190614527565b6040517f3407fd525bf6581e0ae8e3a3636bd90d02112bea34d66802743c28ced73f910e90600090a150565b6000808280602001905181019061335e9190615b58565b9150915061336c82826136e5565b613374613709565b505050505050565b6000613387826130a6565b6133e85760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ede565b60006133f383611d85565b9050806001600160a01b0316846001600160a01b0316148061342e5750836001600160a01b031661342384611345565b6001600160a01b0316145b806123f757506123f78185612b7a565b826001600160a01b031661345182611d85565b6001600160a01b0316146134b95760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610ede565b6001600160a01b03821661351b5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610ede565b6135266000826130c3565b6001600160a01b0383166000908152601b6020526040812080546001929061354f908490615101565b90915550506001600160a01b0382166000908152601b6020526040812080546001929061357d908490614dde565b90915550506000818152601a602052604080822080546001600160a01b0319166001600160a01b038681169182179092559151849391871691600080516020615df383398151915291a4505050565b6060816000036135f35750506040805180820190915260018152600360fc1b602082015290565b8160005b811561361d578061360781615b86565b91506136169050600a83614eb0565b91506135f7565b6000816001600160401b0381111561363757613637614589565b6040519080825280601f01601f191660200182016040528015613661576020820181803683370190505b5090505b84156123f757613676600183615101565b9150613683600a86615b9f565b61368e906030614dde565b60f81b8183815181106136a3576136a361532e565b60200101906001600160f81b031916908160001a9053506136c5600a86614eb0565b9450613665565b60006136d8600d613de2565b6017546110ef9190614dde565b611514828260405180602001604052806000815250613e0d565b613709600d613e40565b611636601680546001019055565b61151460008383613e50565b61151460008383612dd8565b6103e88110158061373e575080155b156137685761374e336014612eae565b613757826135cc565b6040516020016115ad929190615bb3565b600b80546001600160a01b0319166001600160a01b038416908117909155600c8290556040805183815260208101929092527f184520f1b2fcf99836992b9a6b987afc0e4867f26a00ef438c654318763fe1e39101611d21565b6001600160a01b0381166137e957604051630330dbc960e11b8152600401610ede90615a92565b60006137f482613f1d565b600a805491925060009161380a90600190615101565b8154811061381a5761381a61532e565b600091825260209091200154600a80546001600160a01b0390921692508291849081106138495761384961532e565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600a80548061388857613888615c42565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0385168252600890526040812080549190556006546138d5908290615101565b6006556040517f104b8837ec12e86f303ac7ce5e3bf20c6790f843fabd7451943f3390fc8376cb906110d49086908490614559565b600061391582611d85565b90506139226000836130c3565b6001600160a01b0381166000908152601b6020526040812080546001929061394b908490615101565b90915550506000828152601a602052604080822080546001600160a01b0319169055518391906001600160a01b03841690600080516020615df3833981519152908390a45050565b6116366016613f77565b804710156139ed5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610ede565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613a3a576040519150601f19603f3d011682016040523d82523d6000602084013e613a3f565b606091505b50509050806114d85760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610ede565b60006112ad826007015490565b600060058054613ad290614ba0565b80601f0160208091040260200160405190810160405280929190818152602001828054613afe90614ba0565b8015613b4b5780601f10613b2057610100808354040283529160200191613b4b565b820191906000526020600020905b815481529060010190602001808311613b2e57829003601f168201915b505050505090508160059081613b6191906151ca565b507f17f75bb1e35b058872a221a8c16d8b3e39eacbda214fd7da20f192b9291ecc3b816005604051611d21929190615300565b816001600160a01b0316836001600160a01b031603613bf15760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b6044820152606401610ede565b6001600160a01b038381166000818152601d6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b600b80546001600160a01b03191690556000600c8190556040805182815260208101929092527f184520f1b2fcf99836992b9a6b987afc0e4867f26a00ef438c654318763fe1e39101612c70565b613cb784848461343e565b613cc384848484613fe0565b6110dd5760405162461bcd60e51b8152600401610ede90615c58565b613ce9600d613e40565b613709600d6140e1565b6060602280546112c290614ba0565b6017839055613d12600d836140f1565b613d1d600d82614131565b7f0e59e2733e85d32179b3dffa920faef60cc432823591194c4e5f0ac15db3dcec8284613d4a8183614dde565b60408051938452602084019290925290820152606001611c16565b613d70600d82614171565b613d7b600d83614245565b611514600d614319565b60006001600160a01b038216613dad576040516282b42960e81b815260040160405180910390fd5b506001600160a01b03166000908152602092835260408082206001600160e01b03199390931682529190925290205460ff1690565b60008160020154613df4836006015490565b8360010154613e039190614dde565b6112ad9190615b9f565b613e178383614406565b613e246000848484613fe0565b6114d85760405162461bcd60e51b8152600401610ede90615c58565b6118d78160060180546001019055565b6001600160a01b038116613e76576040516282b42960e81b815260040160405180910390fd5b613e81838383613d85565b613eb957613e99816001600160a01b03166014612eae565b613ea860e084901c6004612eae565b6040516020016115ad929190615caa565b6001600160a01b0381166000908152602084815260408083206001600160e01b031986168452909152808220805460ff19169055517fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f791611c169185918591615a4e565b600a54600090815b81811015613f7057836001600160a01b0316600a8281548110613f4a57613f4a61532e565b6000918252602090912001546001600160a01b031603613f68578092505b600101613f25565b5050919050565b80546000819003613fd557604051630330dbc960e11b815260206004820152602160248201527f436f756e7465727356323a204e6f206e656761746976657320696e2075696e746044820152607360f81b6064820152608401610ede565b508054600019019055565b60006001600160a01b0384163b156140d657604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614024903390899088908890600401615d10565b6020604051808303816000875af192505050801561405f575060408051601f3d908101601f1916820190925261405c91810190615d4d565b60015b6140bc573d80801561408d576040519150601f19603f3d011682016040523d82523d6000602084013e614092565b606091505b5080516000036140b45760405162461bcd60e51b8152600401610ede90615c58565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506123f7565b506001949350505050565b6118d78160070180546001019055565b6002820180549082905560408051838152602081018390527fe26aa1327aec5016c96875498202eebb896e3c2a79cd281ff17ed5bde4e545db9101611c16565b6003820180549082905560408051838152602081018390527fef40c7688f323b7ccad323bec82bfee336d16c0939c46bee1f3e5df296dadde39101611c16565b600082600501805461418290614ba0565b80601f01602080910402602001604051908101604052809291908181526020018280546141ae90614ba0565b80156141fb5780601f106141d0576101008083540402835291602001916141fb565b820191906000526020600020905b8154815290600101906020018083116141de57829003601f168201915b505050505090508183600501908161421391906151ca565b507f5769620297eb5047703c0ba55dd28b8ea50ba49818a91a43217fedce8eb69a308282604051611c16929190615d6a565b600082600401805461425690614ba0565b80601f016020809104026020016040519081016040528092919081815260200182805461428290614ba0565b80156142cf5780601f106142a4576101008083540402835291602001916142cf565b820191906000526020600020905b8154815290600101906020018083116142b257829003601f168201915b50505050509050818360040190816142e791906151ca565b507f7058c986a2931f38a70c3f70689d1f2bb75efb4d0082511082db4b2d40492b4f8282604051611c16929190615d6a565b806002015460000361438257604051630330dbc960e11b815260206004820152602b60248201527f50737565646f52616e646f6d204c69623a204d6178696d756d2043617061636960448201526a7479206e6f74207365742160a81b6064820152608401610ede565b806002015442338360040184600501446040516020016143a6959493929190615d8f565b6040516020818303038152906040528051906020012060001c6143c99190615b9f565b600182018190556040519081527f74d17dde2d5b61215fe87f93cddcd2470527e8b0381734da7d0dfeb3fcf6f8179060200160405180910390a150565b6001600160a01b03821661445c5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610ede565b614465816130a6565b156144b25760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610ede565b6001600160a01b0382166000908152601b602052604081208054600192906144db908490614dde565b90915550506000818152601a602052604080822080546001600160a01b0319166001600160a01b0386169081179091559051839290600080516020615df3833981519152908290a45050565b50805460008255906000526020600020908101906118d791905b808211156145555760008155600101614541565b5090565b6001600160a01b03929092168252602082015260400190565b803561ffff8116811461458457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126145b057600080fd5b81356001600160401b03808211156145ca576145ca614589565b604051601f8301601f19908116603f011681019082821181831017156145f2576145f2614589565b8160405283815286602085880101111561460b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b80356001600160401b038116811461458457600080fd5b6000806000806080858703121561465857600080fd5b61466185614572565b935060208501356001600160401b038082111561467d57600080fd5b6146898883890161459f565b94506146976040880161462b565b935060608701359150808211156146ad57600080fd5b506146ba8782880161459f565b91505092959194509250565b6001600160e01b0319811681146118d757600080fd5b6000602082840312156146ee57600080fd5b8135611524816146c6565b60005b838110156147145781810151838201526020016146fc565b838111156110dd5750506000910152565b6000815180845261473d8160208601602086016146f9565b601f01601f19169290920160200192915050565b6020815260006115246020830184614725565b60006020828403121561477657600080fd5b5035919050565b6001600160a01b03811681146118d757600080fd5b600080604083850312156147a557600080fd5b82356147b08161477d565b946020939093013593505050565b600080604083850312156147d157600080fd5b82356147dc816146c6565b915060208301356147ec8161477d565b809150509250929050565b60006020828403121561480957600080fd5b81356115248161477d565b60008060006060848603121561482957600080fd5b83356148348161477d565b925060208401356148448161477d565b929592945050506040919091013590565b6000806040838503121561486857600080fd5b50508035926020909101359150565b60006020828403121561488957600080fd5b81356001600160401b0381111561489f57600080fd5b6123f78482850161459f565b6000602082840312156148bd57600080fd5b61152482614572565b6000806000606084860312156148db57600080fd5b6148e484614572565b925060208401356001600160401b038111156148ff57600080fd5b61490b8682870161459f565b925050604084013590509250925092565b6000806040838503121561492f57600080fd5b823561493a8161477d565b9150602083013580151581146147ec57600080fd5b6000806000806080858703121561496557600080fd5b84356149708161477d565b935060208501356149808161477d565b92506040850135915060608501356001600160401b038111156149a257600080fd5b6146ba8782880161459f565b600080604083850312156149c157600080fd5b6147b083614572565b60008083601f8401126149dc57600080fd5b5081356001600160401b038111156149f357600080fd5b602083019150836020828501011115614a0b57600080fd5b9250929050565b600080600080600060808688031215614a2a57600080fd5b614a3386614572565b945060208601356001600160401b0380821115614a4f57600080fd5b614a5b89838a0161459f565b9550614a696040890161462b565b94506060880135915080821115614a7f57600080fd5b50614a8c888289016149ca565b969995985093965092949392505050565b60008060408385031215614ab057600080fd5b82356147dc8161477d565b600080600060408486031215614ad057600080fd5b614ad984614572565b925060208401356001600160401b03811115614af457600080fd5b614b00868287016149ca565b9497909650939450505050565b60008060008060008060c08789031215614b2657600080fd5b86359550602087013594506040870135935060608701356001600160401b0380821115614b5257600080fd5b614b5e8a838b0161459f565b94506080890135915080821115614b7457600080fd5b50614b8189828a0161459f565b92505060a0870135614b928161477d565b809150509295509295509295565b600181811c90821680614bb457607f821691505b602082108103614bd457634e487b7160e01b600052602260045260246000fd5b50919050565b60008154614be781614ba0565b60018281168015614bff5760018114614c1457614c43565b60ff1984168752821515830287019450614c43565b8560005260208060002060005b85811015614c3a5781548a820152908401908201614c21565b50505082870194505b5050505092915050565b60006115248284614bda565b61ffff85168152608060208201526000614c766080830186614725565b6001600160401b03851660408401528281036060840152614c978185614725565b979650505050505050565b60008251614cb48184602087016146f9565b9190910192915050565b76026b0bc20b1b1b2b9b99d102a34329030b2323932b9b99604d1b815260008451614cf08160178501602089016146f9565b7f206973206e6f7420616e206f776e657220616e6420646f6573206e6f742068616017918401918201526b03b32903a3432903937b632960a51b60378201528451614d428160438401602089016146f9565b660103a3432b932960cd1b604392909101918201528351614d6a81604a8401602088016146f9565b01604a0195945050505050565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008219821115614df157614df1614dc8565b500190565b6902a37b5b2b71d1027b5960b51b815260008351614e1b81600a8501602088016146f9565b690103cb7ba903430bb32960b51b600a918401918201528351614e458160148401602088016146f9565b7f206d6178696d756d20617420746869732074696d652069732031302e0000000060149290910191820152603001949350505050565b6000816000190483118215151615614e9557614e95614dc8565b500290565b634e487b7160e01b600052601260045260246000fd5b600082614ebf57614ebf614e9a565b500490565b7f4d61784163636573733a20596f75206172652061206e6f7420616e2000000000815260008451614efc81601c8501602089016146f9565b80830190506301037b9160e51b601c8201528451614f218160208401602089016146f9565b808201915050600160fd1b60208201528351614f448160218401602088016146f9565b0160210195945050505050565b6f022a9219b9918a13ab93730b136329d160851b815260008251614f7c8160108501602087016146f9565b7f206973206e6f74206f776e6572206e6f7220617070726f7665640000000000006010939091019283015250602a01919050565b7f4d61784163636573733a20596f752061726520612070656e64696e6720646576815268032b637b832b91414960bd1b602082015260290190565b6000614ff682614fb0565b8551615006818360208a016146f9565b780103cb7ba9031b0b7103737ba103932bb37b5b2903937b6329603d1b9101908152845161503b8160198401602089016146f9565b630103a37960e51b60199290910191820152835161506081601d8401602088016146f9565b01601d0195945050505050565b7f4d61784163636573733a20596f752061726520612070656e64696e67206f776e815264032b91414960dd1b602082015260250190565b6000614ff68261506d565b7002830bcb6b2b73a29b83634ba3a32b91d1607d1b8152600082516150db8160118501602087016146f9565b6e103430b99037379039b430b932b99760891b6011939091019283015250602001919050565b60008282101561511357615113614dc8565b500390565b7002830bcb6b2b73a29b83634ba3a32b91d1607d1b8152600082516151448160118501602087016146f9565b731034b9903737ba10323ab2903830bcb6b2b73a1760611b6011939091019283015250602501919050565b601f8211156114d857600081815260208120601f850160051c810160208610156151965750805b601f850160051c820191505b81811015613374578281556001016151a2565b600019600383901b1c191660019190911b1790565b81516001600160401b038111156151e3576151e3614589565b6151f7816151f18454614ba0565b8461516f565b602080601f83116001811461522657600084156152145750858301515b61521e85826151b5565b865550613374565b600085815260208120601f198616915b8281101561525557888601518255948401946001909101908401615236565b50858210156152735787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000815461529081614ba0565b8085526020600183811680156152ad57600181146152c7576152f5565b60ff1985168884015283151560051b8801830195506152f5565b866000528260002060005b858110156152ed5781548a82018601529083019084016152d2565b890184019650505b505050505092915050565b6040815260006153136040830185614725565b82810360208401526153258185615283565b95945050505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561535657600080fd5b5051919050565b60006020828403121561536f57600080fd5b81516115248161477d565b7f4552433732314d657461646174613a2055524920717565727920666f722000008152600082516153b281601e8501602087016146f9565b7f2072657475726e73206e6f6e6578697374656e7420746f6b656e000000000000601e939091019283015250603801919050565b600084516153f88184602089016146f9565b84519083019061540c8183602089016146f9565b845191019061541f8183602088016146f9565b0195945050505050565b6902a37b5b2b71d1027b5960b51b81526000835161544e81600a8501602088016146f9565b690103cb7ba903430bb32960b51b600a9184019182015283516154788160148401602088016146f9565b7a1036b0bc34b6bab69030ba103a3434b9903a34b6b29034b9901a1760291b60149290910191820152602f01949350505050565b6902a37b5b2b71d1027b5960b51b8152600083516154d181600a8501602088016146f9565b730103cb7ba903bb0b73a32b2103a379036b4b73a160651b600a91840191820152835161550581601e8401602088016146f9565b7110191037b9103632b9b990383632b0b9b29760711b601e9290910191820152603001949350505050565b6902a37b5b2b71d1027b5960b51b81526000845161555581600a8501602089016146f9565b730103cb7ba903bb0b73a32b2103a379036b4b73a160651b600a91840191820152845161558981601e8401602089016146f9565b710103a3430ba10383aba39903cb7ba9030ba160751b601e929091019182015283516155bc8160308401602088016146f9565b7a1036b0bc34b6bab69030ba103a3434b9903a34b6b29034b9901a1760291b60309290910191820152604b0195945050505050565b61ffff861681526001600160a01b038516602082015260a06040820181905260009061561f90830186614725565b841515606084015282810360808401526156398185614725565b98975050505050505050565b6000806040838503121561565857600080fd5b505080516020909101519092909150565b6602a37b5b2b71d160cd1b81526000845161568b8160078501602089016146f9565b6501039b2b73a160d51b60079184019182015284516156b181600d8401602089016146f9565b6b01034b739ba32b0b21037b3160a51b600d929091019182015283516156de8160198401602088016146f9565b0160190195945050505050565b61ffff8716815260c06020820152600061570860c0830188615283565b828103604084015261571a8188614725565b6001600160a01b0387811660608601528616608085015283810360a085015290506157458185614725565b9998505050505050505050565b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff861681526080602082015260006157a86080830187614725565b6001600160401b03861660408401528281036060840152615639818587615762565b60006157d582614fb0565b85516157e5818360208a016146f9565b770103cb7ba9031b0b7103737ba1033b930b73a103937b632960451b910190815284516158198160188401602089016146f9565b630103a37960e51b60189290910191820152835161583e81601c8401602088016146f9565b01601c0195945050505050565b60006157d58261506d565b6001600160401b0383111561586d5761586d614589565b6158818361587b8354614ba0565b8361516f565b6000601f8411600181146158af576000851561589d5750838201355b6158a786826151b5565b845550615909565b600083815260209020601f19861690835b828110156158e057868501358255602094850194600190920191016158c0565b50868210156158fd5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b61ffff84168152604060208201526000615325604083018486615762565b76026b0bc20b1b1b2b9b99d102a34329030b2323932b9b99604d1b8152600084516159608160178501602089016146f9565b7f206973206e6f74206120646576656c6f70657220616e6420646f6573206e6f746017918401918201526e0103430bb32903a3432903937b6329608d1b603782015284516159b58160468401602089016146f9565b660103a3432b932960cd1b6046929091019182015283516159dd81604d8401602088016146f9565b01604d0195945050505050565b6a02634b1102937b632b99d160ad1b815260008351615a1081600b8501602088016146f9565b7101030b63932b0b23c903430b9903937b632960751b600b918401918201528351615a4281601d8401602088016146f9565b01601d01949350505050565b6001600160e01b03199390931683526001600160a01b039190911660208301521515604082015260600190565b600081615a8a57615a8a614dc8565b506000190190565b6020808252602c908201527f5061796d656e7453706c69747465723a206163636f756e74206973207468652060408201526b7a65726f206164647265737360a01b606082015260800190565b7002830bcb6b2b73a29b83634ba3a32b91d1607d1b815260008351615b0a8160118501602088016146f9565b6c01030b63932b0b23c903430b99609d1b6011918401918201528351615b3781601e8401602088016146f9565b671039b430b932b99760c11b601e9290910191820152602601949350505050565b60008060408385031215615b6b57600080fd5b8251615b768161477d565b6020939093015192949293505050565b600060018201615b9857615b98614dc8565b5060010190565b600082615bae57615bae614e9a565b500690565b72022a921991c9c18a1b7b63632b1ba34b7b71d1606d1b815260008351615be18160138501602088016146f9565b6a01039bab136b4ba3a32b2160ad1b6013918401918201528351615c0c81601e8401602088016146f9565b7f20616e642074686174206973206f7574206f6620626f756e6473210000000000601e9290910191820152603901949350505050565b634e487b7160e01b600052603160045260246000fd5b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6a02634b1102937b632b99d160ad1b815260008351615cd081600b8501602088016146f9565b730103237b2b9903737ba103430bb32903937b632960651b600b918401918201528351615d0481601f8401602088016146f9565b01601f01949350505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090615d4390830184614725565b9695505050505050565b600060208284031215615d5f57600080fd5b8151611524816146c6565b604081526000615d7d6040830185614725565b82810360208401526153258185614725565b8581526bffffffffffffffffffffffff198560601b1660208201526000615dc2615dbc6034840187614bda565b85614bda565b928352505060200194935050505056fe4e6f6e626c6f636b696e6752656365697665723a2054686973206d6573736167ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212203141b7ea1d69d1dba90a4aa8c8ceb739713a9cc2ac8d184bde9f9da53c19d3bb64736f6c634300080f0033

Deployed Bytecode

0x6080604052600436106104815760003560e01c80637544671611610255578063c87b56dd11610144578063de02cde7116100c1578063eb8d72b711610085578063eb8d72b714610db9578063ecc7afa914610dd9578063ed88c68e14610dee578063f2fde38b14610df6578063fd0198e814610e16578063ff70fa4914610e36576104c1565b8063de02cde714610d3a578063e33b7de314610d5a578063e68b796114610d6f578063e8a3d48514610d84578063e985e9c514610d99576104c1565b8063d1deba1f11610108578063d1deba1f14610cbd578063d39ce77c14610cd0578063d4d714be14610cf0578063d792d2a014610d10578063d95ae16214610d25576104c1565b8063c87b56dd14610c16578063c9b298f114610c36578063ca4b208b14610c56578063ce7c2ac214610c74578063cf89fa0314610caa576104c1565b806395d89b41116101d2578063aac3f28111610196578063aac3f28114610ba2578063ad6d9c1714610bb7578063ae47b2da14610bcc578063b88d4fde14610be1578063ba7a86b814610c01576104c1565b806395d89b4114610b0d5780639852595c14610b225780639c12b17f14610b58578063a22cb46514610b6d578063a86ff96014610b8d576104c1565b80638da5cb5b116102195780638da5cb5b14610a2f5780638ee7491214610a4d578063938e3d7b14610ab85780639435267614610ad8578063943fb87214610aed576104c1565b806375446716146109b057806378c5939b146109c557806379ba5097146109da5780638b83209b146109ef5780638c7ea24b14610a0f576104c1565b8063312744261161037157806355f804b3116102ee57806364cb4edb116102b257806364cb4edb1461091b57806366278a6c1461093b57806370a082311461095b578063715018a61461097b5780637533d78814610990576104c1565b806355f804b3146108665780635ba5e9f0146108865780635c17e370146108c65780636149d871146108db5780636352211e146108fb576104c1565b806342966c681161033557806342966c68146107e757806344faded014610807578063475de12e1461082757806348e3bab21461083c5780634e71d92d14610851576104c1565b8063312744261461075d57806331e26cfd1461077d5780633400ec63146107925780633a98ef39146107b257806342842e0e146107c7576104c1565b806313af4035116103ff57806323b872dd116103c357806323b872dd146106cd57806326092b83146106ed5780632a55205a146107025780632bfcf0f2146107305780632ecd28ab14610745576104c1565b806313af40351461064e57806318160ddd1461066e57806318a66a7e146106835780631c37a822146106985780631efb051a146106b8576104c1565b8063081812fc11610446578063081812fc146105a3578063095ea7b3146105db5780630f0efdbc146105fb57806310ab94321461061b57806312065fe01461063b576104c1565b80621d3567146104f2578063018f007e1461051457806301ffc9a71461053c578063049157bb1461056c57806306fdde0314610581576104c1565b366104c1577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033346040516104b7929190614559565b60405180910390a1005b7f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033346040516104b7929190614559565b3480156104fe57600080fd5b5061051261050d366004614642565b610e56565b005b34801561052057600080fd5b506105296110e3565b6040519081526020015b60405180910390f35b34801561054857600080fd5b5061055c6105573660046146dc565b6110f4565b6040519015158152602001610533565b34801561057857600080fd5b50601054610529565b34801561058d57600080fd5b506105966112b3565b6040516105339190614751565b3480156105af57600080fd5b506105c36105be366004614764565b611345565b6040516001600160a01b039091168152602001610533565b3480156105e757600080fd5b506105126105f6366004614792565b6113cd565b34801561060757600080fd5b50610512610616366004614792565b6114dd565b34801561062757600080fd5b5061055c6106363660046147be565b611518565b34801561064757600080fd5b5047610529565b34801561065a57600080fd5b506105126106693660046147f7565b61152b565b34801561067a57600080fd5b506105296115f6565b34801561068f57600080fd5b50610512611601565b3480156106a457600080fd5b506105126106b3366004614642565b611638565b3480156106c457600080fd5b50600e54610529565b3480156106d957600080fd5b506105126106e8366004614814565b6116be565b3480156106f957600080fd5b506105126116f0565b34801561070e57600080fd5b5061072261071d366004614855565b611815565b604051610533929190614559565b34801561073c57600080fd5b5061051261184b565b34801561075157600080fd5b5060155460ff1661055c565b34801561076957600080fd5b50610512610778366004614764565b6118da565b34801561078957600080fd5b50610512611911565b34801561079e57600080fd5b506105126107ad3660046147f7565b611951565b3480156107be57600080fd5b50600654610529565b3480156107d357600080fd5b506105126107e2366004614814565b611987565b3480156107f357600080fd5b50610512610802366004614764565b6119a2565b34801561081357600080fd5b506105126108223660046147be565b6119db565b34801561083357600080fd5b50602154610529565b34801561084857600080fd5b50601754610529565b34801561085d57600080fd5b50610512611adc565b34801561087257600080fd5b50610512610881366004614877565b611c23565b34801561089257600080fd5b506108ad6108a13660046146dc565b506303e1469160e61b90565b6040516001600160e01b03199091168152602001610533565b3480156108d257600080fd5b50610529611d2d565b3480156108e757600080fd5b506105126108f63660046147f7565b611d46565b34801561090757600080fd5b506105c3610916366004614764565b611d85565b34801561092757600080fd5b506105126109363660046147f7565b611dfc565b34801561094757600080fd5b506105126109563660046146dc565b611e4d565b34801561096757600080fd5b506105296109763660046147f7565b611e7f565b34801561098757600080fd5b50610512611f06565b34801561099c57600080fd5b506105966109ab3660046148ab565b611f46565b3480156109bc57600080fd5b50610529611fdf565b3480156109d157600080fd5b50600f54610529565b3480156109e657600080fd5b50610512611ff1565b3480156109fb57600080fd5b506105c3610a0a366004614764565b612042565b348015610a1b57600080fd5b50610512610a2a366004614792565b612072565b348015610a3b57600080fd5b506002546001600160a01b03166105c3565b348015610a5957600080fd5b50610aa3610a683660046148c6565b601f60209081526000938452604080852084518086018401805192815290840195840195909520945292905282529020805460019091015482565b60408051928352602083019190915201610533565b348015610ac457600080fd5b50610512610ad3366004614877565b6120a9565b348015610ae457600080fd5b506105966120df565b348015610af957600080fd5b50610512610b08366004614764565b6120f1565b348015610b1957600080fd5b50610596612123565b348015610b2e57600080fd5b50610529610b3d3660046147f7565b6001600160a01b031660009081526009602052604090205490565b348015610b6457600080fd5b50610aa3612132565b348015610b7957600080fd5b50610512610b8836600461491c565b612150565b348015610b9957600080fd5b5061051261215b565b348015610bae57600080fd5b50600354610529565b348015610bc357600080fd5b5061051261219b565b348015610bd857600080fd5b506105126121db565b348015610bed57600080fd5b50610512610bfc36600461494f565b612210565b348015610c0d57600080fd5b50610512612242565b348015610c2257600080fd5b50610596610c31366004614764565b61235d565b348015610c4257600080fd5b50610512610c51366004614764565b6123ff565b348015610c6257600080fd5b506001546001600160a01b03166105c3565b348015610c8057600080fd5b50610529610c8f3660046147f7565b6001600160a01b031660009081526008602052604090205490565b610512610cb83660046149ae565b612551565b610512610ccb366004614a12565b6127c9565b348015610cdc57600080fd5b50610512610ceb3660046147f7565b612994565b348015610cfc57600080fd5b50610512610d0b366004614855565b6129d3565b348015610d1c57600080fd5b50610596612a40565b348015610d3157600080fd5b50600d54610529565b348015610d4657600080fd5b50610512610d553660046147be565b612a52565b348015610d6657600080fd5b50600754610529565b348015610d7b57600080fd5b50610529612b5f565b348015610d9057600080fd5b50610596612b6b565b348015610da557600080fd5b5061055c610db4366004614a9d565b612b7a565b348015610dc557600080fd5b50610512610dd4366004614abb565b612ba8565b348015610de557600080fd5b50610529612c26565b610512612c3f565b348015610e0257600080fd5b50610512610e113660046147f7565b612c7a565b348015610e2257600080fd5b50610512610e31366004614b0d565b612ccb565b348015610e4257600080fd5b50610512610e513660046147f7565b612d34565b601e546001600160a01b03163314610ee757604051630330dbc960e11b81526020600482015260546024820152600080516020615dd383398151915260448201527f6520646964206e6f7420636f6d652066726f6d2074686520656e64706f696e746064820152732c20796f75206661696c65642c204920776f6e2160601b608482015260a4015b60405180910390fd5b61ffff8416600090815260208052604090208054610f0490614ba0565b90508351141580610f43575061ffff84166000908152602080526040908190209051610f309190614c4d565b6040518091039020838051906020012014155b15610fcb57604051630330dbc960e11b815260206004820152605a6024820152600080516020615dd383398151915260448201527f6520646964206e6f7420636f6d652066726f6d2061207472757374656420636f60648201527f6e74726163742c20796f75206661696c65642c204920776f6e21000000000000608482015260a401610ede565b604051630e1bd41160e11b81523090631c37a82290610ff4908790879087908790600401614c59565b600060405180830381600087803b15801561100e57600080fd5b505af192505050801561101f575060015b6110dd576040518060400160405280825181526020018280519060200120815250601f60008661ffff1661ffff168152602001908152602001600020846040516110699190614ca2565b9081526040805191829003602090810183206001600160401b038716600090815290825291909120835181559201516001909201919091557fe6f254030bcb01ffd20558175c13fcaed6d1520be7becee4c961b65f79243b0d906110d4908690869086908690614c59565b60405180910390a15b50505050565b60006110ef600d613049565b905090565b60006001600160e01b0319821663b7d1e49960e01b148061112557506001600160e01b031982166303edf24760e01b145b8061114057506001600160e01b03198216633daba23f60e11b145b8061115b57506001600160e01b03198216630704183b60e11b145b8061117657506001600160e01b031982166302494e8b60e01b145b8061119157506001600160e01b0319821663152a902d60e11b145b806111ac57506001600160e01b0319821663131e54b760e01b145b806111c757506001600160e01b031982166323a87ba160e01b145b806111e257506001600160e01b0319821663253f8c7960e11b145b806111fd57506001600160e01b031982166329499a2560e01b145b8061121857506001600160e01b031982166317573c7360e21b145b8061123357506001600160e01b03198216632471dd5960e11b145b8061124e57506001600160e01b03198216634ba1182b60e11b145b8061126957506001600160e01b0319821663e8a3d48560e01b145b8061128457506001600160e01b0319821663938e3d7b60e01b145b8061129e57506001600160e01b03198216621d356760e01b145b806112ad57506112ad82613056565b92915050565b6060601880546112c290614ba0565b80601f01602080910402602001604051908101604052809291908181526020018280546112ee90614ba0565b801561133b5780601f106113105761010080835404028352916020019161133b565b820191906000526020600020905b81548152906001019060200180831161131e57829003601f168201915b5050505050905090565b6000611350826130a6565b6113b15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ede565b506000908152601c60205260409020546001600160a01b031690565b60006113d882611d85565b9050806001600160a01b0316836001600160a01b0316036114455760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610ede565b336001600160a01b038216148061146157506114618133612b7a565b6114ce5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776044820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b6064820152608401610ede565b6114d883836130c3565b505050565b6114ee63ca4b208b60e01b33613131565b61150a576040516282b42960e81b815260040160405180910390fd5b611514828261313e565b5050565b60006115248383613131565b9392505050565b61153c638da5cb5b60e01b33613131565b611558576040516282b42960e81b815260040160405180910390fd5b611569638da5cb5b60e01b82613131565b6115d457611581816001600160a01b03166014612eae565b611590638da5cb5b6004612eae565b61159b336014612eae565b6040516020016115ad93929190614cbe565b60408051601f1981840301815290829052630330dbc960e11b8252610ede91600401614751565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60006110ef60165490565b61161263ca4b208b60e01b33613131565b61162e576040516282b42960e81b815260040160405180910390fd5b6116366132b8565b565b3330146116b257604051630330dbc960e11b815260206004820152604d6024820152600080516020615dd383398151915260448201527f6520646964206e6f7420636f6d6520696e7465726e616c6c792c20796f75206660648201526c61696c65642c204920776f6e2160981b608482015260a401610ede565b6110dd84848484613347565b6116c9335b8261337c565b6116e55760405162461bcd60e51b8152600401610ede90614d77565b6114d883838361343e565b6004546003546117009190614dde565b42101561173a57426004546003546117189190614dde565b60405163f3f82ac560e01b815260048101929092526024820152604401610ede565b6003546000036117bf57604051630330dbc960e11b815260206004820152604360248201527f54696d65436f703a20596f75277665206265656e2054696d6520436f7070656460448201527f2e204e474c206f6e6c794465762829206861736e277420736574207468652074606482015262696d6560e81b608482015260a401610ede565b600a6117ca33611e7f565b106117fc576117da336014612eae565b6117eb6117e633611e7f565b6135cc565b6040516020016115ad929190614df6565b61180d336118086136cc565b6136e5565b6116366136ff565b600b54600c546001600160a01b03909116906000906103e8906118389085614e7b565b6118429190614eb0565b90509250929050565b636525904560e11b61185d8133613131565b8061187457506118746303e1469160e61b33613131565b1561189c573361188b636525904560e11b82613717565b61151463ca4b208b60e01b82613723565b6118ab60e082901c6004612eae565b6118ba63f851a4406004612eae565b6118c5336014612eae565b6040516020016115ad93929190614ec4565b50565b6118eb638da5cb5b60e01b33613131565b611907576040516282b42960e81b815260040160405180910390fd5b6118d7308261372f565b636525904560e11b6119238133613131565b8061193a575061193a6303e1469160e61b33613131565b1561189c5733611514636525904560e11b82613717565b61196263ca4b208b60e01b33613131565b61197e576040516282b42960e81b815260040160405180910390fd5b6118d7816137c2565b6114d883838360405180602001604052806000815250612210565b6119ab336116c3565b6119ca576119ba336014612eae565b6040516020016115ad9190614f51565b6119d38161390a565b6118d7613993565b816119e68133613131565b806119fd57506119fd6303e1469160e61b33613131565b1561189c57631ada6fbb60e11b6001600160e01b0319841601611a6a576001600160a01b0382163314611a6a57611a35336014612eae565b611a4460e085901c6004612eae565b611a58846001600160a01b03166014612eae565b6040516020016115ad93929190614feb565b63392d1a5360e11b6001600160e01b0319841601611ad2576001600160a01b0382163314611ad257611a9d336014612eae565b611aac60e085901c6004612eae565b611ac0846001600160a01b03166014612eae565b6040516020016115ad939291906150a4565b6114d88383613717565b336000818152600860205260408120549003611b0d57611afd336014612eae565b6040516020016115ad91906150af565b600060075447611b1d9190614dde565b6001600160a01b0383166000908152600960209081526040808320546006546008909352908320549394509192611b549085614e7b565b611b5e9190614eb0565b611b689190615101565b905080600003611b8d57611b7d336014612eae565b6040516020016115ad9190615118565b6001600160a01b038316600090815260096020526040902054611bb1908290614dde565b6001600160a01b038416600090815260096020526040902055600754611bd8908290614dde565b600755611be5838261399d565b7fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b0568382604051611c16929190614559565b60405180910390a1505050565b611c3463ca4b208b60e01b33613131565b611c50576040516282b42960e81b815260040160405180910390fd5b600060228054611c5f90614ba0565b80601f0160208091040260200160405190810160405280929190818152602001828054611c8b90614ba0565b8015611cd85780601f10611cad57610100808354040283529160200191611cd8565b820191906000526020600020905b815481529060010190602001808311611cbb57829003601f168201915b505050505090508160229081611cee91906151ca565b507fd2877107a884510f506ed0bd833e6601f4344691e32a0ce4bcdedb1d9d9d28e1816022604051611d21929190615300565b60405180910390a15050565b6000611d39600d613ab6565b6010546110ef9190615101565b63ca4b208b60e01b611d588133613131565b80611d6f5750611d6f6303e1469160e61b33613131565b1561189c57611514636525904560e11b83613723565b6000818152601a60205260408120546001600160a01b0316806112ad5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610ede565b63ca4b208b60e01b611e0e8133613131565b80611e255750611e256303e1469160e61b33613131565b1561189c5733611e3c63ca4b208b60e01b84613723565b6114d863ca4b208b60e01b82613717565b80611e588133613131565b80611e6f5750611e6f6303e1469160e61b33613131565b1561189c57336114d88382613717565b60006001600160a01b038216611eea5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610ede565b506001600160a01b03166000908152601b602052604090205490565b638da5cb5b60e01b611f188133613131565b80611f2f5750611f2f6303e1469160e61b33613131565b1561189c5733611514638da5cb5b60e01b82613717565b602080526000908152604090208054611f5e90614ba0565b80601f0160208091040260200160405190810160405280929190818152602001828054611f8a90614ba0565b8015611fd75780601f10611fac57610100808354040283529160200191611fd7565b820191906000526020600020905b815481529060010190602001808311611fba57829003601f168201915b505050505081565b60006004546003546110ef9190614dde565b6346d2e5ad60e11b6120038133613131565b8061201a575061201a6303e1469160e61b33613131565b1561189c57336120316346d2e5ad60e11b82613717565b611514638da5cb5b60e01b82613723565b6000600a82815481106120575761205761532e565b6000918252602090912001546001600160a01b031692915050565b612083638da5cb5b60e01b33613131565b61209f576040516282b42960e81b815260040160405180910390fd5b611514828261372f565b6120ba63ca4b208b60e01b33613131565b6120d6576040516282b42960e81b815260040160405180910390fd5b6118d781613ac3565b6060600d60050180546112c290614ba0565b612102638da5cb5b60e01b33613131565b61211e576040516282b42960e81b815260040160405180910390fd5b602155565b6060601980546112c290614ba0565b6000806003546004546003546121489190614dde565b915091509091565b611514338383613b94565b6346d2e5ad60e11b61216d8133613131565b8061218457506121846303e1469160e61b33613131565b1561189c57336115146346d2e5ad60e11b82613717565b63ca4b208b60e01b6121ad8133613131565b806121c457506121c46303e1469160e61b33613131565b1561189c573361151463ca4b208b60e01b82613717565b6121ec638da5cb5b60e01b33613131565b612208576040516282b42960e81b815260040160405180910390fd5b611636613c5e565b61221a338361337c565b6122365760405162461bcd60e51b8152600401610ede90614d77565b6110dd84848484613cac565b61225363ca4b208b60e01b33613131565b61226f576040516282b42960e81b815260040160405180910390fd5b6000306001600160a01b0316635c17e3706040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d39190615344565b905060005b818110156115145761234d306001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612321573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612345919061535d565b6118086136cc565b612355613cdf565b6001016122d8565b6060612368826130a6565b61238557612375826135cc565b6040516020016115ad919061537a565b600061238f613cf3565b604080518082019091526005815264173539b7b760d91b60208201528151919250906123ca57604051806020016040528060008152506123f7565b816123d4856135cc565b826040516020016123e7939291906153e6565b6040516020818303038152906040525b949350505050565b60035442101561242f5760035460405163f3f82ac560e01b81524260048201526024810191909152604401610ede565b60045460035461243f9190614dde565b421061247857426004546003546124569190614dde565b6040516343c540ef60e01b815260048101929092526024820152604401610ede565b600461248333611e7f565b106124b057612493336014612eae565b61249f6117e633611e7f565b6040516020016115ad929190615429565b60028111156124de576124c4336014612eae565b6124cd826135cc565b6040516020016115ad9291906154ac565b60005b818110156115145760046124f433611e7f565b1061253557612504336014612eae565b61250d836135cc565b61252361251933611e7f565b6117e69086614dde565b6040516020016115ad93929190615530565b612541336118086136cc565b6125496136ff565b6001016124e1565b61255a81611d85565b6001600160a01b0316336001600160a01b03161461258a576040516282b42960e81b815260040160405180910390fd5b61ffff82166000908152602080526040902080546125a790614ba0565b905060000361262b57604051630330dbc960e11b815260206004820152604360248201527f546f6b656e3a204f6b2074686520446576206469646e2774207365742074686960448201527f7320706172616d617465722c20636f6e74616374204d6178466c6f774f322e656064820152623a341760e91b608482015260a401610ede565b6126348161390a565b61263c613993565b60003382604051602001612651929190614559565b60408051601f1981840301815290829052602154600160f01b60208401526022830152915060019060009060420160408051601f1981840301815290829052601e5463040a7bb160e41b83529092506000916001600160a01b03909116906340a7bb10906126cb90899030908990879089906004016155f1565b6040805180830381865afa1580156126e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061270b9190615645565b5090503481111561274557612721336014612eae565b61272a346135cc565b612733836135cc565b6040516020016115ad93929190615669565b601e5461ffff87166000908152602080526040808220905162c5803160e81b81526001600160a01b039093169263c580310092349261278f928c928b913391908b906004016156eb565b6000604051808303818588803b1580156127a857600080fd5b505af11580156127bc573d6000803e3d6000fd5b5050505050505050505050565b61ffff85166000908152601f602052604080822090516127ea908790614ca2565b90815260408051602092819003830190206001600160401b038716600090815292529020600181015490915061288a57604051630330dbc960e11b815260206004820152604a6024820152600080516020615dd383398151915260448201527f652077617320616c72656164792065786563757465642c20796f75206661696c60648201526965642c204920776f6e2160b01b608482015260a401610ede565b8054821415806128b55750806001015483836040516128aa929190615752565b604051809103902014155b1561292557604051630330dbc960e11b815260206004820152604460248201819052600080516020615dd3833981519152908201527f6520776173206e6f742073746f7265642c20796f75206661696c65642c204920606482015263776f6e2160e01b608482015260a401610ede565b60008082556001820155604051630e1bd41160e11b81523090631c37a8229061295a908990899089908990899060040161578b565b600060405180830381600087803b15801561297457600080fd5b505af1158015612988573d6000803e3d6000fd5b50505050505050505050565b638da5cb5b60e01b6129a68133613131565b806129bd57506129bd6303e1469160e61b33613131565b1561189c576115146346d2e5ad60e11b83613723565b6129e463ca4b208b60e01b33613131565b612a00576040516282b42960e81b815260040160405180910390fd5b6003829055600481905560408051838152602081018390527f5ef81ff0fe28d74938986521db9f3fb5637cae3d1cec04a94b4a0d3a3b0fc3c49101611d21565b6060600d60040180546112c290614ba0565b81612a5d8133613131565b80612a745750612a746303e1469160e61b33613131565b1561189c57631ada6fbb60e11b6001600160e01b0319841601612ae757612aa2636525904560e11b33613131565b15612ae757612ab2336014612eae565b612ac160e085901c6004612eae565b612ad5846001600160a01b03166014612eae565b6040516020016115ad939291906157ca565b63392d1a5360e11b6001600160e01b0319841601612b5557612b106346d2e5ad60e11b33613131565b15612b5557612b20336014612eae565b612b2f60e085901c6004612eae565b612b43846001600160a01b03166014612eae565b6040516020016115ad9392919061584b565b6114d88383613723565b60006110ef600d613ab6565b6060600580546112c290614ba0565b6001600160a01b039182166000908152601d6020908152604080832093909416825291909152205460ff1690565b612bb963ca4b208b60e01b33613131565b612bd5576040516282b42960e81b815260040160405180910390fd5b61ffff831660009081526020805260409020612bf2828483615856565b507f93c35c217d799290d33244ef8905b63167d13758ab18343cd8055ed1b8056748838383604051611c1693929190615910565b6000612c32600d613049565b600f546110ef9190615101565b7f9a064d674ddc42ac41b38566457161f1ded37e65a59162da003dd25bcb057b603334604051612c70929190614559565b60405180910390a1565b638da5cb5b60e01b612c8c8133613131565b80612ca35750612ca36303e1469160e61b33613131565b1561189c5733612cba638da5cb5b60e01b84613723565b6114d8638da5cb5b60e01b82613717565b612cdc63ca4b208b60e01b33613131565b612cf8576040516282b42960e81b815260040160405180910390fd5b612d03868686613d02565b612d0d8383613d65565b601e80546001600160a01b0319166001600160a01b03929092169190911790555050505050565b612d4563ca4b208b60e01b33613131565b612d61576040516282b42960e81b815260040160405180910390fd5b612d7263ca4b208b60e01b82613131565b612db657612d8a816001600160a01b03166014612eae565b612d9963ca4b208b6004612eae565b612da4336014612eae565b6040516020016115ad9392919061592e565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038116612dfe576040516282b42960e81b815260040160405180910390fd5b612e09838383613d85565b15612e4257612e22816001600160a01b03166014612eae565b612e3160e084901c6004612eae565b6040516020016115ad9291906159ea565b6001600160a01b0381166000908152602084815260408083206001600160e01b03198616845290915290819020805460ff1916600190811790915590517fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f791611c169185918591615a4e565b60606000612ebd836002614e7b565b612ec8906002614dde565b6001600160401b03811115612edf57612edf614589565b6040519080825280601f01601f191660200182016040528015612f09576020820181803683370190505b509050600360fc1b81600081518110612f2457612f2461532e565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612f5357612f5361532e565b60200101906001600160f81b031916908160001a9053506000612f77846002614e7b565b612f82906001614dde565b90505b6001811115612ffa576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612fb657612fb661532e565b1a60f81b828281518110612fcc57612fcc61532e565b60200101906001600160f81b031916908160001a90535060049490941c93612ff381615a7b565b9050612f85565b5083156115245760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610ede565b60006112ad826006015490565b60006001600160e01b031982166380ac58cd60e01b148061308757506001600160e01b03198216635b5e139f60e01b145b806112ad57506301ffc9a760e01b6001600160e01b03198316146112ad565b6000908152601a60205260409020546001600160a01b0316151590565b6000818152601c6020526040902080546001600160a01b0319166001600160a01b03841690811790915581906130f882611d85565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611524818484613d85565b6001600160a01b03821661316557604051630330dbc960e11b8152600401610ede90615a92565b806000036131b657604051630330dbc960e11b815260206004820152601d60248201527f5061796d656e7453706c69747465723a207368617265732061726520300000006044820152606401610ede565b6001600160a01b0382166000908152600860205260409020541561321b576131e8826001600160a01b03166014612eae565b6001600160a01b03831660009081526008602052604090205461320a906135cc565b6040516020016115ad929190615ade565b600a8054600181019091557fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a80180546001600160a01b0319166001600160a01b0384169081179091556000908152600860205260409020819055600654613283908290614dde565b6006556040517f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac90611d219084908490614559565b600a5460005b81811015613306576000600a82815481106132db576132db61532e565b60009182526020808320909101546001600160a01b03168252600890526040812055506001016132be565b50600660009055600a600061331b9190614527565b6040517f3407fd525bf6581e0ae8e3a3636bd90d02112bea34d66802743c28ced73f910e90600090a150565b6000808280602001905181019061335e9190615b58565b9150915061336c82826136e5565b613374613709565b505050505050565b6000613387826130a6565b6133e85760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ede565b60006133f383611d85565b9050806001600160a01b0316846001600160a01b0316148061342e5750836001600160a01b031661342384611345565b6001600160a01b0316145b806123f757506123f78185612b7a565b826001600160a01b031661345182611d85565b6001600160a01b0316146134b95760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610ede565b6001600160a01b03821661351b5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610ede565b6135266000826130c3565b6001600160a01b0383166000908152601b6020526040812080546001929061354f908490615101565b90915550506001600160a01b0382166000908152601b6020526040812080546001929061357d908490614dde565b90915550506000818152601a602052604080822080546001600160a01b0319166001600160a01b038681169182179092559151849391871691600080516020615df383398151915291a4505050565b6060816000036135f35750506040805180820190915260018152600360fc1b602082015290565b8160005b811561361d578061360781615b86565b91506136169050600a83614eb0565b91506135f7565b6000816001600160401b0381111561363757613637614589565b6040519080825280601f01601f191660200182016040528015613661576020820181803683370190505b5090505b84156123f757613676600183615101565b9150613683600a86615b9f565b61368e906030614dde565b60f81b8183815181106136a3576136a361532e565b60200101906001600160f81b031916908160001a9053506136c5600a86614eb0565b9450613665565b60006136d8600d613de2565b6017546110ef9190614dde565b611514828260405180602001604052806000815250613e0d565b613709600d613e40565b611636601680546001019055565b61151460008383613e50565b61151460008383612dd8565b6103e88110158061373e575080155b156137685761374e336014612eae565b613757826135cc565b6040516020016115ad929190615bb3565b600b80546001600160a01b0319166001600160a01b038416908117909155600c8290556040805183815260208101929092527f184520f1b2fcf99836992b9a6b987afc0e4867f26a00ef438c654318763fe1e39101611d21565b6001600160a01b0381166137e957604051630330dbc960e11b8152600401610ede90615a92565b60006137f482613f1d565b600a805491925060009161380a90600190615101565b8154811061381a5761381a61532e565b600091825260209091200154600a80546001600160a01b0390921692508291849081106138495761384961532e565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600a80548061388857613888615c42565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0385168252600890526040812080549190556006546138d5908290615101565b6006556040517f104b8837ec12e86f303ac7ce5e3bf20c6790f843fabd7451943f3390fc8376cb906110d49086908490614559565b600061391582611d85565b90506139226000836130c3565b6001600160a01b0381166000908152601b6020526040812080546001929061394b908490615101565b90915550506000828152601a602052604080822080546001600160a01b0319169055518391906001600160a01b03841690600080516020615df3833981519152908390a45050565b6116366016613f77565b804710156139ed5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610ede565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613a3a576040519150601f19603f3d011682016040523d82523d6000602084013e613a3f565b606091505b50509050806114d85760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610ede565b60006112ad826007015490565b600060058054613ad290614ba0565b80601f0160208091040260200160405190810160405280929190818152602001828054613afe90614ba0565b8015613b4b5780601f10613b2057610100808354040283529160200191613b4b565b820191906000526020600020905b815481529060010190602001808311613b2e57829003601f168201915b505050505090508160059081613b6191906151ca565b507f17f75bb1e35b058872a221a8c16d8b3e39eacbda214fd7da20f192b9291ecc3b816005604051611d21929190615300565b816001600160a01b0316836001600160a01b031603613bf15760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b6044820152606401610ede565b6001600160a01b038381166000818152601d6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b600b80546001600160a01b03191690556000600c8190556040805182815260208101929092527f184520f1b2fcf99836992b9a6b987afc0e4867f26a00ef438c654318763fe1e39101612c70565b613cb784848461343e565b613cc384848484613fe0565b6110dd5760405162461bcd60e51b8152600401610ede90615c58565b613ce9600d613e40565b613709600d6140e1565b6060602280546112c290614ba0565b6017839055613d12600d836140f1565b613d1d600d82614131565b7f0e59e2733e85d32179b3dffa920faef60cc432823591194c4e5f0ac15db3dcec8284613d4a8183614dde565b60408051938452602084019290925290820152606001611c16565b613d70600d82614171565b613d7b600d83614245565b611514600d614319565b60006001600160a01b038216613dad576040516282b42960e81b815260040160405180910390fd5b506001600160a01b03166000908152602092835260408082206001600160e01b03199390931682529190925290205460ff1690565b60008160020154613df4836006015490565b8360010154613e039190614dde565b6112ad9190615b9f565b613e178383614406565b613e246000848484613fe0565b6114d85760405162461bcd60e51b8152600401610ede90615c58565b6118d78160060180546001019055565b6001600160a01b038116613e76576040516282b42960e81b815260040160405180910390fd5b613e81838383613d85565b613eb957613e99816001600160a01b03166014612eae565b613ea860e084901c6004612eae565b6040516020016115ad929190615caa565b6001600160a01b0381166000908152602084815260408083206001600160e01b031986168452909152808220805460ff19169055517fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f791611c169185918591615a4e565b600a54600090815b81811015613f7057836001600160a01b0316600a8281548110613f4a57613f4a61532e565b6000918252602090912001546001600160a01b031603613f68578092505b600101613f25565b5050919050565b80546000819003613fd557604051630330dbc960e11b815260206004820152602160248201527f436f756e7465727356323a204e6f206e656761746976657320696e2075696e746044820152607360f81b6064820152608401610ede565b508054600019019055565b60006001600160a01b0384163b156140d657604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614024903390899088908890600401615d10565b6020604051808303816000875af192505050801561405f575060408051601f3d908101601f1916820190925261405c91810190615d4d565b60015b6140bc573d80801561408d576040519150601f19603f3d011682016040523d82523d6000602084013e614092565b606091505b5080516000036140b45760405162461bcd60e51b8152600401610ede90615c58565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506123f7565b506001949350505050565b6118d78160070180546001019055565b6002820180549082905560408051838152602081018390527fe26aa1327aec5016c96875498202eebb896e3c2a79cd281ff17ed5bde4e545db9101611c16565b6003820180549082905560408051838152602081018390527fef40c7688f323b7ccad323bec82bfee336d16c0939c46bee1f3e5df296dadde39101611c16565b600082600501805461418290614ba0565b80601f01602080910402602001604051908101604052809291908181526020018280546141ae90614ba0565b80156141fb5780601f106141d0576101008083540402835291602001916141fb565b820191906000526020600020905b8154815290600101906020018083116141de57829003601f168201915b505050505090508183600501908161421391906151ca565b507f5769620297eb5047703c0ba55dd28b8ea50ba49818a91a43217fedce8eb69a308282604051611c16929190615d6a565b600082600401805461425690614ba0565b80601f016020809104026020016040519081016040528092919081815260200182805461428290614ba0565b80156142cf5780601f106142a4576101008083540402835291602001916142cf565b820191906000526020600020905b8154815290600101906020018083116142b257829003601f168201915b50505050509050818360040190816142e791906151ca565b507f7058c986a2931f38a70c3f70689d1f2bb75efb4d0082511082db4b2d40492b4f8282604051611c16929190615d6a565b806002015460000361438257604051630330dbc960e11b815260206004820152602b60248201527f50737565646f52616e646f6d204c69623a204d6178696d756d2043617061636960448201526a7479206e6f74207365742160a81b6064820152608401610ede565b806002015442338360040184600501446040516020016143a6959493929190615d8f565b6040516020818303038152906040528051906020012060001c6143c99190615b9f565b600182018190556040519081527f74d17dde2d5b61215fe87f93cddcd2470527e8b0381734da7d0dfeb3fcf6f8179060200160405180910390a150565b6001600160a01b03821661445c5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610ede565b614465816130a6565b156144b25760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610ede565b6001600160a01b0382166000908152601b602052604081208054600192906144db908490614dde565b90915550506000818152601a602052604080822080546001600160a01b0319166001600160a01b0386169081179091559051839290600080516020615df3833981519152908290a45050565b50805460008255906000526020600020908101906118d791905b808211156145555760008155600101614541565b5090565b6001600160a01b03929092168252602082015260400190565b803561ffff8116811461458457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126145b057600080fd5b81356001600160401b03808211156145ca576145ca614589565b604051601f8301601f19908116603f011681019082821181831017156145f2576145f2614589565b8160405283815286602085880101111561460b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b80356001600160401b038116811461458457600080fd5b6000806000806080858703121561465857600080fd5b61466185614572565b935060208501356001600160401b038082111561467d57600080fd5b6146898883890161459f565b94506146976040880161462b565b935060608701359150808211156146ad57600080fd5b506146ba8782880161459f565b91505092959194509250565b6001600160e01b0319811681146118d757600080fd5b6000602082840312156146ee57600080fd5b8135611524816146c6565b60005b838110156147145781810151838201526020016146fc565b838111156110dd5750506000910152565b6000815180845261473d8160208601602086016146f9565b601f01601f19169290920160200192915050565b6020815260006115246020830184614725565b60006020828403121561477657600080fd5b5035919050565b6001600160a01b03811681146118d757600080fd5b600080604083850312156147a557600080fd5b82356147b08161477d565b946020939093013593505050565b600080604083850312156147d157600080fd5b82356147dc816146c6565b915060208301356147ec8161477d565b809150509250929050565b60006020828403121561480957600080fd5b81356115248161477d565b60008060006060848603121561482957600080fd5b83356148348161477d565b925060208401356148448161477d565b929592945050506040919091013590565b6000806040838503121561486857600080fd5b50508035926020909101359150565b60006020828403121561488957600080fd5b81356001600160401b0381111561489f57600080fd5b6123f78482850161459f565b6000602082840312156148bd57600080fd5b61152482614572565b6000806000606084860312156148db57600080fd5b6148e484614572565b925060208401356001600160401b038111156148ff57600080fd5b61490b8682870161459f565b925050604084013590509250925092565b6000806040838503121561492f57600080fd5b823561493a8161477d565b9150602083013580151581146147ec57600080fd5b6000806000806080858703121561496557600080fd5b84356149708161477d565b935060208501356149808161477d565b92506040850135915060608501356001600160401b038111156149a257600080fd5b6146ba8782880161459f565b600080604083850312156149c157600080fd5b6147b083614572565b60008083601f8401126149dc57600080fd5b5081356001600160401b038111156149f357600080fd5b602083019150836020828501011115614a0b57600080fd5b9250929050565b600080600080600060808688031215614a2a57600080fd5b614a3386614572565b945060208601356001600160401b0380821115614a4f57600080fd5b614a5b89838a0161459f565b9550614a696040890161462b565b94506060880135915080821115614a7f57600080fd5b50614a8c888289016149ca565b969995985093965092949392505050565b60008060408385031215614ab057600080fd5b82356147dc8161477d565b600080600060408486031215614ad057600080fd5b614ad984614572565b925060208401356001600160401b03811115614af457600080fd5b614b00868287016149ca565b9497909650939450505050565b60008060008060008060c08789031215614b2657600080fd5b86359550602087013594506040870135935060608701356001600160401b0380821115614b5257600080fd5b614b5e8a838b0161459f565b94506080890135915080821115614b7457600080fd5b50614b8189828a0161459f565b92505060a0870135614b928161477d565b809150509295509295509295565b600181811c90821680614bb457607f821691505b602082108103614bd457634e487b7160e01b600052602260045260246000fd5b50919050565b60008154614be781614ba0565b60018281168015614bff5760018114614c1457614c43565b60ff1984168752821515830287019450614c43565b8560005260208060002060005b85811015614c3a5781548a820152908401908201614c21565b50505082870194505b5050505092915050565b60006115248284614bda565b61ffff85168152608060208201526000614c766080830186614725565b6001600160401b03851660408401528281036060840152614c978185614725565b979650505050505050565b60008251614cb48184602087016146f9565b9190910192915050565b76026b0bc20b1b1b2b9b99d102a34329030b2323932b9b99604d1b815260008451614cf08160178501602089016146f9565b7f206973206e6f7420616e206f776e657220616e6420646f6573206e6f742068616017918401918201526b03b32903a3432903937b632960a51b60378201528451614d428160438401602089016146f9565b660103a3432b932960cd1b604392909101918201528351614d6a81604a8401602088016146f9565b01604a0195945050505050565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008219821115614df157614df1614dc8565b500190565b6902a37b5b2b71d1027b5960b51b815260008351614e1b81600a8501602088016146f9565b690103cb7ba903430bb32960b51b600a918401918201528351614e458160148401602088016146f9565b7f206d6178696d756d20617420746869732074696d652069732031302e0000000060149290910191820152603001949350505050565b6000816000190483118215151615614e9557614e95614dc8565b500290565b634e487b7160e01b600052601260045260246000fd5b600082614ebf57614ebf614e9a565b500490565b7f4d61784163636573733a20596f75206172652061206e6f7420616e2000000000815260008451614efc81601c8501602089016146f9565b80830190506301037b9160e51b601c8201528451614f218160208401602089016146f9565b808201915050600160fd1b60208201528351614f448160218401602088016146f9565b0160210195945050505050565b6f022a9219b9918a13ab93730b136329d160851b815260008251614f7c8160108501602087016146f9565b7f206973206e6f74206f776e6572206e6f7220617070726f7665640000000000006010939091019283015250602a01919050565b7f4d61784163636573733a20596f752061726520612070656e64696e6720646576815268032b637b832b91414960bd1b602082015260290190565b6000614ff682614fb0565b8551615006818360208a016146f9565b780103cb7ba9031b0b7103737ba103932bb37b5b2903937b6329603d1b9101908152845161503b8160198401602089016146f9565b630103a37960e51b60199290910191820152835161506081601d8401602088016146f9565b01601d0195945050505050565b7f4d61784163636573733a20596f752061726520612070656e64696e67206f776e815264032b91414960dd1b602082015260250190565b6000614ff68261506d565b7002830bcb6b2b73a29b83634ba3a32b91d1607d1b8152600082516150db8160118501602087016146f9565b6e103430b99037379039b430b932b99760891b6011939091019283015250602001919050565b60008282101561511357615113614dc8565b500390565b7002830bcb6b2b73a29b83634ba3a32b91d1607d1b8152600082516151448160118501602087016146f9565b731034b9903737ba10323ab2903830bcb6b2b73a1760611b6011939091019283015250602501919050565b601f8211156114d857600081815260208120601f850160051c810160208610156151965750805b601f850160051c820191505b81811015613374578281556001016151a2565b600019600383901b1c191660019190911b1790565b81516001600160401b038111156151e3576151e3614589565b6151f7816151f18454614ba0565b8461516f565b602080601f83116001811461522657600084156152145750858301515b61521e85826151b5565b865550613374565b600085815260208120601f198616915b8281101561525557888601518255948401946001909101908401615236565b50858210156152735787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000815461529081614ba0565b8085526020600183811680156152ad57600181146152c7576152f5565b60ff1985168884015283151560051b8801830195506152f5565b866000528260002060005b858110156152ed5781548a82018601529083019084016152d2565b890184019650505b505050505092915050565b6040815260006153136040830185614725565b82810360208401526153258185615283565b95945050505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561535657600080fd5b5051919050565b60006020828403121561536f57600080fd5b81516115248161477d565b7f4552433732314d657461646174613a2055524920717565727920666f722000008152600082516153b281601e8501602087016146f9565b7f2072657475726e73206e6f6e6578697374656e7420746f6b656e000000000000601e939091019283015250603801919050565b600084516153f88184602089016146f9565b84519083019061540c8183602089016146f9565b845191019061541f8183602088016146f9565b0195945050505050565b6902a37b5b2b71d1027b5960b51b81526000835161544e81600a8501602088016146f9565b690103cb7ba903430bb32960b51b600a9184019182015283516154788160148401602088016146f9565b7a1036b0bc34b6bab69030ba103a3434b9903a34b6b29034b9901a1760291b60149290910191820152602f01949350505050565b6902a37b5b2b71d1027b5960b51b8152600083516154d181600a8501602088016146f9565b730103cb7ba903bb0b73a32b2103a379036b4b73a160651b600a91840191820152835161550581601e8401602088016146f9565b7110191037b9103632b9b990383632b0b9b29760711b601e9290910191820152603001949350505050565b6902a37b5b2b71d1027b5960b51b81526000845161555581600a8501602089016146f9565b730103cb7ba903bb0b73a32b2103a379036b4b73a160651b600a91840191820152845161558981601e8401602089016146f9565b710103a3430ba10383aba39903cb7ba9030ba160751b601e929091019182015283516155bc8160308401602088016146f9565b7a1036b0bc34b6bab69030ba103a3434b9903a34b6b29034b9901a1760291b60309290910191820152604b0195945050505050565b61ffff861681526001600160a01b038516602082015260a06040820181905260009061561f90830186614725565b841515606084015282810360808401526156398185614725565b98975050505050505050565b6000806040838503121561565857600080fd5b505080516020909101519092909150565b6602a37b5b2b71d160cd1b81526000845161568b8160078501602089016146f9565b6501039b2b73a160d51b60079184019182015284516156b181600d8401602089016146f9565b6b01034b739ba32b0b21037b3160a51b600d929091019182015283516156de8160198401602088016146f9565b0160190195945050505050565b61ffff8716815260c06020820152600061570860c0830188615283565b828103604084015261571a8188614725565b6001600160a01b0387811660608601528616608085015283810360a085015290506157458185614725565b9998505050505050505050565b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff861681526080602082015260006157a86080830187614725565b6001600160401b03861660408401528281036060840152615639818587615762565b60006157d582614fb0565b85516157e5818360208a016146f9565b770103cb7ba9031b0b7103737ba1033b930b73a103937b632960451b910190815284516158198160188401602089016146f9565b630103a37960e51b60189290910191820152835161583e81601c8401602088016146f9565b01601c0195945050505050565b60006157d58261506d565b6001600160401b0383111561586d5761586d614589565b6158818361587b8354614ba0565b8361516f565b6000601f8411600181146158af576000851561589d5750838201355b6158a786826151b5565b845550615909565b600083815260209020601f19861690835b828110156158e057868501358255602094850194600190920191016158c0565b50868210156158fd5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b61ffff84168152604060208201526000615325604083018486615762565b76026b0bc20b1b1b2b9b99d102a34329030b2323932b9b99604d1b8152600084516159608160178501602089016146f9565b7f206973206e6f74206120646576656c6f70657220616e6420646f6573206e6f746017918401918201526e0103430bb32903a3432903937b6329608d1b603782015284516159b58160468401602089016146f9565b660103a3432b932960cd1b6046929091019182015283516159dd81604d8401602088016146f9565b01604d0195945050505050565b6a02634b1102937b632b99d160ad1b815260008351615a1081600b8501602088016146f9565b7101030b63932b0b23c903430b9903937b632960751b600b918401918201528351615a4281601d8401602088016146f9565b01601d01949350505050565b6001600160e01b03199390931683526001600160a01b039190911660208301521515604082015260600190565b600081615a8a57615a8a614dc8565b506000190190565b6020808252602c908201527f5061796d656e7453706c69747465723a206163636f756e74206973207468652060408201526b7a65726f206164647265737360a01b606082015260800190565b7002830bcb6b2b73a29b83634ba3a32b91d1607d1b815260008351615b0a8160118501602088016146f9565b6c01030b63932b0b23c903430b99609d1b6011918401918201528351615b3781601e8401602088016146f9565b671039b430b932b99760c11b601e9290910191820152602601949350505050565b60008060408385031215615b6b57600080fd5b8251615b768161477d565b6020939093015192949293505050565b600060018201615b9857615b98614dc8565b5060010190565b600082615bae57615bae614e9a565b500690565b72022a921991c9c18a1b7b63632b1ba34b7b71d1606d1b815260008351615be18160138501602088016146f9565b6a01039bab136b4ba3a32b2160ad1b6013918401918201528351615c0c81601e8401602088016146f9565b7f20616e642074686174206973206f7574206f6620626f756e6473210000000000601e9290910191820152603901949350505050565b634e487b7160e01b600052603160045260246000fd5b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6a02634b1102937b632b99d160ad1b815260008351615cd081600b8501602088016146f9565b730103237b2b9903737ba103430bb32903937b632960651b600b918401918201528351615d0481601f8401602088016146f9565b01601f01949350505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090615d4390830184614725565b9695505050505050565b600060208284031215615d5f57600080fd5b8151611524816146c6565b604081526000615d7d6040830185614725565b82810360208401526153258185614725565b8581526bffffffffffffffffffffffff198560601b1660208201526000615dc2615dbc6034840187614bda565b85614bda565b928352505060200194935050505056fe4e6f6e626c6f636b696e6752656365697665723a2054686973206d6573736167ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212203141b7ea1d69d1dba90a4aa8c8ceb739713a9cc2ac8d184bde9f9da53c19d3bb64736f6c634300080f0033

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.