ETH Price: $3,146.22 (-8.04%)
Gas: 6 Gwei

Contract

0x677aB613FcfbB9f595035422bA7e2f7E6a822d7A
 

Overview

ETH Balance

0.9064 ETH

Eth Value

$2,851.74 (@ $3,146.22/ETH)

Multichain Info

1 address found via
Transaction Hash
Method
Block
From
To
Transfer From197047042024-04-21 15:34:1195 days ago1713713651IN
Daemonican Entities: DAE0 Token
0 ETH0.0012333612.91578932
Set Approval For...190294932024-01-17 22:11:59189 days ago1705529519IN
Daemonican Entities: DAE0 Token
0 ETH0.0009464838.30851168
Set Approval For...189711552024-01-09 18:21:11197 days ago1704824471IN
Daemonican Entities: DAE0 Token
0 ETH0.0009174919.68071471
Set Approval For...189703112024-01-09 15:30:47198 days ago1704814247IN
Daemonican Entities: DAE0 Token
0 ETH0.0009533920.4507521
Set Approval For...189338812024-01-04 12:10:35203 days ago1704370235IN
Daemonican Entities: DAE0 Token
0 ETH0.0004078116.45028581
Set Approval For...188524002023-12-24 1:34:47214 days ago1703381687IN
Daemonican Entities: DAE0 Token
0 ETH0.0008069417.30932265
Set Approval For...178288202023-08-02 17:31:47357 days ago1690997507IN
Daemonican Entities: DAE0 Token
0 ETH0.0012159726.08321423
Transfer From176190012023-07-04 7:13:23387 days ago1688454803IN
Daemonican Entities: DAE0 Token
0 ETH0.0011942614.04386402
Set Approval For...175658052023-06-26 19:56:11394 days ago1687809371IN
Daemonican Entities: DAE0 Token
0 ETH0.000642613.7841049
Set Approval For...175186092023-06-20 4:43:35401 days ago1687236215IN
Daemonican Entities: DAE0 Token
0 ETH0.0003957115.96193256
Set Approval For...175010532023-06-17 17:35:47403 days ago1687023347IN
Daemonican Entities: DAE0 Token
0 ETH0.0007324615.71181552
Set Approval For...175000812023-06-17 14:19:23404 days ago1687011563IN
Daemonican Entities: DAE0 Token
0 ETH0.0009922321.28389735
Set Approval For...174970442023-06-17 4:07:11404 days ago1686974831IN
Daemonican Entities: DAE0 Token
0 ETH0.0006526614
Set Approval For...173513282023-05-27 15:37:11425 days ago1685201831IN
Daemonican Entities: DAE0 Token
0 ETH0.00127727.39236085
Set Approval For...172854162023-05-18 9:02:11434 days ago1684400531IN
Daemonican Entities: DAE0 Token
0 ETH0.0018138138.90723289
Safe Transfer Fr...172185862023-05-08 21:57:35443 days ago1683583055IN
Daemonican Entities: DAE0 Token
0 ETH0.0079096286.31102948
Set Approval For...171442062023-04-28 11:03:59454 days ago1682679839IN
Daemonican Entities: DAE0 Token
0 ETH0.0018704740.1225764
Safe Transfer Fr...171372922023-04-27 11:43:47455 days ago1682595827IN
Daemonican Entities: DAE0 Token
0 ETH0.0028552831.16139256
Set Approval For...171247202023-04-25 17:20:11456 days ago1682443211IN
Daemonican Entities: DAE0 Token
0 ETH0.0018400139.46922002
Set Approval For...170615942023-04-16 19:45:59465 days ago1681674359IN
Daemonican Entities: DAE0 Token
0 ETH0.0011832525.38148385
Set Approval For...170425382023-04-14 2:36:59468 days ago1681439819IN
Daemonican Entities: DAE0 Token
0 ETH0.0013987830.00464493
Cast170084442023-04-09 4:39:23473 days ago1681015163IN
Daemonican Entities: DAE0 Token
0.0088 ETH0.007893321.06621689
Set Approval For...169994692023-04-07 22:09:47474 days ago1680905387IN
Daemonican Entities: DAE0 Token
0 ETH0.0008610218.46930725
Cast169293652023-03-29 0:23:47484 days ago1680049427IN
Daemonican Entities: DAE0 Token
0.0088 ETH0.0080775324.746214
Transfer From169172882023-03-27 7:38:59486 days ago1679902739IN
Daemonican Entities: DAE0 Token
0 ETH0.0013139215.279445
View all transactions

Latest 2 internal transactions

Advanced mode:
Parent Transaction Hash Block From To
137533272021-12-06 16:25:07961 days ago1638807907
Daemonican Entities: DAE0 Token
48.4176 ETH
137529882021-12-06 15:06:24962 days ago1638803184
Daemonican Entities: DAE0 Token
48.4176 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Entity

Compiler Version
v0.8.6+commit.11564f7e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 1 of 22: Entity.sol
// SPDX-License-Identifier: MIT

// https://kanon.art - K21
// https://daemonica.io
//
//
//                                   $@@@@@@@@@@@$$$
//                               $$@@@@@@$$$$$$$$$$$$$$##
//                           $$$$$$$$$$$$$$$$$#########***
//                        $$$$$$$$$$$$$$$#######**!!!!!!
//                     ##$$$$$$$$$$$$#######****!!!!=========
//                   ##$$$$$$$$$#$#######*#***!!!=!===;;;;;
//                 *#################*#***!*!!======;;;:::
//                ################********!!!!====;;;:::~~~~~
//              **###########******!!!!!!==;;;;::~~~--,,,-~
//             ***########*#*******!*!!!!====;;;::::~~-,,......,-
//            ******#**********!*!!!!=!===;;::~~~-,........
//           ***************!*!!!!====;;:::~~-,,..........
//         !************!!!!!!===;;::~~--,............
//         !!!*****!!*!!!!!===;;:::~~--,,..........
//        =!!!!!!!!!=!==;;;::~~-,,...........
//        =!!!!!!!!!====;;;;:::~~--,........
//       ==!!!!!!=!==;=;;:::~~--,...:~~--,,,..
//       ===!!!!!=====;;;;;:::~~~--,,..#*=;;:::~--,.
//       ;=============;;;;;;::::~~~-,,...$$###==;;:~--.
//      :;;==========;;;;;;::::~~~--,,....@@$$##*!=;:~-.
//      :;;;;;===;;;;;;;::::~~~--,,...$$$$#*!!=;~-
//       :;;;;;;;;;;:::::~~~~---,,...!*##**!==;~,
//       :::;:;;;;:::~~~~---,,,...~;=!!!!=;;:~.
//       ~:::::::::::::~~~~~---,,,....-:;;=;;;~,
//        ~~::::::::~~~~~~~-----,,,......,~~::::~-.
//         -~~~~~~~~~~~~~-----------,,,.......,-~~~~~,.
//          ---~~~-----,,,,,........,---,.
//           ,,--------,,,,,,.........
//             .,,,,,,,,,,,,......
//                ...............
//                    .........

pragma solidity ^0.8.0;

import "./Ownable.sol";
import "./ReentrancyGuard.sol";
import "./ERC721Enumerable.sol";


import "./OccultMath.sol";
import "./Base64.sol";
import "./Daemonica.sol";
import "./Manifest.sol";
import "./Xe_ntity.sol";
import "./Helpers.sol";
import "./Sacred.sol";


interface IEntity is IERC721Enumerable, IERC721Metadata {
  function getModulo() external view returns (uint8);
  function getTick(uint256 _tokenId, uint256 _tick) external view returns (uint8[8][8] memory, string[] memory, uint256);
}


/** @title Daemonica Entity contract
  * @author @0xAnimist
  * @notice Orchestrates the manifestation of n-dimensional Daemonica entities
  */
contract Entity is ERC721Enumerable, ReentrancyGuard, Ownable {

  bool public initialized = false;

  IDaemonica daemonica;
  IXe_ntity xe_ntity;

  address public artist;
  uint256 public artistBalance = 0;
  uint256 public ownerBalance = 0;

  bool public publicsale = false;
  uint256 public maxperhodler = 3;
  uint256 public maxperanimo = 3;

  uint256 public entitySupply;
  uint256 public ownerArtistQuota = 320;
  uint256 public ownerArtistClaimed = 0;
  uint256 public maxEntities = 4108;//4428-320
  uint8 public modulo;
  uint256 public offering;

  struct Tick {
    uint256 newday;//timestamp
    uint256 xe_ntityId;//0 for self
    string[] tau;//dims
  }

  mapping (uint256 => Tick[]) public ticks;



   /** @notice Xe_ntity interface loaded on initialization
     */
   modifier onlyInitialized() {
     require(initialized, "not initialized");
     _;
   }


   /**  @notice Set the value of the publicsale flag
     *  @dev Only owner
     *  @param _publicsale New value of the publicsale flag
     *  @param _maxperhodler New value of the per-address maximum
     *  @param _maxperanimo New value of the per-animo maximum
     */
   function setSaleTerms(bool _publicsale, uint256 _maxperhodler, uint256 _maxperanimo) external onlyOwner {
     _publicsale = _publicsale;
     maxperhodler = _maxperhodler;
     maxperanimo = _maxperanimo;
   }

   /**  @notice Increase the total entity supply up to a limit maxEntities - artistQuota - ownerQuota
     *  @dev Only owner
     *  @param _addition Number of entities to add
     */
   function increaseSupply(uint256 _addition) external onlyOwner {
     require((_addition + entitySupply) <= 4108, "too many");
     entitySupply += _addition;
   }


   /**  @notice Returns modulo state variable
     *  @return modulo
     */
   function getModulo() external view returns (uint8){
     return modulo;
   }

   /**  @notice Returns current tick for an entity with _tokenId
     *  @param  _tokenId  TokenId of the entity
     *  @return The current tick
     */
   function getTickCount(uint256 _tokenId) public view returns (uint256){
     if(_exists(_tokenId)){
       return (ticks[_tokenId].length - 1);
     }else{
       return 0;
     }
   }

   /**  @notice Returns an entity's theta and tau for a given tick value
     *  @dev  Future tick values are returned with the present value of tau
     *  @param  _tokenId tokenId of the entity
     *  @param  _tick Tick value
     *  @return theta values (8x8 matrix of numbers from 0 to modulo)
     *  @return tau array of dims
     */
   function getTick(uint256 _tokenId, uint256 _tick) public view returns (uint8[8][8] memory, string[] memory, uint256) {
     string[] memory tau;
     uint8[8][8] memory theta;
     uint256 newday;

     //future ticks default to present
     if(!_exists(_tokenId)){
       //require(_tick == 0, "no future without animo");
       tau = daemonica.getTau(address(0));
       newday = 0;
       theta = daemonica.getTheta(_tokenId, modulo, tau);
       return (theta, tau, newday);
     }else{
       if(_tick < getTickCount(_tokenId)){//all past ticks
         tau = ticks[_tokenId][_tick].tau;
         newday = ticks[_tokenId][_tick].newday;
       }else{//current and future ticks
         tau = daemonica.getTau(ownerOf(_tokenId));//all current and future ticks use current tau
         newday = block.timestamp;
       }
     }

     theta = daemonica.getTheta(_tokenId, modulo, tau);

     for(uint256 i = 0; i < _tick; i++){
       theta = OccultMath.sub888(theta, OccultMath.syzygy888(theta, modulo));
     }

     return (theta, tau, newday);
   }



   /**  @notice Calculates and returns base64 encoded entity metadata and image SVG
     *  @dev Uses the Manifest library
     *  @param _tokenId tokenId of the entity to render
     */
   function tokenURI(uint256 _tokenId) override public view returns (string memory) {
     return tokenURI(_tokenId, getTickCount(_tokenId));
   }



   /**  @notice Calculates and returns base64 encoded entity metadata and image SVG for a given moment in the entity's timeline
     *  @dev Uses the Manifest library
     *  @param _tokenId tokenId of the entity to render
     *  @param _tick Moment in the entity's timeline to render
     */
   function tokenURI(uint256 _tokenId, uint256 _tick) public view returns (string memory) {
     uint8[8][8] memory theta;
     string[] memory tau;
     uint256 newday;

     if(_exists(_tokenId)){
       (theta, tau, newday) = getTick(_tokenId, _tick);
       return Manifest.entity(_tokenId, theta, tau, _tick, newday);
     }else{
       tau = daemonica.getTau(address(0));
       theta = daemonica.getTheta(_tokenId, modulo, tau);
       return Manifest.entity(_tokenId, theta, tau, 0, 0);
     }
   }

   /**  @notice Mints the next available entity if msg.sender and msg.value qualifies
     */
  function animo() external payable {
    animoMulti(1);
  }


   /**  @notice Mints the next available _n entities if msg.sender and msg.value qualifies
     *  @dev _n is gated by maxperanimo and maxperhodler
     *  @param _n The number of entities to mint
     */
  function animoMulti(uint256 _n) public payable nonReentrant {
    if(_msgSender() == owner()){
      require((ownerArtistClaimed + _n) < ownerArtistQuota, "no more, owner and artist");
    }else{
      if(maxperanimo > 0){
        require(_n <= maxperanimo, "too many at one time");
      }
      require((totalSupply() + _n) <= entitySupply, "no more");
      require((offering * _n) <= msg.value, "insufficient offering");
      require(daemonica.isQualified(_msgSender()), "must hodl >= 1 qualified token");
      if(maxperhodler > 0){//maxperhodler == 0 == unlimited
        require((balanceOf(_msgSender()) + _n) <= maxperhodler, "quota exceeded");
      }
      ownerBalance += msg.value/2;
      artistBalance += (msg.value - (msg.value/2));
    }

    for(uint256 i = 0; i < _n; i++){
      _safeMint(_msgSender(), totalSupply());//start at 0
      ticks[totalSupply()-1].push(Tick(block.timestamp, 0, daemonica.getTau(_msgSender())));
    }

  }


  /**  @notice Casts an entity with a xe_ntity
    *  @param _tokenId tokenId of the entity to cast
    */
  function cast(uint256 _tokenId) external payable nonReentrant onlyInitialized {
    require(offering / 10 <= msg.value, "offer up");
    require(ownerOf(_tokenId) == _msgSender(), "not hodler");//also throws if !_exists()

    string[] memory tau = daemonica.getTau(_msgSender());
    uint256 xe_ntityId = xe_ntity.cast(_msgSender(), _tokenId, (ticks[_tokenId].length-1));
    ticks[_tokenId].push(Tick(block.timestamp, xe_ntityId, tau));

    ownerBalance += msg.value/2;
    artistBalance += (msg.value - msg.value/2);
  }


  /** @notice Allows owner or artist to withdraw available balance
    */
  function withdrawAvailableBalance() external nonReentrant {
    if(_msgSender() == owner()){
      uint256 b = ownerBalance;
      ownerBalance = 0;
      payable(_msgSender()).transfer(b);
    }else if(_msgSender() == artist){
      uint256 b = artistBalance;
      artistBalance = 0;
      payable(_msgSender()).transfer(b);
    }
  }


  /**  @notice Initializes the Xe_ntity interface
    *  @param _xe_ntityAddress address of the Xe_ntity contract
    */
  function initialize(address _xe_ntityAddress) external onlyOwner {
    require(!initialized, "already initialized");
    xe_ntity = IXe_ntity(_xe_ntityAddress);
    initialized = true;
  }



  /**  @notice Entity constructor
    *  @param _artist address of the artist
    *  @param _entitySupply initial supply of entities
    *  @param _modulo puts a ceiling on entity matrix values
    *  @param _offering cost of animo/minting an entity and 1/10 cost of casting an entity and minting a xe_ntity
    *  @param _daemonicaAddress address of the Daemonica contract
    */
  constructor(
    address _artist,
    uint256 _entitySupply,
    uint256 _modulo,
    uint256 _offering,
    address _daemonicaAddress
  ) ERC721("Daemonican Entities", "DAE0") Ownable() {
      //STATE
      artist = address(_artist);
      entitySupply = _entitySupply;
      modulo = uint8(_modulo);
      offering = _offering;
      daemonica = IDaemonica(_daemonicaAddress);
  }

}

File 2 of 22: Address.sol
// SPDX-License-Identifier: MIT

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 3 of 22: Base64.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

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

    /// @notice Encodes some bytes to the base64 representation
    function encode(bytes memory data) internal pure returns (string memory) {
        uint256 len = data.length;
        if (len == 0) return "";

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

        // Add some extra buffer at the end
        bytes memory result = new bytes(encodedLen + 32);

        bytes memory table = TABLE;

        assembly {
            let tablePtr := add(table, 1)
            let resultPtr := add(result, 32)

            for {
                let i := 0
            } lt(i, len) {

            } {
                i := add(i, 3)
                let input := and(mload(add(data, i)), 0xffffff)

                let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF))
                out := shl(224, out)

                mstore(resultPtr, out)

                resultPtr := add(resultPtr, 4)
            }

            switch mod(len, 3)
            case 1 {
                mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
            }
            case 2 {
                mstore(sub(resultPtr, 1), shl(248, 0x3d))
            }

            mstore(result, encodedLen)
        }

        return string(result);
    }
}

File 4 of 22: Context.sol
// SPDX-License-Identifier: MIT

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 5 of 22: Daemonica.sol
// SPDX-License-Identifier: MIT

// https://kanon.art - K21
// https://daemonica.io
//
//
//                                   $@@@@@@@@@@@$$$
//                               $$@@@@@@$$$$$$$$$$$$$$##
//                           $$$$$$$$$$$$$$$$$#########***
//                        $$$$$$$$$$$$$$$#######**!!!!!!
//                     ##$$$$$$$$$$$$#######****!!!!=========
//                   ##$$$$$$$$$#$#######*#***!!!=!===;;;;;
//                 *#################*#***!*!!======;;;:::
//                ################********!!!!====;;;:::~~~~~
//              **###########******!!!!!!==;;;;::~~~--,,,-~
//             ***########*#*******!*!!!!====;;;::::~~-,,......,-
//            ******#**********!*!!!!=!===;;::~~~-,........
//           ***************!*!!!!====;;:::~~-,,..........
//         !************!!!!!!===;;::~~--,............
//         !!!*****!!*!!!!!===;;:::~~--,,..........
//        =!!!!!!!!!=!==;;;::~~-,,...........
//        =!!!!!!!!!====;;;;:::~~--,........
//       ==!!!!!!=!==;=;;:::~~--,...:~~--,,,..
//       ===!!!!!=====;;;;;:::~~~--,,..#*=;;:::~--,.
//       ;=============;;;;;;::::~~~-,,...$$###==;;:~--.
//      :;;==========;;;;;;::::~~~--,,....@@$$##*!=;:~-.
//      :;;;;;===;;;;;;;::::~~~--,,...$$$$#*!!=;~-
//       :;;;;;;;;;;:::::~~~~---,,...!*##**!==;~,
//       :::;:;;;;:::~~~~---,,,...~;=!!!!=;;:~.
//       ~:::::::::::::~~~~~---,,,....-:;;=;;;~,
//        ~~::::::::~~~~~~~-----,,,......,~~::::~-.
//         -~~~~~~~~~~~~~-----------,,,.......,-~~~~~,.
//          ---~~~-----,,,,,........,---,.
//           ,,--------,,,,,,.........
//             .,,,,,,,,,,,,......
//                ...............
//                    .........

pragma solidity ^0.8.0;

import "./Ownable.sol";
import "./ReentrancyGuard.sol";
import "./IERC721Metadata.sol";
import "./IERC721Enumerable.sol";

import "./OccultMath.sol";
import "./Helpers.sol";


interface IBase64 is IERC721Enumerable, IERC721Metadata {}

interface IDaemonica {
  function getTau(address _hodler) external view returns (string[] memory);
  function getTheta(uint256 _tokenId, uint8 _modulo, string[] memory _tau) external view returns (uint8[8][8] memory);
  function isQualified(address _hodler) external view returns (bool);
}


/** @title Daemonica contract
  * @author @0xAnimist
  * @notice "Daemonica generates an ever-changing 8 x 8 numerical matrix from base64-encoded
  * onchain art. Each matrix is associated with an "Entity," which in turn can cast "Xe_ntities."
  * The n dimensional relationships that exist within and between each Entity and Xe_ntity can be
  * freely interpreted and understood. Use Daemonica however you wish." –artist
  */
contract Daemonica is Ownable, ReentrancyGuard {

  uint8 public totalDims = 0;

  uint8 public totalAddedDims = 0;
  uint8 public maxAddableDims = 128;
  mapping (string => address) public dimAdder;


  uint8 public totalOwnerAddedDims = 0;
  uint8 public maxOwnerAddableDims = 128;
  bool public presale = true;

  address public artist;
  uint256 public artistBalance = 0;
  uint256 public ownerBalance = 0;

  mapping (string => IBase64) private dims;
  mapping (uint8 => string) private symbolStringByIndex;
  mapping (string => uint8) private symbolIndexByString;


  /** @notice Allows only the artist to broadcast a message
    * @param  _artist Artists's address
    * @param  _message Artist's message
    */
  event Broadcast(address indexed _artist, string _message);


  /** @notice Only the artist can call function
    */
  modifier onlyArtist() {
    require(artist == _msgSender(), "caller is not the artist");
    _;
  }

  /** @notice Only the artist or owner can call function
    */
  modifier onlyAdmin() {
    require(artist == _msgSender() || owner() == _msgSender(), "caller is not the artist or owner");
    _;
  }


  /** @notice Requires dim with symbol _symbol to be initialized
    * @param  _symbol Symbol associated with the dim's contract
    */
  modifier dimExists(string memory _symbol) {
    require(Helpers.compareStrings(symbolStringByIndex[symbolIndexByString[_symbol]],_symbol), "dim not exist");
    _;
  }


  /** @notice Allows only the artist to broadcast a message
    * @param  _message Artist's message
    */
  function artistBroadcast(string memory _message) external onlyArtist {
    emit Broadcast(msg.sender, _message);
  }


  /** @notice Allows the owner to set the presale flag
    * @param  _value the new value
    */
  function setPresale(bool _value) external onlyOwner {
    presale = _value;
  }


  /** @notice Returns lists of all dims by symbol and address
    * @dev    different contracts with the same symbol cannot be registered, only the first registered will be accepted
    * @return string array of each dim symbol
    * @return address array of each dim contract address
    */
  function getDims() external view returns (string[] memory, address[] memory) {
    string[] memory symbols = new string[](totalDims);
    address[] memory addresses = new address[](totalDims);
    for(uint8 i = 0; i < totalDims; i++){
      symbols[i] = symbolStringByIndex[i];
      addresses[i] = address(dims[symbols[i]]);
    }
    return (symbols, addresses);
  }


  /** @notice Registers a new dim
    * @dev    different contracts with the same symbol cannot be registered, only the first registered will be accepted
    * @param  _address  Contract address of dim to register
    */
  function registerDim(address _address) internal {
    IBase64 dim = IBase64(_address);

    //name the new dim symbolically and increment the dims counter
    string memory symbol = dim.symbol();
    require(!Helpers.compareStrings(dim.symbol(), ""), "requires symbol");
    require(!Helpers.compareStrings(symbolStringByIndex[symbolIndexByString[symbol]],symbol), "symbol already registered");

    //ensure the new dim is base64 encoded
    require(isValidLootverseURI(dim.tokenURI(1)));//test it against the first token

    symbolStringByIndex[totalDims] = symbol;
    symbolIndexByString[symbol] = totalDims;
    totalDims++;

    dims[symbol] = dim;
    dimAdder[symbol] = _msgSender();
  }


  /** @notice Allows owner to add a dim with a quota of maxOwnerAddableDims
    * @param  _address  Contract address of dim to register
    */
  function adminAddDim(address _address) external onlyAdmin {
    require(totalOwnerAddedDims < maxOwnerAddableDims, "owner quota exceeded");
    registerDim(_address);
    totalOwnerAddedDims++;
  }


  /** @notice Anyone can add a valid dim for 1 ether
    * @param  _address  Contract address of dim to register
    */
  function addDim(address _address) external payable nonReentrant {
    require(!presale, "not yet");
    require(msg.value >= 1 ether, "costs 1 eth");
    require(totalAddedDims < maxAddableDims, "public quota exceeded");
    registerDim(_address);
    totalAddedDims++;
    ownerBalance += msg.value/2;
    artistBalance += msg.value/2;//TODO (msg.value - msg.value/2);
  }

  /** @notice Refunds a dimAdder if owner has to delete the dim the added in case
    * of emergency
    * @param  _symbol Symbol of the dim being removed that needs refunding
    */
  function refund(string memory _symbol) internal {
    require(address(this).balance >= 1 ether, "owner cannot afford refund");
    payable(dimAdder[_symbol]).transfer(1 ether);

    uint256 half = (1 ether)/2;
    if(ownerBalance >= half){
      if(artistBalance >= half){
        ownerBalance -= half;
        artistBalance -= half;
      }else{
        ownerBalance -= (1 ether) - artistBalance;
        artistBalance = 0;
      }
    }else{
      artistBalance -= (1 ether) - ownerBalance;
      ownerBalance = 0;
    }
  }


  /** @notice Allows owner to remove a dim and refund the dimAdder
    * @dev  Emergency use only
    * @param  _symbol Symbol of the dim to remove
    */
  function adminRemoveDim(string memory _symbol) external onlyAdmin dimExists(_symbol) {
    require(totalDims > 0, "no dims");

    refund(_symbol);

    delete(dims[_symbol]);//delete the interface
    //refactor the mappings
    for(uint8 i = symbolIndexByString[_symbol]; i < totalDims; i++){
      symbolStringByIndex[i] = symbolStringByIndex[i+1];
      symbolIndexByString[symbolStringByIndex[i]] = i;
    }
    //delete the mappings
    delete(symbolIndexByString[_symbol]);
    delete(symbolStringByIndex[totalDims]);
    //decrement the count
    totalDims--;


  }


  /** @notice Returns true if the given tokenURI() return value has a valid base64 header, payload, and its contract has a valid symbol
    * @param  _str  Return value from tokenURI() to test
    * @return  true or false
    */
  function isValidLootverseURI(string memory _str) internal pure returns (bool) {
    require(Helpers.compareStrings("data:application/json;base64,", Helpers.substring(_str, 0, 29)), 'Invalid prefix');
    string memory payload = Helpers.substring(_str, 29, 0);
    require( OccultMath.isValidBase64String(payload), "non-base64 chars");
    return true;
  }


  /** @notice Returns true if _hodler holds tokens from any dim in _animolist
    * @param  _hodler would be _hodler
    * @return True or false
    */
  function isQualified(address _hodler) external view returns (bool){
    for(uint8 i = 0; i < totalDims; i++){
      if(dims[symbolStringByIndex[i]].balanceOf(_hodler) > 0){
        return true;
      }
    }
    return false;
  }


  /** @notice 𝜏 = tau, a rarely used Greek symbol, *facta bruta* :( 𝜏 symbolizes  ( life | regeneration | resurrection | the power to find new life paths or choices )+. A striking phonetic relationship exists between 𝜏 and "tao", the Chinese term for ( the way | the true path | inner compass )+. *Hic et nunc*, the Daemonican way is death * life, or θ𝜏=X(ξ).
    * @dev    Returns any dims in which the _hodler owns at least one token of any tokenId
    * @param  _hodler entity hodler
    * @return A string array of the symbols of one or more tokens from each dim held by the hodler
    */
  function getTau(address _hodler) public view returns (string[] memory){
    string[] memory tau;
    uint8 count = 0;

    if(_hodler == address(0)){//no hodler, default to first dim
      tau = new string[](1);
      tau[count++] = symbolStringByIndex[0];
      return tau;
    }else{
      tau = new string[](totalDims);

      for(uint8 i = 0; i < totalDims; i++){
        if(dims[symbolStringByIndex[i]].balanceOf(_hodler) > 0){
          tau[count++] = symbolStringByIndex[i];
        }
      }

      if(count == 0){//default to first dim
        string[] memory output = new string[](1);
        output[0] = symbolStringByIndex[0];
        return output;
      }else{//splice to length
        string[] memory output = new string[](count);
        for(uint8 i = 0; i < count; i++){
          output[i] = tau[i];
        }
        return output;
      }
    }
  }


  /** @notice θ = theta, symbol of change in angle or rotation. *Thanatos* (death) hides in this symbol. There is no ξ without θ, no *existentialia* without change. θ is also therefore a talismanic sign for passage to the “underworld”, to a realm closer to life’s origins.
    * @dev    Returns theta, the 8x8 base-_modulo frequency matrix of an entity
    * @param  _tokenId  tokenId of the entity being queried
    * @param  _modulo   caps all values at base-_modulo
    * @param  _tau      tau is the dimensions of _tokenId's hodler
    */
  function getTheta(uint256 _tokenId, uint8 _modulo, string[] memory _tau) external view returns (uint8[8][8] memory) {
    bytes[] memory bytePayloads = new bytes[](_tau.length);

    for(uint8 i = 0; i < _tau.length; i++){
      bytePayloads[i] = bytes(Helpers.substring(dims[_tau[i]].tokenURI(_tokenId), 29, 0));
    }

    uint8[8][8] memory thetas = OccultMath.sixtyFourier(bytePayloads, _modulo);

    return thetas;
  }


  /** @notice Allows owner to withdraw available balance
    */
  function ownerWithdrawAvailableBalance() public nonReentrant onlyOwner {
      uint256 b = ownerBalance;
      ownerBalance = 0;
      payable(msg.sender).transfer(b);
  }

  /** @notice Allows artist to withdraw available balance
    */
  function artistWithdrawAvailableBalance() public nonReentrant onlyArtist {
      uint256 b = artistBalance;
      artistBalance = 0;
      payable(msg.sender).transfer(b);
  }


  /** @notice Daemonica constructor
    * @param _artist The Ethereum address of the artist
    */
  constructor (address _artist) {
    artist = _artist;
  }


}

File 6 of 22: ERC165.sol
// SPDX-License-Identifier: MIT

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 7 of 22: ERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./IERC721Metadata.sol";
import "./Address.sol";
import "./Context.sol";
import "./Strings.sol";
import "./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 {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_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 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 {}
}

File 8 of 22: ERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../ERC721.sol";
import "./IERC721Enumerable.sol";

/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

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

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @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` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * 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 override {
        super._beforeTokenTransfer(from, to, tokenId);

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}

File 9 of 22: Helpers.sol
// SPDX-License-Identifier: MIT

// https://kanon.art - K21
// https://daemonica.io
//
//
//                                   $@@@@@@@@@@@$$$
//                               $$@@@@@@$$$$$$$$$$$$$$##
//                           $$$$$$$$$$$$$$$$$#########***
//                        $$$$$$$$$$$$$$$#######**!!!!!!
//                     ##$$$$$$$$$$$$#######****!!!!=========
//                   ##$$$$$$$$$#$#######*#***!!!=!===;;;;;
//                 *#################*#***!*!!======;;;:::
//                ################********!!!!====;;;:::~~~~~
//              **###########******!!!!!!==;;;;::~~~--,,,-~
//             ***########*#*******!*!!!!====;;;::::~~-,,......,-
//            ******#**********!*!!!!=!===;;::~~~-,........
//           ***************!*!!!!====;;:::~~-,,..........
//         !************!!!!!!===;;::~~--,............
//         !!!*****!!*!!!!!===;;:::~~--,,..........
//        =!!!!!!!!!=!==;;;::~~-,,...........
//        =!!!!!!!!!====;;;;:::~~--,........
//       ==!!!!!!=!==;=;;:::~~--,...:~~--,,,..
//       ===!!!!!=====;;;;;:::~~~--,,..#*=;;:::~--,.
//       ;=============;;;;;;::::~~~-,,...$$###==;;:~--.
//      :;;==========;;;;;;::::~~~--,,....@@$$##*!=;:~-.
//      :;;;;;===;;;;;;;::::~~~--,,...$$$$#*!!=;~-
//       :;;;;;;;;;;:::::~~~~---,,...!*##**!==;~,
//       :::;:;;;;:::~~~~---,,,...~;=!!!!=;;:~.
//       ~:::::::::::::~~~~~---,,,....-:;;=;;;~,
//        ~~::::::::~~~~~~~-----,,,......,~~::::~-.
//         -~~~~~~~~~~~~~-----------,,,.......,-~~~~~,.
//          ---~~~-----,,,,,........,---,.
//           ,,--------,,,,,,.........
//             .,,,,,,,,,,,,......
//                ...............
//                    .........

pragma solidity ^0.8.0;


/** @title Daemonica helper functions
  * @author @0xAnimist
  * @notice Misc support for Daemonica contract suite
  */
library Helpers{

  /** @notice Converts boolean to a string
    * @param  value The boolean value
    * @return A string that reads "true" or "false"
    */
  function boolToString(bool value) public pure returns (string memory) {
    if(value){
      return "true";
    }else{
      return "false";
    }
  }

  /** @notice Converts uint256 to a string
    * @param  value The uint256 value
    * @return A string that represents the numerical value of the input
    */
  function toString(uint256 value) public pure returns (string memory) {
  // Inspired by OraclizeAPI's implementation - MIT license
  // 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);
  }

  /** @notice Converts uint8 to a string
    * @param  value The uint8 value
    * @return A string that represents the numerical value of the input
    */
  function toString8(uint8 value) public pure returns (string memory) {
    if (value == 0) {
      return "00";
    }

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

    return string(buffer);
  }



  /** @notice Returns a _delimiter delimited string of all the values in an 8 uint8 long array
    * @param  _array Array of uint8 values to concatenate
    * @param  _delimiter String to delimit each value
    * @return Concatenated string of all the values delimited by _delimiter
    */
  function stringifyRow(uint8[8] memory _array, string memory _delimiter) internal pure returns (string memory) {
    string memory output = string(abi.encodePacked(
      '<tspan x="153">',toString8(_array[0]),'</tspan>',_delimiter,
      '<tspan x="198">',toString8(_array[1]),'</tspan>',_delimiter,
      '<tspan x="243">',toString8(_array[2]),'</tspan>',_delimiter
    ));

    output = string(abi.encodePacked(
      output,
      '<tspan x="288">',toString8(_array[3]),'</tspan>',_delimiter,
      '<tspan x="333">',toString8(_array[4]),'</tspan>',_delimiter,
      '<tspan x="378">',toString8(_array[5]),'</tspan>',_delimiter
    ));

    return string(abi.encodePacked(
      output,
      '<tspan x="423">',toString8(_array[6]),'</tspan>',_delimiter,
      '<tspan x="468">',toString8(_array[7]),'</tspan>',_delimiter
    ));
  }

  /** @notice Compares two strings
    * @param  _a First string to compare
    * @param  _b Second string to compare
    * @return True if equal, false if not
    */
  function compareStrings(string memory _a, string memory _b) public pure returns (bool) {
    return (keccak256(abi.encodePacked((_a))) == keccak256(abi.encodePacked((_b))));
  }


  /** @notice Returns a substring of the given string
    * @param  str The string
    * @param  startIndex Starting index determining the substring to return
    * @param  endIndex Ending index determining the substring to return
    * @return Substring parsed from the string
    */
  function substring(string memory str, uint startIndex, uint endIndex) public pure returns (string memory) {
      bytes memory strBytes = bytes(str);
      if(endIndex == 0){
        endIndex = strBytes.length;
      }
      bytes memory result = new bytes(endIndex-startIndex);
      for(uint i = startIndex; i < endIndex; i++) {
          result[i-startIndex] = strBytes[i];
      }
      return string(result);
  }


  /** @notice Returns a pseudorandom number from a string input
    * @param  input A string to seed the pseudorandom number generator
    * @return  A pseudorandom uint256 number based on the input string
    */
  function random(string memory input) internal pure returns (uint256) {
      return uint256(keccak256(abi.encodePacked(input)));
  }


}

File 10 of 22: IERC165.sol
// SPDX-License-Identifier: MIT

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 11 of 22: IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./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 12 of 22: IERC721Custodian.sol
// SPDX-License-Identifier: MIT

// https://kanon.art - K21
// https://daemonica.io
//
//
//                                   $@@@@@@@@@@@$$$
//                               $$@@@@@@$$$$$$$$$$$$$$##
//                           $$$$$$$$$$$$$$$$$#########***
//                        $$$$$$$$$$$$$$$#######**!!!!!!
//                     ##$$$$$$$$$$$$#######****!!!!=========
//                   ##$$$$$$$$$#$#######*#***!!!=!===;;;;;
//                 *#################*#***!*!!======;;;:::
//                ################********!!!!====;;;:::~~~~~
//              **###########******!!!!!!==;;;;::~~~--,,,-~
//             ***########*#*******!*!!!!====;;;::::~~-,,......,-
//            ******#**********!*!!!!=!===;;::~~~-,........
//           ***************!*!!!!====;;:::~~-,,..........
//         !************!!!!!!===;;::~~--,............
//         !!!*****!!*!!!!!===;;:::~~--,,..........
//        =!!!!!!!!!=!==;;;::~~-,,...........
//        =!!!!!!!!!====;;;;:::~~--,........
//       ==!!!!!!=!==;=;;:::~~--,...:~~--,,,..
//       ===!!!!!=====;;;;;:::~~~--,,..#*=;;:::~--,.
//       ;=============;;;;;;::::~~~-,,...$$###==;;:~--.
//      :;;==========;;;;;;::::~~~--,,....@@$$##*!=;:~-.
//      :;;;;;===;;;;;;;::::~~~--,,...$$$$#*!!=;~-
//       :;;;;;;;;;;:::::~~~~---,,...!*##**!==;~,
//       :::;:;;;;:::~~~~---,,,...~;=!!!!=;;:~.
//       ~:::::::::::::~~~~~---,,,....-:;;=;;;~,
//        ~~::::::::~~~~~~~-----,,,......,~~::::~-.
//         -~~~~~~~~~~~~~-----------,,,.......,-~~~~~,.
//          ---~~~-----,,,,,........,---,.
//           ,,--------,,,,,,.........
//             .,,,,,,,,,,,,......
//                ...............
//                    .........

pragma solidity ^0.8.0;

import "./IERC721.sol";

/**
 * @title ERC721 NFT Custodian contract interface
 * @author 0xAnimist
 * @notice For binding two NFTs together
 */
interface IERC721Custodian is IERC721 {

  /** @notice Returns the guardian token contract and tokenId for a given source
    * @param _sourceContract The ERC721 source contract for a token in guardianship
    * @param _sourceTokenId The tokenId of a ERC721 source token in guardianship
    * @return The contract address of the guardian token
    * @return The tokenId of the guardian token
    */
  function getGuardianToken(
    address _sourceContract,
    uint256 _sourceTokenId
  ) external view returns (address, uint256);


  /** @notice Returns the owner address of a guardian token
    * @param _sourceContract The ERC721 source contract for a token in guardianship
    * @param _sourceTokenId The tokenId of a ERC721 source token in guardianship
    * @return The Ethereum address of the guardian token's owner
    */
  function getGuardianOwner(
    address _sourceContract,
    uint256 _sourceTokenId
  ) external view returns (address);


  /** @notice Returns the message sent by the source NFT owner when they put it
    * into guardianship
    * @param _sourceContract The ERC721 source contract for a token in guardianship
    * @param _xe_ntityId The tokenId of a ERC721 source token in guardianship
    * @return The message
    */
  function getBindingMessage(
    address _sourceContract,
    uint256 _xe_ntityId
  ) external view returns (bytes memory);


  /** @notice Binds the source NFT to the guardian NFT, giving the guardian token
    * owner the right to claim it at any time by unbinding
    * @param _sourceContract The ERC721 source contract for a token in guardianship
    * @param _sourceTokenId The tokenId of a ERC721 source token in guardianship
    * @param _guardianContract The ERC721 guardian contract
    * @param _guardianTokenId The tokenId of a ERC721 guardian token
    */
  function bind(
    address _sourceContract,
    uint256 _sourceTokenId,
    address _guardianContract,
    uint256 _guardianTokenId
  ) external;


  /** @notice Binds the source NFT to the guardian NFT with a message, giving the
    * guardian token owner the right to claim it at any time by unbinding
    * @param _sourceContract The ERC721 source contract for a token in guardianship
    * @param _sourceTokenId The tokenId of a ERC721 source token in guardianship
    * @param _guardianContract The ERC721 guardian contract
    * @param _guardianTokenId The tokenId of a ERC721 guardian token
    * @param _data The message
    */
  function bind(
    address _sourceContract,
    uint256 _sourceTokenId,
    address _guardianContract,
    uint256 _guardianTokenId,
    bytes memory _data
  ) external;


  /** @notice Unbinds the source NFT from the guardian NFT, giving the guardian
    * token owner the ownership of the source NFT
    * @param _sourceContract The ERC721 source contract for a token in guardianship
    * @param _sourceTokenId The tokenId of a ERC721 source token in guardianship
    */
  function unbind(
    address _sourceContract,
    uint256 _sourceTokenId
  ) external;


  /** @notice Unbinds the source NFT from the guardian NFT with a message, giving
    * the guardian token owner the ownership of the source NFT
    * @param _sourceContract The ERC721 source contract for a token in guardianship
    * @param _sourceTokenId The tokenId of a ERC721 source token in guardianship
    * @param _data The message
    */
  function unbind(
    address _sourceContract,
    uint256 _sourceTokenId,
    bytes memory _data
  ) external;

}

File 13 of 22: IERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

File 14 of 22: IERC721Metadata.sol
// SPDX-License-Identifier: MIT

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 15 of 22: IERC721Receiver.sol
// SPDX-License-Identifier: MIT

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 16 of 22: Manifest.sol
// SPDX-License-Identifier: MIT

// https://kanon.art - K21
// https://daemonica.io
//
//
//                                   $@@@@@@@@@@@$$$
//                               $$@@@@@@$$$$$$$$$$$$$$##
//                           $$$$$$$$$$$$$$$$$#########***
//                        $$$$$$$$$$$$$$$#######**!!!!!!
//                     ##$$$$$$$$$$$$#######****!!!!=========
//                   ##$$$$$$$$$#$#######*#***!!!=!===;;;;;
//                 *#################*#***!*!!======;;;:::
//                ################********!!!!====;;;:::~~~~~
//              **###########******!!!!!!==;;;;::~~~--,,,-~
//             ***########*#*******!*!!!!====;;;::::~~-,,......,-
//            ******#**********!*!!!!=!===;;::~~~-,........
//           ***************!*!!!!====;;:::~~-,,..........
//         !************!!!!!!===;;::~~--,............
//         !!!*****!!*!!!!!===;;:::~~--,,..........
//        =!!!!!!!!!=!==;;;::~~-,,...........
//        =!!!!!!!!!====;;;;:::~~--,........
//       ==!!!!!!=!==;=;;:::~~--,...:~~--,,,..
//       ===!!!!!=====;;;;;:::~~~--,,..#*=;;:::~--,.
//       ;=============;;;;;;::::~~~-,,...$$###==;;:~--.
//      :;;==========;;;;;;::::~~~--,,....@@$$##*!=;:~-.
//      :;;;;;===;;;;;;;::::~~~--,,...$$$$#*!!=;~-
//       :;;;;;;;;;;:::::~~~~---,,...!*##**!==;~,
//       :::;:;;;;:::~~~~---,,,...~;=!!!!=;;:~.
//       ~:::::::::::::~~~~~---,,,....-:;;=;;;~,
//        ~~::::::::~~~~~~~-----,,,......,~~::::~-.
//         -~~~~~~~~~~~~~-----------,,,.......,-~~~~~,.
//          ---~~~-----,,,,,........,---,.
//           ,,--------,,,,,,.........
//             .,,,,,,,,,,,,......
//                ...............
//                    .........

pragma solidity ^0.8.0;

import "./Base64.sol";
import "./Helpers.sol";
import "./Sacred.sol";



/** @title Daemonica Manifest library
  * @author @0xAnimist
  * @notice Manifests Daemonica entities
  */
library Manifest {

   string public constant DELIMITER = " ";


   /** @notice Packs numerical matrix values into a DELIMITER-delimited string
     * @param _theta The 8 x 8 matrix of uint8 values
     * @return String representation of the matrix
     */
   function packSvg(uint8[8][8] memory _theta) public pure returns (string memory) {
     string[17] memory parts;
     parts[0] = '<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0 666 888"><style>.en { fill: #973036; font-family: serif; font-size: 30px; letter-spacing: 3px; white-space: pre; text-align: justify; text-justify: inter-word;}</style><rect width="100%" height="100%" fill="black"/><text y="150" class="en">';

     parts[1] = Helpers.stringifyRow(_theta[0], DELIMITER);//row 0

     parts[2] = '</text><text y="195" class="en">';

     parts[3] = Helpers.stringifyRow(_theta[1], DELIMITER);//row 1

     parts[4] = '</text><text y="240" class="en">';

     parts[5] = Helpers.stringifyRow(_theta[2], DELIMITER);//row 2

     parts[6] = '</text><text y="285" class="en">';

     parts[7] = Helpers.stringifyRow(_theta[3], DELIMITER);//row 3

     parts[8] = '</text><text y="330" class="en">';

     parts[9] = Helpers.stringifyRow(_theta[4], DELIMITER);//row 4

     parts[10] = '</text><text y="375" class="en">';

     parts[11] = Helpers.stringifyRow(_theta[5], DELIMITER);//row 5

     parts[12] = '</text><text y="420" class="en">';

     parts[13] = Helpers.stringifyRow(_theta[6], DELIMITER);//row 6

     parts[14] = '</text><text y="465" class="en">';

     parts[15] = Helpers.stringifyRow(_theta[7], DELIMITER);//row 7

     parts[16] = '</text></svg>';

     string memory output = string(abi.encodePacked(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6], parts[7], parts[8]));
     output = string(abi.encodePacked(output, parts[9], parts[10], parts[11], parts[12], parts[13], parts[14], parts[15], parts[16]));

     return output;
   }


   /** @notice Packs an entity's attributes into a string for rendering as metadata
     * @param _tau The dims of an entity at the given moment in 3d time
     * @param _tick The tick value of an entity at the given moment in 3d time
     */
   function packAttributes(string[] memory _tau, uint256 _tick) public pure returns (string memory) {
     string memory attributes = string(abi.encodePacked(
       '"attributes": [{ "tick": ',
       Helpers.toString(_tick),
       '},{ "trait_type": "dimensions", "value": ',
       Helpers.toString(_tau.length),
       '}'
     ));

     if(_tau.length > 0){
       for(uint8 i = 0; i < _tau.length-1; i++){
         attributes = string(abi.encodePacked(attributes, ',{ "trait_type": "dimension", "value": "', _tau[i], '"}'));
       }
       return string(abi.encodePacked(attributes, ',{ "trait_type": "dimension", "value": "', _tau[_tau.length-1], '"}],'));
     }else{
       return string(abi.encodePacked(attributes, '],'));
     }
   }


   /** @notice Manifests a Daemonica entity
     * @param _tokenId The _tokenId of the entity to render
     * @param _theta The matrix of frequency values of the entity at the given moment in 3d time
     * @param _tau The dims of an entity at the given moment in 3d time
     * @param _tick The tick value of an entity at the given moment in 3d time
     * @param _newday The corresponding block.timestamp to the given moment in 3d time
     */
   function entity(
     uint256 _tokenId,
     uint8[8][8] memory _theta,
     string[] memory _tau,
     uint256 _tick,
     uint256 _newday
   ) public pure returns (string memory) {
     string memory svg = packSvg(_theta);

     string memory attributes;

     if(_newday > 0){
       attributes = string(abi.encodePacked(
         '"manifested": ',
         Helpers.toString(_newday),
         ',',
         attributes,
         packAttributes(_tau, _tick)
       ));
     }else{
       attributes = string(abi.encodePacked('"manifested": 0,'));
     }

     string memory json = Base64.encode(
       bytes(
         string(
           abi.encodePacked(
             '{"name": "',
             Sacred.callBy(_tokenId),
             '", "description": "Daemonican entity ',
             Helpers.toString(_tokenId),
             '\u002F8888: ',
             '\u03BE = Xi, *in intentione recta*. Ludwig Wittgenstein used \u03BE as a variable in Tractatus Logico-Philosophicus to represent aspects of his \u201Cpropositions\u201D. He was a mystic who hid his incantations in his philosophy, like how 6.522 + 2.003 = 7. A Daemonican entity is also a proposition, *qualitas occulta*.',
             '", ',
             attributes,
             '"image": "data:image/svg+xml;base64,',
             Base64.encode(bytes(svg)), '"}'
           )
         )
       )
     );

     return string(abi.encodePacked('data:application/json;base64,', json));
   }

}

File 17 of 22: OccultMath.sol
// SPDX-License-Identifier: MIT

// https://kanon.art - K21
// https://daemonica.io
//
//
//                                   $@@@@@@@@@@@$$$
//                               $$@@@@@@$$$$$$$$$$$$$$##
//                           $$$$$$$$$$$$$$$$$#########***
//                        $$$$$$$$$$$$$$$#######**!!!!!!
//                     ##$$$$$$$$$$$$#######****!!!!=========
//                   ##$$$$$$$$$#$#######*#***!!!=!===;;;;;
//                 *#################*#***!*!!======;;;:::
//                ################********!!!!====;;;:::~~~~~
//              **###########******!!!!!!==;;;;::~~~--,,,-~
//             ***########*#*******!*!!!!====;;;::::~~-,,......,-
//            ******#**********!*!!!!=!===;;::~~~-,........
//           ***************!*!!!!====;;:::~~-,,..........
//         !************!!!!!!===;;::~~--,............
//         !!!*****!!*!!!!!===;;:::~~--,,..........
//        =!!!!!!!!!=!==;;;::~~-,,...........
//        =!!!!!!!!!====;;;;:::~~--,........
//       ==!!!!!!=!==;=;;:::~~--,...:~~--,,,..
//       ===!!!!!=====;;;;;:::~~~--,,..#*=;;:::~--,.
//       ;=============;;;;;;::::~~~-,,...$$###==;;:~--.
//      :;;==========;;;;;;::::~~~--,,....@@$$##*!=;:~-.
//      :;;;;;===;;;;;;;::::~~~--,,...$$$$#*!!=;~-
//       :;;;;;;;;;;:::::~~~~---,,...!*##**!==;~,
//       :::;:;;;;:::~~~~---,,,...~;=!!!!=;;:~.
//       ~:::::::::::::~~~~~---,,,....-:;;=;;;~,
//        ~~::::::::~~~~~~~-----,,,......,~~::::~-.
//         -~~~~~~~~~~~~~-----------,,,.......,-~~~~~,.
//          ---~~~-----,,,,,........,---,.
//           ,,--------,,,,,,.........
//             .,,,,,,,,,,,,......
//                ...............
//                    .........

pragma solidity ^0.8.0;


/*
 * @title OccultMath library
 * @author @0xAnimist
 * @notice Unsafe Math
 */
library OccultMath {

  string public constant defaultTic = ":";
  string public constant defaultNthPrimeOpen = "(";
  string public constant defaultNthPrimeClose = ")";
  string public constant defaultDeplex = "-P";

  struct Index {
    uint8 i;
    uint8 j;
  }


  /** @notice Slices an array
    * @param _array The array
    * @param _length The length of the resulting array
    * @return An array with the first _length values of the input array, _array
    */
  function slice(uint256[] memory _array, uint256 _length) public pure returns (uint256[] memory){
    uint256[] memory output = new uint256[](_length);

    for (uint256 i = 0; i < _length; i++) {
        output[i] = _array[i];
    }

    return output;
  }


  /** @notice Square root of a number
    * @param y The number
    * @return z Square root of the number, y
    */
  function sqrt(uint256 y) public pure returns (uint256 z) {
      if (y > 3) {
          z = y;
          uint256 x = y / 2 + 1;
          while (x < z) {
              z = x;
              x = (y / x + x) / 2;
          }
      } else if (y != 0) {
          z = 1;
      }
  }


  /** @notice Returns the smallest factor of a number
    * @param _number The number
    * @return Smallest factor of the number, _number
    */
  function smallestFactor(uint _number) public pure returns (uint256){
    require(_number >= 2, "Number must be greater than or equal to 2");

    if((_number % 2) == 0){
      return 2;
    }

    uint end = sqrt(_number);

		for(uint i = 3; i <= end; i += 2) {
			if (_number % i == 0)
				return i;
		}
		return _number;
	}


  /** @notice Returns an array of the factors of a number
    * @param _number The number
    * @return Array of factors of the number, _number
    */
  function factorize(uint256 _number) public pure returns (uint256[] memory){
    uint n = _number;
    uint[] memory factors = new uint[](100);
    uint len = 0;

		while (n > 1) {
			uint smallest = smallestFactor(n);
      require(len < 100, "factor overflow");
      factors[len] = smallest;
      len = len + 1;
      n = n / smallest;
		}

    uint[] memory output = slice(factors, len);

		return output;
  }


  /** @notice Returns an array of the prime numbers between _first and _last
    * @param _first The smallest number to consider
    * @param _last The largest number to consider
    * @return Array of prime numbers between _first and _last
    */
  function listPrimes(uint256 _first, uint256 _last) public pure returns (uint256[] memory){
    // Validate input and initialize storage for primes
    require(_first > 1, "The starting number must be a positive integer greater than 1");
    require(_last > _first, "The range of search values must be greater than 0");

    uint firstPrime = 2;

    uint len = _last - firstPrime + 1;
    uint256[] memory list = new uint256[](len);

    // Generate list of all natural numbers in [_first, _first+_total]
    for(uint i = 0; i < len; i++){
      list[i] = i + firstPrime;
    }

    // Find primes and eliminate their multiples
    uint256 limit = sqrt(len);
    for(uint256 i = 0; i <= limit; i++) {
      if(list[i] != 0) {
        for(uint256 pos = i + list[i]; pos < len; pos += list[i]) {
          list[pos] = 0;
        }
      }
    }

    uint256 primesTotal = 0;
    uint256 primesIndex = 0;

    for(uint256 i = 0; i < len; i++){
      if(list[i] != 0){
        primesTotal++;
      }
    }

    uint256[] memory primesList = new uint256[](primesTotal);

    // Populate primes[] with all prime numbers in order
    for (uint256 i = 0; i < len; i++) {
      if(list[i] != 0){
        primesList[primesIndex++] = list[i];
      }
    }

    // Trim primes from given start and return
    if (_first != 2) {
      uint returnTotal = 0;
      for(uint i = 0; i < primesTotal; i++){
        if(primesList[i] >= _first){
          returnTotal = returnTotal + 1;
        }
      }

      uint256[] memory sliced = new uint256[](returnTotal);
      uint diff = primesTotal - returnTotal;

      for (uint256 i = 0; i < returnTotal; i++) {
        sliced[i] = primesList[i+diff];
      }
      return sliced;
    }

    return primesList;
  }


  /** @notice Returns the base-_base syzygetic pair of a given 8 x 8 matrix of uint8 values
    * @param _entity The matrix of an entity
    * @param _base The numerical base of the operation
    * @return The base-_base syzygetic pair matrix
    */
  function syzygy888(uint8[8][8] memory _entity, uint8 _base) public pure returns (uint8[8][8] memory) {
    uint8[8][8] memory pair;
    for(uint8 i = 0; i < 8; i++){
      for(uint8 j = 0; j < 8; j++){
        require(_entity[i][j] < _base, "entity value out of range");
        pair[i][j] = _base - 1 - _entity[i][j];
      }
    }
    return pair;
  }


  /** @notice Returns the base-_base syzygetic pair of a given uint8 value
    * @param _i The uint8 value
    * @param _base The numerical base of the operation
    * @return The base-_base syzygetic pair value
    */
  function getSyzygyPartner8(uint8 _i, uint8 _base) public pure returns (uint8) {
    require(_i <= _base, "pair out of range");
    return _base - 1 - _i;
  }


  /** @notice Returns the absolute value of the difference between uint8 values in
    * corresponding cells in two 8 x 8 matrices
    * @param _a The first matrix
    * @param _b The second matrix
    * @return The matrix of absolute value differences
    */
  function sub888(uint8[8][8] memory _a, uint8[8][8] memory _b) public pure returns (uint8[8][8] memory) {
    uint8[8][8] memory diff;
    for(uint8 i = 0; i < 8; i++){
      for(uint8 j = 0; j < 8; j++){
        if(_a[i][j] >= _b[i][j]){
          diff[i][j] = _a[i][j] - _b[i][j];
        }else{
          diff[i][j] = _b[i][j] - _a[i][j];
        }
      }
    }
    return diff;

  }



  /** @notice Implements the canonical version of D.C. Barker's Tic Xenotation
    * @param _number The number to encode
    * @return The encoded string value
    */
  function encodeTX(uint256 _number) public view returns (string memory) {
    return encodeTX(_number, defaultTic, defaultNthPrimeOpen, defaultNthPrimeClose, defaultDeplex);
  }


  /** @notice Implements a customizable version of D.C. Barker's Tic Xenotation
    * @param _number The number to encode
    * @param tic The tic string
    * @param nthPrimeOpen Open parenthesis
    * @param nthPrimeClose Close parenthesis
    * @param deplexToken Deplex token
    * @return The encoded string value
    */
  function encodeTX(
    uint256 _number,
    string memory tic,//canonically ":"
    string memory nthPrimeOpen,//canonically "("
    string memory nthPrimeClose,//canonically ")"
    string memory deplexToken//canonically "-P"
  ) public view returns (string memory) {
    //zero
    if(_number == 0){
      return string(abi.encodePacked(nthPrimeOpen, nthPrimeOpen, deplexToken, nthPrimeClose, nthPrimeClose, tic));
    }

    //one
    if(_number == 1){
      return string(abi.encodePacked(nthPrimeOpen, deplexToken, nthPrimeClose, tic));
    }

    //1st prime
    if(_number == 2){
      return tic;
    }

    //2nd prime
    if(_number == 3){
      return string(abi.encodePacked(nthPrimeOpen, tic, nthPrimeClose));
    }

    //initialize primes
    uint256[] memory primes = listPrimes(2, _number);

    //initialize hyprimes
    uint256[] memory hyprimes = new uint256[](primes[primes.length-1]+1);
    for(uint256 i = 0; i < primes.length; i++){
      hyprimes[primes[i]] = i+1; //+1 because primes is 0-based array and hyprimes is 1-based
    }

    if(primes[primes.length-1] == _number){//ie. if _number is prime it would be the last in the primes array
      //nth prime
      uint256 ordinate = hyprimes[_number];

      string memory output;

      if(hyprimes[ordinate] != 0){//ie. if ordinate is prime
        //_number is hyprime
        output = string(
          abi.encodePacked(
            encodeTX(
              ordinate,
              tic,
              nthPrimeOpen,
              nthPrimeClose,
              deplexToken
            )));
      }else{
        //_number is !hyprime
        uint[] memory ordinateFactors = factorize(ordinate);

        for(uint i = 0; i < ordinateFactors.length; i++){
          output = string(
            abi.encodePacked(
              encodeTX(
                ordinateFactors[i],
                tic,
                nthPrimeOpen,
                nthPrimeClose,
                deplexToken
              ), output));
        }
      }
      return string(abi.encodePacked(nthPrimeOpen, output, nthPrimeClose));
    }else{
      uint[] memory factors = factorize(_number);
      string memory output = encodeTX(
        factors[0],
        tic,
        nthPrimeOpen,
        nthPrimeClose,
        deplexToken
      );

      for(uint i = 1; i < factors.length; i++){
        //encode left to right from the largest factor to the smallest
        output = string(
          abi.encodePacked(
            encodeTX(
              factors[i],
              tic,
              nthPrimeOpen,
              nthPrimeClose,
              deplexToken
            ), output));
      }

      return output;
    }
  }


  /** @notice Returns the 2d base64 8 x 8 alphanumeric gematria matrix
    * @return The Gematrix
    */
  function getGEMATRIX() public pure returns (uint8[8][8] memory){

    uint8[8][8] memory GEMATRIX = [
      [ 65,  66,  67,  68,  69,  70,  71,  72], // A B C D E F G H
      [ 73,  74,  75,  76,  77,  78,  79,  80], // I J K L M N O P
      [ 81,  82,  83,  84,  85,  86,  87,  88], // Q R S T U V W X
      [ 89,  90,  97,  98,  99, 100, 101, 102], // Y Z a b c d e f
      [103, 104, 105, 106, 107, 108, 109, 110], // g h i j k l m n
      [111, 112, 113, 114, 115, 116, 117, 118], // o p q r s t u v
      [119, 120, 121, 122,  48,  49,  50,  51], // w x y z 0 1 2 3
      [ 52,  53,  54,  55,  56,  57,  43,  47]  // 4 5 6 7 8 9 + /
    ];

    return GEMATRIX;
  }


  /** @notice An occult Fourier transform that onverts base64 tokenURI values of
    * an array of onchain NFTs into base-_modulo frequency values conformal mapped
    * (surjective) to the Gematrix
    * @dev For doing onchain art exegesis
    * @return The resulting 8 x 8 uint8 matrix of frequency values
    */
  function sixtyFourier(bytes[] memory _tokenURIs, uint8 _modulo) public pure returns (uint8[8][8] memory) {
    require(_modulo <= 256, "Mod > 2^8");//modulo cannot exceed max value of uint8
    uint8[8][8] memory GEMATRIX = getGEMATRIX();

    //build a linear index of the GEMATRIX
    Index[] memory index = new Index[](123);//122 is the highest value in the GEMATRIX

    //fill in the index values that point on map
    for(uint8 i = 0; i < 8; i++){
      for(uint8 j = 0; j < 8; j++){
        index[GEMATRIX[i][j]] = Index(i,j);
      }
    }

    //construct the frequency cipher
    uint8[8][8] memory frequencies;
    uint8 zero = 0;

    for(uint8 t = 0; t < _tokenURIs.length; t++){

      for(uint256 b = 0; b < _tokenURIs[t].length; b++){
        uint8 char = uint8(bytes1(_tokenURIs[t][b]));
        if(char != 61){//skip "="
          uint8 i = index[char].i;//TODO plex variable down uint8 i = index[uint8(_tokenURIs[t][d])].i
          uint8 j = index[char].j;//TODO plex variable down uint8 j = index[uint8(_tokenURIs[t][d])].j;

          //map frequency onto a _modulo-degree circle
          //since we are counting one-by-one, this is equivalent to % _modulo
          if(frequencies[i][j] == (_modulo - 1)){
            frequencies[i][j] = zero;
          }else{
            frequencies[i][j]++;
          }
        }

      }
    }

    return frequencies;
  }


  function isBase64Character(bytes1 _c) public pure returns (bool) {
    uint8 _cint = uint8(_c);
    //+
    if(_cint == 43 || _cint == 47){//+/
      return true;
    }else if(_cint >= 48 && _cint <= 57){//0-9
      return true;
    }else if(_cint >= 65 && _cint <= 90){//A-Z
      return true;
    }else if(_cint >= 97 && _cint <= 122) {//a-z
      return true;
    }
    return false;
  }


  function isValidBase64String(string memory _string) public pure returns (bool) {
    bytes memory data = bytes(_string);
    require( (data.length % 4) == 0, "!= %4");

    for (uint i = 0; i < data.length; i++) {
      bytes1 c = data[i];
      if(!isBase64Character(c)){
        if(i >= (data.length - 3)){//last two bytes may be = for padding
          if(uint8(c) != 61){//=
            return false;
          }
        }else{
          return false;
        }
      }
    }
    return true;
  }
}

File 18 of 22: Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./Context.sol";

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

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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

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

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

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 19 of 22: ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 20 of 22: Sacred.sol
// SPDX-License-Identifier: MIT

// https://kanon.art - K21
// https://daemonica.io
//
//
//                                   $@@@@@@@@@@@$$$
//                               $$@@@@@@$$$$$$$$$$$$$$##
//                           $$$$$$$$$$$$$$$$$#########***
//                        $$$$$$$$$$$$$$$#######**!!!!!!
//                     ##$$$$$$$$$$$$#######****!!!!=========
//                   ##$$$$$$$$$#$#######*#***!!!=!===;;;;;
//                 *#################*#***!*!!======;;;:::
//                ################********!!!!====;;;:::~~~~~
//              **###########******!!!!!!==;;;;::~~~--,,,-~
//             ***########*#*******!*!!!!====;;;::::~~-,,......,-
//            ******#**********!*!!!!=!===;;::~~~-,........
//           ***************!*!!!!====;;:::~~-,,..........
//         !************!!!!!!===;;::~~--,............
//         !!!*****!!*!!!!!===;;:::~~--,,..........
//        =!!!!!!!!!=!==;;;::~~-,,...........
//        =!!!!!!!!!====;;;;:::~~--,........
//       ==!!!!!!=!==;=;;:::~~--,...:~~--,,,..
//       ===!!!!!=====;;;;;:::~~~--,,..#*=;;:::~--,.
//       ;=============;;;;;;::::~~~-,,...$$###==;;:~--.
//      :;;==========;;;;;;::::~~~--,,....@@$$##*!=;:~-.
//      :;;;;;===;;;;;;;::::~~~--,,...$$$$#*!!=;~-
//       :;;;;;;;;;;:::::~~~~---,,...!*##**!==;~,
//       :::;:;;;;:::~~~~---,,,...~;=!!!!=;;:~.
//       ~:::::::::::::~~~~~---,,,....-:;;=;;;~,
//        ~~::::::::~~~~~~~-----,,,......,~~::::~-.
//         -~~~~~~~~~~~~~-----------,,,.......,-~~~~~,.
//          ---~~~-----,,,,,........,---,.
//           ,,--------,,,,,,.........
//             .,,,,,,,,,,,,......
//                ...............
//                    .........

pragma solidity ^0.8.0;

import "./Helpers.sol";


/*
 * @title Sacred contract
 * @author @0xAnimist
 * @notice Used for pseudorandomly assigning sacred names
 */
library Sacred {

  uint8 public constant tokensPerName = 4;
  uint8 public constant totalNgrams = 89;
  string public constant nameDelimiter = ".";


  /** @notice Returns a sacred syllable from a host of languages, ancient and
    * contemporary, based on the _index
    * @param _index The index value from 0-88
    * @return The sacred syllable ngram
    */
  function ngram(uint8 _index) public pure returns (string memory) {
    string[totalNgrams] memory ngrams = [
      //Sanskrit sacred seeds
      "\u0101\u1E25",//birth of the universe
      "o\u1E43",//opening syllable
      "h\u016B\u1E43",//closing syllable
      "dh\u012B\u1E25",//perfect wisdom
      "pha\u1E6D",//ancient magical word
      "au",//Sanskrit, "o"

      //Sanskrit consonants, Egyptian and Maori terms
      "akh",//Egyptian
      "ua",//Egyptian: "one who becomes eight" / "growth comes to be"
      "kh",//Egyptian: "pool of water rises up"
      "qet",//Egyptian: fire, grain, Serpent, "pedestal gives circle"
      "ka",//Sanskrit, Egypt
      "kha",//Sanskrit
      "ba",//Sanskrit, Egypt
      "bha",//Sanskrit
      "la",//Sanskrit
      "\u1E6Da",//Sanskrit
      "\u1E6Dha",//Sanskrit
      "pa",//Sanskrit, Maori
      "pha",//Sanskrit
      "ga",//Sanskrit
      "gha",//Sanskrit
      "ja",//Sanskrit
      "jha",//Sanskrit
      "\u1E0Da",//Sanskrit
      "\u1E0Dha",//Sanskrit
      "\u00F1a",//Sanskrit
      "ya",//Sanskrit, Dogon
      "ra",//Sanskrit, Egyptian
      "\u015Ba",//Sanskrit

      //Dogon
      "\u0119mm\u0119",//from female sorghum
      "p\u014D",//digitaria
      "sigi",//Sigui, Sirius
      "tolo",//star

      //Angels
      "el",
      "ael",
      "iel",
      "al",
      "iah",
      "vehu",
      "jel",
      "nik",
      "sit",
      "man",
      "leu",

      //Goetia
      "mon",
      "eth",
      "deus",
      "aga",
      "bar",
      "ast",
      "mur",
      "ion",
      "tri",
      "nab",
      "ius",

      //Faerie
      "tit",
      "mabd",
      "elf",
      "gno",
      "tua",
      "d\u00E9",
      "aos",
      "s\u00ED",

      //Q'ero
      "ayni",
      "hua",
      "nee",
      "ska",

      //Greek
      "nym",
      "pan",
      "syb",

      //Urbit
      "zod",
      "bin",
      "ryx",

      //Chinese
      "tian",
      "ren",
      "jing",
      "dao",
      "zhi",
      "ye",
      "xu",
      "shi",
      "gu\u01D0",

      //Shintoism
      "ama",
      "chi",
      "edo",
      "gi",
      "kon",
      "oni",
      "sei"
    ];

    return ngrams[_index];
  }


  /** @notice Pseudorandomly selects and punctuates an ngram
    * @param _tokenId The _tokenId of the token name to reveal
    * @param _index The index of the ngram (for names with > 1 ngram)
    * @return The resulting ngram
    */
  function pluckNGram(uint256 _tokenId, uint256 _index) public pure returns (string memory) {
      uint256 rand = Helpers.random(string(abi.encodePacked(Helpers.toString(_index), Helpers.toString(_tokenId))));
      string memory output = ngram(uint8(rand % totalNgrams));
      //punctuate pseudorandomly
      if(_index < (tokensPerName - 1)){
        uint256 daemonicPotential  = rand % 33;
        if (daemonicPotential >= 13) {
            output = string(abi.encodePacked(output, nameDelimiter));
        }
      }

      return output;
  }


  /** @notice Reveals the name of a token
    * @param _tokenId The _tokenId of the token name to reveal
    * @return The name of _tokenId
    */
  function callBy(uint256 _tokenId) public pure returns (string memory) {
    string memory name = "";

    for(uint i = 0; i < tokensPerName; i++){
      name = string(abi.encodePacked(name, pluckNGram(_tokenId, i)));
    }

    return name;
  }


}

File 21 of 22: Strings.sol
// SPDX-License-Identifier: MIT

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 22 of 22: Xe_ntity.sol
// SPDX-License-Identifier: MIT

// https://kanon.art - K21
// https://daemonica.io
//
//
//                                   $@@@@@@@@@@@$$$
//                               $$@@@@@@$$$$$$$$$$$$$$##
//                           $$$$$$$$$$$$$$$$$#########***
//                        $$$$$$$$$$$$$$$#######**!!!!!!
//                     ##$$$$$$$$$$$$#######****!!!!=========
//                   ##$$$$$$$$$#$#######*#***!!!=!===;;;;;
//                 *#################*#***!*!!======;;;:::
//                ################********!!!!====;;;:::~~~~~
//              **###########******!!!!!!==;;;;::~~~--,,,-~
//             ***########*#*******!*!!!!====;;;::::~~-,,......,-
//            ******#**********!*!!!!=!===;;::~~~-,........
//           ***************!*!!!!====;;:::~~-,,..........
//         !************!!!!!!===;;::~~--,............
//         !!!*****!!*!!!!!===;;:::~~--,,..........
//        =!!!!!!!!!=!==;;;::~~-,,...........
//        =!!!!!!!!!====;;;;:::~~--,........
//       ==!!!!!!=!==;=;;:::~~--,...:~~--,,,..
//       ===!!!!!=====;;;;;:::~~~--,,..#*=;;:::~--,.
//       ;=============;;;;;;::::~~~-,,...$$###==;;:~--.
//      :;;==========;;;;;;::::~~~--,,....@@$$##*!=;:~-.
//      :;;;;;===;;;;;;;::::~~~--,,...$$$$#*!!=;~-
//       :;;;;;;;;;;:::::~~~~---,,...!*##**!==;~,
//       :::;:;;;;:::~~~~---,,,...~;=!!!!=;;:~.
//       ~:::::::::::::~~~~~---,,,....-:;;=;;;~,
//        ~~::::::::~~~~~~~-----,,,......,~~::::~-.
//         -~~~~~~~~~~~~~-----------,,,.......,-~~~~~,.
//          ---~~~-----,,,,,........,---,.
//           ,,--------,,,,,,.........
//             .,,,,,,,,,,,,......
//                ...............
//                    .........

pragma solidity ^0.8.0;

import "./Ownable.sol";
import "./ERC721Enumerable.sol";
import "./ReentrancyGuard.sol";

import "./IERC721Custodian.sol";

import "./OccultMath.sol";
import "./Entity.sol";
import "./Base64.sol";
import "./Helpers.sol";


interface IXe_ntity {
  function cast(address _hodler, uint256 _entityId, uint256 _tick) external returns (uint256);
}

/**
 * @title Daemonica Xe_ntity contract
 * @author @0xAnimist
 * @notice Orchestrates the casting and binding of n-dimensional Daemonica xe_entities
 */
contract Xe_ntity is ERC721Enumerable, ReentrancyGuard, Ownable {

  IEntity entity;
  IERC721Custodian custodian;
  bool public bindable = false;

  address public artist;
  uint256 public offering;
  bool public initialized = false;
  uint256 public artistBalance = 0;
  uint256 public ownerBalance = 0;

  string private tic = "*";
  string private nthPrimeOpen = "`   `";
  string private nthPrimeClose = "     ";
  string private deplexToken = "ha";
  string private ROW_DELIMITER = "no";
  string private COL_DELIMITER = "ys";


  /*
   *  "Quasiparticle of intensive multiplicity. Tics (or castings) are intrinsically
   *  several components of autonomously numbering anorganic populations, propagating
   *  by contagion between segmentary divisions in the order of nature. Ticks –
   *  as nonqualitative differentially-decomposable counting marks – each designate
   *  a multitude comprehended as a singular variation in tic(k)-density."
   *  -Ccru, *Ccru: Writings 1997-2003*, Time Spiral Press
   */
  struct Cast {
    uint256 tick;
    uint256 entityId;
  }
  mapping (uint256 => Cast) public castings;


  /** @notice Only the Daemonica entity contract can call function
    */
  modifier onlyEntity() {
    require(msg.sender == address(entity), "onlyEntity");//TODO _msgSender()
    _;
  }


  /** @notice Only the Daemonica xe_ntity hodler can call function
    */
  modifier onlyHodler(uint256 _xe_ntityId) {
    require(_exists(_xe_ntityId), "does not exist");
    require(ownerOf(_xe_ntityId) == _msgSender(), "not hodler");
    _;
  }


  /** @notice Returns the attributes of the xe_ntity with _tokenId
    * @param _tokenId The _tokenId of the xe_ntity
    * @return Attributes for rendering with tokenURI
    */
  function packAttributes(uint256 _tokenId) public view returns (string memory) {
    return string(abi.encodePacked(
      '"attributes": [{ "entity": ',
      Helpers.toString(castings[_tokenId].entityId),
      '},{ "tick": ',
      Helpers.toString(castings[_tokenId].entityId),
      '}],'
    ));
  }


  /**  @notice Calculates and returns base64 encoded xe_ntity metadata and image SVG
    *  encoded using Tic Xenotation from the OccultMath library
    *  @param _tokenId tokenId of the xe_ntity to render
    */
  function tokenURI(uint256 _tokenId) override public view returns (string memory) {
     string memory X = "";

     if(_exists(_tokenId)){
       uint8[8][8] memory theta;
       (theta,,) = entity.getTick(castings[_tokenId].entityId, castings[_tokenId].tick);

       uint8[8][8] memory antiTheta = OccultMath.syzygy888(theta, entity.getModulo());

       for(uint8 i = 0; i < 8; i++){
         for(uint8 j = 0; j < 8; j++){
           X = string(abi.encodePacked(
             X,
             OccultMath.encodeTX(antiTheta[i][j], tic, nthPrimeOpen, nthPrimeClose, deplexToken),
             COL_DELIMITER
           ));
         }
         X = string(abi.encodePacked(X, ROW_DELIMITER));
       }
     }else{
       X = "not yet cast";
     }

     string memory prefix = '<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0 666 888"><style>.xen { color: black; font-family: serif; font-size: 19px; line-height: 19px; white-space: break-spaces; }</style><rect width="100%" height="100%" fill="red" /><foreignObject x="90" y="90" width="486" height="798" class="xen"><div xmlns="http://www.w3.org/1999/xhtml">';

     string memory postfix = '</div></foreignObject></svg>';

     string memory output = string(abi.encodePacked(prefix, X, postfix));

     string memory json = Base64.encode(
       bytes(
         string(
           abi.encodePacked(
             '{"name": "Xe_ntity #',
             Helpers.toString(_tokenId),
             '", "description": "Functions are secularized incantations as code. A Xe_ntity is X where X(entity) = entity^. Participants that own an entity can cast a xe_ntity from it, transforming the entity in the process. *Ens divinum cognoscibile per inspirationem est subiectum*=?",',
             packAttributes(_tokenId),
             '"image": "data:image/svg+xml;base64,',
             Base64.encode(bytes(output)), '"}'
           )
         )
       )
     );

     return string(abi.encodePacked('data:application/json;base64,', json));

  }

  /**  @notice Casts an entity with a xe_ntity, minting the xe_ntity
    *  @param _hodler Owner of the entity
    *  @param _entityId tokenId of the entity to cast
    *  @param _tick 3d time parameter that chronicles how many casts the entity has undergone
    */
  function cast(address _hodler, uint256 _entityId, uint256 _tick) external nonReentrant onlyEntity returns (uint256){
    _safeMint(_hodler, totalSupply()+1);//start at 1
    castings[totalSupply()] = Cast(_tick, _entityId);
    return totalSupply();
  }


  /**  @notice Binds the ownership of a xe_ntity to another ERC721 NFT
    * @param _xe_ntityId The tokenId of the xe_ntity to bind
    * @param _guardianContract The ERC721 guardian contract
    * @param _guardianTokenId The tokenId of a ERC721 guardian token
    */
  function bind(
    uint256 _xe_ntityId,
    address _guardianContract,
    uint256 _guardianTokenId
  ) public payable {
    bind(_xe_ntityId, _guardianContract, _guardianTokenId, "");
  }


  /**  @notice Binds the ownership of a xe_ntity to another ERC721 NFT with a message
    * @param _xe_ntityId The tokenId of the xe_ntity to bind
    * @param _guardianContract The ERC721 guardian contract
    * @param _guardianTokenId The tokenId of a ERC721 guardian token
    * @param _data The message
    */
  function bind(
    uint256 _xe_ntityId,
    address _guardianContract,
    uint256 _guardianTokenId,
    bytes memory _data
  ) public payable nonReentrant {
    require(bindable, "not bindable");
    require(_msgSender() == ownerOf(_xe_ntityId), "not yours to bind");
    require(msg.value >= offering, "insufficient offering");

    custodian.bind(address(this), _xe_ntityId, _guardianContract, _guardianTokenId, _data);

    ownerBalance += msg.value/2;
    artistBalance += (msg.value - (msg.value/2));
  }


  /** @notice Unbinds the xe_ntity from the guardian NFT, giving the guardian
    * token owner the ownership of the xe_ntity
    * @param _xe_ntityId The tokenId of the bound xe_ntity
    */
  function unbind(
    uint256 _xe_ntityId
  ) public payable {
    unbind(_xe_ntityId, "");
  }


  /** @notice Unbinds the xe_ntity from the guardian NFT with a message, giving
    * the guardian token owner the ownership of the xe_ntity
    * @param _xe_ntityId The tokenId of the bound xe_ntity
    * @param _data The message
    */
  function unbind(
    uint256 _xe_ntityId,
    bytes memory _data
  ) public payable nonReentrant {
    require(_msgSender() == custodian.getGuardianOwner(address(this), _xe_ntityId), "not yours to unbind");
    require(msg.value >= offering, "insufficient offering");

    custodian.unbind(address(this), _xe_ntityId, _data);

    ownerBalance += msg.value/2;
    artistBalance += (msg.value - (msg.value/2));
  }


  /** @notice Returns the guardian token contract and tokenId for a given xe_ntity
    * @param _xe_ntityId The tokenId of the bound xe_ntity
    * @return The contract address of the guardian token
    * @return The tokenId of the guardian token
    */
  function getGuardianToken(
    uint256 _xe_ntityId
  ) external view returns (address, uint256) {
    return custodian.getGuardianToken(address(this), _xe_ntityId);
  }


  /** @notice Returns the owner address of a guardian token
    * @param _xe_ntityId The tokenId of the bound xe_ntity
    * @return The Ethereum address of the guardian token's owner
    */
  function getGuardianOwner(
    uint256 _xe_ntityId
  ) external view returns (address) {
    return custodian.getGuardianOwner(address(this), _xe_ntityId);
  }


  /** @notice Returns the message sent by the source NFT owner when they put it
    * into guardianship
    * @param _xe_ntityId The tokenId of the bound xe_ntity
    * @return The message
    */
  function getBindingMessage(
    uint256 _xe_ntityId
  ) external view returns (bytes memory) {
    return custodian.getBindingMessage(address(this), _xe_ntityId);
  }

  /** @notice Sets the address of the guardian contract and initiates binding
    * @param _custodianAddress The Ethereum address of the guardian contract
    * @param _bindable The new value of the bindable flag
    */
  function setCustodian(address _custodianAddress, bool _bindable) external onlyOwner {
    custodian = IERC721Custodian(_custodianAddress);
    bindable = _bindable;
  }


  /** @notice Allows owner or artist to withdraw available balance
    */
  function withdrawAvailableBalance() external nonReentrant {
    if(_msgSender() == owner()){
      uint256 b = ownerBalance;
      ownerBalance = 0;
      payable(_msgSender()).transfer(b);
    }else if(_msgSender() == artist){
      uint256 b = artistBalance;
      artistBalance = 0;
      payable(_msgSender()).transfer(b);
    }
  }

  /**  @notice Initializes the Entity interface
    *  @param _entityAddress address of the Entity contract
    */
  function initialize(address _entityAddress) external onlyOwner {
    require(!initialized, "already initialized");
    entity = IEntity(_entityAddress);
    initialized = true;
  }


  /**  @notice Xe_ntity constructor
    *  @param _artist address of the artist
    *  @param _offering cost of binding a xe_ntity
    */
  constructor(address _artist, uint256 _offering) ERC721("Daemonic Xe_ntities", "XEN0") Ownable() {
    artist = _artist;
    offering = _offering;
  }

}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_artist","type":"address"},{"internalType":"uint256","name":"_entitySupply","type":"uint256"},{"internalType":"uint256","name":"_modulo","type":"uint256"},{"internalType":"uint256","name":"_offering","type":"uint256"},{"internalType":"address","name":"_daemonicaAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"animo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_n","type":"uint256"}],"name":"animoMulti","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"artist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"artistBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"cast","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"entitySupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"getModulo","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_tick","type":"uint256"}],"name":"getTick","outputs":[{"internalType":"uint8[8][8]","name":"","type":"uint8[8][8]"},{"internalType":"string[]","name":"","type":"string[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getTickCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_addition","type":"uint256"}],"name":"increaseSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_xe_ntityAddress","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialized","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":[],"name":"maxEntities","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxperanimo","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxperhodler","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"modulo","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"offering","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownerArtistClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownerArtistQuota","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownerBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicsale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","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":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_publicsale","type":"bool"},{"internalType":"uint256","name":"_maxperhodler","type":"uint256"},{"internalType":"uint256","name":"_maxperanimo","type":"uint256"}],"name":"setSaleTerms","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"ticks","outputs":[{"internalType":"uint256","name":"newday","type":"uint256"},{"internalType":"uint256","name":"xe_ntityId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_tick","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAvailableBalance","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526000600b60146101000a81548160ff0219169083151502179055506000600f5560006010556000601160006101000a81548160ff02191690831515021790555060036012556003601355610140601555600060165561100c6017553480156200006c57600080fd5b506040516200651a3803806200651a8339818101604052810190620000929190620003bc565b6040518060400160405280601381526020017f4461656d6f6e6963616e20456e746974696573000000000000000000000000008152506040518060400160405280600481526020017f4441453000000000000000000000000000000000000000000000000000000000815250816000908051906020019062000116929190620002de565b5080600190805190602001906200012f929190620002de565b5050506001600a819055506200015a6200014e6200021060201b60201c565b6200021860201b60201c565b84600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508360148190555082601860006101000a81548160ff021916908360ff1602179055508160198190555080600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050505062000520565b600033905090565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054620002ec9062000482565b90600052602060002090601f0160209004810192826200031057600085556200035c565b82601f106200032b57805160ff19168380011785556200035c565b828001600101855582156200035c579182015b828111156200035b5782518255916020019190600101906200033e565b5b5090506200036b91906200036f565b5090565b5b808211156200038a57600081600090555060010162000370565b5090565b6000815190506200039f81620004ec565b92915050565b600081519050620003b68162000506565b92915050565b600080600080600060a08688031215620003db57620003da620004e7565b5b6000620003eb888289016200038e565b9550506020620003fe88828901620003a5565b94505060406200041188828901620003a5565b93505060606200042488828901620003a5565b925050608062000437888289016200038e565b9150509295509295909350565b6000620004518262000458565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060028204905060018216806200049b57607f821691505b60208210811415620004b257620004b1620004b8565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600080fd5b620004f78162000444565b81146200050357600080fd5b50565b620005118162000478565b81146200051d57600080fd5b50565b615fea80620005306000396000f3fe6080604052600436106102675760003560e01c80637564580111610144578063bedcf003116100b6578063cd46471d1161007a578063cd46471d14610909578063d159b4ae14610946578063e985e9c514610985578063ebb737eb146109c2578063f2fde38b146109ed578063faf9658914610a1657610267565b8063bedcf0031461080f578063bfe448481461083a578063c4d66de814610878578063c87b56dd146108a1578063cad6ed62146108de57610267565b8063a22cb46511610108578063a22cb46514610727578063b111135914610750578063b266cb0114610767578063b88d4fde14610792578063b921e163146107bb578063b94805a2146107e457610267565b8063756458011461063e5780638b608e37146106695780638da5cb5b1461069457806392cb829d146106bf57806395d89b41146106fc57610267565b806329745262116101dd5780634f6ccce7116101a15780634f6ccce7146105295780636352211e146105665780636e8299b7146105a357806370a08231146105ce578063715018a61461060b578063738198b41461062257610267565b806329745262146104635780632f745c591461048e5780633866b05c146104cb57806342842e0e146104d557806343bc1612146104fe57610267565b80630c4f2ee01161022f5780630c4f2ee0146103655780630e7ce7ab14610390578063158ef93e146103bb57806318160ddd146103e65780631c7b97331461041157806323b872dd1461043a57610267565b806301ffc9a71461026c57806306fdde03146102a9578063075b74cf146102d4578063081812fc146102ff578063095ea7b31461033c575b600080fd5b34801561027857600080fd5b50610293600480360381019061028e91906142e7565b610a32565b6040516102a09190614d8b565b60405180910390f35b3480156102b557600080fd5b506102be610aac565b6040516102cb9190614da6565b60405180910390f35b3480156102e057600080fd5b506102e9610b3e565b6040516102f69190615168565b60405180910390f35b34801561030b57600080fd5b506103266004803603810190610321919061438a565b610b44565b6040516103339190614c56565b60405180910390f35b34801561034857600080fd5b50610363600480360381019061035e91906141b0565b610bc9565b005b34801561037157600080fd5b5061037a610ce1565b6040516103879190615168565b60405180910390f35b34801561039c57600080fd5b506103a5610ce7565b6040516103b29190615168565b60405180910390f35b3480156103c757600080fd5b506103d0610ced565b6040516103dd9190614d8b565b60405180910390f35b3480156103f257600080fd5b506103fb610d00565b6040516104089190615168565b60405180910390f35b34801561041d57600080fd5b5061043860048036038101906104339190614294565b610d0d565b005b34801561044657600080fd5b50610461600480360381019061045c919061409a565b610d9c565b005b34801561046f57600080fd5b50610478610dfc565b60405161048591906152a6565b60405180910390f35b34801561049a57600080fd5b506104b560048036038101906104b091906141b0565b610e0f565b6040516104c29190615168565b60405180910390f35b6104d3610eb4565b005b3480156104e157600080fd5b506104fc60048036038101906104f7919061409a565b610ec0565b005b34801561050a57600080fd5b50610513610ee0565b6040516105209190614c56565b60405180910390f35b34801561053557600080fd5b50610550600480360381019061054b919061438a565b610f06565b60405161055d9190615168565b60405180910390f35b34801561057257600080fd5b5061058d6004803603810190610588919061438a565b610f77565b60405161059a9190614c56565b60405180910390f35b3480156105af57600080fd5b506105b8611029565b6040516105c591906152a6565b60405180910390f35b3480156105da57600080fd5b506105f560048036038101906105f0919061402d565b611040565b6040516106029190615168565b60405180910390f35b34801561061757600080fd5b506106206110f8565b005b61063c6004803603810190610637919061438a565b611180565b005b34801561064a57600080fd5b50610653611570565b6040516106609190615168565b60405180910390f35b34801561067557600080fd5b5061067e611576565b60405161068b9190615168565b60405180910390f35b3480156106a057600080fd5b506106a961157c565b6040516106b69190614c56565b60405180910390f35b3480156106cb57600080fd5b506106e660048036038101906106e191906143e4565b6115a6565b6040516106f39190614da6565b60405180910390f35b34801561070857600080fd5b5061071161188b565b60405161071e9190614da6565b60405180910390f35b34801561073357600080fd5b5061074e60048036038101906107499190614170565b61191d565b005b34801561075c57600080fd5b50610765611a9e565b005b34801561077357600080fd5b5061077c611c58565b6040516107899190615168565b60405180910390f35b34801561079e57600080fd5b506107b960048036038101906107b491906140ed565b611c5e565b005b3480156107c757600080fd5b506107e260048036038101906107dd919061438a565b611cc0565b005b3480156107f057600080fd5b506107f9611daa565b6040516108069190614d8b565b60405180910390f35b34801561081b57600080fd5b50610824611dbd565b6040516108319190615168565b60405180910390f35b34801561084657600080fd5b50610861600480360381019061085c91906143e4565b611dc3565b60405161086f92919061523f565b60405180910390f35b34801561088457600080fd5b5061089f600480360381019061089a919061402d565b611e04565b005b3480156108ad57600080fd5b506108c860048036038101906108c3919061438a565b611f2f565b6040516108d59190614da6565b60405180910390f35b3480156108ea57600080fd5b506108f3611f4a565b6040516109009190615168565b60405180910390f35b34801561091557600080fd5b50610930600480360381019061092b919061438a565b611f50565b60405161093d9190615168565b60405180910390f35b34801561095257600080fd5b5061096d600480360381019061096891906143e4565b611f94565b60405161097c93929190614d1f565b60405180910390f35b34801561099157600080fd5b506109ac60048036038101906109a7919061405a565b61256e565b6040516109b99190614d8b565b60405180910390f35b3480156109ce57600080fd5b506109d7612602565b6040516109e49190615168565b60405180910390f35b3480156109f957600080fd5b50610a146004803603810190610a0f919061402d565b612608565b005b610a306004803603810190610a2b919061438a565b612700565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610aa55750610aa482612c26565b5b9050919050565b606060008054610abb906156be565b80601f0160208091040260200160405190810160405280929190818152602001828054610ae7906156be565b8015610b345780601f10610b0957610100808354040283529160200191610b34565b820191906000526020600020905b815481529060010190602001808311610b1757829003601f168201915b5050505050905090565b600f5481565b6000610b4f82612d08565b610b8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8590615008565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610bd482610f77565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610c45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3c906150a8565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610c64612d74565b73ffffffffffffffffffffffffffffffffffffffff161480610c935750610c9281610c8d612d74565b61256e565b5b610cd2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc990614f28565b60405180910390fd5b610cdc8383612d7c565b505050565b60165481565b60175481565b600b60149054906101000a900460ff1681565b6000600880549050905090565b610d15612d74565b73ffffffffffffffffffffffffffffffffffffffff16610d3361157c565b73ffffffffffffffffffffffffffffffffffffffff1614610d89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d8090615028565b60405180910390fd5b8160128190555080601381905550505050565b610dad610da7612d74565b82612e35565b610dec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de3906150c8565b60405180910390fd5b610df7838383612f13565b505050565b601860009054906101000a900460ff1681565b6000610e1a83611040565b8210610e5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5290614e28565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b610ebe6001612700565b565b610edb83838360405180602001604052806000815250611c5e565b505050565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000610f10610d00565b8210610f51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f48906150e8565b60405180910390fd5b60088281548110610f6557610f64615826565b5b90600052602060002001549050919050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611020576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101790614f88565b60405180910390fd5b80915050919050565b6000601860009054906101000a900460ff16905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156110b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110a890614f68565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611100612d74565b73ffffffffffffffffffffffffffffffffffffffff1661111e61157c565b73ffffffffffffffffffffffffffffffffffffffff1614611174576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116b90615028565b60405180910390fd5b61117e600061316f565b565b6002600a5414156111c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111bd90615148565b60405180910390fd5b6002600a81905550600b60149054906101000a900460ff1661121d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121490614e68565b60405180910390fd5b34600a60195461122d919061552a565b111561126e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161126590614dc8565b60405180910390fd5b611276612d74565b73ffffffffffffffffffffffffffffffffffffffff1661129582610f77565b73ffffffffffffffffffffffffffffffffffffffff16146112eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112e290614fe8565b60405180910390fd5b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a3704246611333612d74565b6040518263ffffffff1660e01b815260040161134f9190614c56565b60006040518083038186803b15801561136757600080fd5b505afa15801561137b573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906113a4919061421e565b90506000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663064125876113ee612d74565b856001601a60008981526020019081526020016000208054905061141291906155b5565b6040518463ffffffff1660e01b815260040161143093929190614cbd565b602060405180830381600087803b15801561144a57600080fd5b505af115801561145e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148291906143b7565b9050601a600084815260200190815260200160002060405180606001604052804281526020018381526020018481525090806001815401808255809150506001900390600052602060002090600302016000909190919091506000820151816000015560208201518160010155604082015181600201908051906020019061150b929190613b0b565b50505060023461151b919061552a565b6010600082825461152c91906154d4565b92505081905550600234611540919061552a565b3461154b91906155b5565b600f600082825461155c91906154d4565b9250508190555050506001600a8190555050565b60125481565b60155481565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606115b0613b6b565b606060006115bd86612d08565b15611676576115cc8686611f94565b80935081945082955050505073709265b376897f4611c67842719f28abc1dd9f1b63ce7cd32b87858589866040518663ffffffff1660e01b81526004016116179594939291906151e1565b60006040518083038186803b15801561162f57600080fd5b505af4158015611643573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061166c9190614341565b9350505050611885565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a370424660006040518263ffffffff1660e01b81526004016116d29190614c56565b60006040518083038186803b1580156116ea57600080fd5b505afa1580156116fe573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611727919061421e565b9150600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663236cee0c87601860009054906101000a900460ff16856040518463ffffffff1660e01b815260040161179793929190615268565b6108006040518083038186803b1580156117b057600080fd5b505afa1580156117c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e891906141f0565b925073709265b376897f4611c67842719f28abc1dd9f1b63ce7cd32b8785856000806040518663ffffffff1660e01b815260040161182a959493929190615183565b60006040518083038186803b15801561184257600080fd5b505af4158015611856573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061187f9190614341565b93505050505b92915050565b60606001805461189a906156be565b80601f01602080910402602001604051908101604052809291908181526020018280546118c6906156be565b80156119135780601f106118e857610100808354040283529160200191611913565b820191906000526020600020905b8154815290600101906020018083116118f657829003601f168201915b5050505050905090565b611925612d74565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611993576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161198a90614ee8565b60405180910390fd5b80600560006119a0612d74565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611a4d612d74565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611a929190614d8b565b60405180910390a35050565b6002600a541415611ae4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611adb90615148565b60405180910390fd5b6002600a81905550611af461157c565b73ffffffffffffffffffffffffffffffffffffffff16611b12612d74565b73ffffffffffffffffffffffffffffffffffffffff161415611b9157600060105490506000601081905550611b45612d74565b73ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611b8a573d6000803e3d6000fd5b5050611c4e565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611bd2612d74565b73ffffffffffffffffffffffffffffffffffffffff161415611c4d576000600f5490506000600f81905550611c05612d74565b73ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611c4a573d6000803e3d6000fd5b50505b5b6001600a81905550565b60195481565b611c6f611c69612d74565b83612e35565b611cae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ca5906150c8565b60405180910390fd5b611cba84848484613235565b50505050565b611cc8612d74565b73ffffffffffffffffffffffffffffffffffffffff16611ce661157c565b73ffffffffffffffffffffffffffffffffffffffff1614611d3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3390615028565b60405180910390fd5b61100c60145482611d4d91906154d4565b1115611d8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d8590615088565b60405180910390fd5b8060146000828254611da091906154d4565b9250508190555050565b601160009054906101000a900460ff1681565b60105481565b601a6020528160005260406000208181548110611ddf57600080fd5b9060005260206000209060030201600091509150508060000154908060010154905082565b611e0c612d74565b73ffffffffffffffffffffffffffffffffffffffff16611e2a61157c565b73ffffffffffffffffffffffffffffffffffffffff1614611e80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e7790615028565b60405180910390fd5b600b60149054906101000a900460ff1615611ed0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ec790614f48565b60405180910390fd5b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600b60146101000a81548160ff02191690831515021790555050565b6060611f4382611f3e84611f50565b6115a6565b9050919050565b60135481565b6000611f5b82612d08565b15611f8a576001601a600084815260200190815260200160002080549050611f8391906155b5565b9050611f8f565b600090505b919050565b611f9c613b6b565b606060006060611faa613b6b565b6000611fb588612d08565b61214257600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a370424660006040518263ffffffff1660e01b81526004016120159190614c56565b60006040518083038186803b15801561202d57600080fd5b505afa158015612041573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061206a919061421e565b925060009050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663236cee0c89601860009054906101000a900460ff16866040518463ffffffff1660e01b81526004016120de93929190615268565b6108006040518083038186803b1580156120f757600080fd5b505afa15801561210b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061212f91906141f0565b9150818382955095509550505050612567565b61214b88611f50565b87101561229857601a6000898152602001908152602001600020878154811061217757612176615826565b5b9060005260206000209060030201600201805480602002602001604051908101604052809291908181526020016000905b828210156122545783829060005260206000200180546121c7906156be565b80601f01602080910402602001604051908101604052809291908181526020018280546121f3906156be565b80156122405780601f1061221557610100808354040283529160200191612240565b820191906000526020600020905b81548152906001019060200180831161222357829003601f168201915b5050505050815260200190600101906121a8565b505050509250601a6000898152602001908152602001600020878154811061227f5761227e615826565b5b9060005260206000209060030201600001549050612356565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a37042466122df8a610f77565b6040518263ffffffff1660e01b81526004016122fb9190614c56565b60006040518083038186803b15801561231357600080fd5b505afa158015612327573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190612350919061421e565b92504290505b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663236cee0c89601860009054906101000a900460ff16866040518463ffffffff1660e01b81526004016123c493929190615268565b6108006040518083038186803b1580156123dd57600080fd5b505afa1580156123f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061241591906141f0565b915060005b8781101561255957732175b6b2219dcaaf7020cde8f2b59e0a6f373d4563940c8d0584732175b6b2219dcaaf7020cde8f2b59e0a6f373d45632cd80e1087601860009054906101000a900460ff166040518363ffffffff1660e01b8152600401612485929190614d60565b6108006040518083038186803b15801561249e57600080fd5b505af41580156124b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124d691906141f0565b6040518363ffffffff1660e01b81526004016124f3929190614cf4565b6108006040518083038186803b15801561250c57600080fd5b505af4158015612520573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061254491906141f0565b9250808061255190615721565b91505061241a565b508183829550955095505050505b9250925092565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60145481565b612610612d74565b73ffffffffffffffffffffffffffffffffffffffff1661262e61157c565b73ffffffffffffffffffffffffffffffffffffffff1614612684576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161267b90615028565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156126f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126eb90614e88565b60405180910390fd5b6126fd8161316f565b50565b6002600a541415612746576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161273d90615148565b60405180910390fd5b6002600a8190555061275661157c565b73ffffffffffffffffffffffffffffffffffffffff16612774612d74565b73ffffffffffffffffffffffffffffffffffffffff1614156127e657601554816016546127a191906154d4565b106127e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127d890615108565b60405180910390fd5b612a90565b6000601354111561283757601354811115612836576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161282d90615128565b60405180910390fd5b5b60145481612843610d00565b61284d91906154d4565b111561288e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161288590614de8565b60405180910390fd5b348160195461289d919061555b565b11156128de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128d590614fa8565b60405180910390fd5b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a421d668612924612d74565b6040518263ffffffff1660e01b81526004016129409190614c56565b60206040518083038186803b15801561295857600080fd5b505afa15801561296c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129909190614267565b6129cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129c690614e08565b60405180910390fd5b60006012541115612a3a57601254816129ee6129e9612d74565b611040565b6129f891906154d4565b1115612a39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a3090615068565b60405180910390fd5b5b600234612a47919061552a565b60106000828254612a5891906154d4565b92505081905550600234612a6c919061552a565b34612a7791906155b5565b600f6000828254612a8891906154d4565b925050819055505b60005b81811015612c1a57612ab3612aa6612d74565b612aae610d00565b613291565b601a60006001612ac1610d00565b612acb91906155b5565b8152602001908152602001600020604051806060016040528042815260200160008152602001600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a3704246612b37612d74565b6040518263ffffffff1660e01b8152600401612b539190614c56565b60006040518083038186803b158015612b6b57600080fd5b505afa158015612b7f573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190612ba8919061421e565b815250908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000155602082015181600101556040820151816002019080519060200190612c04929190613b0b565b5050508080612c1290615721565b915050612a93565b506001600a8190555050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612cf157507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80612d015750612d00826132af565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16612def83610f77565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000612e4082612d08565b612e7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e7690614f08565b60405180910390fd5b6000612e8a83610f77565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612ef957508373ffffffffffffffffffffffffffffffffffffffff16612ee184610b44565b73ffffffffffffffffffffffffffffffffffffffff16145b80612f0a5750612f09818561256e565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16612f3382610f77565b73ffffffffffffffffffffffffffffffffffffffff1614612f89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f8090615048565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612ff9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ff090614ec8565b60405180910390fd5b613004838383613319565b61300f600082612d7c565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461305f91906155b5565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546130b691906154d4565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b613240848484612f13565b61324c8484848461342d565b61328b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161328290614e48565b60405180910390fd5b50505050565b6132ab8282604051806020016040528060008152506135c4565b5050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61332483838361361f565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156133675761336281613624565b6133a6565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146133a5576133a4838261366d565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156133e9576133e4816137da565b613428565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146134275761342682826138ab565b5b5b505050565b600061344e8473ffffffffffffffffffffffffffffffffffffffff1661392a565b156135b7578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613477612d74565b8786866040518563ffffffff1660e01b81526004016134999493929190614c71565b602060405180830381600087803b1580156134b357600080fd5b505af19250505080156134e457506040513d601f19601f820116820180604052508101906134e19190614314565b60015b613567573d8060008114613514576040519150601f19603f3d011682016040523d82523d6000602084013e613519565b606091505b5060008151141561355f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161355690614e48565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506135bc565b600190505b949350505050565b6135ce838361393d565b6135db600084848461342d565b61361a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161361190614e48565b60405180910390fd5b505050565b505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b6000600161367a84611040565b61368491906155b5565b9050600060076000848152602001908152602001600020549050818114613769576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016008805490506137ee91906155b5565b905060006009600084815260200190815260200160002054905060006008838154811061381e5761381d615826565b5b9060005260206000200154905080600883815481106138405761383f615826565b5b90600052602060002001819055508160096000838152602001908152602001600020819055506009600085815260200190815260200160002060009055600880548061388f5761388e6157f7565b5b6001900381819060005260206000200160009055905550505050565b60006138b683611040565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600080823b905060008111915050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156139ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139a490614fc8565b60405180910390fd5b6139b681612d08565b156139f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139ed90614ea8565b60405180910390fd5b613a0260008383613319565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254613a5291906154d4565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b828054828255906000526020600020908101928215613b5a579160200282015b82811115613b59578251829080519060200190613b49929190613b99565b5091602001919060010190613b2b565b5b509050613b679190613c1f565b5090565b6040518061010001604052806008905b613b83613c43565b815260200190600190039081613b7b5790505090565b828054613ba5906156be565b90600052602060002090601f016020900481019282613bc75760008555613c0e565b82601f10613be057805160ff1916838001178555613c0e565b82800160010185558215613c0e579182015b82811115613c0d578251825591602001919060010190613bf2565b5b509050613c1b9190613c66565b5090565b5b80821115613c3f5760008181613c369190613c83565b50600101613c20565b5090565b604051806101000160405280600890602082028036833780820191505090505090565b5b80821115613c7f576000816000905550600101613c67565b5090565b508054613c8f906156be565b6000825580601f10613ca15750613cc0565b601f016020900490600052602060002090810190613cbf9190613c66565b5b50565b6000613cd6613cd1846152e6565b6152c1565b9050808285610100860282011115613cf157613cf0615889565b5b60005b85811015613d225781613d078882613f13565b84526020840193506101008301925050600181019050613cf4565b5050509392505050565b6000613d3f613d3a8461530c565b6152c1565b90508083825260208201905082856020860282011115613d6257613d61615889565b5b60005b85811015613db057815167ffffffffffffffff811115613d8857613d87615884565b5b808601613d958982613fc0565b85526020850194506020840193505050600181019050613d65565b5050509392505050565b6000613dcd613dc884615338565b6152c1565b90508082856020860282011115613de757613de6615889565b5b60005b85811015613e175781613dfd8882614018565b845260208401935060208301925050600181019050613dea565b5050509392505050565b6000613e34613e2f8461535e565b6152c1565b905082815260208101848484011115613e5057613e4f61588e565b5b613e5b84828561567c565b509392505050565b6000613e76613e718461538f565b6152c1565b905082815260208101848484011115613e9257613e9161588e565b5b613e9d84828561568b565b509392505050565b600081359050613eb481615f41565b92915050565b600082601f830112613ecf57613ece615884565b5b6008613edc848285613cc3565b91505092915050565b600082601f830112613efa57613ef9615884565b5b8151613f0a848260208601613d2c565b91505092915050565b600082601f830112613f2857613f27615884565b5b6008613f35848285613dba565b91505092915050565b600081359050613f4d81615f58565b92915050565b600081519050613f6281615f58565b92915050565b600081359050613f7781615f6f565b92915050565b600081519050613f8c81615f6f565b92915050565b600082601f830112613fa757613fa6615884565b5b8135613fb7848260208601613e21565b91505092915050565b600082601f830112613fd557613fd4615884565b5b8151613fe5848260208601613e63565b91505092915050565b600081359050613ffd81615f86565b92915050565b60008151905061401281615f86565b92915050565b60008151905061402781615f9d565b92915050565b60006020828403121561404357614042615898565b5b600061405184828501613ea5565b91505092915050565b6000806040838503121561407157614070615898565b5b600061407f85828601613ea5565b925050602061409085828601613ea5565b9150509250929050565b6000806000606084860312156140b3576140b2615898565b5b60006140c186828701613ea5565b93505060206140d286828701613ea5565b92505060406140e386828701613fee565b9150509250925092565b6000806000806080858703121561410757614106615898565b5b600061411587828801613ea5565b945050602061412687828801613ea5565b935050604061413787828801613fee565b925050606085013567ffffffffffffffff81111561415857614157615893565b5b61416487828801613f92565b91505092959194509250565b6000806040838503121561418757614186615898565b5b600061419585828601613ea5565b92505060206141a685828601613f3e565b9150509250929050565b600080604083850312156141c7576141c6615898565b5b60006141d585828601613ea5565b92505060206141e685828601613fee565b9150509250929050565b6000610800828403121561420757614206615898565b5b600061421584828501613eba565b91505092915050565b60006020828403121561423457614233615898565b5b600082015167ffffffffffffffff81111561425257614251615893565b5b61425e84828501613ee5565b91505092915050565b60006020828403121561427d5761427c615898565b5b600061428b84828501613f53565b91505092915050565b6000806000606084860312156142ad576142ac615898565b5b60006142bb86828701613f3e565b93505060206142cc86828701613fee565b92505060406142dd86828701613fee565b9150509250925092565b6000602082840312156142fd576142fc615898565b5b600061430b84828501613f68565b91505092915050565b60006020828403121561432a57614329615898565b5b600061433884828501613f7d565b91505092915050565b60006020828403121561435757614356615898565b5b600082015167ffffffffffffffff81111561437557614374615893565b5b61438184828501613fc0565b91505092915050565b6000602082840312156143a05761439f615898565b5b60006143ae84828501613fee565b91505092915050565b6000602082840312156143cd576143cc615898565b5b60006143db84828501614003565b91505092915050565b600080604083850312156143fb576143fa615898565b5b600061440985828601613fee565b925050602061441a85828601613fee565b9150509250929050565b60006144308383614655565b6101008301905092915050565b600061444983836146ac565b6101008301905092915050565b6000614462838361475a565b905092915050565b600061447683836147cc565b905092915050565b600061448a8383614c1a565b60208301905092915050565b60006144a28383614c47565b60208301905092915050565b6144b7816155e9565b82525050565b6144c6816153e4565b6144d08184615442565b92506144db826153c0565b8060005b8381101561450c5781516144f38782614424565b96506144fe8361541b565b9250506001810190506144df565b505050505050565b61451d816153e4565b614527818461544d565b9250614532826153c0565b8060005b8381101561456357815161454a878261443d565b96506145558361541b565b925050600181019050614536565b505050505050565b6000614576826153ef565b6145808185615458565b935083602082028501614592856153ca565b8060005b858110156145ce57848403895281516145af8582614456565b94506145ba83615428565b925060208a01995050600181019050614596565b50829750879550505050505092915050565b60006145eb826153ef565b6145f58185615469565b935083602082028501614607856153ca565b8060005b858110156146435784840389528151614624858261446a565b945061462f83615428565b925060208a0199505060018101905061460b565b50829750879550505050505092915050565b61465e816153fa565b614668818461547a565b9250614673826153da565b8060005b838110156146a457815161468b878261447e565b965061469683615435565b925050600181019050614677565b505050505050565b6146b5816153fa565b6146bf8184615485565b92506146ca826153da565b8060005b838110156146fb5781516146e28782614496565b96506146ed83615435565b9250506001810190506146ce565b505050505050565b61470c816155fb565b82525050565b600061471d82615405565b6147278185615490565b935061473781856020860161568b565b6147408161589d565b840191505092915050565b6147548161566a565b82525050565b600061476582615410565b61476f81856154a1565b935061477f81856020860161568b565b6147888161589d565b840191505092915050565b600061479e82615410565b6147a881856154b2565b93506147b881856020860161568b565b6147c18161589d565b840191505092915050565b60006147d782615410565b6147e181856154c3565b93506147f181856020860161568b565b6147fa8161589d565b840191505092915050565b60006148126008836154b2565b915061481d826158ae565b602082019050919050565b60006148356007836154b2565b9150614840826158d7565b602082019050919050565b6000614858601e836154b2565b915061486382615900565b602082019050919050565b600061487b602b836154b2565b915061488682615929565b604082019050919050565b600061489e6032836154b2565b91506148a982615978565b604082019050919050565b60006148c1600f836154b2565b91506148cc826159c7565b602082019050919050565b60006148e46026836154b2565b91506148ef826159f0565b604082019050919050565b6000614907601c836154b2565b915061491282615a3f565b602082019050919050565b600061492a6024836154b2565b915061493582615a68565b604082019050919050565b600061494d6019836154b2565b915061495882615ab7565b602082019050919050565b6000614970602c836154b2565b915061497b82615ae0565b604082019050919050565b60006149936038836154b2565b915061499e82615b2f565b604082019050919050565b60006149b66013836154b2565b91506149c182615b7e565b602082019050919050565b60006149d9602a836154b2565b91506149e482615ba7565b604082019050919050565b60006149fc6029836154b2565b9150614a0782615bf6565b604082019050919050565b6000614a1f6015836154b2565b9150614a2a82615c45565b602082019050919050565b6000614a426020836154b2565b9150614a4d82615c6e565b602082019050919050565b6000614a65600a836154b2565b9150614a7082615c97565b602082019050919050565b6000614a88602c836154b2565b9150614a9382615cc0565b604082019050919050565b6000614aab6020836154b2565b9150614ab682615d0f565b602082019050919050565b6000614ace6029836154b2565b9150614ad982615d38565b604082019050919050565b6000614af1600e836154b2565b9150614afc82615d87565b602082019050919050565b6000614b146008836154b2565b9150614b1f82615db0565b602082019050919050565b6000614b376021836154b2565b9150614b4282615dd9565b604082019050919050565b6000614b5a6031836154b2565b9150614b6582615e28565b604082019050919050565b6000614b7d602c836154b2565b9150614b8882615e77565b604082019050919050565b6000614ba06019836154b2565b9150614bab82615ec6565b602082019050919050565b6000614bc36014836154b2565b9150614bce82615eef565b602082019050919050565b6000614be6601f836154b2565b9150614bf182615f18565b602082019050919050565b614c0581615653565b82525050565b614c1481615653565b82525050565b614c238161565d565b82525050565b614c328161565d565b82525050565b614c418161565d565b82525050565b614c508161565d565b82525050565b6000602082019050614c6b60008301846144ae565b92915050565b6000608082019050614c8660008301876144ae565b614c9360208301866144ae565b614ca06040830185614bfc565b8181036060830152614cb28184614712565b905095945050505050565b6000606082019050614cd260008301866144ae565b614cdf6020830185614bfc565b614cec6040830184614bfc565b949350505050565b600061100082019050614d0a6000830185614514565b614d18610800830184614514565b9392505050565b600061084082019050614d3560008301866144bd565b818103610800830152614d48818561456b565b9050614d58610820830184614bfc565b949350505050565b600061082082019050614d766000830185614514565b614d84610800830184614c38565b9392505050565b6000602082019050614da06000830184614703565b92915050565b60006020820190508181036000830152614dc08184614793565b905092915050565b60006020820190508181036000830152614de181614805565b9050919050565b60006020820190508181036000830152614e0181614828565b9050919050565b60006020820190508181036000830152614e218161484b565b9050919050565b60006020820190508181036000830152614e418161486e565b9050919050565b60006020820190508181036000830152614e6181614891565b9050919050565b60006020820190508181036000830152614e81816148b4565b9050919050565b60006020820190508181036000830152614ea1816148d7565b9050919050565b60006020820190508181036000830152614ec1816148fa565b9050919050565b60006020820190508181036000830152614ee18161491d565b9050919050565b60006020820190508181036000830152614f0181614940565b9050919050565b60006020820190508181036000830152614f2181614963565b9050919050565b60006020820190508181036000830152614f4181614986565b9050919050565b60006020820190508181036000830152614f61816149a9565b9050919050565b60006020820190508181036000830152614f81816149cc565b9050919050565b60006020820190508181036000830152614fa1816149ef565b9050919050565b60006020820190508181036000830152614fc181614a12565b9050919050565b60006020820190508181036000830152614fe181614a35565b9050919050565b6000602082019050818103600083015261500181614a58565b9050919050565b6000602082019050818103600083015261502181614a7b565b9050919050565b6000602082019050818103600083015261504181614a9e565b9050919050565b6000602082019050818103600083015261506181614ac1565b9050919050565b6000602082019050818103600083015261508181614ae4565b9050919050565b600060208201905081810360008301526150a181614b07565b9050919050565b600060208201905081810360008301526150c181614b2a565b9050919050565b600060208201905081810360008301526150e181614b4d565b9050919050565b6000602082019050818103600083015261510181614b70565b9050919050565b6000602082019050818103600083015261512181614b93565b9050919050565b6000602082019050818103600083015261514181614bb6565b9050919050565b6000602082019050818103600083015261516181614bd9565b9050919050565b600060208201905061517d6000830184614bfc565b92915050565b6000610880820190506151996000830188614c0b565b6151a66020830187614514565b8181036108208301526151b981866145e0565b90506151c961084083018561474b565b6151d761086083018461474b565b9695505050505050565b6000610880820190506151f76000830188614c0b565b6152046020830187614514565b81810361082083015261521781866145e0565b9050615227610840830185614c0b565b615235610860830184614c0b565b9695505050505050565b60006040820190506152546000830185614bfc565b6152616020830184614bfc565b9392505050565b600060608201905061527d6000830186614bfc565b61528a6020830185614c29565b818103604083015261529c818461456b565b9050949350505050565b60006020820190506152bb6000830184614c29565b92915050565b60006152cb6152dc565b90506152d782826156f0565b919050565b6000604051905090565b600067ffffffffffffffff82111561530157615300615855565b5b602082029050919050565b600067ffffffffffffffff82111561532757615326615855565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561535357615352615855565b5b602082029050919050565b600067ffffffffffffffff82111561537957615378615855565b5b6153828261589d565b9050602081019050919050565b600067ffffffffffffffff8211156153aa576153a9615855565b5b6153b38261589d565b9050602081019050919050565b6000819050919050565b6000819050602082019050919050565b6000819050919050565b600060089050919050565b600081519050919050565b600060089050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b600081905092915050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60006154df82615653565b91506154ea83615653565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561551f5761551e61576a565b5b828201905092915050565b600061553582615653565b915061554083615653565b9250826155505761554f615799565b5b828204905092915050565b600061556682615653565b915061557183615653565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156155aa576155a961576a565b5b828202905092915050565b60006155c082615653565b91506155cb83615653565b9250828210156155de576155dd61576a565b5b828203905092915050565b60006155f482615633565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600061567582615653565b9050919050565b82818337600083830152505050565b60005b838110156156a957808201518184015260208101905061568e565b838111156156b8576000848401525b50505050565b600060028204905060018216806156d657607f821691505b602082108114156156ea576156e96157c8565b5b50919050565b6156f98261589d565b810181811067ffffffffffffffff8211171561571857615717615855565b5b80604052505050565b600061572c82615653565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561575f5761575e61576a565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f6f66666572207570000000000000000000000000000000000000000000000000600082015250565b7f6e6f206d6f726500000000000000000000000000000000000000000000000000600082015250565b7f6d75737420686f646c203e3d2031207175616c696669656420746f6b656e0000600082015250565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f6e6f7420696e697469616c697a65640000000000000000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f616c726561647920696e697469616c697a656400000000000000000000000000600082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b7f696e73756666696369656e74206f66666572696e670000000000000000000000600082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f6e6f7420686f646c657200000000000000000000000000000000000000000000600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f71756f7461206578636565646564000000000000000000000000000000000000600082015250565b7f746f6f206d616e79000000000000000000000000000000000000000000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b7f6e6f206d6f72652c206f776e657220616e642061727469737400000000000000600082015250565b7f746f6f206d616e79206174206f6e652074696d65000000000000000000000000600082015250565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b615f4a816155e9565b8114615f5557600080fd5b50565b615f61816155fb565b8114615f6c57600080fd5b50565b615f7881615607565b8114615f8357600080fd5b50565b615f8f81615653565b8114615f9a57600080fd5b50565b615fa68161565d565b8114615fb157600080fd5b5056fea2646970667358221220129d6fe3e61e5a14939a66c25585986d4760919ba7d5709f2bc785ca2271719b64736f6c634300080600330000000000000000000000002f59aa8b33b0db6ef148f9be2b88a896bd908e9b000000000000000000000000000000000000000000000000000000000000045300000000000000000000000000000000000000000000000000000000000000590000000000000000000000000000000000000000000000000138a388a43c0000000000000000000000000000ab90665ca0ee7783f2a841d68a6276d3db8285e2

Deployed Bytecode

0x6080604052600436106102675760003560e01c80637564580111610144578063bedcf003116100b6578063cd46471d1161007a578063cd46471d14610909578063d159b4ae14610946578063e985e9c514610985578063ebb737eb146109c2578063f2fde38b146109ed578063faf9658914610a1657610267565b8063bedcf0031461080f578063bfe448481461083a578063c4d66de814610878578063c87b56dd146108a1578063cad6ed62146108de57610267565b8063a22cb46511610108578063a22cb46514610727578063b111135914610750578063b266cb0114610767578063b88d4fde14610792578063b921e163146107bb578063b94805a2146107e457610267565b8063756458011461063e5780638b608e37146106695780638da5cb5b1461069457806392cb829d146106bf57806395d89b41146106fc57610267565b806329745262116101dd5780634f6ccce7116101a15780634f6ccce7146105295780636352211e146105665780636e8299b7146105a357806370a08231146105ce578063715018a61461060b578063738198b41461062257610267565b806329745262146104635780632f745c591461048e5780633866b05c146104cb57806342842e0e146104d557806343bc1612146104fe57610267565b80630c4f2ee01161022f5780630c4f2ee0146103655780630e7ce7ab14610390578063158ef93e146103bb57806318160ddd146103e65780631c7b97331461041157806323b872dd1461043a57610267565b806301ffc9a71461026c57806306fdde03146102a9578063075b74cf146102d4578063081812fc146102ff578063095ea7b31461033c575b600080fd5b34801561027857600080fd5b50610293600480360381019061028e91906142e7565b610a32565b6040516102a09190614d8b565b60405180910390f35b3480156102b557600080fd5b506102be610aac565b6040516102cb9190614da6565b60405180910390f35b3480156102e057600080fd5b506102e9610b3e565b6040516102f69190615168565b60405180910390f35b34801561030b57600080fd5b506103266004803603810190610321919061438a565b610b44565b6040516103339190614c56565b60405180910390f35b34801561034857600080fd5b50610363600480360381019061035e91906141b0565b610bc9565b005b34801561037157600080fd5b5061037a610ce1565b6040516103879190615168565b60405180910390f35b34801561039c57600080fd5b506103a5610ce7565b6040516103b29190615168565b60405180910390f35b3480156103c757600080fd5b506103d0610ced565b6040516103dd9190614d8b565b60405180910390f35b3480156103f257600080fd5b506103fb610d00565b6040516104089190615168565b60405180910390f35b34801561041d57600080fd5b5061043860048036038101906104339190614294565b610d0d565b005b34801561044657600080fd5b50610461600480360381019061045c919061409a565b610d9c565b005b34801561046f57600080fd5b50610478610dfc565b60405161048591906152a6565b60405180910390f35b34801561049a57600080fd5b506104b560048036038101906104b091906141b0565b610e0f565b6040516104c29190615168565b60405180910390f35b6104d3610eb4565b005b3480156104e157600080fd5b506104fc60048036038101906104f7919061409a565b610ec0565b005b34801561050a57600080fd5b50610513610ee0565b6040516105209190614c56565b60405180910390f35b34801561053557600080fd5b50610550600480360381019061054b919061438a565b610f06565b60405161055d9190615168565b60405180910390f35b34801561057257600080fd5b5061058d6004803603810190610588919061438a565b610f77565b60405161059a9190614c56565b60405180910390f35b3480156105af57600080fd5b506105b8611029565b6040516105c591906152a6565b60405180910390f35b3480156105da57600080fd5b506105f560048036038101906105f0919061402d565b611040565b6040516106029190615168565b60405180910390f35b34801561061757600080fd5b506106206110f8565b005b61063c6004803603810190610637919061438a565b611180565b005b34801561064a57600080fd5b50610653611570565b6040516106609190615168565b60405180910390f35b34801561067557600080fd5b5061067e611576565b60405161068b9190615168565b60405180910390f35b3480156106a057600080fd5b506106a961157c565b6040516106b69190614c56565b60405180910390f35b3480156106cb57600080fd5b506106e660048036038101906106e191906143e4565b6115a6565b6040516106f39190614da6565b60405180910390f35b34801561070857600080fd5b5061071161188b565b60405161071e9190614da6565b60405180910390f35b34801561073357600080fd5b5061074e60048036038101906107499190614170565b61191d565b005b34801561075c57600080fd5b50610765611a9e565b005b34801561077357600080fd5b5061077c611c58565b6040516107899190615168565b60405180910390f35b34801561079e57600080fd5b506107b960048036038101906107b491906140ed565b611c5e565b005b3480156107c757600080fd5b506107e260048036038101906107dd919061438a565b611cc0565b005b3480156107f057600080fd5b506107f9611daa565b6040516108069190614d8b565b60405180910390f35b34801561081b57600080fd5b50610824611dbd565b6040516108319190615168565b60405180910390f35b34801561084657600080fd5b50610861600480360381019061085c91906143e4565b611dc3565b60405161086f92919061523f565b60405180910390f35b34801561088457600080fd5b5061089f600480360381019061089a919061402d565b611e04565b005b3480156108ad57600080fd5b506108c860048036038101906108c3919061438a565b611f2f565b6040516108d59190614da6565b60405180910390f35b3480156108ea57600080fd5b506108f3611f4a565b6040516109009190615168565b60405180910390f35b34801561091557600080fd5b50610930600480360381019061092b919061438a565b611f50565b60405161093d9190615168565b60405180910390f35b34801561095257600080fd5b5061096d600480360381019061096891906143e4565b611f94565b60405161097c93929190614d1f565b60405180910390f35b34801561099157600080fd5b506109ac60048036038101906109a7919061405a565b61256e565b6040516109b99190614d8b565b60405180910390f35b3480156109ce57600080fd5b506109d7612602565b6040516109e49190615168565b60405180910390f35b3480156109f957600080fd5b50610a146004803603810190610a0f919061402d565b612608565b005b610a306004803603810190610a2b919061438a565b612700565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610aa55750610aa482612c26565b5b9050919050565b606060008054610abb906156be565b80601f0160208091040260200160405190810160405280929190818152602001828054610ae7906156be565b8015610b345780601f10610b0957610100808354040283529160200191610b34565b820191906000526020600020905b815481529060010190602001808311610b1757829003601f168201915b5050505050905090565b600f5481565b6000610b4f82612d08565b610b8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8590615008565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610bd482610f77565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610c45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3c906150a8565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610c64612d74565b73ffffffffffffffffffffffffffffffffffffffff161480610c935750610c9281610c8d612d74565b61256e565b5b610cd2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc990614f28565b60405180910390fd5b610cdc8383612d7c565b505050565b60165481565b60175481565b600b60149054906101000a900460ff1681565b6000600880549050905090565b610d15612d74565b73ffffffffffffffffffffffffffffffffffffffff16610d3361157c565b73ffffffffffffffffffffffffffffffffffffffff1614610d89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d8090615028565b60405180910390fd5b8160128190555080601381905550505050565b610dad610da7612d74565b82612e35565b610dec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de3906150c8565b60405180910390fd5b610df7838383612f13565b505050565b601860009054906101000a900460ff1681565b6000610e1a83611040565b8210610e5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5290614e28565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b610ebe6001612700565b565b610edb83838360405180602001604052806000815250611c5e565b505050565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000610f10610d00565b8210610f51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f48906150e8565b60405180910390fd5b60088281548110610f6557610f64615826565b5b90600052602060002001549050919050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611020576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101790614f88565b60405180910390fd5b80915050919050565b6000601860009054906101000a900460ff16905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156110b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110a890614f68565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611100612d74565b73ffffffffffffffffffffffffffffffffffffffff1661111e61157c565b73ffffffffffffffffffffffffffffffffffffffff1614611174576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116b90615028565b60405180910390fd5b61117e600061316f565b565b6002600a5414156111c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111bd90615148565b60405180910390fd5b6002600a81905550600b60149054906101000a900460ff1661121d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121490614e68565b60405180910390fd5b34600a60195461122d919061552a565b111561126e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161126590614dc8565b60405180910390fd5b611276612d74565b73ffffffffffffffffffffffffffffffffffffffff1661129582610f77565b73ffffffffffffffffffffffffffffffffffffffff16146112eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112e290614fe8565b60405180910390fd5b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a3704246611333612d74565b6040518263ffffffff1660e01b815260040161134f9190614c56565b60006040518083038186803b15801561136757600080fd5b505afa15801561137b573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906113a4919061421e565b90506000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663064125876113ee612d74565b856001601a60008981526020019081526020016000208054905061141291906155b5565b6040518463ffffffff1660e01b815260040161143093929190614cbd565b602060405180830381600087803b15801561144a57600080fd5b505af115801561145e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148291906143b7565b9050601a600084815260200190815260200160002060405180606001604052804281526020018381526020018481525090806001815401808255809150506001900390600052602060002090600302016000909190919091506000820151816000015560208201518160010155604082015181600201908051906020019061150b929190613b0b565b50505060023461151b919061552a565b6010600082825461152c91906154d4565b92505081905550600234611540919061552a565b3461154b91906155b5565b600f600082825461155c91906154d4565b9250508190555050506001600a8190555050565b60125481565b60155481565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606115b0613b6b565b606060006115bd86612d08565b15611676576115cc8686611f94565b80935081945082955050505073709265b376897f4611c67842719f28abc1dd9f1b63ce7cd32b87858589866040518663ffffffff1660e01b81526004016116179594939291906151e1565b60006040518083038186803b15801561162f57600080fd5b505af4158015611643573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061166c9190614341565b9350505050611885565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a370424660006040518263ffffffff1660e01b81526004016116d29190614c56565b60006040518083038186803b1580156116ea57600080fd5b505afa1580156116fe573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611727919061421e565b9150600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663236cee0c87601860009054906101000a900460ff16856040518463ffffffff1660e01b815260040161179793929190615268565b6108006040518083038186803b1580156117b057600080fd5b505afa1580156117c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e891906141f0565b925073709265b376897f4611c67842719f28abc1dd9f1b63ce7cd32b8785856000806040518663ffffffff1660e01b815260040161182a959493929190615183565b60006040518083038186803b15801561184257600080fd5b505af4158015611856573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061187f9190614341565b93505050505b92915050565b60606001805461189a906156be565b80601f01602080910402602001604051908101604052809291908181526020018280546118c6906156be565b80156119135780601f106118e857610100808354040283529160200191611913565b820191906000526020600020905b8154815290600101906020018083116118f657829003601f168201915b5050505050905090565b611925612d74565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611993576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161198a90614ee8565b60405180910390fd5b80600560006119a0612d74565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611a4d612d74565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611a929190614d8b565b60405180910390a35050565b6002600a541415611ae4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611adb90615148565b60405180910390fd5b6002600a81905550611af461157c565b73ffffffffffffffffffffffffffffffffffffffff16611b12612d74565b73ffffffffffffffffffffffffffffffffffffffff161415611b9157600060105490506000601081905550611b45612d74565b73ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611b8a573d6000803e3d6000fd5b5050611c4e565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611bd2612d74565b73ffffffffffffffffffffffffffffffffffffffff161415611c4d576000600f5490506000600f81905550611c05612d74565b73ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611c4a573d6000803e3d6000fd5b50505b5b6001600a81905550565b60195481565b611c6f611c69612d74565b83612e35565b611cae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ca5906150c8565b60405180910390fd5b611cba84848484613235565b50505050565b611cc8612d74565b73ffffffffffffffffffffffffffffffffffffffff16611ce661157c565b73ffffffffffffffffffffffffffffffffffffffff1614611d3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3390615028565b60405180910390fd5b61100c60145482611d4d91906154d4565b1115611d8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d8590615088565b60405180910390fd5b8060146000828254611da091906154d4565b9250508190555050565b601160009054906101000a900460ff1681565b60105481565b601a6020528160005260406000208181548110611ddf57600080fd5b9060005260206000209060030201600091509150508060000154908060010154905082565b611e0c612d74565b73ffffffffffffffffffffffffffffffffffffffff16611e2a61157c565b73ffffffffffffffffffffffffffffffffffffffff1614611e80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e7790615028565b60405180910390fd5b600b60149054906101000a900460ff1615611ed0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ec790614f48565b60405180910390fd5b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600b60146101000a81548160ff02191690831515021790555050565b6060611f4382611f3e84611f50565b6115a6565b9050919050565b60135481565b6000611f5b82612d08565b15611f8a576001601a600084815260200190815260200160002080549050611f8391906155b5565b9050611f8f565b600090505b919050565b611f9c613b6b565b606060006060611faa613b6b565b6000611fb588612d08565b61214257600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a370424660006040518263ffffffff1660e01b81526004016120159190614c56565b60006040518083038186803b15801561202d57600080fd5b505afa158015612041573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061206a919061421e565b925060009050600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663236cee0c89601860009054906101000a900460ff16866040518463ffffffff1660e01b81526004016120de93929190615268565b6108006040518083038186803b1580156120f757600080fd5b505afa15801561210b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061212f91906141f0565b9150818382955095509550505050612567565b61214b88611f50565b87101561229857601a6000898152602001908152602001600020878154811061217757612176615826565b5b9060005260206000209060030201600201805480602002602001604051908101604052809291908181526020016000905b828210156122545783829060005260206000200180546121c7906156be565b80601f01602080910402602001604051908101604052809291908181526020018280546121f3906156be565b80156122405780601f1061221557610100808354040283529160200191612240565b820191906000526020600020905b81548152906001019060200180831161222357829003601f168201915b5050505050815260200190600101906121a8565b505050509250601a6000898152602001908152602001600020878154811061227f5761227e615826565b5b9060005260206000209060030201600001549050612356565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a37042466122df8a610f77565b6040518263ffffffff1660e01b81526004016122fb9190614c56565b60006040518083038186803b15801561231357600080fd5b505afa158015612327573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190612350919061421e565b92504290505b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663236cee0c89601860009054906101000a900460ff16866040518463ffffffff1660e01b81526004016123c493929190615268565b6108006040518083038186803b1580156123dd57600080fd5b505afa1580156123f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061241591906141f0565b915060005b8781101561255957732175b6b2219dcaaf7020cde8f2b59e0a6f373d4563940c8d0584732175b6b2219dcaaf7020cde8f2b59e0a6f373d45632cd80e1087601860009054906101000a900460ff166040518363ffffffff1660e01b8152600401612485929190614d60565b6108006040518083038186803b15801561249e57600080fd5b505af41580156124b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124d691906141f0565b6040518363ffffffff1660e01b81526004016124f3929190614cf4565b6108006040518083038186803b15801561250c57600080fd5b505af4158015612520573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061254491906141f0565b9250808061255190615721565b91505061241a565b508183829550955095505050505b9250925092565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60145481565b612610612d74565b73ffffffffffffffffffffffffffffffffffffffff1661262e61157c565b73ffffffffffffffffffffffffffffffffffffffff1614612684576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161267b90615028565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156126f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126eb90614e88565b60405180910390fd5b6126fd8161316f565b50565b6002600a541415612746576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161273d90615148565b60405180910390fd5b6002600a8190555061275661157c565b73ffffffffffffffffffffffffffffffffffffffff16612774612d74565b73ffffffffffffffffffffffffffffffffffffffff1614156127e657601554816016546127a191906154d4565b106127e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127d890615108565b60405180910390fd5b612a90565b6000601354111561283757601354811115612836576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161282d90615128565b60405180910390fd5b5b60145481612843610d00565b61284d91906154d4565b111561288e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161288590614de8565b60405180910390fd5b348160195461289d919061555b565b11156128de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128d590614fa8565b60405180910390fd5b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a421d668612924612d74565b6040518263ffffffff1660e01b81526004016129409190614c56565b60206040518083038186803b15801561295857600080fd5b505afa15801561296c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129909190614267565b6129cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129c690614e08565b60405180910390fd5b60006012541115612a3a57601254816129ee6129e9612d74565b611040565b6129f891906154d4565b1115612a39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a3090615068565b60405180910390fd5b5b600234612a47919061552a565b60106000828254612a5891906154d4565b92505081905550600234612a6c919061552a565b34612a7791906155b5565b600f6000828254612a8891906154d4565b925050819055505b60005b81811015612c1a57612ab3612aa6612d74565b612aae610d00565b613291565b601a60006001612ac1610d00565b612acb91906155b5565b8152602001908152602001600020604051806060016040528042815260200160008152602001600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a3704246612b37612d74565b6040518263ffffffff1660e01b8152600401612b539190614c56565b60006040518083038186803b158015612b6b57600080fd5b505afa158015612b7f573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190612ba8919061421e565b815250908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000155602082015181600101556040820151816002019080519060200190612c04929190613b0b565b5050508080612c1290615721565b915050612a93565b506001600a8190555050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612cf157507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80612d015750612d00826132af565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16612def83610f77565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000612e4082612d08565b612e7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e7690614f08565b60405180910390fd5b6000612e8a83610f77565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612ef957508373ffffffffffffffffffffffffffffffffffffffff16612ee184610b44565b73ffffffffffffffffffffffffffffffffffffffff16145b80612f0a5750612f09818561256e565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16612f3382610f77565b73ffffffffffffffffffffffffffffffffffffffff1614612f89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f8090615048565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612ff9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ff090614ec8565b60405180910390fd5b613004838383613319565b61300f600082612d7c565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461305f91906155b5565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546130b691906154d4565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b613240848484612f13565b61324c8484848461342d565b61328b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161328290614e48565b60405180910390fd5b50505050565b6132ab8282604051806020016040528060008152506135c4565b5050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61332483838361361f565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156133675761336281613624565b6133a6565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146133a5576133a4838261366d565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156133e9576133e4816137da565b613428565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146134275761342682826138ab565b5b5b505050565b600061344e8473ffffffffffffffffffffffffffffffffffffffff1661392a565b156135b7578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613477612d74565b8786866040518563ffffffff1660e01b81526004016134999493929190614c71565b602060405180830381600087803b1580156134b357600080fd5b505af19250505080156134e457506040513d601f19601f820116820180604052508101906134e19190614314565b60015b613567573d8060008114613514576040519150601f19603f3d011682016040523d82523d6000602084013e613519565b606091505b5060008151141561355f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161355690614e48565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506135bc565b600190505b949350505050565b6135ce838361393d565b6135db600084848461342d565b61361a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161361190614e48565b60405180910390fd5b505050565b505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b6000600161367a84611040565b61368491906155b5565b9050600060076000848152602001908152602001600020549050818114613769576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016008805490506137ee91906155b5565b905060006009600084815260200190815260200160002054905060006008838154811061381e5761381d615826565b5b9060005260206000200154905080600883815481106138405761383f615826565b5b90600052602060002001819055508160096000838152602001908152602001600020819055506009600085815260200190815260200160002060009055600880548061388f5761388e6157f7565b5b6001900381819060005260206000200160009055905550505050565b60006138b683611040565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600080823b905060008111915050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156139ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139a490614fc8565b60405180910390fd5b6139b681612d08565b156139f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139ed90614ea8565b60405180910390fd5b613a0260008383613319565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254613a5291906154d4565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b828054828255906000526020600020908101928215613b5a579160200282015b82811115613b59578251829080519060200190613b49929190613b99565b5091602001919060010190613b2b565b5b509050613b679190613c1f565b5090565b6040518061010001604052806008905b613b83613c43565b815260200190600190039081613b7b5790505090565b828054613ba5906156be565b90600052602060002090601f016020900481019282613bc75760008555613c0e565b82601f10613be057805160ff1916838001178555613c0e565b82800160010185558215613c0e579182015b82811115613c0d578251825591602001919060010190613bf2565b5b509050613c1b9190613c66565b5090565b5b80821115613c3f5760008181613c369190613c83565b50600101613c20565b5090565b604051806101000160405280600890602082028036833780820191505090505090565b5b80821115613c7f576000816000905550600101613c67565b5090565b508054613c8f906156be565b6000825580601f10613ca15750613cc0565b601f016020900490600052602060002090810190613cbf9190613c66565b5b50565b6000613cd6613cd1846152e6565b6152c1565b9050808285610100860282011115613cf157613cf0615889565b5b60005b85811015613d225781613d078882613f13565b84526020840193506101008301925050600181019050613cf4565b5050509392505050565b6000613d3f613d3a8461530c565b6152c1565b90508083825260208201905082856020860282011115613d6257613d61615889565b5b60005b85811015613db057815167ffffffffffffffff811115613d8857613d87615884565b5b808601613d958982613fc0565b85526020850194506020840193505050600181019050613d65565b5050509392505050565b6000613dcd613dc884615338565b6152c1565b90508082856020860282011115613de757613de6615889565b5b60005b85811015613e175781613dfd8882614018565b845260208401935060208301925050600181019050613dea565b5050509392505050565b6000613e34613e2f8461535e565b6152c1565b905082815260208101848484011115613e5057613e4f61588e565b5b613e5b84828561567c565b509392505050565b6000613e76613e718461538f565b6152c1565b905082815260208101848484011115613e9257613e9161588e565b5b613e9d84828561568b565b509392505050565b600081359050613eb481615f41565b92915050565b600082601f830112613ecf57613ece615884565b5b6008613edc848285613cc3565b91505092915050565b600082601f830112613efa57613ef9615884565b5b8151613f0a848260208601613d2c565b91505092915050565b600082601f830112613f2857613f27615884565b5b6008613f35848285613dba565b91505092915050565b600081359050613f4d81615f58565b92915050565b600081519050613f6281615f58565b92915050565b600081359050613f7781615f6f565b92915050565b600081519050613f8c81615f6f565b92915050565b600082601f830112613fa757613fa6615884565b5b8135613fb7848260208601613e21565b91505092915050565b600082601f830112613fd557613fd4615884565b5b8151613fe5848260208601613e63565b91505092915050565b600081359050613ffd81615f86565b92915050565b60008151905061401281615f86565b92915050565b60008151905061402781615f9d565b92915050565b60006020828403121561404357614042615898565b5b600061405184828501613ea5565b91505092915050565b6000806040838503121561407157614070615898565b5b600061407f85828601613ea5565b925050602061409085828601613ea5565b9150509250929050565b6000806000606084860312156140b3576140b2615898565b5b60006140c186828701613ea5565b93505060206140d286828701613ea5565b92505060406140e386828701613fee565b9150509250925092565b6000806000806080858703121561410757614106615898565b5b600061411587828801613ea5565b945050602061412687828801613ea5565b935050604061413787828801613fee565b925050606085013567ffffffffffffffff81111561415857614157615893565b5b61416487828801613f92565b91505092959194509250565b6000806040838503121561418757614186615898565b5b600061419585828601613ea5565b92505060206141a685828601613f3e565b9150509250929050565b600080604083850312156141c7576141c6615898565b5b60006141d585828601613ea5565b92505060206141e685828601613fee565b9150509250929050565b6000610800828403121561420757614206615898565b5b600061421584828501613eba565b91505092915050565b60006020828403121561423457614233615898565b5b600082015167ffffffffffffffff81111561425257614251615893565b5b61425e84828501613ee5565b91505092915050565b60006020828403121561427d5761427c615898565b5b600061428b84828501613f53565b91505092915050565b6000806000606084860312156142ad576142ac615898565b5b60006142bb86828701613f3e565b93505060206142cc86828701613fee565b92505060406142dd86828701613fee565b9150509250925092565b6000602082840312156142fd576142fc615898565b5b600061430b84828501613f68565b91505092915050565b60006020828403121561432a57614329615898565b5b600061433884828501613f7d565b91505092915050565b60006020828403121561435757614356615898565b5b600082015167ffffffffffffffff81111561437557614374615893565b5b61438184828501613fc0565b91505092915050565b6000602082840312156143a05761439f615898565b5b60006143ae84828501613fee565b91505092915050565b6000602082840312156143cd576143cc615898565b5b60006143db84828501614003565b91505092915050565b600080604083850312156143fb576143fa615898565b5b600061440985828601613fee565b925050602061441a85828601613fee565b9150509250929050565b60006144308383614655565b6101008301905092915050565b600061444983836146ac565b6101008301905092915050565b6000614462838361475a565b905092915050565b600061447683836147cc565b905092915050565b600061448a8383614c1a565b60208301905092915050565b60006144a28383614c47565b60208301905092915050565b6144b7816155e9565b82525050565b6144c6816153e4565b6144d08184615442565b92506144db826153c0565b8060005b8381101561450c5781516144f38782614424565b96506144fe8361541b565b9250506001810190506144df565b505050505050565b61451d816153e4565b614527818461544d565b9250614532826153c0565b8060005b8381101561456357815161454a878261443d565b96506145558361541b565b925050600181019050614536565b505050505050565b6000614576826153ef565b6145808185615458565b935083602082028501614592856153ca565b8060005b858110156145ce57848403895281516145af8582614456565b94506145ba83615428565b925060208a01995050600181019050614596565b50829750879550505050505092915050565b60006145eb826153ef565b6145f58185615469565b935083602082028501614607856153ca565b8060005b858110156146435784840389528151614624858261446a565b945061462f83615428565b925060208a0199505060018101905061460b565b50829750879550505050505092915050565b61465e816153fa565b614668818461547a565b9250614673826153da565b8060005b838110156146a457815161468b878261447e565b965061469683615435565b925050600181019050614677565b505050505050565b6146b5816153fa565b6146bf8184615485565b92506146ca826153da565b8060005b838110156146fb5781516146e28782614496565b96506146ed83615435565b9250506001810190506146ce565b505050505050565b61470c816155fb565b82525050565b600061471d82615405565b6147278185615490565b935061473781856020860161568b565b6147408161589d565b840191505092915050565b6147548161566a565b82525050565b600061476582615410565b61476f81856154a1565b935061477f81856020860161568b565b6147888161589d565b840191505092915050565b600061479e82615410565b6147a881856154b2565b93506147b881856020860161568b565b6147c18161589d565b840191505092915050565b60006147d782615410565b6147e181856154c3565b93506147f181856020860161568b565b6147fa8161589d565b840191505092915050565b60006148126008836154b2565b915061481d826158ae565b602082019050919050565b60006148356007836154b2565b9150614840826158d7565b602082019050919050565b6000614858601e836154b2565b915061486382615900565b602082019050919050565b600061487b602b836154b2565b915061488682615929565b604082019050919050565b600061489e6032836154b2565b91506148a982615978565b604082019050919050565b60006148c1600f836154b2565b91506148cc826159c7565b602082019050919050565b60006148e46026836154b2565b91506148ef826159f0565b604082019050919050565b6000614907601c836154b2565b915061491282615a3f565b602082019050919050565b600061492a6024836154b2565b915061493582615a68565b604082019050919050565b600061494d6019836154b2565b915061495882615ab7565b602082019050919050565b6000614970602c836154b2565b915061497b82615ae0565b604082019050919050565b60006149936038836154b2565b915061499e82615b2f565b604082019050919050565b60006149b66013836154b2565b91506149c182615b7e565b602082019050919050565b60006149d9602a836154b2565b91506149e482615ba7565b604082019050919050565b60006149fc6029836154b2565b9150614a0782615bf6565b604082019050919050565b6000614a1f6015836154b2565b9150614a2a82615c45565b602082019050919050565b6000614a426020836154b2565b9150614a4d82615c6e565b602082019050919050565b6000614a65600a836154b2565b9150614a7082615c97565b602082019050919050565b6000614a88602c836154b2565b9150614a9382615cc0565b604082019050919050565b6000614aab6020836154b2565b9150614ab682615d0f565b602082019050919050565b6000614ace6029836154b2565b9150614ad982615d38565b604082019050919050565b6000614af1600e836154b2565b9150614afc82615d87565b602082019050919050565b6000614b146008836154b2565b9150614b1f82615db0565b602082019050919050565b6000614b376021836154b2565b9150614b4282615dd9565b604082019050919050565b6000614b5a6031836154b2565b9150614b6582615e28565b604082019050919050565b6000614b7d602c836154b2565b9150614b8882615e77565b604082019050919050565b6000614ba06019836154b2565b9150614bab82615ec6565b602082019050919050565b6000614bc36014836154b2565b9150614bce82615eef565b602082019050919050565b6000614be6601f836154b2565b9150614bf182615f18565b602082019050919050565b614c0581615653565b82525050565b614c1481615653565b82525050565b614c238161565d565b82525050565b614c328161565d565b82525050565b614c418161565d565b82525050565b614c508161565d565b82525050565b6000602082019050614c6b60008301846144ae565b92915050565b6000608082019050614c8660008301876144ae565b614c9360208301866144ae565b614ca06040830185614bfc565b8181036060830152614cb28184614712565b905095945050505050565b6000606082019050614cd260008301866144ae565b614cdf6020830185614bfc565b614cec6040830184614bfc565b949350505050565b600061100082019050614d0a6000830185614514565b614d18610800830184614514565b9392505050565b600061084082019050614d3560008301866144bd565b818103610800830152614d48818561456b565b9050614d58610820830184614bfc565b949350505050565b600061082082019050614d766000830185614514565b614d84610800830184614c38565b9392505050565b6000602082019050614da06000830184614703565b92915050565b60006020820190508181036000830152614dc08184614793565b905092915050565b60006020820190508181036000830152614de181614805565b9050919050565b60006020820190508181036000830152614e0181614828565b9050919050565b60006020820190508181036000830152614e218161484b565b9050919050565b60006020820190508181036000830152614e418161486e565b9050919050565b60006020820190508181036000830152614e6181614891565b9050919050565b60006020820190508181036000830152614e81816148b4565b9050919050565b60006020820190508181036000830152614ea1816148d7565b9050919050565b60006020820190508181036000830152614ec1816148fa565b9050919050565b60006020820190508181036000830152614ee18161491d565b9050919050565b60006020820190508181036000830152614f0181614940565b9050919050565b60006020820190508181036000830152614f2181614963565b9050919050565b60006020820190508181036000830152614f4181614986565b9050919050565b60006020820190508181036000830152614f61816149a9565b9050919050565b60006020820190508181036000830152614f81816149cc565b9050919050565b60006020820190508181036000830152614fa1816149ef565b9050919050565b60006020820190508181036000830152614fc181614a12565b9050919050565b60006020820190508181036000830152614fe181614a35565b9050919050565b6000602082019050818103600083015261500181614a58565b9050919050565b6000602082019050818103600083015261502181614a7b565b9050919050565b6000602082019050818103600083015261504181614a9e565b9050919050565b6000602082019050818103600083015261506181614ac1565b9050919050565b6000602082019050818103600083015261508181614ae4565b9050919050565b600060208201905081810360008301526150a181614b07565b9050919050565b600060208201905081810360008301526150c181614b2a565b9050919050565b600060208201905081810360008301526150e181614b4d565b9050919050565b6000602082019050818103600083015261510181614b70565b9050919050565b6000602082019050818103600083015261512181614b93565b9050919050565b6000602082019050818103600083015261514181614bb6565b9050919050565b6000602082019050818103600083015261516181614bd9565b9050919050565b600060208201905061517d6000830184614bfc565b92915050565b6000610880820190506151996000830188614c0b565b6151a66020830187614514565b8181036108208301526151b981866145e0565b90506151c961084083018561474b565b6151d761086083018461474b565b9695505050505050565b6000610880820190506151f76000830188614c0b565b6152046020830187614514565b81810361082083015261521781866145e0565b9050615227610840830185614c0b565b615235610860830184614c0b565b9695505050505050565b60006040820190506152546000830185614bfc565b6152616020830184614bfc565b9392505050565b600060608201905061527d6000830186614bfc565b61528a6020830185614c29565b818103604083015261529c818461456b565b9050949350505050565b60006020820190506152bb6000830184614c29565b92915050565b60006152cb6152dc565b90506152d782826156f0565b919050565b6000604051905090565b600067ffffffffffffffff82111561530157615300615855565b5b602082029050919050565b600067ffffffffffffffff82111561532757615326615855565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561535357615352615855565b5b602082029050919050565b600067ffffffffffffffff82111561537957615378615855565b5b6153828261589d565b9050602081019050919050565b600067ffffffffffffffff8211156153aa576153a9615855565b5b6153b38261589d565b9050602081019050919050565b6000819050919050565b6000819050602082019050919050565b6000819050919050565b600060089050919050565b600081519050919050565b600060089050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b600081905092915050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60006154df82615653565b91506154ea83615653565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561551f5761551e61576a565b5b828201905092915050565b600061553582615653565b915061554083615653565b9250826155505761554f615799565b5b828204905092915050565b600061556682615653565b915061557183615653565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156155aa576155a961576a565b5b828202905092915050565b60006155c082615653565b91506155cb83615653565b9250828210156155de576155dd61576a565b5b828203905092915050565b60006155f482615633565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600061567582615653565b9050919050565b82818337600083830152505050565b60005b838110156156a957808201518184015260208101905061568e565b838111156156b8576000848401525b50505050565b600060028204905060018216806156d657607f821691505b602082108114156156ea576156e96157c8565b5b50919050565b6156f98261589d565b810181811067ffffffffffffffff8211171561571857615717615855565b5b80604052505050565b600061572c82615653565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561575f5761575e61576a565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f6f66666572207570000000000000000000000000000000000000000000000000600082015250565b7f6e6f206d6f726500000000000000000000000000000000000000000000000000600082015250565b7f6d75737420686f646c203e3d2031207175616c696669656420746f6b656e0000600082015250565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f6e6f7420696e697469616c697a65640000000000000000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f616c726561647920696e697469616c697a656400000000000000000000000000600082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b7f696e73756666696369656e74206f66666572696e670000000000000000000000600082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f6e6f7420686f646c657200000000000000000000000000000000000000000000600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f71756f7461206578636565646564000000000000000000000000000000000000600082015250565b7f746f6f206d616e79000000000000000000000000000000000000000000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b7f6e6f206d6f72652c206f776e657220616e642061727469737400000000000000600082015250565b7f746f6f206d616e79206174206f6e652074696d65000000000000000000000000600082015250565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b615f4a816155e9565b8114615f5557600080fd5b50565b615f61816155fb565b8114615f6c57600080fd5b50565b615f7881615607565b8114615f8357600080fd5b50565b615f8f81615653565b8114615f9a57600080fd5b50565b615fa68161565d565b8114615fb157600080fd5b5056fea2646970667358221220129d6fe3e61e5a14939a66c25585986d4760919ba7d5709f2bc785ca2271719b64736f6c63430008060033

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

0000000000000000000000002f59aa8b33b0db6ef148f9be2b88a896bd908e9b000000000000000000000000000000000000000000000000000000000000045300000000000000000000000000000000000000000000000000000000000000590000000000000000000000000000000000000000000000000138a388a43c0000000000000000000000000000ab90665ca0ee7783f2a841d68a6276d3db8285e2

-----Decoded View---------------
Arg [0] : _artist (address): 0x2F59Aa8B33b0Db6EF148F9bE2B88A896bd908e9B
Arg [1] : _entitySupply (uint256): 1107
Arg [2] : _modulo (uint256): 89
Arg [3] : _offering (uint256): 88000000000000000
Arg [4] : _daemonicaAddress (address): 0xaB90665CA0EE7783f2A841d68A6276D3dB8285e2

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000002f59aa8b33b0db6ef148f9be2b88a896bd908e9b
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000453
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000059
Arg [3] : 0000000000000000000000000000000000000000000000000138a388a43c0000
Arg [4] : 000000000000000000000000ab90665ca0ee7783f2a841d68a6276d3db8285e2


Deployed Bytecode Sourcemap

2380:8218:7:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;910:222:6;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2349:98:5;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2555:32:7;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3860:217:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3398:401;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2803:37:7;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2844:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2447:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1535:111:6;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3536:210:7;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4724:330:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2891:19:7;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1211:253:6;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7238:58:7;;;:::i;:::-;;5120:179:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2530:21:7;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1718:230:6;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2052:235:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4181:76:7;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1790:205:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1598:92:17;;;;;;;;;;;;;:::i;:::-;;8572:524:7;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2661:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2762:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;966:85:17;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6637:503:7;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2511:102:5;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4144:290;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;9175:336:7;;;;;;;;;;;;;:::i;:::-;;2914:23;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5365:320:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3936:162:7;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2627:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2591:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3054:40;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;9637:188;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;6193:143;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2696:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4416:183;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4945:1054;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;4500:162:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2731:27:7;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1839:189:17;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;7506:954:7;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;910:222:6;1012:4;1050:35;1035:50;;;:11;:50;;;;:90;;;;1089:36;1113:11;1089:23;:36::i;:::-;1035:90;1028:97;;910:222;;;:::o;2349:98:5:-;2403:13;2435:5;2428:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2349:98;:::o;2555:32:7:-;;;;:::o;3860:217:5:-;3936:7;3963:16;3971:7;3963;:16::i;:::-;3955:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;4046:15;:24;4062:7;4046:24;;;;;;;;;;;;;;;;;;;;;4039:31;;3860:217;;;:::o;3398:401::-;3478:13;3494:23;3509:7;3494:14;:23::i;:::-;3478:39;;3541:5;3535:11;;:2;:11;;;;3527:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;3632:5;3616:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;3641:37;3658:5;3665:12;:10;:12::i;:::-;3641:16;:37::i;:::-;3616:62;3595:165;;;;;;;;;;;;:::i;:::-;;;;;;;;;3771:21;3780:2;3784:7;3771:8;:21::i;:::-;3468:331;3398:401;;:::o;2803:37:7:-;;;;:::o;2844:33::-;;;;:::o;2447:31::-;;;;;;;;;;;;;:::o;1535:111:6:-;1596:7;1622:10;:17;;;;1615:24;;1535:111;:::o;3536:210:7:-;1189:12:17;:10;:12::i;:::-;1178:23;;:7;:5;:7::i;:::-;:23;;;1170:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;3694:13:7::1;3679:12;:28;;;;3728:12;3714:11;:26;;;;3536:210:::0;;;:::o;4724:330:5:-;4913:41;4932:12;:10;:12::i;:::-;4946:7;4913:18;:41::i;:::-;4905:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;5019:28;5029:4;5035:2;5039:7;5019:9;:28::i;:::-;4724:330;;;:::o;2891:19:7:-;;;;;;;;;;;;;:::o;1211:253:6:-;1308:7;1343:23;1360:5;1343:16;:23::i;:::-;1335:5;:31;1327:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;1431:12;:19;1444:5;1431:19;;;;;;;;;;;;;;;:26;1451:5;1431:26;;;;;;;;;;;;1424:33;;1211:253;;;;:::o;7238:58:7:-;7278:13;7289:1;7278:10;:13::i;:::-;7238:58::o;5120:179:5:-;5253:39;5270:4;5276:2;5280:7;5253:39;;;;;;;;;;;;:16;:39::i;:::-;5120:179;;;:::o;2530:21:7:-;;;;;;;;;;;;;:::o;1718:230:6:-;1793:7;1828:30;:28;:30::i;:::-;1820:5;:38;1812:95;;;;;;;;;;;;:::i;:::-;;;;;;;;;1924:10;1935:5;1924:17;;;;;;;;:::i;:::-;;;;;;;;;;1917:24;;1718:230;;;:::o;2052:235:5:-;2124:7;2143:13;2159:7;:16;2167:7;2159:16;;;;;;;;;;;;;;;;;;;;;2143:32;;2210:1;2193:19;;:5;:19;;;;2185:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;2275:5;2268:12;;;2052:235;;;:::o;4181:76:7:-;4225:5;4245:6;;;;;;;;;;;4238:13;;4181:76;:::o;1790:205:5:-;1862:7;1906:1;1889:19;;:5;:19;;;;1881:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;1972:9;:16;1982:5;1972:16;;;;;;;;;;;;;;;;1965:23;;1790:205;;;:::o;1598:92:17:-;1189:12;:10;:12::i;:::-;1178:23;;:7;:5;:7::i;:::-;:23;;;1170:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;1662:21:::1;1680:1;1662:9;:21::i;:::-;1598:92::o:0;8572:524:7:-;1680:1:18;2259:7;;:19;;2251:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;1680:1;2389:7;:18;;;;3211:11:7::1;;;;;;;;;;;3203:39;;;;;;;;;;;;:::i;:::-;;;;;;;;;8681:9:::2;8675:2;8664:8;;:13;;;;:::i;:::-;:26;;8656:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;8738:12;:10;:12::i;:::-;8717:33;;:17;8725:8;8717:7;:17::i;:::-;:33;;;8709:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;8799:19;8821:9;;;;;;;;;;;:16;;;8838:12;:10;:12::i;:::-;8821:30;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8799:52;;8857:18;8878:8;;;;;;;;;;;:13;;;8892:12;:10;:12::i;:::-;8906:8;8940:1;8917:5;:15;8923:8;8917:15;;;;;;;;;;;:22;;;;:24;;;;:::i;:::-;8878:65;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8857:86;;8949:5;:15;8955:8;8949:15;;;;;;;;;;;8970:38;;;;;;;;8975:15;8970:38;;;;8992:10;8970:38;;;;9004:3;8970:38;;::::0;8949:60:::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;9042:1;9032:9;:11;;;;:::i;:::-;9016:12;;:27;;;;;;;:::i;:::-;;;;;;;;9089:1;9079:9;:11;;;;:::i;:::-;9067:9;:23;;;;:::i;:::-;9049:13;;:42;;;;;;;:::i;:::-;;;;;;;;8650:446;;1637:1:18::0;2562:7;:22;;;;8572:524:7;:::o;2661:31::-;;;;:::o;2762:37::-;;;;:::o;966:85:17:-;1012:7;1038:6;;;;;;;;;;;1031:13;;966:85;:::o;6637:503:7:-;6709:13;6731:24;;:::i;:::-;6762:19;6788:14;6813:17;6821:8;6813:7;:17::i;:::-;6810:325;;;6863:24;6871:8;6881:5;6863:7;:24::i;:::-;6840:47;;;;;;;;;;;;6903:8;:15;6919:8;6929:5;6936:3;6941:5;6948:6;6903:52;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6896:59;;;;;;;6810:325;6982:9;;;;;;;;;;;:16;;;7007:1;6982:28;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6976:34;;7027:9;;;;;;;;;;;:18;;;7046:8;7056:6;;;;;;;;;;;7064:3;7027:41;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7019:49;;7084:8;:15;7100:8;7110:5;7117:3;7122:1;7125;7084:43;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7077:50;;;;;6637:503;;;;;:::o;2511:102:5:-;2567:13;2599:7;2592:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2511:102;:::o;4144:290::-;4258:12;:10;:12::i;:::-;4246:24;;:8;:24;;;;4238:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;4356:8;4311:18;:32;4330:12;:10;:12::i;:::-;4311:32;;;;;;;;;;;;;;;:42;4344:8;4311:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;4408:8;4379:48;;4394:12;:10;:12::i;:::-;4379:48;;;4418:8;4379:48;;;;;;:::i;:::-;;;;;;;;4144:290;;:::o;9175:336:7:-;1680:1:18;2259:7;;:19;;2251:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;1680:1;2389:7;:18;;;;9258:7:7::1;:5;:7::i;:::-;9242:23;;:12;:10;:12::i;:::-;:23;;;9239:268;;;9274:9;9286:12;;9274:24;;9321:1;9306:12;:16;;;;9338:12;:10;:12::i;:::-;9330:30;;:33;9361:1;9330:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;9266:104;9239:268;;;9394:6;;;;;;;;;;;9378:22;;:12;:10;:12::i;:::-;:22;;;9375:132;;;9409:9;9421:13;;9409:25;;9458:1;9442:13;:17;;;;9475:12;:10;:12::i;:::-;9467:30;;:33;9498:1;9467:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;9401:106;9375:132;9239:268;1637:1:18::0;2562:7;:22;;;;9175:336:7:o;2914:23::-;;;;:::o;5365:320:5:-;5534:41;5553:12;:10;:12::i;:::-;5567:7;5534:18;:41::i;:::-;5526:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;5639:39;5653:4;5659:2;5663:7;5672:5;5639:13;:39::i;:::-;5365:320;;;;:::o;3936:162:7:-;1189:12:17;:10;:12::i;:::-;1178:23;;:7;:5;:7::i;:::-;:23;;;1170:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;4043:4:7::1;4026:12;;4014:9;:24;;;;:::i;:::-;4013:34;;4005:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;4083:9;4067:12;;:25;;;;;;;:::i;:::-;;;;;;;;3936:162:::0;:::o;2627:30::-;;;;;;;;;;;;;:::o;2591:31::-;;;;:::o;3054:40::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;9637:188::-;1189:12:17;:10;:12::i;:::-;1178:23;;:7;:5;:7::i;:::-;:23;;;1170:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;9717:11:7::1;;;;;;;;;;;9716:12;9708:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;9779:16;9758:8;;:38;;;;;;;;;;;;;;;;;;9816:4;9802:11;;:18;;;;;;;;;;;;;;;;;;9637:188:::0;:::o;6193:143::-;6259:13;6288:42;6297:8;6307:22;6320:8;6307:12;:22::i;:::-;6288:8;:42::i;:::-;6281:49;;6193:143;;;:::o;2696:30::-;;;;:::o;4416:183::-;4477:7;4495:17;4503:8;4495:7;:17::i;:::-;4492:102;;;4555:1;4530:5;:15;4536:8;4530:15;;;;;;;;;;;:22;;;;:26;;;;:::i;:::-;4522:35;;;;4492:102;4585:1;4578:8;;4416:183;;;;:::o;4945:1054::-;5016:18;;:::i;:::-;5036:15;5053:7;5069:19;5095:24;;:::i;:::-;5126:14;5191:17;5199:8;5191:7;:17::i;:::-;5187:588;;5281:9;;;;;;;;;;;:16;;;5306:1;5281:28;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5275:34;;5327:1;5318:10;;5345:9;;;;;;;;;;;:18;;;5364:8;5374:6;;;;;;;;;;;5382:3;5345:41;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5337:49;;5403:5;5410:3;5415:6;5395:27;;;;;;;;;;;5187:588;5454:22;5467:8;5454:12;:22::i;:::-;5446:5;:30;5443:325;;;5510:5;:15;5516:8;5510:15;;;;;;;;;;;5526:5;5510:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:26;;5504:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5556:5;:15;5562:8;5556:15;;;;;;;;;;;5572:5;5556:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:29;;;5547:38;;5443:325;;;5642:9;;;;;;;;;;;:16;;;5659:17;5667:8;5659:7;:17::i;:::-;5642:35;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5636:41;;5743:15;5734:24;;5443:325;5790:9;;;;;;;;;;;:18;;;5809:8;5819:6;;;;;;;;;;;5827:3;5790:41;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5782:49;;5843:9;5839:120;5862:5;5858:1;:9;5839:120;;;5890:10;:17;5908:5;5915:10;:20;5936:5;5943:6;;;;;;;;;;;5915:35;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5890:61;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5882:69;;5869:3;;;;;:::i;:::-;;;;5839:120;;;;5974:5;5981:3;5986:6;5966:27;;;;;;;;;4945:1054;;;;;;:::o;4500:162:5:-;4597:4;4620:18;:25;4639:5;4620:25;;;;;;;;;;;;;;;:35;4646:8;4620:35;;;;;;;;;;;;;;;;;;;;;;;;;4613:42;;4500:162;;;;:::o;2731:27:7:-;;;;:::o;1839:189:17:-;1189:12;:10;:12::i;:::-;1178:23;;:7;:5;:7::i;:::-;:23;;;1170:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;1947:1:::1;1927:22;;:8;:22;;;;1919:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;2002:19;2012:8;2002:9;:19::i;:::-;1839:189:::0;:::o;7506:954:7:-;1680:1:18;2259:7;;:19;;2251:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;1680:1;2389:7;:18;;;;7591:7:7::1;:5;:7::i;:::-;7575:23;;:12;:10;:12::i;:::-;:23;;;7572:688;;;7643:16;;7637:2;7616:18;;:23;;;;:::i;:::-;7615:44;7607:82;;;;;;;;;;;;:::i;:::-;;;;;;;;;7572:688;;;7725:1;7711:11;;:15;7708:88;;;7751:11;;7745:2;:17;;7737:50;;;;;;;;;;;;:::i;:::-;;;;;;;;;7708:88;7835:12;;7828:2;7812:13;:11;:13::i;:::-;:18;;;;:::i;:::-;7811:36;;7803:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;7894:9;7887:2;7876:8;;:13;;;;:::i;:::-;7875:28;;7867:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;7945:9;;;;;;;;;;;:21;;;7967:12;:10;:12::i;:::-;7945:35;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7937:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;8041:1;8026:12;;:16;8023:144;;;8127:12;;8120:2;8094:23;8104:12;:10;:12::i;:::-;8094:9;:23::i;:::-;:28;;;;:::i;:::-;8093:46;;8085:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;8023:144;8200:1;8190:9;:11;;;;:::i;:::-;8174:12;;:27;;;;;;;:::i;:::-;;;;;;;;8250:1;8240:9;:11;;;;:::i;:::-;8227:9;:25;;;;:::i;:::-;8209:13;;:44;;;;;;;:::i;:::-;;;;;;;;7572:688;8270:9;8266:189;8289:2;8285:1;:6;8266:189;;;8305:38;8315:12;:10;:12::i;:::-;8329:13;:11;:13::i;:::-;8305:9;:38::i;:::-;8363:5;:22;8383:1;8369:13;:11;:13::i;:::-;:15;;;;:::i;:::-;8363:22;;;;;;;;;;;8391:56;;;;;;;;8396:15;8391:56;;;;8413:1;8391:56;;;;8416:9;;;;;;;;;;;:16;;;8433:12;:10;:12::i;:::-;8416:30;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8391:56;;::::0;8363:85:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;8293:3;;;;;:::i;:::-;;;;8266:189;;;;1637:1:18::0;2562:7;:22;;;;7506:954:7;:::o;1431:300:5:-;1533:4;1583:25;1568:40;;;:11;:40;;;;:104;;;;1639:33;1624:48;;;:11;:48;;;;1568:104;:156;;;;1688:36;1712:11;1688:23;:36::i;:::-;1568:156;1549:175;;1431:300;;;:::o;7157:125::-;7222:4;7273:1;7245:30;;:7;:16;7253:7;7245:16;;;;;;;;;;;;;;;;;;;;;:30;;;;7238:37;;7157:125;;;:::o;587:96:2:-;640:7;666:10;659:17;;587:96;:::o;11008:171:5:-;11109:2;11082:15;:24;11098:7;11082:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;11164:7;11160:2;11126:46;;11135:23;11150:7;11135:14;:23::i;:::-;11126:46;;;;;;;;;;;;11008:171;;:::o;7440:344::-;7533:4;7557:16;7565:7;7557;:16::i;:::-;7549:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;7632:13;7648:23;7663:7;7648:14;:23::i;:::-;7632:39;;7700:5;7689:16;;:7;:16;;;:51;;;;7733:7;7709:31;;:20;7721:7;7709:11;:20::i;:::-;:31;;;7689:51;:87;;;;7744:32;7761:5;7768:7;7744:16;:32::i;:::-;7689:87;7681:96;;;7440:344;;;;:::o;10337:560::-;10491:4;10464:31;;:23;10479:7;10464:14;:23::i;:::-;:31;;;10456:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;10573:1;10559:16;;:2;:16;;;;10551:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;10627:39;10648:4;10654:2;10658:7;10627:20;:39::i;:::-;10728:29;10745:1;10749:7;10728:8;:29::i;:::-;10787:1;10768:9;:15;10778:4;10768:15;;;;;;;;;;;;;;;;:20;;;;;;;:::i;:::-;;;;;;;;10815:1;10798:9;:13;10808:2;10798:13;;;;;;;;;;;;;;;;:18;;;;;;;:::i;:::-;;;;;;;;10845:2;10826:7;:16;10834:7;10826:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;10882:7;10878:2;10863:27;;10872:4;10863:27;;;;;;;;;;;;10337:560;;;:::o;2034:169:17:-;2089:16;2108:6;;;;;;;;;;;2089:25;;2133:8;2124:6;;:17;;;;;;;;;;;;;;;;;;2187:8;2156:40;;2177:8;2156:40;;;;;;;;;;;;2079:124;2034:169;:::o;6547:307:5:-;6698:28;6708:4;6714:2;6718:7;6698:9;:28::i;:::-;6744:48;6767:4;6773:2;6777:7;6786:5;6744:22;:48::i;:::-;6736:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;6547:307;;;;:::o;8114:108::-;8189:26;8199:2;8203:7;8189:26;;;;;;;;;;;;:9;:26::i;:::-;8114:108;;:::o;763:155:4:-;848:4;886:25;871:40;;;:11;:40;;;;864:47;;763:155;;;:::o;2544:572:6:-;2683:45;2710:4;2716:2;2720:7;2683:26;:45::i;:::-;2759:1;2743:18;;:4;:18;;;2739:183;;;2777:40;2809:7;2777:31;:40::i;:::-;2739:183;;;2846:2;2838:10;;:4;:10;;;2834:88;;2864:47;2897:4;2903:7;2864:32;:47::i;:::-;2834:88;2739:183;2949:1;2935:16;;:2;:16;;;2931:179;;;2967:45;3004:7;2967:36;:45::i;:::-;2931:179;;;3039:4;3033:10;;:2;:10;;;3029:81;;3059:40;3087:2;3091:7;3059:27;:40::i;:::-;3029:81;2931:179;2544:572;;;:::o;11732:778:5:-;11882:4;11902:15;:2;:13;;;:15::i;:::-;11898:606;;;11953:2;11937:36;;;11974:12;:10;:12::i;:::-;11988:4;11994:7;12003:5;11937:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;11933:519;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12193:1;12176:6;:13;:18;12172:266;;;12218:60;;;;;;;;;;:::i;:::-;;;;;;;;12172:266;12390:6;12384:13;12375:6;12371:2;12367:15;12360:38;11933:519;12069:41;;;12059:51;;;:6;:51;;;;12052:58;;;;;11898:606;12489:4;12482:11;;11732:778;;;;;;;:::o;8443:311::-;8568:18;8574:2;8578:7;8568:5;:18::i;:::-;8617:54;8648:1;8652:2;8656:7;8665:5;8617:22;:54::i;:::-;8596:151;;;;;;;;;;;;:::i;:::-;;;;;;;;;8443:311;;;:::o;13066:122::-;;;;:::o;3822:161:6:-;3925:10;:17;;;;3898:15;:24;3914:7;3898:24;;;;;;;;;;;:44;;;;3952:10;3968:7;3952:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3822:161;:::o;4600:970::-;4862:22;4912:1;4887:22;4904:4;4887:16;:22::i;:::-;:26;;;;:::i;:::-;4862:51;;4923:18;4944:17;:26;4962:7;4944:26;;;;;;;;;;;;4923:47;;5088:14;5074:10;:28;5070:323;;5118:19;5140:12;:18;5153:4;5140:18;;;;;;;;;;;;;;;:34;5159:14;5140:34;;;;;;;;;;;;5118:56;;5222:11;5189:12;:18;5202:4;5189:18;;;;;;;;;;;;;;;:30;5208:10;5189:30;;;;;;;;;;;:44;;;;5338:10;5305:17;:30;5323:11;5305:30;;;;;;;;;;;:43;;;;5104:289;5070:323;5486:17;:26;5504:7;5486:26;;;;;;;;;;;5479:33;;;5529:12;:18;5542:4;5529:18;;;;;;;;;;;;;;;:34;5548:14;5529:34;;;;;;;;;;;5522:41;;;4681:889;;4600:970;;:::o;5858:1061::-;6107:22;6152:1;6132:10;:17;;;;:21;;;;:::i;:::-;6107:46;;6163:18;6184:15;:24;6200:7;6184:24;;;;;;;;;;;;6163:45;;6530:19;6552:10;6563:14;6552:26;;;;;;;;:::i;:::-;;;;;;;;;;6530:48;;6614:11;6589:10;6600;6589:22;;;;;;;;:::i;:::-;;;;;;;;;:36;;;;6724:10;6693:15;:28;6709:11;6693:28;;;;;;;;;;;:41;;;;6862:15;:24;6878:7;6862:24;;;;;;;;;;;6855:31;;;6896:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;5929:990;;;5858:1061;:::o;3410:217::-;3494:14;3511:20;3528:2;3511:16;:20::i;:::-;3494:37;;3568:7;3541:12;:16;3554:2;3541:16;;;;;;;;;;;;;;;:24;3558:6;3541:24;;;;;;;;;;;:34;;;;3614:6;3585:17;:26;3603:7;3585:26;;;;;;;;;;;:35;;;;3484:143;3410:217;;:::o;718:377:0:-;778:4;981:12;1046:7;1034:20;1026:28;;1087:1;1080:4;:8;1073:15;;;718:377;;;:::o;9076:372:5:-;9169:1;9155:16;;:2;:16;;;;9147:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;9227:16;9235:7;9227;:16::i;:::-;9226:17;9218:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;9287:45;9316:1;9320:2;9324:7;9287:20;:45::i;:::-;9360:1;9343:9;:13;9353:2;9343:13;;;;;;;;;;;;;;;;:18;;;;;;;:::i;:::-;;;;;;;;9390:2;9371:7;:16;9379:7;9371:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;9433:7;9429:2;9408:33;;9425:1;9408:33;;;;;;;;;;;;9076:372;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;26:744:22:-;152:5;177:100;193:83;269:6;193:83;:::i;:::-;177:100;:::i;:::-;168:109;;297:5;323:6;375:3;365:6;357;353:19;348:3;344:29;341:38;338:2;;;394:79;;:::i;:::-;338:2;507:1;492:272;517:6;514:1;511:13;492:272;;;585:3;614:69;679:3;667:10;614:69;:::i;:::-;609:3;602:82;713:4;708:3;704:14;697:21;;747:6;742:3;738:16;731:23;;552:212;539:1;536;532:9;527:14;;492:272;;;496:14;158:612;;;;;;;:::o;792:972::-;909:5;934:91;950:74;1017:6;950:74;:::i;:::-;934:91;:::i;:::-;925:100;;1045:5;1074:6;1067:5;1060:21;1108:4;1101:5;1097:16;1090:23;;1134:6;1184:3;1176:4;1168:6;1164:17;1159:3;1155:27;1152:36;1149:2;;;1203:79;;:::i;:::-;1149:2;1316:1;1301:457;1326:6;1323:1;1320:13;1301:457;;;1401:3;1395:10;1437:18;1424:11;1421:35;1418:2;;;1459:79;;:::i;:::-;1418:2;1583:11;1575:6;1571:24;1621:58;1675:3;1663:10;1621:58;:::i;:::-;1616:3;1609:71;1709:4;1704:3;1700:14;1693:21;;1743:4;1738:3;1734:14;1727:21;;1361:397;;1348:1;1345;1341:9;1336:14;;1301:457;;;1305:14;915:849;;;;;;;:::o;1786:671::-;1889:5;1914:77;1930:60;1983:6;1930:60;:::i;:::-;1914:77;:::i;:::-;1905:86;;2011:5;2037:6;2087:3;2079:4;2071:6;2067:17;2062:3;2058:27;2055:36;2052:2;;;2106:79;;:::i;:::-;2052:2;2219:1;2204:247;2229:6;2226:1;2223:13;2204:247;;;2297:3;2326:46;2368:3;2356:10;2326:46;:::i;:::-;2321:3;2314:59;2402:4;2397:3;2393:14;2386:21;;2436:4;2431:3;2427:14;2420:21;;2264:187;2251:1;2248;2244:9;2239:14;;2204:247;;;2208:14;1895:562;;;;;;;:::o;2463:410::-;2540:5;2565:65;2581:48;2622:6;2581:48;:::i;:::-;2565:65;:::i;:::-;2556:74;;2653:6;2646:5;2639:21;2691:4;2684:5;2680:16;2729:3;2720:6;2715:3;2711:16;2708:25;2705:2;;;2736:79;;:::i;:::-;2705:2;2826:41;2860:6;2855:3;2850;2826:41;:::i;:::-;2546:327;;;;;;:::o;2879:421::-;2968:5;2993:66;3009:49;3051:6;3009:49;:::i;:::-;2993:66;:::i;:::-;2984:75;;3082:6;3075:5;3068:21;3120:4;3113:5;3109:16;3158:3;3149:6;3144:3;3140:16;3137:25;3134:2;;;3165:79;;:::i;:::-;3134:2;3255:39;3287:6;3282:3;3277;3255:39;:::i;:::-;2974:326;;;;;;:::o;3306:139::-;3352:5;3390:6;3377:20;3368:29;;3406:33;3433:5;3406:33;:::i;:::-;3358:87;;;;:::o;3470:403::-;3571:5;3620:3;3613:4;3605:6;3601:17;3597:27;3587:2;;3628:79;;:::i;:::-;3587:2;3732:4;3754:113;3863:3;3855:6;3847;3754:113;:::i;:::-;3745:122;;3577:296;;;;;:::o;3895:405::-;3987:5;4036:3;4029:4;4021:6;4017:17;4013:27;4003:2;;4044:79;;:::i;:::-;4003:2;4154:6;4148:13;4179:115;4290:3;4282:6;4275:4;4267:6;4263:17;4179:115;:::i;:::-;4170:124;;3993:307;;;;;:::o;4322:357::-;4400:5;4449:3;4442:4;4434:6;4430:17;4426:27;4416:2;;4457:79;;:::i;:::-;4416:2;4561:4;4583:90;4669:3;4661:6;4653;4583:90;:::i;:::-;4574:99;;4406:273;;;;;:::o;4685:133::-;4728:5;4766:6;4753:20;4744:29;;4782:30;4806:5;4782:30;:::i;:::-;4734:84;;;;:::o;4824:137::-;4878:5;4909:6;4903:13;4894:22;;4925:30;4949:5;4925:30;:::i;:::-;4884:77;;;;:::o;4967:137::-;5012:5;5050:6;5037:20;5028:29;;5066:32;5092:5;5066:32;:::i;:::-;5018:86;;;;:::o;5110:141::-;5166:5;5197:6;5191:13;5182:22;;5213:32;5239:5;5213:32;:::i;:::-;5172:79;;;;:::o;5270:338::-;5325:5;5374:3;5367:4;5359:6;5355:17;5351:27;5341:2;;5382:79;;:::i;:::-;5341:2;5499:6;5486:20;5524:78;5598:3;5590:6;5583:4;5575:6;5571:17;5524:78;:::i;:::-;5515:87;;5331:277;;;;;:::o;5628:355::-;5695:5;5744:3;5737:4;5729:6;5725:17;5721:27;5711:2;;5752:79;;:::i;:::-;5711:2;5862:6;5856:13;5887:90;5973:3;5965:6;5958:4;5950:6;5946:17;5887:90;:::i;:::-;5878:99;;5701:282;;;;;:::o;5989:139::-;6035:5;6073:6;6060:20;6051:29;;6089:33;6116:5;6089:33;:::i;:::-;6041:87;;;;:::o;6134:143::-;6191:5;6222:6;6216:13;6207:22;;6238:33;6265:5;6238:33;:::i;:::-;6197:80;;;;:::o;6283:139::-;6338:5;6369:6;6363:13;6354:22;;6385:31;6410:5;6385:31;:::i;:::-;6344:78;;;;:::o;6428:329::-;6487:6;6536:2;6524:9;6515:7;6511:23;6507:32;6504:2;;;6542:79;;:::i;:::-;6504:2;6662:1;6687:53;6732:7;6723:6;6712:9;6708:22;6687:53;:::i;:::-;6677:63;;6633:117;6494:263;;;;:::o;6763:474::-;6831:6;6839;6888:2;6876:9;6867:7;6863:23;6859:32;6856:2;;;6894:79;;:::i;:::-;6856:2;7014:1;7039:53;7084:7;7075:6;7064:9;7060:22;7039:53;:::i;:::-;7029:63;;6985:117;7141:2;7167:53;7212:7;7203:6;7192:9;7188:22;7167:53;:::i;:::-;7157:63;;7112:118;6846:391;;;;;:::o;7243:619::-;7320:6;7328;7336;7385:2;7373:9;7364:7;7360:23;7356:32;7353:2;;;7391:79;;:::i;:::-;7353:2;7511:1;7536:53;7581:7;7572:6;7561:9;7557:22;7536:53;:::i;:::-;7526:63;;7482:117;7638:2;7664:53;7709:7;7700:6;7689:9;7685:22;7664:53;:::i;:::-;7654:63;;7609:118;7766:2;7792:53;7837:7;7828:6;7817:9;7813:22;7792:53;:::i;:::-;7782:63;;7737:118;7343:519;;;;;:::o;7868:943::-;7963:6;7971;7979;7987;8036:3;8024:9;8015:7;8011:23;8007:33;8004:2;;;8043:79;;:::i;:::-;8004:2;8163:1;8188:53;8233:7;8224:6;8213:9;8209:22;8188:53;:::i;:::-;8178:63;;8134:117;8290:2;8316:53;8361:7;8352:6;8341:9;8337:22;8316:53;:::i;:::-;8306:63;;8261:118;8418:2;8444:53;8489:7;8480:6;8469:9;8465:22;8444:53;:::i;:::-;8434:63;;8389:118;8574:2;8563:9;8559:18;8546:32;8605:18;8597:6;8594:30;8591:2;;;8627:79;;:::i;:::-;8591:2;8732:62;8786:7;8777:6;8766:9;8762:22;8732:62;:::i;:::-;8722:72;;8517:287;7994:817;;;;;;;:::o;8817:468::-;8882:6;8890;8939:2;8927:9;8918:7;8914:23;8910:32;8907:2;;;8945:79;;:::i;:::-;8907:2;9065:1;9090:53;9135:7;9126:6;9115:9;9111:22;9090:53;:::i;:::-;9080:63;;9036:117;9192:2;9218:50;9260:7;9251:6;9240:9;9236:22;9218:50;:::i;:::-;9208:60;;9163:115;8897:388;;;;;:::o;9291:474::-;9359:6;9367;9416:2;9404:9;9395:7;9391:23;9387:32;9384:2;;;9422:79;;:::i;:::-;9384:2;9542:1;9567:53;9612:7;9603:6;9592:9;9588:22;9567:53;:::i;:::-;9557:63;;9513:117;9669:2;9695:53;9740:7;9731:6;9720:9;9716:22;9695:53;:::i;:::-;9685:63;;9640:118;9374:391;;;;;:::o;9771:441::-;9885:6;9934:4;9922:9;9913:7;9909:23;9905:34;9902:2;;;9942:79;;:::i;:::-;9902:2;10062:1;10087:108;10187:7;10178:6;10167:9;10163:22;10087:108;:::i;:::-;10077:118;;10033:172;9892:320;;;;:::o;10218:574::-;10323:6;10372:2;10360:9;10351:7;10347:23;10343:32;10340:2;;;10378:79;;:::i;:::-;10340:2;10519:1;10508:9;10504:17;10498:24;10549:18;10541:6;10538:30;10535:2;;;10571:79;;:::i;:::-;10535:2;10676:99;10767:7;10758:6;10747:9;10743:22;10676:99;:::i;:::-;10666:109;;10469:316;10330:462;;;;:::o;10798:345::-;10865:6;10914:2;10902:9;10893:7;10889:23;10885:32;10882:2;;;10920:79;;:::i;:::-;10882:2;11040:1;11065:61;11118:7;11109:6;11098:9;11094:22;11065:61;:::i;:::-;11055:71;;11011:125;10872:271;;;;:::o;11149:613::-;11223:6;11231;11239;11288:2;11276:9;11267:7;11263:23;11259:32;11256:2;;;11294:79;;:::i;:::-;11256:2;11414:1;11439:50;11481:7;11472:6;11461:9;11457:22;11439:50;:::i;:::-;11429:60;;11385:114;11538:2;11564:53;11609:7;11600:6;11589:9;11585:22;11564:53;:::i;:::-;11554:63;;11509:118;11666:2;11692:53;11737:7;11728:6;11717:9;11713:22;11692:53;:::i;:::-;11682:63;;11637:118;11246:516;;;;;:::o;11768:327::-;11826:6;11875:2;11863:9;11854:7;11850:23;11846:32;11843:2;;;11881:79;;:::i;:::-;11843:2;12001:1;12026:52;12070:7;12061:6;12050:9;12046:22;12026:52;:::i;:::-;12016:62;;11972:116;11833:262;;;;:::o;12101:349::-;12170:6;12219:2;12207:9;12198:7;12194:23;12190:32;12187:2;;;12225:79;;:::i;:::-;12187:2;12345:1;12370:63;12425:7;12416:6;12405:9;12401:22;12370:63;:::i;:::-;12360:73;;12316:127;12177:273;;;;:::o;12456:524::-;12536:6;12585:2;12573:9;12564:7;12560:23;12556:32;12553:2;;;12591:79;;:::i;:::-;12553:2;12732:1;12721:9;12717:17;12711:24;12762:18;12754:6;12751:30;12748:2;;;12784:79;;:::i;:::-;12748:2;12889:74;12955:7;12946:6;12935:9;12931:22;12889:74;:::i;:::-;12879:84;;12682:291;12543:437;;;;:::o;12986:329::-;13045:6;13094:2;13082:9;13073:7;13069:23;13065:32;13062:2;;;13100:79;;:::i;:::-;13062:2;13220:1;13245:53;13290:7;13281:6;13270:9;13266:22;13245:53;:::i;:::-;13235:63;;13191:117;13052:263;;;;:::o;13321:351::-;13391:6;13440:2;13428:9;13419:7;13415:23;13411:32;13408:2;;;13446:79;;:::i;:::-;13408:2;13566:1;13591:64;13647:7;13638:6;13627:9;13623:22;13591:64;:::i;:::-;13581:74;;13537:128;13398:274;;;;:::o;13678:474::-;13746:6;13754;13803:2;13791:9;13782:7;13778:23;13774:32;13771:2;;;13809:79;;:::i;:::-;13771:2;13929:1;13954:53;13999:7;13990:6;13979:9;13975:22;13954:53;:::i;:::-;13944:63;;13900:117;14056:2;14082:53;14127:7;14118:6;14107:9;14103:22;14082:53;:::i;:::-;14072:63;;14027:118;13761:391;;;;;:::o;14158:265::-;14269:10;14290:88;14374:3;14366:6;14290:88;:::i;:::-;14410:6;14405:3;14401:16;14387:30;;14280:143;;;;:::o;14429:281::-;14548:10;14569:96;14661:3;14653:6;14569:96;:::i;:::-;14697:6;14692:3;14688:16;14674:30;;14559:151;;;;:::o;14716:196::-;14805:10;14840:66;14902:3;14894:6;14840:66;:::i;:::-;14826:80;;14816:96;;;;:::o;14918:212::-;15015:10;15050:74;15120:3;15112:6;15050:74;:::i;:::-;15036:88;;15026:104;;;;:::o;15136:171::-;15201:10;15222:42;15260:3;15252:6;15222:42;:::i;:::-;15296:4;15291:3;15287:14;15273:28;;15212:95;;;;:::o;15313:187::-;15386:10;15407:50;15453:3;15445:6;15407:50;:::i;:::-;15489:4;15484:3;15480:14;15466:28;;15397:103;;;;:::o;15506:118::-;15593:24;15611:5;15593:24;:::i;:::-;15588:3;15581:37;15571:53;;:::o;15664:862::-;15842:73;15909:5;15842:73;:::i;:::-;15931:105;16029:6;16024:3;15931:105;:::i;:::-;15924:112;;16060:75;16129:5;16060:75;:::i;:::-;16158:7;16189:1;16174:345;16199:6;16196:1;16193:13;16174:345;;;16275:6;16269:13;16302:105;16403:3;16388:13;16302:105;:::i;:::-;16295:112;;16430:79;16502:6;16430:79;:::i;:::-;16420:89;;16234:285;16221:1;16218;16214:9;16209:14;;16174:345;;;16178:14;15818:708;;;;;:::o;16566:886::-;16752:73;16819:5;16752:73;:::i;:::-;16841:113;16947:6;16942:3;16841:113;:::i;:::-;16834:120;;16978:75;17047:5;16978:75;:::i;:::-;17076:7;17107:1;17092:353;17117:6;17114:1;17111:13;17092:353;;;17193:6;17187:13;17220:113;17329:3;17314:13;17220:113;:::i;:::-;17213:120;;17356:79;17428:6;17356:79;:::i;:::-;17346:89;;17152:293;17139:1;17136;17132:9;17127:14;;17092:353;;;17096:14;16728:724;;;;;:::o;17486:991::-;17625:3;17654:64;17712:5;17654:64;:::i;:::-;17734:96;17823:6;17818:3;17734:96;:::i;:::-;17727:103;;17856:3;17901:4;17893:6;17889:17;17884:3;17880:27;17931:66;17991:5;17931:66;:::i;:::-;18020:7;18051:1;18036:396;18061:6;18058:1;18055:13;18036:396;;;18132:9;18126:4;18122:20;18117:3;18110:33;18183:6;18177:13;18211:84;18290:4;18275:13;18211:84;:::i;:::-;18203:92;;18318:70;18381:6;18318:70;:::i;:::-;18308:80;;18417:4;18412:3;18408:14;18401:21;;18096:336;18083:1;18080;18076:9;18071:14;;18036:396;;;18040:14;18448:4;18441:11;;18468:3;18461:10;;17630:847;;;;;;;;;:::o;18511:1015::-;18658:3;18687:64;18745:5;18687:64;:::i;:::-;18767:104;18864:6;18859:3;18767:104;:::i;:::-;18760:111;;18897:3;18942:4;18934:6;18930:17;18925:3;18921:27;18972:66;19032:5;18972:66;:::i;:::-;19061:7;19092:1;19077:404;19102:6;19099:1;19096:13;19077:404;;;19173:9;19167:4;19163:20;19158:3;19151:33;19224:6;19218:13;19252:92;19339:4;19324:13;19252:92;:::i;:::-;19244:100;;19367:70;19430:6;19367:70;:::i;:::-;19357:80;;19466:4;19461:3;19457:14;19450:21;;19137:344;19124:1;19121;19117:9;19112:14;;19077:404;;;19081:14;19497:4;19490:11;;19517:3;19510:10;;18663:863;;;;;;;;;:::o;19560:658::-;19682:50;19726:5;19682:50;:::i;:::-;19748:72;19813:6;19808:3;19748:72;:::i;:::-;19741:79;;19844:52;19890:5;19844:52;:::i;:::-;19919:7;19950:1;19935:276;19960:6;19957:1;19954:13;19935:276;;;20036:6;20030:13;20063:59;20118:3;20103:13;20063:59;:::i;:::-;20056:66;;20145:56;20194:6;20145:56;:::i;:::-;20135:66;;19995:216;19982:1;19979;19975:9;19970:14;;19935:276;;;19939:14;19658:560;;;;;:::o;20252:682::-;20382:50;20426:5;20382:50;:::i;:::-;20448:80;20521:6;20516:3;20448:80;:::i;:::-;20441:87;;20552:52;20598:5;20552:52;:::i;:::-;20627:7;20658:1;20643:284;20668:6;20665:1;20662:13;20643:284;;;20744:6;20738:13;20771:67;20834:3;20819:13;20771:67;:::i;:::-;20764:74;;20861:56;20910:6;20861:56;:::i;:::-;20851:66;;20703:224;20690:1;20687;20683:9;20678:14;;20643:284;;;20647:14;20358:576;;;;;:::o;20940:109::-;21021:21;21036:5;21021:21;:::i;:::-;21016:3;21009:34;20999:50;;:::o;21055:360::-;21141:3;21169:38;21201:5;21169:38;:::i;:::-;21223:70;21286:6;21281:3;21223:70;:::i;:::-;21216:77;;21302:52;21347:6;21342:3;21335:4;21328:5;21324:16;21302:52;:::i;:::-;21379:29;21401:6;21379:29;:::i;:::-;21374:3;21370:39;21363:46;;21145:270;;;;;:::o;21421:155::-;21524:45;21563:5;21524:45;:::i;:::-;21519:3;21512:58;21502:74;;:::o;21582:344::-;21660:3;21688:39;21721:5;21688:39;:::i;:::-;21743:61;21797:6;21792:3;21743:61;:::i;:::-;21736:68;;21813:52;21858:6;21853:3;21846:4;21839:5;21835:16;21813:52;:::i;:::-;21890:29;21912:6;21890:29;:::i;:::-;21885:3;21881:39;21874:46;;21664:262;;;;;:::o;21932:364::-;22020:3;22048:39;22081:5;22048:39;:::i;:::-;22103:71;22167:6;22162:3;22103:71;:::i;:::-;22096:78;;22183:52;22228:6;22223:3;22216:4;22209:5;22205:16;22183:52;:::i;:::-;22260:29;22282:6;22260:29;:::i;:::-;22255:3;22251:39;22244:46;;22024:272;;;;;:::o;22302:360::-;22388:3;22416:39;22449:5;22416:39;:::i;:::-;22471:69;22533:6;22528:3;22471:69;:::i;:::-;22464:76;;22549:52;22594:6;22589:3;22582:4;22575:5;22571:16;22549:52;:::i;:::-;22626:29;22648:6;22626:29;:::i;:::-;22621:3;22617:39;22610:46;;22392:270;;;;;:::o;22668:365::-;22810:3;22831:66;22895:1;22890:3;22831:66;:::i;:::-;22824:73;;22906:93;22995:3;22906:93;:::i;:::-;23024:2;23019:3;23015:12;23008:19;;22814:219;;;:::o;23039:365::-;23181:3;23202:66;23266:1;23261:3;23202:66;:::i;:::-;23195:73;;23277:93;23366:3;23277:93;:::i;:::-;23395:2;23390:3;23386:12;23379:19;;23185:219;;;:::o;23410:366::-;23552:3;23573:67;23637:2;23632:3;23573:67;:::i;:::-;23566:74;;23649:93;23738:3;23649:93;:::i;:::-;23767:2;23762:3;23758:12;23751:19;;23556:220;;;:::o;23782:366::-;23924:3;23945:67;24009:2;24004:3;23945:67;:::i;:::-;23938:74;;24021:93;24110:3;24021:93;:::i;:::-;24139:2;24134:3;24130:12;24123:19;;23928:220;;;:::o;24154:366::-;24296:3;24317:67;24381:2;24376:3;24317:67;:::i;:::-;24310:74;;24393:93;24482:3;24393:93;:::i;:::-;24511:2;24506:3;24502:12;24495:19;;24300:220;;;:::o;24526:366::-;24668:3;24689:67;24753:2;24748:3;24689:67;:::i;:::-;24682:74;;24765:93;24854:3;24765:93;:::i;:::-;24883:2;24878:3;24874:12;24867:19;;24672:220;;;:::o;24898:366::-;25040:3;25061:67;25125:2;25120:3;25061:67;:::i;:::-;25054:74;;25137:93;25226:3;25137:93;:::i;:::-;25255:2;25250:3;25246:12;25239:19;;25044:220;;;:::o;25270:366::-;25412:3;25433:67;25497:2;25492:3;25433:67;:::i;:::-;25426:74;;25509:93;25598:3;25509:93;:::i;:::-;25627:2;25622:3;25618:12;25611:19;;25416:220;;;:::o;25642:366::-;25784:3;25805:67;25869:2;25864:3;25805:67;:::i;:::-;25798:74;;25881:93;25970:3;25881:93;:::i;:::-;25999:2;25994:3;25990:12;25983:19;;25788:220;;;:::o;26014:366::-;26156:3;26177:67;26241:2;26236:3;26177:67;:::i;:::-;26170:74;;26253:93;26342:3;26253:93;:::i;:::-;26371:2;26366:3;26362:12;26355:19;;26160:220;;;:::o;26386:366::-;26528:3;26549:67;26613:2;26608:3;26549:67;:::i;:::-;26542:74;;26625:93;26714:3;26625:93;:::i;:::-;26743:2;26738:3;26734:12;26727:19;;26532:220;;;:::o;26758:366::-;26900:3;26921:67;26985:2;26980:3;26921:67;:::i;:::-;26914:74;;26997:93;27086:3;26997:93;:::i;:::-;27115:2;27110:3;27106:12;27099:19;;26904:220;;;:::o;27130:366::-;27272:3;27293:67;27357:2;27352:3;27293:67;:::i;:::-;27286:74;;27369:93;27458:3;27369:93;:::i;:::-;27487:2;27482:3;27478:12;27471:19;;27276:220;;;:::o;27502:366::-;27644:3;27665:67;27729:2;27724:3;27665:67;:::i;:::-;27658:74;;27741:93;27830:3;27741:93;:::i;:::-;27859:2;27854:3;27850:12;27843:19;;27648:220;;;:::o;27874:366::-;28016:3;28037:67;28101:2;28096:3;28037:67;:::i;:::-;28030:74;;28113:93;28202:3;28113:93;:::i;:::-;28231:2;28226:3;28222:12;28215:19;;28020:220;;;:::o;28246:366::-;28388:3;28409:67;28473:2;28468:3;28409:67;:::i;:::-;28402:74;;28485:93;28574:3;28485:93;:::i;:::-;28603:2;28598:3;28594:12;28587:19;;28392:220;;;:::o;28618:366::-;28760:3;28781:67;28845:2;28840:3;28781:67;:::i;:::-;28774:74;;28857:93;28946:3;28857:93;:::i;:::-;28975:2;28970:3;28966:12;28959:19;;28764:220;;;:::o;28990:366::-;29132:3;29153:67;29217:2;29212:3;29153:67;:::i;:::-;29146:74;;29229:93;29318:3;29229:93;:::i;:::-;29347:2;29342:3;29338:12;29331:19;;29136:220;;;:::o;29362:366::-;29504:3;29525:67;29589:2;29584:3;29525:67;:::i;:::-;29518:74;;29601:93;29690:3;29601:93;:::i;:::-;29719:2;29714:3;29710:12;29703:19;;29508:220;;;:::o;29734:366::-;29876:3;29897:67;29961:2;29956:3;29897:67;:::i;:::-;29890:74;;29973:93;30062:3;29973:93;:::i;:::-;30091:2;30086:3;30082:12;30075:19;;29880:220;;;:::o;30106:366::-;30248:3;30269:67;30333:2;30328:3;30269:67;:::i;:::-;30262:74;;30345:93;30434:3;30345:93;:::i;:::-;30463:2;30458:3;30454:12;30447:19;;30252:220;;;:::o;30478:366::-;30620:3;30641:67;30705:2;30700:3;30641:67;:::i;:::-;30634:74;;30717:93;30806:3;30717:93;:::i;:::-;30835:2;30830:3;30826:12;30819:19;;30624:220;;;:::o;30850:365::-;30992:3;31013:66;31077:1;31072:3;31013:66;:::i;:::-;31006:73;;31088:93;31177:3;31088:93;:::i;:::-;31206:2;31201:3;31197:12;31190:19;;30996:219;;;:::o;31221:366::-;31363:3;31384:67;31448:2;31443:3;31384:67;:::i;:::-;31377:74;;31460:93;31549:3;31460:93;:::i;:::-;31578:2;31573:3;31569:12;31562:19;;31367:220;;;:::o;31593:366::-;31735:3;31756:67;31820:2;31815:3;31756:67;:::i;:::-;31749:74;;31832:93;31921:3;31832:93;:::i;:::-;31950:2;31945:3;31941:12;31934:19;;31739:220;;;:::o;31965:366::-;32107:3;32128:67;32192:2;32187:3;32128:67;:::i;:::-;32121:74;;32204:93;32293:3;32204:93;:::i;:::-;32322:2;32317:3;32313:12;32306:19;;32111:220;;;:::o;32337:366::-;32479:3;32500:67;32564:2;32559:3;32500:67;:::i;:::-;32493:74;;32576:93;32665:3;32576:93;:::i;:::-;32694:2;32689:3;32685:12;32678:19;;32483:220;;;:::o;32709:366::-;32851:3;32872:67;32936:2;32931:3;32872:67;:::i;:::-;32865:74;;32948:93;33037:3;32948:93;:::i;:::-;33066:2;33061:3;33057:12;33050:19;;32855:220;;;:::o;33081:366::-;33223:3;33244:67;33308:2;33303:3;33244:67;:::i;:::-;33237:74;;33320:93;33409:3;33320:93;:::i;:::-;33438:2;33433:3;33429:12;33422:19;;33227:220;;;:::o;33453:118::-;33540:24;33558:5;33540:24;:::i;:::-;33535:3;33528:37;33518:53;;:::o;33577:126::-;33672:24;33690:5;33672:24;:::i;:::-;33667:3;33660:37;33650:53;;:::o;33709:102::-;33782:22;33798:5;33782:22;:::i;:::-;33777:3;33770:35;33760:51;;:::o;33817:112::-;33900:22;33916:5;33900:22;:::i;:::-;33895:3;33888:35;33878:51;;:::o;33935:120::-;34026:22;34042:5;34026:22;:::i;:::-;34021:3;34014:35;34004:51;;:::o;34061:110::-;34142:22;34158:5;34142:22;:::i;:::-;34137:3;34130:35;34120:51;;:::o;34177:222::-;34270:4;34308:2;34297:9;34293:18;34285:26;;34321:71;34389:1;34378:9;34374:17;34365:6;34321:71;:::i;:::-;34275:124;;;;:::o;34405:640::-;34600:4;34638:3;34627:9;34623:19;34615:27;;34652:71;34720:1;34709:9;34705:17;34696:6;34652:71;:::i;:::-;34733:72;34801:2;34790:9;34786:18;34777:6;34733:72;:::i;:::-;34815;34883:2;34872:9;34868:18;34859:6;34815:72;:::i;:::-;34934:9;34928:4;34924:20;34919:2;34908:9;34904:18;34897:48;34962:76;35033:4;35024:6;34962:76;:::i;:::-;34954:84;;34605:440;;;;;;;:::o;35051:442::-;35200:4;35238:2;35227:9;35223:18;35215:26;;35251:71;35319:1;35308:9;35304:17;35295:6;35251:71;:::i;:::-;35332:72;35400:2;35389:9;35385:18;35376:6;35332:72;:::i;:::-;35414;35482:2;35471:9;35467:18;35458:6;35414:72;:::i;:::-;35205:288;;;;;;:::o;35499:712::-;35804:4;35842;35831:9;35827:20;35819:28;;35857:167;36021:1;36010:9;36006:17;35997:6;35857:167;:::i;:::-;36034:170;36198:4;36187:9;36183:20;36174:6;36034:170;:::i;:::-;35809:402;;;;;:::o;36217:815::-;36524:4;36562;36551:9;36547:20;36539:28;;36577:159;36733:1;36722:9;36718:17;36709:6;36577:159;:::i;:::-;36785:9;36779:4;36775:20;36768:4;36757:9;36753:20;36746:50;36813:128;36936:4;36927:6;36813:128;:::i;:::-;36805:136;;36951:74;37019:4;37008:9;37004:20;36995:6;36951:74;:::i;:::-;36529:503;;;;;;:::o;37038:528::-;37251:4;37289;37278:9;37274:20;37266:28;;37304:167;37468:1;37457:9;37453:17;37444:6;37304:167;:::i;:::-;37481:78;37553:4;37542:9;37538:20;37529:6;37481:78;:::i;:::-;37256:310;;;;;:::o;37572:210::-;37659:4;37697:2;37686:9;37682:18;37674:26;;37710:65;37772:1;37761:9;37757:17;37748:6;37710:65;:::i;:::-;37664:118;;;;:::o;37788:313::-;37901:4;37939:2;37928:9;37924:18;37916:26;;37988:9;37982:4;37978:20;37974:1;37963:9;37959:17;37952:47;38016:78;38089:4;38080:6;38016:78;:::i;:::-;38008:86;;37906:195;;;;:::o;38107:419::-;38273:4;38311:2;38300:9;38296:18;38288:26;;38360:9;38354:4;38350:20;38346:1;38335:9;38331:17;38324:47;38388:131;38514:4;38388:131;:::i;:::-;38380:139;;38278:248;;;:::o;38532:419::-;38698:4;38736:2;38725:9;38721:18;38713:26;;38785:9;38779:4;38775:20;38771:1;38760:9;38756:17;38749:47;38813:131;38939:4;38813:131;:::i;:::-;38805:139;;38703:248;;;:::o;38957:419::-;39123:4;39161:2;39150:9;39146:18;39138:26;;39210:9;39204:4;39200:20;39196:1;39185:9;39181:17;39174:47;39238:131;39364:4;39238:131;:::i;:::-;39230:139;;39128:248;;;:::o;39382:419::-;39548:4;39586:2;39575:9;39571:18;39563:26;;39635:9;39629:4;39625:20;39621:1;39610:9;39606:17;39599:47;39663:131;39789:4;39663:131;:::i;:::-;39655:139;;39553:248;;;:::o;39807:419::-;39973:4;40011:2;40000:9;39996:18;39988:26;;40060:9;40054:4;40050:20;40046:1;40035:9;40031:17;40024:47;40088:131;40214:4;40088:131;:::i;:::-;40080:139;;39978:248;;;:::o;40232:419::-;40398:4;40436:2;40425:9;40421:18;40413:26;;40485:9;40479:4;40475:20;40471:1;40460:9;40456:17;40449:47;40513:131;40639:4;40513:131;:::i;:::-;40505:139;;40403:248;;;:::o;40657:419::-;40823:4;40861:2;40850:9;40846:18;40838:26;;40910:9;40904:4;40900:20;40896:1;40885:9;40881:17;40874:47;40938:131;41064:4;40938:131;:::i;:::-;40930:139;;40828:248;;;:::o;41082:419::-;41248:4;41286:2;41275:9;41271:18;41263:26;;41335:9;41329:4;41325:20;41321:1;41310:9;41306:17;41299:47;41363:131;41489:4;41363:131;:::i;:::-;41355:139;;41253:248;;;:::o;41507:419::-;41673:4;41711:2;41700:9;41696:18;41688:26;;41760:9;41754:4;41750:20;41746:1;41735:9;41731:17;41724:47;41788:131;41914:4;41788:131;:::i;:::-;41780:139;;41678:248;;;:::o;41932:419::-;42098:4;42136:2;42125:9;42121:18;42113:26;;42185:9;42179:4;42175:20;42171:1;42160:9;42156:17;42149:47;42213:131;42339:4;42213:131;:::i;:::-;42205:139;;42103:248;;;:::o;42357:419::-;42523:4;42561:2;42550:9;42546:18;42538:26;;42610:9;42604:4;42600:20;42596:1;42585:9;42581:17;42574:47;42638:131;42764:4;42638:131;:::i;:::-;42630:139;;42528:248;;;:::o;42782:419::-;42948:4;42986:2;42975:9;42971:18;42963:26;;43035:9;43029:4;43025:20;43021:1;43010:9;43006:17;42999:47;43063:131;43189:4;43063:131;:::i;:::-;43055:139;;42953:248;;;:::o;43207:419::-;43373:4;43411:2;43400:9;43396:18;43388:26;;43460:9;43454:4;43450:20;43446:1;43435:9;43431:17;43424:47;43488:131;43614:4;43488:131;:::i;:::-;43480:139;;43378:248;;;:::o;43632:419::-;43798:4;43836:2;43825:9;43821:18;43813:26;;43885:9;43879:4;43875:20;43871:1;43860:9;43856:17;43849:47;43913:131;44039:4;43913:131;:::i;:::-;43905:139;;43803:248;;;:::o;44057:419::-;44223:4;44261:2;44250:9;44246:18;44238:26;;44310:9;44304:4;44300:20;44296:1;44285:9;44281:17;44274:47;44338:131;44464:4;44338:131;:::i;:::-;44330:139;;44228:248;;;:::o;44482:419::-;44648:4;44686:2;44675:9;44671:18;44663:26;;44735:9;44729:4;44725:20;44721:1;44710:9;44706:17;44699:47;44763:131;44889:4;44763:131;:::i;:::-;44755:139;;44653:248;;;:::o;44907:419::-;45073:4;45111:2;45100:9;45096:18;45088:26;;45160:9;45154:4;45150:20;45146:1;45135:9;45131:17;45124:47;45188:131;45314:4;45188:131;:::i;:::-;45180:139;;45078:248;;;:::o;45332:419::-;45498:4;45536:2;45525:9;45521:18;45513:26;;45585:9;45579:4;45575:20;45571:1;45560:9;45556:17;45549:47;45613:131;45739:4;45613:131;:::i;:::-;45605:139;;45503:248;;;:::o;45757:419::-;45923:4;45961:2;45950:9;45946:18;45938:26;;46010:9;46004:4;46000:20;45996:1;45985:9;45981:17;45974:47;46038:131;46164:4;46038:131;:::i;:::-;46030:139;;45928:248;;;:::o;46182:419::-;46348:4;46386:2;46375:9;46371:18;46363:26;;46435:9;46429:4;46425:20;46421:1;46410:9;46406:17;46399:47;46463:131;46589:4;46463:131;:::i;:::-;46455:139;;46353:248;;;:::o;46607:419::-;46773:4;46811:2;46800:9;46796:18;46788:26;;46860:9;46854:4;46850:20;46846:1;46835:9;46831:17;46824:47;46888:131;47014:4;46888:131;:::i;:::-;46880:139;;46778:248;;;:::o;47032:419::-;47198:4;47236:2;47225:9;47221:18;47213:26;;47285:9;47279:4;47275:20;47271:1;47260:9;47256:17;47249:47;47313:131;47439:4;47313:131;:::i;:::-;47305:139;;47203:248;;;:::o;47457:419::-;47623:4;47661:2;47650:9;47646:18;47638:26;;47710:9;47704:4;47700:20;47696:1;47685:9;47681:17;47674:47;47738:131;47864:4;47738:131;:::i;:::-;47730:139;;47628:248;;;:::o;47882:419::-;48048:4;48086:2;48075:9;48071:18;48063:26;;48135:9;48129:4;48125:20;48121:1;48110:9;48106:17;48099:47;48163:131;48289:4;48163:131;:::i;:::-;48155:139;;48053:248;;;:::o;48307:419::-;48473:4;48511:2;48500:9;48496:18;48488:26;;48560:9;48554:4;48550:20;48546:1;48535:9;48531:17;48524:47;48588:131;48714:4;48588:131;:::i;:::-;48580:139;;48478:248;;;:::o;48732:419::-;48898:4;48936:2;48925:9;48921:18;48913:26;;48985:9;48979:4;48975:20;48971:1;48960:9;48956:17;48949:47;49013:131;49139:4;49013:131;:::i;:::-;49005:139;;48903:248;;;:::o;49157:419::-;49323:4;49361:2;49350:9;49346:18;49338:26;;49410:9;49404:4;49400:20;49396:1;49385:9;49381:17;49374:47;49438:131;49564:4;49438:131;:::i;:::-;49430:139;;49328:248;;;:::o;49582:419::-;49748:4;49786:2;49775:9;49771:18;49763:26;;49835:9;49829:4;49825:20;49821:1;49810:9;49806:17;49799:47;49863:131;49989:4;49863:131;:::i;:::-;49855:139;;49753:248;;;:::o;50007:419::-;50173:4;50211:2;50200:9;50196:18;50188:26;;50260:9;50254:4;50250:20;50246:1;50235:9;50231:17;50224:47;50288:131;50414:4;50288:131;:::i;:::-;50280:139;;50178:248;;;:::o;50432:222::-;50525:4;50563:2;50552:9;50548:18;50540:26;;50576:71;50644:1;50633:9;50629:17;50620:6;50576:71;:::i;:::-;50530:124;;;;:::o;50660:1117::-;51047:4;51085;51074:9;51070:20;51062:28;;51100:79;51176:1;51165:9;51161:17;51152:6;51100:79;:::i;:::-;51189:168;51353:2;51342:9;51338:18;51329:6;51189:168;:::i;:::-;51406:9;51400:4;51396:20;51389:4;51378:9;51374:20;51367:50;51434:136;51565:4;51556:6;51434:136;:::i;:::-;51426:144;;51580:90;51664:4;51653:9;51649:20;51640:6;51580:90;:::i;:::-;51680;51764:4;51753:9;51749:20;51740:6;51680:90;:::i;:::-;51052:725;;;;;;;;:::o;51783:1085::-;52154:4;52192;52181:9;52177:20;52169:28;;52207:79;52283:1;52272:9;52268:17;52259:6;52207:79;:::i;:::-;52296:168;52460:2;52449:9;52445:18;52436:6;52296:168;:::i;:::-;52513:9;52507:4;52503:20;52496:4;52485:9;52481:20;52474:50;52541:136;52672:4;52663:6;52541:136;:::i;:::-;52533:144;;52687:82;52763:4;52752:9;52748:20;52739:6;52687:82;:::i;:::-;52779;52855:4;52844:9;52840:20;52831:6;52779:82;:::i;:::-;52159:709;;;;;;;;:::o;52874:332::-;52995:4;53033:2;53022:9;53018:18;53010:26;;53046:71;53114:1;53103:9;53099:17;53090:6;53046:71;:::i;:::-;53127:72;53195:2;53184:9;53180:18;53171:6;53127:72;:::i;:::-;53000:206;;;;;:::o;53212:625::-;53427:4;53465:2;53454:9;53450:18;53442:26;;53478:71;53546:1;53535:9;53531:17;53522:6;53478:71;:::i;:::-;53559:68;53623:2;53612:9;53608:18;53599:6;53559:68;:::i;:::-;53674:9;53668:4;53664:20;53659:2;53648:9;53644:18;53637:48;53702:128;53825:4;53816:6;53702:128;:::i;:::-;53694:136;;53432:405;;;;;;:::o;53843:214::-;53932:4;53970:2;53959:9;53955:18;53947:26;;53983:67;54047:1;54036:9;54032:17;54023:6;53983:67;:::i;:::-;53937:120;;;;:::o;54063:129::-;54097:6;54124:20;;:::i;:::-;54114:30;;54153:33;54181:4;54173:6;54153:33;:::i;:::-;54104:88;;;:::o;54198:75::-;54231:6;54264:2;54258:9;54248:19;;54238:35;:::o;54279:270::-;54375:4;54465:18;54457:6;54454:30;54451:2;;;54487:18;;:::i;:::-;54451:2;54537:4;54529:6;54525:17;54517:25;;54380:169;;;:::o;54555:321::-;54642:4;54732:18;54724:6;54721:30;54718:2;;;54754:18;;:::i;:::-;54718:2;54804:4;54796:6;54792:17;54784:25;;54864:4;54858;54854:15;54846:23;;54647:229;;;:::o;54882:247::-;54955:4;55045:18;55037:6;55034:30;55031:2;;;55067:18;;:::i;:::-;55031:2;55117:4;55109:6;55105:17;55097:25;;54960:169;;;:::o;55135:307::-;55196:4;55286:18;55278:6;55275:30;55272:2;;;55308:18;;:::i;:::-;55272:2;55346:29;55368:6;55346:29;:::i;:::-;55338:37;;55430:4;55424;55420:15;55412:23;;55201:241;;;:::o;55448:308::-;55510:4;55600:18;55592:6;55589:30;55586:2;;;55622:18;;:::i;:::-;55586:2;55660:29;55682:6;55660:29;:::i;:::-;55652:37;;55744:4;55738;55734:15;55726:23;;55515:241;;;:::o;55762:119::-;55848:4;55871:3;55863:11;;55853:28;;;:::o;55887:142::-;55964:4;55987:3;55979:11;;56017:4;56012:3;56008:14;56000:22;;55969:60;;;:::o;56035:96::-;56098:4;56121:3;56113:11;;56103:28;;;:::o;56137:125::-;56223:6;56251:4;56241:14;;56230:32;;;:::o;56268:124::-;56345:6;56379:5;56373:12;56363:22;;56352:40;;;:::o;56398:102::-;56461:6;56489:4;56479:14;;56468:32;;;:::o;56506:98::-;56557:6;56591:5;56585:12;56575:22;;56564:40;;;:::o;56610:99::-;56662:6;56696:5;56690:12;56680:22;;56669:40;;;:::o;56715:132::-;56804:4;56836;56831:3;56827:14;56819:22;;56809:38;;;:::o;56853:123::-;56933:4;56965;56960:3;56956:14;56948:22;;56938:38;;;:::o;56982:109::-;57048:4;57080;57075:3;57071:14;57063:22;;57053:38;;;:::o;57097:164::-;57215:11;57252:3;57237:18;;57227:34;;;;:::o;57267:172::-;57393:11;57430:3;57415:18;;57405:34;;;;:::o;57445:194::-;57554:11;57588:6;57583:3;57576:19;57628:4;57623:3;57619:14;57604:29;;57566:73;;;;:::o;57645:202::-;57762:11;57796:6;57791:3;57784:19;57836:4;57831:3;57827:14;57812:29;;57774:73;;;;:::o;57853:131::-;57938:11;57975:3;57960:18;;57950:34;;;;:::o;57990:139::-;58083:11;58120:3;58105:18;;58095:34;;;;:::o;58135:168::-;58218:11;58252:6;58247:3;58240:19;58292:4;58287:3;58283:14;58268:29;;58230:73;;;;:::o;58309:159::-;58383:11;58417:6;58412:3;58405:19;58457:4;58452:3;58448:14;58433:29;;58395:73;;;;:::o;58474:169::-;58558:11;58592:6;58587:3;58580:19;58632:4;58627:3;58623:14;58608:29;;58570:73;;;;:::o;58649:167::-;58731:11;58765:6;58760:3;58753:19;58805:4;58800:3;58796:14;58781:29;;58743:73;;;;:::o;58822:305::-;58862:3;58881:20;58899:1;58881:20;:::i;:::-;58876:25;;58915:20;58933:1;58915:20;:::i;:::-;58910:25;;59069:1;59001:66;58997:74;58994:1;58991:81;58988:2;;;59075:18;;:::i;:::-;58988:2;59119:1;59116;59112:9;59105:16;;58866:261;;;;:::o;59133:185::-;59173:1;59190:20;59208:1;59190:20;:::i;:::-;59185:25;;59224:20;59242:1;59224:20;:::i;:::-;59219:25;;59263:1;59253:2;;59268:18;;:::i;:::-;59253:2;59310:1;59307;59303:9;59298:14;;59175:143;;;;:::o;59324:348::-;59364:7;59387:20;59405:1;59387:20;:::i;:::-;59382:25;;59421:20;59439:1;59421:20;:::i;:::-;59416:25;;59609:1;59541:66;59537:74;59534:1;59531:81;59526:1;59519:9;59512:17;59508:105;59505:2;;;59616:18;;:::i;:::-;59505:2;59664:1;59661;59657:9;59646:20;;59372:300;;;;:::o;59678:191::-;59718:4;59738:20;59756:1;59738:20;:::i;:::-;59733:25;;59772:20;59790:1;59772:20;:::i;:::-;59767:25;;59811:1;59808;59805:8;59802:2;;;59816:18;;:::i;:::-;59802:2;59861:1;59858;59854:9;59846:17;;59723:146;;;;:::o;59875:96::-;59912:7;59941:24;59959:5;59941:24;:::i;:::-;59930:35;;59920:51;;;:::o;59977:90::-;60011:7;60054:5;60047:13;60040:21;60029:32;;60019:48;;;:::o;60073:149::-;60109:7;60149:66;60142:5;60138:78;60127:89;;60117:105;;;:::o;60228:126::-;60265:7;60305:42;60298:5;60294:54;60283:65;;60273:81;;;:::o;60360:77::-;60397:7;60426:5;60415:16;;60405:32;;;:::o;60443:86::-;60478:7;60518:4;60511:5;60507:16;60496:27;;60486:43;;;:::o;60535:121::-;60593:9;60626:24;60644:5;60626:24;:::i;:::-;60613:37;;60603:53;;;:::o;60662:154::-;60746:6;60741:3;60736;60723:30;60808:1;60799:6;60794:3;60790:16;60783:27;60713:103;;;:::o;60822:307::-;60890:1;60900:113;60914:6;60911:1;60908:13;60900:113;;;60999:1;60994:3;60990:11;60984:18;60980:1;60975:3;60971:11;60964:39;60936:2;60933:1;60929:10;60924:15;;60900:113;;;61031:6;61028:1;61025:13;61022:2;;;61111:1;61102:6;61097:3;61093:16;61086:27;61022:2;60871:258;;;;:::o;61135:320::-;61179:6;61216:1;61210:4;61206:12;61196:22;;61263:1;61257:4;61253:12;61284:18;61274:2;;61340:4;61332:6;61328:17;61318:27;;61274:2;61402;61394:6;61391:14;61371:18;61368:38;61365:2;;;61421:18;;:::i;:::-;61365:2;61186:269;;;;:::o;61461:281::-;61544:27;61566:4;61544:27;:::i;:::-;61536:6;61532:40;61674:6;61662:10;61659:22;61638:18;61626:10;61623:34;61620:62;61617:2;;;61685:18;;:::i;:::-;61617:2;61725:10;61721:2;61714:22;61504:238;;;:::o;61748:233::-;61787:3;61810:24;61828:5;61810:24;:::i;:::-;61801:33;;61856:66;61849:5;61846:77;61843:2;;;61926:18;;:::i;:::-;61843:2;61973:1;61966:5;61962:13;61955:20;;61791:190;;;:::o;61987:180::-;62035:77;62032:1;62025:88;62132:4;62129:1;62122:15;62156:4;62153:1;62146:15;62173:180;62221:77;62218:1;62211:88;62318:4;62315:1;62308:15;62342:4;62339:1;62332:15;62359:180;62407:77;62404:1;62397:88;62504:4;62501:1;62494:15;62528:4;62525:1;62518:15;62545:180;62593:77;62590:1;62583:88;62690:4;62687:1;62680:15;62714:4;62711:1;62704:15;62731:180;62779:77;62776:1;62769:88;62876:4;62873:1;62866:15;62900:4;62897:1;62890:15;62917:180;62965:77;62962:1;62955:88;63062:4;63059:1;63052:15;63086:4;63083:1;63076:15;63103:117;63212:1;63209;63202:12;63226:117;63335:1;63332;63325:12;63349:117;63458:1;63455;63448:12;63472:117;63581:1;63578;63571:12;63595:117;63704:1;63701;63694:12;63718:102;63759:6;63810:2;63806:7;63801:2;63794:5;63790:14;63786:28;63776:38;;63766:54;;;:::o;63826:158::-;63966:10;63962:1;63954:6;63950:14;63943:34;63932:52;:::o;63990:157::-;64130:9;64126:1;64118:6;64114:14;64107:33;64096:51;:::o;64153:180::-;64293:32;64289:1;64281:6;64277:14;64270:56;64259:74;:::o;64339:230::-;64479:34;64475:1;64467:6;64463:14;64456:58;64548:13;64543:2;64535:6;64531:15;64524:38;64445:124;:::o;64575:237::-;64715:34;64711:1;64703:6;64699:14;64692:58;64784:20;64779:2;64771:6;64767:15;64760:45;64681:131;:::o;64818:165::-;64958:17;64954:1;64946:6;64942:14;64935:41;64924:59;:::o;64989:225::-;65129:34;65125:1;65117:6;65113:14;65106:58;65198:8;65193:2;65185:6;65181:15;65174:33;65095:119;:::o;65220:178::-;65360:30;65356:1;65348:6;65344:14;65337:54;65326:72;:::o;65404:223::-;65544:34;65540:1;65532:6;65528:14;65521:58;65613:6;65608:2;65600:6;65596:15;65589:31;65510:117;:::o;65633:175::-;65773:27;65769:1;65761:6;65757:14;65750:51;65739:69;:::o;65814:231::-;65954:34;65950:1;65942:6;65938:14;65931:58;66023:14;66018:2;66010:6;66006:15;65999:39;65920:125;:::o;66051:243::-;66191:34;66187:1;66179:6;66175:14;66168:58;66260:26;66255:2;66247:6;66243:15;66236:51;66157:137;:::o;66300:169::-;66440:21;66436:1;66428:6;66424:14;66417:45;66406:63;:::o;66475:229::-;66615:34;66611:1;66603:6;66599:14;66592:58;66684:12;66679:2;66671:6;66667:15;66660:37;66581:123;:::o;66710:228::-;66850:34;66846:1;66838:6;66834:14;66827:58;66919:11;66914:2;66906:6;66902:15;66895:36;66816:122;:::o;66944:171::-;67084:23;67080:1;67072:6;67068:14;67061:47;67050:65;:::o;67121:182::-;67261:34;67257:1;67249:6;67245:14;67238:58;67227:76;:::o;67309:160::-;67449:12;67445:1;67437:6;67433:14;67426:36;67415:54;:::o;67475:231::-;67615:34;67611:1;67603:6;67599:14;67592:58;67684:14;67679:2;67671:6;67667:15;67660:39;67581:125;:::o;67712:182::-;67852:34;67848:1;67840:6;67836:14;67829:58;67818:76;:::o;67900:228::-;68040:34;68036:1;68028:6;68024:14;68017:58;68109:11;68104:2;68096:6;68092:15;68085:36;68006:122;:::o;68134:164::-;68274:16;68270:1;68262:6;68258:14;68251:40;68240:58;:::o;68304:158::-;68444:10;68440:1;68432:6;68428:14;68421:34;68410:52;:::o;68468:220::-;68608:34;68604:1;68596:6;68592:14;68585:58;68677:3;68672:2;68664:6;68660:15;68653:28;68574:114;:::o;68694:236::-;68834:34;68830:1;68822:6;68818:14;68811:58;68903:19;68898:2;68890:6;68886:15;68879:44;68800:130;:::o;68936:231::-;69076:34;69072:1;69064:6;69060:14;69053:58;69145:14;69140:2;69132:6;69128:15;69121:39;69042:125;:::o;69173:175::-;69313:27;69309:1;69301:6;69297:14;69290:51;69279:69;:::o;69354:170::-;69494:22;69490:1;69482:6;69478:14;69471:46;69460:64;:::o;69530:181::-;69670:33;69666:1;69658:6;69654:14;69647:57;69636:75;:::o;69717:122::-;69790:24;69808:5;69790:24;:::i;:::-;69783:5;69780:35;69770:2;;69829:1;69826;69819:12;69770:2;69760:79;:::o;69845:116::-;69915:21;69930:5;69915:21;:::i;:::-;69908:5;69905:32;69895:2;;69951:1;69948;69941:12;69895:2;69885:76;:::o;69967:120::-;70039:23;70056:5;70039:23;:::i;:::-;70032:5;70029:34;70019:2;;70077:1;70074;70067:12;70019:2;70009:78;:::o;70093:122::-;70166:24;70184:5;70166:24;:::i;:::-;70159:5;70156:35;70146:2;;70205:1;70202;70195:12;70146:2;70136:79;:::o;70221:118::-;70292:22;70308:5;70292:22;:::i;:::-;70285:5;70282:33;70272:2;;70329:1;70326;70319:12;70272:2;70262:77;:::o

Swarm Source

ipfs://129d6fe3e61e5a14939a66c25585986d4760919ba7d5709f2bc785ca2271719b

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.