ETH Price: $3,337.72 (-1.10%)

Token

Daemonic Xe_ntities (XEN0)
 

Overview

Max Total Supply

367 XEN0

Holders

204

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
sanjo.eth
Balance
1 XEN0
0x83E6Ca50Ba68Dc7bc11BeF6A1a34a3c3629Dc3fe
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

A Xe_ntity is imbued with the power to “shapeshift” any Daemonic Entity by changing that Entity's properties. A Xe.ntity owner can cast it on an Entity they own to transform that Entity’s numerical composition. A Xe_ntity is a secularized incantation expressed as a function.

# Exchange Pair Price  24H Volume % Volume
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
Xe_ntity

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

}

File 1 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 2 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 3 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 4 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 5 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 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);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_artist","type":"address"},{"internalType":"uint256","name":"_offering","type":"uint256"}],"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":[{"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":"_xe_ntityId","type":"uint256"},{"internalType":"address","name":"_guardianContract","type":"address"},{"internalType":"uint256","name":"_guardianTokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"bind","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_xe_ntityId","type":"uint256"},{"internalType":"address","name":"_guardianContract","type":"address"},{"internalType":"uint256","name":"_guardianTokenId","type":"uint256"}],"name":"bind","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"bindable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_hodler","type":"address"},{"internalType":"uint256","name":"_entityId","type":"uint256"},{"internalType":"uint256","name":"_tick","type":"uint256"}],"name":"cast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"castings","outputs":[{"internalType":"uint256","name":"tick","type":"uint256"},{"internalType":"uint256","name":"entityId","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":[{"internalType":"uint256","name":"_xe_ntityId","type":"uint256"}],"name":"getBindingMessage","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_xe_ntityId","type":"uint256"}],"name":"getGuardianOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_xe_ntityId","type":"uint256"}],"name":"getGuardianToken","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_entityAddress","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":"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":"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":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"packAttributes","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"address","name":"_custodianAddress","type":"address"},{"internalType":"bool","name":"_bindable","type":"bool"}],"name":"setCustodian","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":"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"}],"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":[{"internalType":"uint256","name":"_xe_ntityId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"unbind","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_xe_ntityId","type":"uint256"}],"name":"unbind","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdrawAvailableBalance","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526000600d60146101000a81548160ff0219169083151502179055506000601060006101000a81548160ff021916908315150217905550600060115560006012556040518060400160405280600181526020017f2a00000000000000000000000000000000000000000000000000000000000000815250601390805190602001906200009192919062000431565b506040518060400160405280600581526020017f602020206000000000000000000000000000000000000000000000000000000081525060149080519060200190620000df92919062000431565b506040518060400160405280600581526020017f2020202020000000000000000000000000000000000000000000000000000000815250601590805190602001906200012d92919062000431565b506040518060400160405280600281526020017f6861000000000000000000000000000000000000000000000000000000000000815250601690805190602001906200017b92919062000431565b506040518060400160405280600281526020017f6e6f00000000000000000000000000000000000000000000000000000000000081525060179080519060200190620001c992919062000431565b506040518060400160405280600281526020017f7973000000000000000000000000000000000000000000000000000000000000815250601890805190602001906200021792919062000431565b503480156200022557600080fd5b50604051620066193803806200661983398181016040528101906200024b91906200050f565b6040518060400160405280601381526020017f4461656d6f6e69632058655f6e746974696573000000000000000000000000008152506040518060400160405280600481526020017f58454e30000000000000000000000000000000000000000000000000000000008152508160009080519060200190620002cf92919062000431565b508060019080519060200190620002e892919062000431565b5050506001600a8190555062000313620003076200036360201b60201c565b6200036b60201b60201c565b81600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600f81905550505062000632565b600033905090565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8280546200043f9062000594565b90600052602060002090601f016020900481019282620004635760008555620004af565b82601f106200047e57805160ff1916838001178555620004af565b82800160010185558215620004af579182015b82811115620004ae57825182559160200191906001019062000491565b5b509050620004be9190620004c2565b5090565b5b80821115620004dd576000816000905550600101620004c3565b5090565b600081519050620004f281620005fe565b92915050565b600081519050620005098162000618565b92915050565b60008060408385031215620005295762000528620005f9565b5b60006200053985828601620004e1565b92505060206200054c85828601620004f8565b9150509250929050565b600062000563826200056a565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006002820490506001821680620005ad57607f821691505b60208210811415620005c457620005c3620005ca565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600080fd5b620006098162000556565b81146200061557600080fd5b50565b62000623816200058a565b81146200062f57600080fd5b50565b615fd780620006426000396000f3fe6080604052600436106102245760003560e01c80636352211e11610123578063b1111359116100ab578063c144822e1161006f578063c144822e1461080b578063c4d66de814610849578063c87b56dd14610872578063e985e9c5146108af578063f2fde38b146108ec57610224565b8063b111135914610738578063b266cb011461074f578063b88d4fde1461077a578063bbff7bb6146107a3578063bedcf003146107e057610224565b80638da5cb5b116100f25780638da5cb5b1461066057806395d89b411461068b578063994e5f74146106b6578063a22cb465146106d2578063aeb87c71146106fb57610224565b80636352211e146105b357806370a08231146105f0578063715018a61461062d57806383b4fd421461064457610224565b80631f49d1f1116101b157806343bc16121161017557806343bc1612146104a557806346efde31146104d057806348f8b572146104fb5780634b3abffb146105385780634f6ccce71461057657610224565b80631f49d1f1146103d157806323b872dd146103fa578063286b0b40146104235780632f745c591461043f57806342842e0e1461047c57610224565b8063075b74cf116101f8578063075b74cf146102ea578063081812fc14610315578063095ea7b314610352578063158ef93e1461037b57806318160ddd146103a657610224565b8062b93e1a1461022957806301ffc9a714610245578063064125871461028257806306fdde03146102bf575b600080fd5b610243600480360381019061023e9190614076565b610915565b005b34801561025157600080fd5b5061026c60048036038101906102679190613f0a565b610b6c565b6040516102799190614b6b565b60405180910390f35b34801561028e57600080fd5b506102a960048036038101906102a49190613e17565b610be6565b6040516102b69190614ee5565b60405180910390f35b3480156102cb57600080fd5b506102d4610d42565b6040516102e19190614ba8565b60405180910390f35b3480156102f657600080fd5b506102ff610dd4565b60405161030c9190614ee5565b60405180910390f35b34801561032157600080fd5b5061033c60048036038101906103379190613ff6565b610dda565b6040516103499190614a18565b60405180910390f35b34801561035e57600080fd5b5061037960048036038101906103749190613d97565b610e5f565b005b34801561038757600080fd5b50610390610f77565b60405161039d9190614b6b565b60405180910390f35b3480156103b257600080fd5b506103bb610f8a565b6040516103c89190614ee5565b60405180910390f35b3480156103dd57600080fd5b506103f860048036038101906103f39190613d57565b610f97565b005b34801561040657600080fd5b50610421600480360381019061041c9190613c81565b611072565b005b61043d60048036038101906104389190614023565b6110d2565b005b34801561044b57600080fd5b5061046660048036038101906104619190613d97565b6110f2565b6040516104739190614ee5565b60405180910390f35b34801561048857600080fd5b506104a3600480360381019061049e9190613c81565b611197565b005b3480156104b157600080fd5b506104ba6111b7565b6040516104c79190614a18565b60405180910390f35b3480156104dc57600080fd5b506104e56111dd565b6040516104f29190614b6b565b60405180910390f35b34801561050757600080fd5b50610522600480360381019061051d9190613ff6565b6111f0565b60405161052f9190614b86565b60405180910390f35b34801561054457600080fd5b5061055f600480360381019061055a9190613ff6565b6112ab565b60405161056d929190614f00565b60405180910390f35b34801561058257600080fd5b5061059d60048036038101906105989190613ff6565b6112cf565b6040516105aa9190614ee5565b60405180910390f35b3480156105bf57600080fd5b506105da60048036038101906105d59190613ff6565b611340565b6040516105e79190614a18565b60405180910390f35b3480156105fc57600080fd5b5061061760048036038101906106129190613be7565b6113f2565b6040516106249190614ee5565b60405180910390f35b34801561063957600080fd5b506106426114aa565b005b61065e600480360381019061065991906140f9565b611532565b005b34801561066c57600080fd5b506106756117d8565b6040516106829190614a18565b60405180910390f35b34801561069757600080fd5b506106a0611802565b6040516106ad9190614ba8565b60405180910390f35b6106d060048036038101906106cb9190613ff6565b611894565b005b3480156106de57600080fd5b506106f960048036038101906106f49190613d57565b6118b0565b005b34801561070757600080fd5b50610722600480360381019061071d9190613ff6565b611a31565b60405161072f9190614ba8565b60405180910390f35b34801561074457600080fd5b5061074d611b9e565b005b34801561075b57600080fd5b50610764611d58565b6040516107719190614ee5565b60405180910390f35b34801561078657600080fd5b506107a1600480360381019061079c9190613cd4565b611d5e565b005b3480156107af57600080fd5b506107ca60048036038101906107c59190613ff6565b611dc0565b6040516107d79190614a18565b60405180910390f35b3480156107ec57600080fd5b506107f5611e76565b6040516108029190614ee5565b60405180910390f35b34801561081757600080fd5b50610832600480360381019061082d9190613ff6565b611e7c565b604051610840929190614a7f565b60405180910390f35b34801561085557600080fd5b50610870600480360381019061086b9190613be7565b611f34565b005b34801561087e57600080fd5b5061089960048036038101906108949190613ff6565b61205f565b6040516108a69190614ba8565b60405180910390f35b3480156108bb57600080fd5b506108d660048036038101906108d19190613c41565b6125b3565b6040516108e39190614b6b565b60405180910390f35b3480156108f857600080fd5b50610913600480360381019061090e9190613be7565b612647565b005b6002600a54141561095b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095290614e8a565b60405180910390fd5b6002600a81905550600d60149054906101000a900460ff166109b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109a990614dea565b60405180910390fd5b6109bb84611340565b73ffffffffffffffffffffffffffffffffffffffff166109d961273f565b73ffffffffffffffffffffffffffffffffffffffff1614610a2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2690614e4a565b60405180910390fd5b600f54341015610a74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6b90614d4a565b60405180910390fd5b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166346d5a6e930868686866040518663ffffffff1660e01b8152600401610ad7959493929190614aa8565b600060405180830381600087803b158015610af157600080fd5b505af1158015610b05573d6000803e3d6000fd5b50505050600234610b1691906151b0565b60126000828254610b27919061515a565b92505081905550600234610b3b91906151b0565b34610b46919061523b565b60116000828254610b57919061515a565b925050819055506001600a8190555050505050565b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610bdf5750610bde82612747565b5b9050919050565b60006002600a541415610c2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2590614e8a565b60405180910390fd5b6002600a81905550600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610cc6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cbd90614eaa565b60405180910390fd5b610ce3846001610cd4610f8a565b610cde919061515a565b612829565b60405180604001604052808381526020018481525060196000610d04610f8a565b81526020019081526020016000206000820151816000015560208201518160010155905050610d31610f8a565b90506001600a819055509392505050565b606060008054610d5190615344565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7d90615344565b8015610dca5780601f10610d9f57610100808354040283529160200191610dca565b820191906000526020600020905b815481529060010190602001808311610dad57829003601f168201915b5050505050905090565b60115481565b6000610de582612847565b610e24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e1b90614d8a565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610e6a82611340565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610edb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed290614e0a565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610efa61273f565b73ffffffffffffffffffffffffffffffffffffffff161480610f295750610f2881610f2361273f565b6125b3565b5b610f68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f5f90614cca565b60405180910390fd5b610f7283836128b3565b505050565b601060009054906101000a900460ff1681565b6000600880549050905090565b610f9f61273f565b73ffffffffffffffffffffffffffffffffffffffff16610fbd6117d8565b73ffffffffffffffffffffffffffffffffffffffff1614611013576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161100a90614daa565b60405180910390fd5b81600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600d60146101000a81548160ff0219169083151502179055505050565b61108361107d61273f565b8261296c565b6110c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b990614e2a565b60405180910390fd5b6110cd838383612a4a565b505050565b6110ed83838360405180602001604052806000815250610915565b505050565b60006110fd836113f2565b821061113e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113590614bea565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b6111b283838360405180602001604052806000815250611d5e565b505050565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600d60149054906101000a900460ff1681565b6060600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a99fd74330846040518363ffffffff1660e01b815260040161124f929190614a7f565b60006040518083038186803b15801561126757600080fd5b505afa15801561127b573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906112a49190613f64565b9050919050565b60196020528060005260406000206000915090508060000154908060010154905082565b60006112d9610f8a565b821061131a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131190614e6a565b60405180910390fd5b6008828154811061132e5761132d61548d565b5b90600052602060002001549050919050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156113e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113e090614d2a565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611463576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145a90614d0a565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6114b261273f565b73ffffffffffffffffffffffffffffffffffffffff166114d06117d8565b73ffffffffffffffffffffffffffffffffffffffff1614611526576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151d90614daa565b60405180910390fd5b6115306000612ca6565b565b6002600a541415611578576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161156f90614e8a565b60405180910390fd5b6002600a81905550600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663431512b830846040518363ffffffff1660e01b81526004016115dd929190614a7f565b60206040518083038186803b1580156115f557600080fd5b505afa158015611609573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162d9190613c14565b73ffffffffffffffffffffffffffffffffffffffff1661164b61273f565b73ffffffffffffffffffffffffffffffffffffffff16146116a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169890614bca565b60405180910390fd5b600f543410156116e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116dd90614d4a565b60405180910390fd5b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a35f7863084846040518463ffffffff1660e01b815260040161174593929190614b02565b600060405180830381600087803b15801561175f57600080fd5b505af1158015611773573d6000803e3d6000fd5b5050505060023461178491906151b0565b60126000828254611795919061515a565b925050819055506002346117a991906151b0565b346117b4919061523b565b601160008282546117c5919061515a565b925050819055506001600a819055505050565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606001805461181190615344565b80601f016020809104026020016040519081016040528092919081815260200182805461183d90615344565b801561188a5780601f1061185f5761010080835404028352916020019161188a565b820191906000526020600020905b81548152906001019060200180831161186d57829003601f168201915b5050505050905090565b6118ad8160405180602001604052806000815250611532565b50565b6118b861273f565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611926576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161191d90614c8a565b60405180910390fd5b806005600061193361273f565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166119e061273f565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611a259190614b6b565b60405180910390a35050565b60607330d432918c74193032c0cd03935b02a3e026b933636900a3ae60196000858152602001908152602001600020600101546040518263ffffffff1660e01b8152600401611a809190614eca565b60006040518083038186803b158015611a9857600080fd5b505af4158015611aac573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611ad59190613fad565b7330d432918c74193032c0cd03935b02a3e026b933636900a3ae60196000868152602001908152602001600020600101546040518263ffffffff1660e01b8152600401611b229190614eca565b60006040518083038186803b158015611b3a57600080fd5b505af4158015611b4e573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611b779190613fad565b604051602001611b88929190614954565b6040516020818303038152906040529050919050565b6002600a541415611be4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bdb90614e8a565b60405180910390fd5b6002600a81905550611bf46117d8565b73ffffffffffffffffffffffffffffffffffffffff16611c1261273f565b73ffffffffffffffffffffffffffffffffffffffff161415611c9157600060125490506000601281905550611c4561273f565b73ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611c8a573d6000803e3d6000fd5b5050611d4e565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611cd261273f565b73ffffffffffffffffffffffffffffffffffffffff161415611d4d57600060115490506000601181905550611d0561273f565b73ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611d4a573d6000803e3d6000fd5b50505b5b6001600a81905550565b600f5481565b611d6f611d6961273f565b8361296c565b611dae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611da590614e2a565b60405180910390fd5b611dba84848484612d6c565b50505050565b6000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663431512b830846040518363ffffffff1660e01b8152600401611e1f929190614a7f565b60206040518083038186803b158015611e3757600080fd5b505afa158015611e4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e6f9190613c14565b9050919050565b60125481565b600080600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663337b0c6b30856040518363ffffffff1660e01b8152600401611edc929190614a7f565b604080518083038186803b158015611ef357600080fd5b505afa158015611f07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f2b9190613dd7565b91509150915091565b611f3c61273f565b73ffffffffffffffffffffffffffffffffffffffff16611f5a6117d8565b73ffffffffffffffffffffffffffffffffffffffff1614611fb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa790614daa565b60405180910390fd5b601060009054906101000a900460ff1615612000576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ff790614cea565b60405180910390fd5b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001601060006101000a81548160ff02191690831515021790555050565b6060600060405180602001604052806000815250905061207e83612847565b156124015761208b6137bc565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d159b4ae601960008781526020019081526020016000206001015460196000888152602001908152602001600020600001546040518363ffffffff1660e01b8152600401612114929190614f00565b60006040518083038186803b15801561212c57600080fd5b505afa158015612140573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906121699190613e98565b905050809150506000732175b6b2219dcaaf7020cde8f2b59e0a6f373d45632cd80e1083600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e8299b76040518163ffffffff1660e01b815260040160206040518083038186803b1580156121f557600080fd5b505afa158015612209573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061222d9190614155565b6040518363ffffffff1660e01b815260040161224a929190614b40565b6108006040518083038186803b15801561226357600080fd5b505af4158015612277573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229b9190613e6a565b905060005b60088160ff1610156123f95760005b60088160ff1610156123c05784732175b6b2219dcaaf7020cde8f2b59e0a6f373d45639db02b24858560ff16600881106122ec576122eb61548d565b5b60200201518460ff16600881106123065761230561548d565b5b602002015160136014601560166040518663ffffffff1660e01b8152600401612333959493929190614f29565b60006040518083038186803b15801561234b57600080fd5b505af415801561235f573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906123889190613fad565b601860405160200161239c939291906148ff565b604051602081830303815290604052945080806123b8906153a7565b9150506122af565b508360176040516020016123d5929190614930565b604051602081830303815290604052935080806123f1906153a7565b9150506122a0565b50505061243a565b6040518060400160405280600c81526020017f6e6f74207965742063617374000000000000000000000000000000000000000081525090505b6000604051806101a001604052806101748152602001615dee6101749139905060006040518060400160405280601c81526020017f3c2f6469763e3c2f666f726569676e4f626a6563743e3c2f7376673e00000000815250905060008284836040516020016124ab939291906148ce565b604051602081830303815290604052905060006125857330d432918c74193032c0cd03935b02a3e026b933636900a3ae896040518263ffffffff1660e01b81526004016124f89190614eca565b60006040518083038186803b15801561251057600080fd5b505af4158015612524573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061254d9190613fad565b61255689611a31565b61255f85612dc8565b604051602001612571939291906149bb565b604051602081830303815290604052612dc8565b9050806040516020016125989190614999565b60405160208183030381529060405295505050505050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61264f61273f565b73ffffffffffffffffffffffffffffffffffffffff1661266d6117d8565b73ffffffffffffffffffffffffffffffffffffffff16146126c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126ba90614daa565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612733576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161272a90614c2a565b60405180910390fd5b61273c81612ca6565b50565b600033905090565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061281257507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80612822575061282182612f60565b5b9050919050565b612843828260405180602001604052806000815250612fca565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff1661292683611340565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061297782612847565b6129b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129ad90614caa565b60405180910390fd5b60006129c183611340565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612a3057508373ffffffffffffffffffffffffffffffffffffffff16612a1884610dda565b73ffffffffffffffffffffffffffffffffffffffff16145b80612a415750612a4081856125b3565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16612a6a82611340565b73ffffffffffffffffffffffffffffffffffffffff1614612ac0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ab790614dca565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612b30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b2790614c6a565b60405180910390fd5b612b3b838383613025565b612b466000826128b3565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612b96919061523b565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612bed919061515a565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b612d77848484612a4a565b612d8384848484613139565b612dc2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612db990614c0a565b60405180910390fd5b50505050565b60606000825190506000811415612df15760405180602001604052806000815250915050612f5b565b60006003600283612e02919061515a565b612e0c91906151b0565b6004612e1891906151e1565b90506000602082612e29919061515a565b67ffffffffffffffff811115612e4257612e416154bc565b5b6040519080825280601f01601f191660200182016040528015612e745781602001600182028036833780820191505090505b5090506000604051806060016040528060408152602001615f62604091399050600181016020830160005b86811015612f185760038101905062ffffff818a015116603f8160121c168401518060081b905060ff603f83600c1c1686015116810190508060081b905060ff603f8360061c1686015116810190508060081b905060ff603f831686015116810190508060e01b90508084526004840193505050612e9f565b506003860660018114612f325760028114612f4257612f4d565b613d3d60f01b6002830352612f4d565b603d60f81b60018303525b508484525050819450505050505b919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b612fd483836132d0565b612fe16000848484613139565b613020576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161301790614c0a565b60405180910390fd5b505050565b61303083838361349e565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156130735761306e816134a3565b6130b2565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146130b1576130b083826134ec565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156130f5576130f081613659565b613134565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461313357613132828261372a565b5b5b505050565b600061315a8473ffffffffffffffffffffffffffffffffffffffff166137a9565b156132c3578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261318361273f565b8786866040518563ffffffff1660e01b81526004016131a59493929190614a33565b602060405180830381600087803b1580156131bf57600080fd5b505af19250505080156131f057506040513d601f19601f820116820180604052508101906131ed9190613f37565b60015b613273573d8060008114613220576040519150601f19603f3d011682016040523d82523d6000602084013e613225565b606091505b5060008151141561326b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161326290614c0a565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506132c8565b600190505b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613340576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161333790614d6a565b60405180910390fd5b61334981612847565b15613389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161338090614c4a565b60405180910390fd5b61339560008383613025565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546133e5919061515a565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b600060016134f9846113f2565b613503919061523b565b90506000600760008481526020019081526020016000205490508181146135e8576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b6000600160088054905061366d919061523b565b905060006009600084815260200190815260200160002054905060006008838154811061369d5761369c61548d565b5b9060005260206000200154905080600883815481106136bf576136be61548d565b5b90600052602060002001819055508160096000838152602001908152602001600020819055506009600085815260200190815260200160002060009055600880548061370e5761370d61545e565b5b6001900381819060005260206000200160009055905550505050565b6000613735836113f2565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600080823b905060008111915050919050565b6040518061010001604052806008905b6137d46137ea565b8152602001906001900390816137cc5790505090565b604051806101000160405280600890602082028036833780820191505090505090565b600061382061381b84614fbd565b614f98565b905080828561010086028201111561383b5761383a6154f0565b5b60005b8581101561386c57816138518882613ab4565b8452602084019350610100830192505060018101905061383e565b5050509392505050565b600061388961388484614fe3565b614f98565b905080838252602082019050828560208602820111156138ac576138ab6154f0565b5b60005b858110156138fa57815167ffffffffffffffff8111156138d2576138d16154eb565b5b8086016138df8982613b7a565b855260208501945060208401935050506001810190506138af565b5050509392505050565b60006139176139128461500f565b614f98565b90508082856020860282011115613931576139306154f0565b5b60005b8581101561396157816139478882613bd2565b845260208401935060208301925050600181019050613934565b5050509392505050565b600061397e61397984615035565b614f98565b90508281526020810184848401111561399a576139996154f5565b5b6139a5848285615302565b509392505050565b60006139c06139bb84615035565b614f98565b9050828152602081018484840111156139dc576139db6154f5565b5b6139e7848285615311565b509392505050565b6000613a026139fd84615066565b614f98565b905082815260208101848484011115613a1e57613a1d6154f5565b5b613a29848285615311565b509392505050565b600081359050613a4081615d7a565b92915050565b600081519050613a5581615d7a565b92915050565b600082601f830112613a7057613a6f6154eb565b5b6008613a7d84828561380d565b91505092915050565b600082601f830112613a9b57613a9a6154eb565b5b8151613aab848260208601613876565b91505092915050565b600082601f830112613ac957613ac86154eb565b5b6008613ad6848285613904565b91505092915050565b600081359050613aee81615d91565b92915050565b600081359050613b0381615da8565b92915050565b600081519050613b1881615da8565b92915050565b600082601f830112613b3357613b326154eb565b5b8135613b4384826020860161396b565b91505092915050565b600082601f830112613b6157613b606154eb565b5b8151613b718482602086016139ad565b91505092915050565b600082601f830112613b8f57613b8e6154eb565b5b8151613b9f8482602086016139ef565b91505092915050565b600081359050613bb781615dbf565b92915050565b600081519050613bcc81615dbf565b92915050565b600081519050613be181615dd6565b92915050565b600060208284031215613bfd57613bfc6154ff565b5b6000613c0b84828501613a31565b91505092915050565b600060208284031215613c2a57613c296154ff565b5b6000613c3884828501613a46565b91505092915050565b60008060408385031215613c5857613c576154ff565b5b6000613c6685828601613a31565b9250506020613c7785828601613a31565b9150509250929050565b600080600060608486031215613c9a57613c996154ff565b5b6000613ca886828701613a31565b9350506020613cb986828701613a31565b9250506040613cca86828701613ba8565b9150509250925092565b60008060008060808587031215613cee57613ced6154ff565b5b6000613cfc87828801613a31565b9450506020613d0d87828801613a31565b9350506040613d1e87828801613ba8565b925050606085013567ffffffffffffffff811115613d3f57613d3e6154fa565b5b613d4b87828801613b1e565b91505092959194509250565b60008060408385031215613d6e57613d6d6154ff565b5b6000613d7c85828601613a31565b9250506020613d8d85828601613adf565b9150509250929050565b60008060408385031215613dae57613dad6154ff565b5b6000613dbc85828601613a31565b9250506020613dcd85828601613ba8565b9150509250929050565b60008060408385031215613dee57613ded6154ff565b5b6000613dfc85828601613a46565b9250506020613e0d85828601613bbd565b9150509250929050565b600080600060608486031215613e3057613e2f6154ff565b5b6000613e3e86828701613a31565b9350506020613e4f86828701613ba8565b9250506040613e6086828701613ba8565b9150509250925092565b60006108008284031215613e8157613e806154ff565b5b6000613e8f84828501613a5b565b91505092915050565b60008060006108408486031215613eb257613eb16154ff565b5b6000613ec086828701613a5b565b93505061080084015167ffffffffffffffff811115613ee257613ee16154fa565b5b613eee86828701613a86565b925050610820613f0086828701613bbd565b9150509250925092565b600060208284031215613f2057613f1f6154ff565b5b6000613f2e84828501613af4565b91505092915050565b600060208284031215613f4d57613f4c6154ff565b5b6000613f5b84828501613b09565b91505092915050565b600060208284031215613f7a57613f796154ff565b5b600082015167ffffffffffffffff811115613f9857613f976154fa565b5b613fa484828501613b4c565b91505092915050565b600060208284031215613fc357613fc26154ff565b5b600082015167ffffffffffffffff811115613fe157613fe06154fa565b5b613fed84828501613b7a565b91505092915050565b60006020828403121561400c5761400b6154ff565b5b600061401a84828501613ba8565b91505092915050565b60008060006060848603121561403c5761403b6154ff565b5b600061404a86828701613ba8565b935050602061405b86828701613a31565b925050604061406c86828701613ba8565b9150509250925092565b600080600080608085870312156140905761408f6154ff565b5b600061409e87828801613ba8565b94505060206140af87828801613a31565b93505060406140c087828801613ba8565b925050606085013567ffffffffffffffff8111156140e1576140e06154fa565b5b6140ed87828801613b1e565b91505092959194509250565b600080604083850312156141105761410f6154ff565b5b600061411e85828601613ba8565b925050602083013567ffffffffffffffff81111561413f5761413e6154fa565b5b61414b85828601613b1e565b9150509250929050565b60006020828403121561416b5761416a6154ff565b5b600061417984828501613bd2565b91505092915050565b600061418e8383614219565b6101008301905092915050565b60006141a783836148bf565b60208301905092915050565b6141bc8161526f565b82525050565b6141cb816150c0565b6141d58184615106565b92506141e082615097565b8060005b838110156142115781516141f88782614182565b9650614203836150ec565b9250506001810190506141e4565b505050505050565b614222816150cb565b61422c8184615111565b9250614237826150a1565b8060005b8381101561426857815161424f878261419b565b965061425a836150f9565b92505060018101905061423b565b505050505050565b61427981615281565b82525050565b600061428a826150d6565b614294818561511c565b93506142a4818560208601615311565b6142ad81615504565b840191505092915050565b60006142c3826150e1565b6142cd818561512d565b93506142dd818560208601615311565b6142e681615504565b840191505092915050565b60006142fc826150e1565b614306818561514f565b9350614316818560208601615311565b80840191505092915050565b6000815461432f81615344565b614339818661513e565b94506001821660008114614354576001811461436657614399565b60ff1983168652602086019350614399565b61436f856150ab565b60005b8381101561439157815481890152600182019150602081019050614372565b808801955050505b50505092915050565b600081546143af81615344565b6143b9818661514f565b945060018216600081146143d457600181146143e557614418565b60ff19831686528186019350614418565b6143ee856150ab565b60005b83811015614410578154818901526001820191506020810190506143f1565b838801955050505b50505092915050565b600061442e60138361512d565b915061443982615515565b602082019050919050565b6000614451602b8361512d565b915061445c8261553e565b604082019050919050565b600061447460328361512d565b915061447f8261558d565b604082019050919050565b600061449760268361512d565b91506144a2826155dc565b604082019050919050565b60006144ba601c8361512d565b91506144c58261562b565b602082019050919050565b60006144dd601b8361514f565b91506144e882615654565b601b82019050919050565b600061450060248361512d565b915061450b8261567d565b604082019050919050565b600061452360198361512d565b915061452e826156cc565b602082019050919050565b6000614546602c8361512d565b9150614551826156f5565b604082019050919050565b600061456960388361512d565b915061457482615744565b604082019050919050565b600061458d6101118361514f565b915061459882615793565b61011182019050919050565b60006145b160138361512d565b91506145bc826158ed565b602082019050919050565b60006145d4602a8361512d565b91506145df82615916565b604082019050919050565b60006145f760298361512d565b915061460282615965565b604082019050919050565b600061461a60248361514f565b9150614625826159b4565b602482019050919050565b600061463d60158361512d565b915061464882615a03565b602082019050919050565b600061466060028361514f565b915061466b82615a2c565b600282019050919050565b600061468360208361512d565b915061468e82615a55565b602082019050919050565b60006146a6602c8361512d565b91506146b182615a7e565b604082019050919050565b60006146c960208361512d565b91506146d482615acd565b602082019050919050565b60006146ec60298361512d565b91506146f782615af6565b604082019050919050565b600061470f60038361514f565b915061471a82615b45565b600382019050919050565b6000614732600c8361512d565b915061473d82615b6e565b602082019050919050565b600061475560218361512d565b915061476082615b97565b604082019050919050565b6000614778601d8361514f565b915061478382615be6565b601d82019050919050565b600061479b60318361512d565b91506147a682615c0f565b604082019050919050565b60006147be60118361512d565b91506147c982615c5e565b602082019050919050565b60006147e1602c8361512d565b91506147ec82615c87565b604082019050919050565b6000614804601f8361512d565b915061480f82615cd6565b602082019050919050565b6000614827600a8361512d565b915061483282615cff565b602082019050919050565b600061484a600c8361514f565b915061485582615d28565b600c82019050919050565b600061486d60148361514f565b915061487882615d51565b601482019050919050565b61488c816152d9565b82525050565b61489b816152d9565b82525050565b6148aa816152f0565b82525050565b6148b9816152e3565b82525050565b6148c8816152e3565b82525050565b60006148da82866142f1565b91506148e682856142f1565b91506148f282846142f1565b9150819050949350505050565b600061490b82866142f1565b915061491782856142f1565b915061492382846143a2565b9150819050949350505050565b600061493c82856142f1565b915061494882846143a2565b91508190509392505050565b600061495f826144d0565b915061496b82856142f1565b91506149768261483d565b915061498282846142f1565b915061498d82614702565b91508190509392505050565b60006149a48261476b565b91506149b082846142f1565b915081905092915050565b60006149c682614860565b91506149d282866142f1565b91506149dd8261457f565b91506149e982856142f1565b91506149f48261460d565b9150614a0082846142f1565b9150614a0b82614653565b9150819050949350505050565b6000602082019050614a2d60008301846141b3565b92915050565b6000608082019050614a4860008301876141b3565b614a5560208301866141b3565b614a626040830185614883565b8181036060830152614a74818461427f565b905095945050505050565b6000604082019050614a9460008301856141b3565b614aa16020830184614883565b9392505050565b600060a082019050614abd60008301886141b3565b614aca6020830187614883565b614ad760408301866141b3565b614ae46060830185614883565b8181036080830152614af6818461427f565b90509695505050505050565b6000606082019050614b1760008301866141b3565b614b246020830185614883565b8181036040830152614b36818461427f565b9050949350505050565b600061082082019050614b5660008301856141c2565b614b646108008301846148b0565b9392505050565b6000602082019050614b806000830184614270565b92915050565b60006020820190508181036000830152614ba0818461427f565b905092915050565b60006020820190508181036000830152614bc281846142b8565b905092915050565b60006020820190508181036000830152614be381614421565b9050919050565b60006020820190508181036000830152614c0381614444565b9050919050565b60006020820190508181036000830152614c2381614467565b9050919050565b60006020820190508181036000830152614c438161448a565b9050919050565b60006020820190508181036000830152614c63816144ad565b9050919050565b60006020820190508181036000830152614c83816144f3565b9050919050565b60006020820190508181036000830152614ca381614516565b9050919050565b60006020820190508181036000830152614cc381614539565b9050919050565b60006020820190508181036000830152614ce38161455c565b9050919050565b60006020820190508181036000830152614d03816145a4565b9050919050565b60006020820190508181036000830152614d23816145c7565b9050919050565b60006020820190508181036000830152614d43816145ea565b9050919050565b60006020820190508181036000830152614d6381614630565b9050919050565b60006020820190508181036000830152614d8381614676565b9050919050565b60006020820190508181036000830152614da381614699565b9050919050565b60006020820190508181036000830152614dc3816146bc565b9050919050565b60006020820190508181036000830152614de3816146df565b9050919050565b60006020820190508181036000830152614e0381614725565b9050919050565b60006020820190508181036000830152614e2381614748565b9050919050565b60006020820190508181036000830152614e438161478e565b9050919050565b60006020820190508181036000830152614e63816147b1565b9050919050565b60006020820190508181036000830152614e83816147d4565b9050919050565b60006020820190508181036000830152614ea3816147f7565b9050919050565b60006020820190508181036000830152614ec38161481a565b9050919050565b6000602082019050614edf6000830184614892565b92915050565b6000602082019050614efa6000830184614883565b92915050565b6000604082019050614f156000830185614883565b614f226020830184614883565b9392505050565b600060a082019050614f3e60008301886148a1565b8181036020830152614f508187614322565b90508181036040830152614f648186614322565b90508181036060830152614f788185614322565b90508181036080830152614f8c8184614322565b90509695505050505050565b6000614fa2614fb3565b9050614fae8282615376565b919050565b6000604051905090565b600067ffffffffffffffff821115614fd857614fd76154bc565b5b602082029050919050565b600067ffffffffffffffff821115614ffe57614ffd6154bc565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561502a576150296154bc565b5b602082029050919050565b600067ffffffffffffffff8211156150505761504f6154bc565b5b61505982615504565b9050602081019050919050565b600067ffffffffffffffff821115615081576150806154bc565b5b61508a82615504565b9050602081019050919050565b6000819050919050565b6000819050919050565b60008190508160005260206000209050919050565b600060089050919050565b600060089050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600081905092915050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000615165826152d9565b9150615170836152d9565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156151a5576151a46153d1565b5b828201905092915050565b60006151bb826152d9565b91506151c6836152d9565b9250826151d6576151d5615400565b5b828204905092915050565b60006151ec826152d9565b91506151f7836152d9565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156152305761522f6153d1565b5b828202905092915050565b6000615246826152d9565b9150615251836152d9565b925082821015615264576152636153d1565b5b828203905092915050565b600061527a826152b9565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60006152fb826152e3565b9050919050565b82818337600083830152505050565b60005b8381101561532f578082015181840152602081019050615314565b8381111561533e576000848401525b50505050565b6000600282049050600182168061535c57607f821691505b602082108114156153705761536f61542f565b5b50919050565b61537f82615504565b810181811067ffffffffffffffff8211171561539e5761539d6154bc565b5b80604052505050565b60006153b2826152e3565b915060ff8214156153c6576153c56153d1565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f6e6f7420796f75727320746f20756e62696e6400000000000000000000000000600082015250565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f2261747472696275746573223a205b7b2022656e74697479223a200000000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f222c20226465736372697074696f6e223a202246756e6374696f6e732061726560008201527f20736563756c6172697a656420696e63616e746174696f6e7320617320636f6460208201527f652e20412058655f6e746974792069732058207768657265205828656e74697460408201527f7929203d20656e746974795e2e205061727469636970616e747320746861742060608201527f6f776e20616e20656e746974792063616e206361737420612078655f6e74697460808201527f792066726f6d2069742c207472616e73666f726d696e672074686520656e746960a08201527f747920696e207468652070726f636573732e202a456e7320646976696e756d2060c08201527f636f676e6f73636962696c652070657220696e737069726174696f6e656d206560e08201527f73742073756269656374756d2a3d3f222c00000000000000000000000000000061010082015250565b7f616c726561647920696e697469616c697a656400000000000000000000000000600082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b7f22696d616765223a2022646174613a696d6167652f7376672b786d6c3b62617360008201527f6536342c00000000000000000000000000000000000000000000000000000000602082015250565b7f696e73756666696369656e74206f66666572696e670000000000000000000000600082015250565b7f227d000000000000000000000000000000000000000000000000000000000000600082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f7d5d2c0000000000000000000000000000000000000000000000000000000000600082015250565b7f6e6f742062696e6461626c650000000000000000000000000000000000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b7f6e6f7420796f75727320746f2062696e64000000000000000000000000000000600082015250565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b7f6f6e6c79456e7469747900000000000000000000000000000000000000000000600082015250565b7f7d2c7b20227469636b223a200000000000000000000000000000000000000000600082015250565b7f7b226e616d65223a202258655f6e746974792023000000000000000000000000600082015250565b615d838161526f565b8114615d8e57600080fd5b50565b615d9a81615281565b8114615da557600080fd5b50565b615db18161528d565b8114615dbc57600080fd5b50565b615dc8816152d9565b8114615dd357600080fd5b50565b615ddf816152e3565b8114615dea57600080fd5b5056fe3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207072657365727665417370656374526174696f3d22784d696e594d696e206d656574222076696577426f783d223020302036363620383838223e3c7374796c653e2e78656e207b20636f6c6f723a20626c61636b3b20666f6e742d66616d696c793a2073657269663b20666f6e742d73697a653a20313970783b206c696e652d6865696768743a20313970783b2077686974652d73706163653a20627265616b2d7370616365733b207d3c2f7374796c653e3c726563742077696474683d223130302522206865696768743d2231303025222066696c6c3d2272656422202f3e3c666f726569676e4f626a65637420783d2239302220793d223930222077696474683d2234383622206865696768743d223739382220636c6173733d2278656e223e3c64697620786d6c6e733d22687474703a2f2f7777772e77332e6f72672f313939392f7868746d6c223e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa264697066735822122092e9988b2565cb2c31880566e86082c195bcf63e54fa43a54a30cad604b543ed64736f6c634300080600330000000000000000000000002f59aa8b33b0db6ef148f9be2b88a896bd908e9b000000000000000000000000000000000000000000000000001f438daa060000

Deployed Bytecode

0x6080604052600436106102245760003560e01c80636352211e11610123578063b1111359116100ab578063c144822e1161006f578063c144822e1461080b578063c4d66de814610849578063c87b56dd14610872578063e985e9c5146108af578063f2fde38b146108ec57610224565b8063b111135914610738578063b266cb011461074f578063b88d4fde1461077a578063bbff7bb6146107a3578063bedcf003146107e057610224565b80638da5cb5b116100f25780638da5cb5b1461066057806395d89b411461068b578063994e5f74146106b6578063a22cb465146106d2578063aeb87c71146106fb57610224565b80636352211e146105b357806370a08231146105f0578063715018a61461062d57806383b4fd421461064457610224565b80631f49d1f1116101b157806343bc16121161017557806343bc1612146104a557806346efde31146104d057806348f8b572146104fb5780634b3abffb146105385780634f6ccce71461057657610224565b80631f49d1f1146103d157806323b872dd146103fa578063286b0b40146104235780632f745c591461043f57806342842e0e1461047c57610224565b8063075b74cf116101f8578063075b74cf146102ea578063081812fc14610315578063095ea7b314610352578063158ef93e1461037b57806318160ddd146103a657610224565b8062b93e1a1461022957806301ffc9a714610245578063064125871461028257806306fdde03146102bf575b600080fd5b610243600480360381019061023e9190614076565b610915565b005b34801561025157600080fd5b5061026c60048036038101906102679190613f0a565b610b6c565b6040516102799190614b6b565b60405180910390f35b34801561028e57600080fd5b506102a960048036038101906102a49190613e17565b610be6565b6040516102b69190614ee5565b60405180910390f35b3480156102cb57600080fd5b506102d4610d42565b6040516102e19190614ba8565b60405180910390f35b3480156102f657600080fd5b506102ff610dd4565b60405161030c9190614ee5565b60405180910390f35b34801561032157600080fd5b5061033c60048036038101906103379190613ff6565b610dda565b6040516103499190614a18565b60405180910390f35b34801561035e57600080fd5b5061037960048036038101906103749190613d97565b610e5f565b005b34801561038757600080fd5b50610390610f77565b60405161039d9190614b6b565b60405180910390f35b3480156103b257600080fd5b506103bb610f8a565b6040516103c89190614ee5565b60405180910390f35b3480156103dd57600080fd5b506103f860048036038101906103f39190613d57565b610f97565b005b34801561040657600080fd5b50610421600480360381019061041c9190613c81565b611072565b005b61043d60048036038101906104389190614023565b6110d2565b005b34801561044b57600080fd5b5061046660048036038101906104619190613d97565b6110f2565b6040516104739190614ee5565b60405180910390f35b34801561048857600080fd5b506104a3600480360381019061049e9190613c81565b611197565b005b3480156104b157600080fd5b506104ba6111b7565b6040516104c79190614a18565b60405180910390f35b3480156104dc57600080fd5b506104e56111dd565b6040516104f29190614b6b565b60405180910390f35b34801561050757600080fd5b50610522600480360381019061051d9190613ff6565b6111f0565b60405161052f9190614b86565b60405180910390f35b34801561054457600080fd5b5061055f600480360381019061055a9190613ff6565b6112ab565b60405161056d929190614f00565b60405180910390f35b34801561058257600080fd5b5061059d60048036038101906105989190613ff6565b6112cf565b6040516105aa9190614ee5565b60405180910390f35b3480156105bf57600080fd5b506105da60048036038101906105d59190613ff6565b611340565b6040516105e79190614a18565b60405180910390f35b3480156105fc57600080fd5b5061061760048036038101906106129190613be7565b6113f2565b6040516106249190614ee5565b60405180910390f35b34801561063957600080fd5b506106426114aa565b005b61065e600480360381019061065991906140f9565b611532565b005b34801561066c57600080fd5b506106756117d8565b6040516106829190614a18565b60405180910390f35b34801561069757600080fd5b506106a0611802565b6040516106ad9190614ba8565b60405180910390f35b6106d060048036038101906106cb9190613ff6565b611894565b005b3480156106de57600080fd5b506106f960048036038101906106f49190613d57565b6118b0565b005b34801561070757600080fd5b50610722600480360381019061071d9190613ff6565b611a31565b60405161072f9190614ba8565b60405180910390f35b34801561074457600080fd5b5061074d611b9e565b005b34801561075b57600080fd5b50610764611d58565b6040516107719190614ee5565b60405180910390f35b34801561078657600080fd5b506107a1600480360381019061079c9190613cd4565b611d5e565b005b3480156107af57600080fd5b506107ca60048036038101906107c59190613ff6565b611dc0565b6040516107d79190614a18565b60405180910390f35b3480156107ec57600080fd5b506107f5611e76565b6040516108029190614ee5565b60405180910390f35b34801561081757600080fd5b50610832600480360381019061082d9190613ff6565b611e7c565b604051610840929190614a7f565b60405180910390f35b34801561085557600080fd5b50610870600480360381019061086b9190613be7565b611f34565b005b34801561087e57600080fd5b5061089960048036038101906108949190613ff6565b61205f565b6040516108a69190614ba8565b60405180910390f35b3480156108bb57600080fd5b506108d660048036038101906108d19190613c41565b6125b3565b6040516108e39190614b6b565b60405180910390f35b3480156108f857600080fd5b50610913600480360381019061090e9190613be7565b612647565b005b6002600a54141561095b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095290614e8a565b60405180910390fd5b6002600a81905550600d60149054906101000a900460ff166109b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109a990614dea565b60405180910390fd5b6109bb84611340565b73ffffffffffffffffffffffffffffffffffffffff166109d961273f565b73ffffffffffffffffffffffffffffffffffffffff1614610a2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2690614e4a565b60405180910390fd5b600f54341015610a74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6b90614d4a565b60405180910390fd5b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166346d5a6e930868686866040518663ffffffff1660e01b8152600401610ad7959493929190614aa8565b600060405180830381600087803b158015610af157600080fd5b505af1158015610b05573d6000803e3d6000fd5b50505050600234610b1691906151b0565b60126000828254610b27919061515a565b92505081905550600234610b3b91906151b0565b34610b46919061523b565b60116000828254610b57919061515a565b925050819055506001600a8190555050505050565b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610bdf5750610bde82612747565b5b9050919050565b60006002600a541415610c2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2590614e8a565b60405180910390fd5b6002600a81905550600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610cc6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cbd90614eaa565b60405180910390fd5b610ce3846001610cd4610f8a565b610cde919061515a565b612829565b60405180604001604052808381526020018481525060196000610d04610f8a565b81526020019081526020016000206000820151816000015560208201518160010155905050610d31610f8a565b90506001600a819055509392505050565b606060008054610d5190615344565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7d90615344565b8015610dca5780601f10610d9f57610100808354040283529160200191610dca565b820191906000526020600020905b815481529060010190602001808311610dad57829003601f168201915b5050505050905090565b60115481565b6000610de582612847565b610e24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e1b90614d8a565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610e6a82611340565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610edb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed290614e0a565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610efa61273f565b73ffffffffffffffffffffffffffffffffffffffff161480610f295750610f2881610f2361273f565b6125b3565b5b610f68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f5f90614cca565b60405180910390fd5b610f7283836128b3565b505050565b601060009054906101000a900460ff1681565b6000600880549050905090565b610f9f61273f565b73ffffffffffffffffffffffffffffffffffffffff16610fbd6117d8565b73ffffffffffffffffffffffffffffffffffffffff1614611013576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161100a90614daa565b60405180910390fd5b81600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600d60146101000a81548160ff0219169083151502179055505050565b61108361107d61273f565b8261296c565b6110c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b990614e2a565b60405180910390fd5b6110cd838383612a4a565b505050565b6110ed83838360405180602001604052806000815250610915565b505050565b60006110fd836113f2565b821061113e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113590614bea565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b6111b283838360405180602001604052806000815250611d5e565b505050565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600d60149054906101000a900460ff1681565b6060600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a99fd74330846040518363ffffffff1660e01b815260040161124f929190614a7f565b60006040518083038186803b15801561126757600080fd5b505afa15801561127b573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906112a49190613f64565b9050919050565b60196020528060005260406000206000915090508060000154908060010154905082565b60006112d9610f8a565b821061131a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131190614e6a565b60405180910390fd5b6008828154811061132e5761132d61548d565b5b90600052602060002001549050919050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156113e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113e090614d2a565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611463576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145a90614d0a565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6114b261273f565b73ffffffffffffffffffffffffffffffffffffffff166114d06117d8565b73ffffffffffffffffffffffffffffffffffffffff1614611526576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151d90614daa565b60405180910390fd5b6115306000612ca6565b565b6002600a541415611578576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161156f90614e8a565b60405180910390fd5b6002600a81905550600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663431512b830846040518363ffffffff1660e01b81526004016115dd929190614a7f565b60206040518083038186803b1580156115f557600080fd5b505afa158015611609573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162d9190613c14565b73ffffffffffffffffffffffffffffffffffffffff1661164b61273f565b73ffffffffffffffffffffffffffffffffffffffff16146116a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169890614bca565b60405180910390fd5b600f543410156116e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116dd90614d4a565b60405180910390fd5b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a35f7863084846040518463ffffffff1660e01b815260040161174593929190614b02565b600060405180830381600087803b15801561175f57600080fd5b505af1158015611773573d6000803e3d6000fd5b5050505060023461178491906151b0565b60126000828254611795919061515a565b925050819055506002346117a991906151b0565b346117b4919061523b565b601160008282546117c5919061515a565b925050819055506001600a819055505050565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606001805461181190615344565b80601f016020809104026020016040519081016040528092919081815260200182805461183d90615344565b801561188a5780601f1061185f5761010080835404028352916020019161188a565b820191906000526020600020905b81548152906001019060200180831161186d57829003601f168201915b5050505050905090565b6118ad8160405180602001604052806000815250611532565b50565b6118b861273f565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611926576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161191d90614c8a565b60405180910390fd5b806005600061193361273f565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166119e061273f565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611a259190614b6b565b60405180910390a35050565b60607330d432918c74193032c0cd03935b02a3e026b933636900a3ae60196000858152602001908152602001600020600101546040518263ffffffff1660e01b8152600401611a809190614eca565b60006040518083038186803b158015611a9857600080fd5b505af4158015611aac573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611ad59190613fad565b7330d432918c74193032c0cd03935b02a3e026b933636900a3ae60196000868152602001908152602001600020600101546040518263ffffffff1660e01b8152600401611b229190614eca565b60006040518083038186803b158015611b3a57600080fd5b505af4158015611b4e573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611b779190613fad565b604051602001611b88929190614954565b6040516020818303038152906040529050919050565b6002600a541415611be4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bdb90614e8a565b60405180910390fd5b6002600a81905550611bf46117d8565b73ffffffffffffffffffffffffffffffffffffffff16611c1261273f565b73ffffffffffffffffffffffffffffffffffffffff161415611c9157600060125490506000601281905550611c4561273f565b73ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611c8a573d6000803e3d6000fd5b5050611d4e565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611cd261273f565b73ffffffffffffffffffffffffffffffffffffffff161415611d4d57600060115490506000601181905550611d0561273f565b73ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611d4a573d6000803e3d6000fd5b50505b5b6001600a81905550565b600f5481565b611d6f611d6961273f565b8361296c565b611dae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611da590614e2a565b60405180910390fd5b611dba84848484612d6c565b50505050565b6000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663431512b830846040518363ffffffff1660e01b8152600401611e1f929190614a7f565b60206040518083038186803b158015611e3757600080fd5b505afa158015611e4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e6f9190613c14565b9050919050565b60125481565b600080600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663337b0c6b30856040518363ffffffff1660e01b8152600401611edc929190614a7f565b604080518083038186803b158015611ef357600080fd5b505afa158015611f07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f2b9190613dd7565b91509150915091565b611f3c61273f565b73ffffffffffffffffffffffffffffffffffffffff16611f5a6117d8565b73ffffffffffffffffffffffffffffffffffffffff1614611fb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa790614daa565b60405180910390fd5b601060009054906101000a900460ff1615612000576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ff790614cea565b60405180910390fd5b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001601060006101000a81548160ff02191690831515021790555050565b6060600060405180602001604052806000815250905061207e83612847565b156124015761208b6137bc565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d159b4ae601960008781526020019081526020016000206001015460196000888152602001908152602001600020600001546040518363ffffffff1660e01b8152600401612114929190614f00565b60006040518083038186803b15801561212c57600080fd5b505afa158015612140573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906121699190613e98565b905050809150506000732175b6b2219dcaaf7020cde8f2b59e0a6f373d45632cd80e1083600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e8299b76040518163ffffffff1660e01b815260040160206040518083038186803b1580156121f557600080fd5b505afa158015612209573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061222d9190614155565b6040518363ffffffff1660e01b815260040161224a929190614b40565b6108006040518083038186803b15801561226357600080fd5b505af4158015612277573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229b9190613e6a565b905060005b60088160ff1610156123f95760005b60088160ff1610156123c05784732175b6b2219dcaaf7020cde8f2b59e0a6f373d45639db02b24858560ff16600881106122ec576122eb61548d565b5b60200201518460ff16600881106123065761230561548d565b5b602002015160136014601560166040518663ffffffff1660e01b8152600401612333959493929190614f29565b60006040518083038186803b15801561234b57600080fd5b505af415801561235f573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906123889190613fad565b601860405160200161239c939291906148ff565b604051602081830303815290604052945080806123b8906153a7565b9150506122af565b508360176040516020016123d5929190614930565b604051602081830303815290604052935080806123f1906153a7565b9150506122a0565b50505061243a565b6040518060400160405280600c81526020017f6e6f74207965742063617374000000000000000000000000000000000000000081525090505b6000604051806101a001604052806101748152602001615dee6101749139905060006040518060400160405280601c81526020017f3c2f6469763e3c2f666f726569676e4f626a6563743e3c2f7376673e00000000815250905060008284836040516020016124ab939291906148ce565b604051602081830303815290604052905060006125857330d432918c74193032c0cd03935b02a3e026b933636900a3ae896040518263ffffffff1660e01b81526004016124f89190614eca565b60006040518083038186803b15801561251057600080fd5b505af4158015612524573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061254d9190613fad565b61255689611a31565b61255f85612dc8565b604051602001612571939291906149bb565b604051602081830303815290604052612dc8565b9050806040516020016125989190614999565b60405160208183030381529060405295505050505050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61264f61273f565b73ffffffffffffffffffffffffffffffffffffffff1661266d6117d8565b73ffffffffffffffffffffffffffffffffffffffff16146126c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126ba90614daa565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612733576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161272a90614c2a565b60405180910390fd5b61273c81612ca6565b50565b600033905090565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061281257507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80612822575061282182612f60565b5b9050919050565b612843828260405180602001604052806000815250612fca565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff1661292683611340565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061297782612847565b6129b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129ad90614caa565b60405180910390fd5b60006129c183611340565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612a3057508373ffffffffffffffffffffffffffffffffffffffff16612a1884610dda565b73ffffffffffffffffffffffffffffffffffffffff16145b80612a415750612a4081856125b3565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16612a6a82611340565b73ffffffffffffffffffffffffffffffffffffffff1614612ac0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ab790614dca565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612b30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b2790614c6a565b60405180910390fd5b612b3b838383613025565b612b466000826128b3565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612b96919061523b565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612bed919061515a565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b612d77848484612a4a565b612d8384848484613139565b612dc2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612db990614c0a565b60405180910390fd5b50505050565b60606000825190506000811415612df15760405180602001604052806000815250915050612f5b565b60006003600283612e02919061515a565b612e0c91906151b0565b6004612e1891906151e1565b90506000602082612e29919061515a565b67ffffffffffffffff811115612e4257612e416154bc565b5b6040519080825280601f01601f191660200182016040528015612e745781602001600182028036833780820191505090505b5090506000604051806060016040528060408152602001615f62604091399050600181016020830160005b86811015612f185760038101905062ffffff818a015116603f8160121c168401518060081b905060ff603f83600c1c1686015116810190508060081b905060ff603f8360061c1686015116810190508060081b905060ff603f831686015116810190508060e01b90508084526004840193505050612e9f565b506003860660018114612f325760028114612f4257612f4d565b613d3d60f01b6002830352612f4d565b603d60f81b60018303525b508484525050819450505050505b919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b612fd483836132d0565b612fe16000848484613139565b613020576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161301790614c0a565b60405180910390fd5b505050565b61303083838361349e565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156130735761306e816134a3565b6130b2565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146130b1576130b083826134ec565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156130f5576130f081613659565b613134565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461313357613132828261372a565b5b5b505050565b600061315a8473ffffffffffffffffffffffffffffffffffffffff166137a9565b156132c3578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261318361273f565b8786866040518563ffffffff1660e01b81526004016131a59493929190614a33565b602060405180830381600087803b1580156131bf57600080fd5b505af19250505080156131f057506040513d601f19601f820116820180604052508101906131ed9190613f37565b60015b613273573d8060008114613220576040519150601f19603f3d011682016040523d82523d6000602084013e613225565b606091505b5060008151141561326b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161326290614c0a565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506132c8565b600190505b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613340576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161333790614d6a565b60405180910390fd5b61334981612847565b15613389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161338090614c4a565b60405180910390fd5b61339560008383613025565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546133e5919061515a565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b600060016134f9846113f2565b613503919061523b565b90506000600760008481526020019081526020016000205490508181146135e8576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b6000600160088054905061366d919061523b565b905060006009600084815260200190815260200160002054905060006008838154811061369d5761369c61548d565b5b9060005260206000200154905080600883815481106136bf576136be61548d565b5b90600052602060002001819055508160096000838152602001908152602001600020819055506009600085815260200190815260200160002060009055600880548061370e5761370d61545e565b5b6001900381819060005260206000200160009055905550505050565b6000613735836113f2565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600080823b905060008111915050919050565b6040518061010001604052806008905b6137d46137ea565b8152602001906001900390816137cc5790505090565b604051806101000160405280600890602082028036833780820191505090505090565b600061382061381b84614fbd565b614f98565b905080828561010086028201111561383b5761383a6154f0565b5b60005b8581101561386c57816138518882613ab4565b8452602084019350610100830192505060018101905061383e565b5050509392505050565b600061388961388484614fe3565b614f98565b905080838252602082019050828560208602820111156138ac576138ab6154f0565b5b60005b858110156138fa57815167ffffffffffffffff8111156138d2576138d16154eb565b5b8086016138df8982613b7a565b855260208501945060208401935050506001810190506138af565b5050509392505050565b60006139176139128461500f565b614f98565b90508082856020860282011115613931576139306154f0565b5b60005b8581101561396157816139478882613bd2565b845260208401935060208301925050600181019050613934565b5050509392505050565b600061397e61397984615035565b614f98565b90508281526020810184848401111561399a576139996154f5565b5b6139a5848285615302565b509392505050565b60006139c06139bb84615035565b614f98565b9050828152602081018484840111156139dc576139db6154f5565b5b6139e7848285615311565b509392505050565b6000613a026139fd84615066565b614f98565b905082815260208101848484011115613a1e57613a1d6154f5565b5b613a29848285615311565b509392505050565b600081359050613a4081615d7a565b92915050565b600081519050613a5581615d7a565b92915050565b600082601f830112613a7057613a6f6154eb565b5b6008613a7d84828561380d565b91505092915050565b600082601f830112613a9b57613a9a6154eb565b5b8151613aab848260208601613876565b91505092915050565b600082601f830112613ac957613ac86154eb565b5b6008613ad6848285613904565b91505092915050565b600081359050613aee81615d91565b92915050565b600081359050613b0381615da8565b92915050565b600081519050613b1881615da8565b92915050565b600082601f830112613b3357613b326154eb565b5b8135613b4384826020860161396b565b91505092915050565b600082601f830112613b6157613b606154eb565b5b8151613b718482602086016139ad565b91505092915050565b600082601f830112613b8f57613b8e6154eb565b5b8151613b9f8482602086016139ef565b91505092915050565b600081359050613bb781615dbf565b92915050565b600081519050613bcc81615dbf565b92915050565b600081519050613be181615dd6565b92915050565b600060208284031215613bfd57613bfc6154ff565b5b6000613c0b84828501613a31565b91505092915050565b600060208284031215613c2a57613c296154ff565b5b6000613c3884828501613a46565b91505092915050565b60008060408385031215613c5857613c576154ff565b5b6000613c6685828601613a31565b9250506020613c7785828601613a31565b9150509250929050565b600080600060608486031215613c9a57613c996154ff565b5b6000613ca886828701613a31565b9350506020613cb986828701613a31565b9250506040613cca86828701613ba8565b9150509250925092565b60008060008060808587031215613cee57613ced6154ff565b5b6000613cfc87828801613a31565b9450506020613d0d87828801613a31565b9350506040613d1e87828801613ba8565b925050606085013567ffffffffffffffff811115613d3f57613d3e6154fa565b5b613d4b87828801613b1e565b91505092959194509250565b60008060408385031215613d6e57613d6d6154ff565b5b6000613d7c85828601613a31565b9250506020613d8d85828601613adf565b9150509250929050565b60008060408385031215613dae57613dad6154ff565b5b6000613dbc85828601613a31565b9250506020613dcd85828601613ba8565b9150509250929050565b60008060408385031215613dee57613ded6154ff565b5b6000613dfc85828601613a46565b9250506020613e0d85828601613bbd565b9150509250929050565b600080600060608486031215613e3057613e2f6154ff565b5b6000613e3e86828701613a31565b9350506020613e4f86828701613ba8565b9250506040613e6086828701613ba8565b9150509250925092565b60006108008284031215613e8157613e806154ff565b5b6000613e8f84828501613a5b565b91505092915050565b60008060006108408486031215613eb257613eb16154ff565b5b6000613ec086828701613a5b565b93505061080084015167ffffffffffffffff811115613ee257613ee16154fa565b5b613eee86828701613a86565b925050610820613f0086828701613bbd565b9150509250925092565b600060208284031215613f2057613f1f6154ff565b5b6000613f2e84828501613af4565b91505092915050565b600060208284031215613f4d57613f4c6154ff565b5b6000613f5b84828501613b09565b91505092915050565b600060208284031215613f7a57613f796154ff565b5b600082015167ffffffffffffffff811115613f9857613f976154fa565b5b613fa484828501613b4c565b91505092915050565b600060208284031215613fc357613fc26154ff565b5b600082015167ffffffffffffffff811115613fe157613fe06154fa565b5b613fed84828501613b7a565b91505092915050565b60006020828403121561400c5761400b6154ff565b5b600061401a84828501613ba8565b91505092915050565b60008060006060848603121561403c5761403b6154ff565b5b600061404a86828701613ba8565b935050602061405b86828701613a31565b925050604061406c86828701613ba8565b9150509250925092565b600080600080608085870312156140905761408f6154ff565b5b600061409e87828801613ba8565b94505060206140af87828801613a31565b93505060406140c087828801613ba8565b925050606085013567ffffffffffffffff8111156140e1576140e06154fa565b5b6140ed87828801613b1e565b91505092959194509250565b600080604083850312156141105761410f6154ff565b5b600061411e85828601613ba8565b925050602083013567ffffffffffffffff81111561413f5761413e6154fa565b5b61414b85828601613b1e565b9150509250929050565b60006020828403121561416b5761416a6154ff565b5b600061417984828501613bd2565b91505092915050565b600061418e8383614219565b6101008301905092915050565b60006141a783836148bf565b60208301905092915050565b6141bc8161526f565b82525050565b6141cb816150c0565b6141d58184615106565b92506141e082615097565b8060005b838110156142115781516141f88782614182565b9650614203836150ec565b9250506001810190506141e4565b505050505050565b614222816150cb565b61422c8184615111565b9250614237826150a1565b8060005b8381101561426857815161424f878261419b565b965061425a836150f9565b92505060018101905061423b565b505050505050565b61427981615281565b82525050565b600061428a826150d6565b614294818561511c565b93506142a4818560208601615311565b6142ad81615504565b840191505092915050565b60006142c3826150e1565b6142cd818561512d565b93506142dd818560208601615311565b6142e681615504565b840191505092915050565b60006142fc826150e1565b614306818561514f565b9350614316818560208601615311565b80840191505092915050565b6000815461432f81615344565b614339818661513e565b94506001821660008114614354576001811461436657614399565b60ff1983168652602086019350614399565b61436f856150ab565b60005b8381101561439157815481890152600182019150602081019050614372565b808801955050505b50505092915050565b600081546143af81615344565b6143b9818661514f565b945060018216600081146143d457600181146143e557614418565b60ff19831686528186019350614418565b6143ee856150ab565b60005b83811015614410578154818901526001820191506020810190506143f1565b838801955050505b50505092915050565b600061442e60138361512d565b915061443982615515565b602082019050919050565b6000614451602b8361512d565b915061445c8261553e565b604082019050919050565b600061447460328361512d565b915061447f8261558d565b604082019050919050565b600061449760268361512d565b91506144a2826155dc565b604082019050919050565b60006144ba601c8361512d565b91506144c58261562b565b602082019050919050565b60006144dd601b8361514f565b91506144e882615654565b601b82019050919050565b600061450060248361512d565b915061450b8261567d565b604082019050919050565b600061452360198361512d565b915061452e826156cc565b602082019050919050565b6000614546602c8361512d565b9150614551826156f5565b604082019050919050565b600061456960388361512d565b915061457482615744565b604082019050919050565b600061458d6101118361514f565b915061459882615793565b61011182019050919050565b60006145b160138361512d565b91506145bc826158ed565b602082019050919050565b60006145d4602a8361512d565b91506145df82615916565b604082019050919050565b60006145f760298361512d565b915061460282615965565b604082019050919050565b600061461a60248361514f565b9150614625826159b4565b602482019050919050565b600061463d60158361512d565b915061464882615a03565b602082019050919050565b600061466060028361514f565b915061466b82615a2c565b600282019050919050565b600061468360208361512d565b915061468e82615a55565b602082019050919050565b60006146a6602c8361512d565b91506146b182615a7e565b604082019050919050565b60006146c960208361512d565b91506146d482615acd565b602082019050919050565b60006146ec60298361512d565b91506146f782615af6565b604082019050919050565b600061470f60038361514f565b915061471a82615b45565b600382019050919050565b6000614732600c8361512d565b915061473d82615b6e565b602082019050919050565b600061475560218361512d565b915061476082615b97565b604082019050919050565b6000614778601d8361514f565b915061478382615be6565b601d82019050919050565b600061479b60318361512d565b91506147a682615c0f565b604082019050919050565b60006147be60118361512d565b91506147c982615c5e565b602082019050919050565b60006147e1602c8361512d565b91506147ec82615c87565b604082019050919050565b6000614804601f8361512d565b915061480f82615cd6565b602082019050919050565b6000614827600a8361512d565b915061483282615cff565b602082019050919050565b600061484a600c8361514f565b915061485582615d28565b600c82019050919050565b600061486d60148361514f565b915061487882615d51565b601482019050919050565b61488c816152d9565b82525050565b61489b816152d9565b82525050565b6148aa816152f0565b82525050565b6148b9816152e3565b82525050565b6148c8816152e3565b82525050565b60006148da82866142f1565b91506148e682856142f1565b91506148f282846142f1565b9150819050949350505050565b600061490b82866142f1565b915061491782856142f1565b915061492382846143a2565b9150819050949350505050565b600061493c82856142f1565b915061494882846143a2565b91508190509392505050565b600061495f826144d0565b915061496b82856142f1565b91506149768261483d565b915061498282846142f1565b915061498d82614702565b91508190509392505050565b60006149a48261476b565b91506149b082846142f1565b915081905092915050565b60006149c682614860565b91506149d282866142f1565b91506149dd8261457f565b91506149e982856142f1565b91506149f48261460d565b9150614a0082846142f1565b9150614a0b82614653565b9150819050949350505050565b6000602082019050614a2d60008301846141b3565b92915050565b6000608082019050614a4860008301876141b3565b614a5560208301866141b3565b614a626040830185614883565b8181036060830152614a74818461427f565b905095945050505050565b6000604082019050614a9460008301856141b3565b614aa16020830184614883565b9392505050565b600060a082019050614abd60008301886141b3565b614aca6020830187614883565b614ad760408301866141b3565b614ae46060830185614883565b8181036080830152614af6818461427f565b90509695505050505050565b6000606082019050614b1760008301866141b3565b614b246020830185614883565b8181036040830152614b36818461427f565b9050949350505050565b600061082082019050614b5660008301856141c2565b614b646108008301846148b0565b9392505050565b6000602082019050614b806000830184614270565b92915050565b60006020820190508181036000830152614ba0818461427f565b905092915050565b60006020820190508181036000830152614bc281846142b8565b905092915050565b60006020820190508181036000830152614be381614421565b9050919050565b60006020820190508181036000830152614c0381614444565b9050919050565b60006020820190508181036000830152614c2381614467565b9050919050565b60006020820190508181036000830152614c438161448a565b9050919050565b60006020820190508181036000830152614c63816144ad565b9050919050565b60006020820190508181036000830152614c83816144f3565b9050919050565b60006020820190508181036000830152614ca381614516565b9050919050565b60006020820190508181036000830152614cc381614539565b9050919050565b60006020820190508181036000830152614ce38161455c565b9050919050565b60006020820190508181036000830152614d03816145a4565b9050919050565b60006020820190508181036000830152614d23816145c7565b9050919050565b60006020820190508181036000830152614d43816145ea565b9050919050565b60006020820190508181036000830152614d6381614630565b9050919050565b60006020820190508181036000830152614d8381614676565b9050919050565b60006020820190508181036000830152614da381614699565b9050919050565b60006020820190508181036000830152614dc3816146bc565b9050919050565b60006020820190508181036000830152614de3816146df565b9050919050565b60006020820190508181036000830152614e0381614725565b9050919050565b60006020820190508181036000830152614e2381614748565b9050919050565b60006020820190508181036000830152614e438161478e565b9050919050565b60006020820190508181036000830152614e63816147b1565b9050919050565b60006020820190508181036000830152614e83816147d4565b9050919050565b60006020820190508181036000830152614ea3816147f7565b9050919050565b60006020820190508181036000830152614ec38161481a565b9050919050565b6000602082019050614edf6000830184614892565b92915050565b6000602082019050614efa6000830184614883565b92915050565b6000604082019050614f156000830185614883565b614f226020830184614883565b9392505050565b600060a082019050614f3e60008301886148a1565b8181036020830152614f508187614322565b90508181036040830152614f648186614322565b90508181036060830152614f788185614322565b90508181036080830152614f8c8184614322565b90509695505050505050565b6000614fa2614fb3565b9050614fae8282615376565b919050565b6000604051905090565b600067ffffffffffffffff821115614fd857614fd76154bc565b5b602082029050919050565b600067ffffffffffffffff821115614ffe57614ffd6154bc565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561502a576150296154bc565b5b602082029050919050565b600067ffffffffffffffff8211156150505761504f6154bc565b5b61505982615504565b9050602081019050919050565b600067ffffffffffffffff821115615081576150806154bc565b5b61508a82615504565b9050602081019050919050565b6000819050919050565b6000819050919050565b60008190508160005260206000209050919050565b600060089050919050565b600060089050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600081905092915050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000615165826152d9565b9150615170836152d9565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156151a5576151a46153d1565b5b828201905092915050565b60006151bb826152d9565b91506151c6836152d9565b9250826151d6576151d5615400565b5b828204905092915050565b60006151ec826152d9565b91506151f7836152d9565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156152305761522f6153d1565b5b828202905092915050565b6000615246826152d9565b9150615251836152d9565b925082821015615264576152636153d1565b5b828203905092915050565b600061527a826152b9565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60006152fb826152e3565b9050919050565b82818337600083830152505050565b60005b8381101561532f578082015181840152602081019050615314565b8381111561533e576000848401525b50505050565b6000600282049050600182168061535c57607f821691505b602082108114156153705761536f61542f565b5b50919050565b61537f82615504565b810181811067ffffffffffffffff8211171561539e5761539d6154bc565b5b80604052505050565b60006153b2826152e3565b915060ff8214156153c6576153c56153d1565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f6e6f7420796f75727320746f20756e62696e6400000000000000000000000000600082015250565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f2261747472696275746573223a205b7b2022656e74697479223a200000000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f222c20226465736372697074696f6e223a202246756e6374696f6e732061726560008201527f20736563756c6172697a656420696e63616e746174696f6e7320617320636f6460208201527f652e20412058655f6e746974792069732058207768657265205828656e74697460408201527f7929203d20656e746974795e2e205061727469636970616e747320746861742060608201527f6f776e20616e20656e746974792063616e206361737420612078655f6e74697460808201527f792066726f6d2069742c207472616e73666f726d696e672074686520656e746960a08201527f747920696e207468652070726f636573732e202a456e7320646976696e756d2060c08201527f636f676e6f73636962696c652070657220696e737069726174696f6e656d206560e08201527f73742073756269656374756d2a3d3f222c00000000000000000000000000000061010082015250565b7f616c726561647920696e697469616c697a656400000000000000000000000000600082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b7f22696d616765223a2022646174613a696d6167652f7376672b786d6c3b62617360008201527f6536342c00000000000000000000000000000000000000000000000000000000602082015250565b7f696e73756666696369656e74206f66666572696e670000000000000000000000600082015250565b7f227d000000000000000000000000000000000000000000000000000000000000600082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f7d5d2c0000000000000000000000000000000000000000000000000000000000600082015250565b7f6e6f742062696e6461626c650000000000000000000000000000000000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b7f6e6f7420796f75727320746f2062696e64000000000000000000000000000000600082015250565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b7f6f6e6c79456e7469747900000000000000000000000000000000000000000000600082015250565b7f7d2c7b20227469636b223a200000000000000000000000000000000000000000600082015250565b7f7b226e616d65223a202258655f6e746974792023000000000000000000000000600082015250565b615d838161526f565b8114615d8e57600080fd5b50565b615d9a81615281565b8114615da557600080fd5b50565b615db18161528d565b8114615dbc57600080fd5b50565b615dc8816152d9565b8114615dd357600080fd5b50565b615ddf816152e3565b8114615dea57600080fd5b5056fe3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207072657365727665417370656374526174696f3d22784d696e594d696e206d656574222076696577426f783d223020302036363620383838223e3c7374796c653e2e78656e207b20636f6c6f723a20626c61636b3b20666f6e742d66616d696c793a2073657269663b20666f6e742d73697a653a20313970783b206c696e652d6865696768743a20313970783b2077686974652d73706163653a20627265616b2d7370616365733b207d3c2f7374796c653e3c726563742077696474683d223130302522206865696768743d2231303025222066696c6c3d2272656422202f3e3c666f726569676e4f626a65637420783d2239302220793d223930222077696474683d2234383622206865696768743d223739382220636c6173733d2278656e223e3c64697620786d6c6e733d22687474703a2f2f7777772e77332e6f72672f313939392f7868746d6c223e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa264697066735822122092e9988b2565cb2c31880566e86082c195bcf63e54fa43a54a30cad604b543ed64736f6c63430008060033

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

0000000000000000000000002f59aa8b33b0db6ef148f9be2b88a896bd908e9b000000000000000000000000000000000000000000000000001f438daa060000

-----Decoded View---------------
Arg [0] : _artist (address): 0x2F59Aa8B33b0Db6EF148F9bE2B88A896bd908e9B
Arg [1] : _offering (uint256): 8800000000000000

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000002f59aa8b33b0db6ef148f9be2b88a896bd908e9b
Arg [1] : 000000000000000000000000000000000000000000000000001f438daa060000


Deployed Bytecode Sourcemap

2230:9598:21:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7821:510;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;910:222:6;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6788:253:21;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2349:98:5;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2467:32:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3860:217:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3398:401;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2432:31:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1535:111:6;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10651:168:21;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4724:330:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;7314:188:21;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1211:253:6;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5120:179:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2380:21:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2347:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10261:166;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3311:41;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;1718:230:6;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2052:235:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1790:205;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1598:92:17;;;;;;;;;;;;;:::i;:::-;;8865:413:21;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;966:85:17;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2511:102:5;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8528:94:21;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4144:290:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3976:304:21;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10898:336;;;;;;;;;;;;;:::i;:::-;;2405:23;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5365:320:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;9901:159:21;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2503:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;9537:168;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;11353:180;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4498:2020;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4500:162:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1839:189:17;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;7821:510:21;1680:1:18;2259:7;;:19;;2251:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;1680:1;2389:7;:18;;;;7991:8:21::1;;;;;;;;;;;7983:33;;;;;;;;;;;;:::i;:::-;;;;;;;;;8046:20;8054:11;8046:7;:20::i;:::-;8030:36;;:12;:10;:12::i;:::-;:36;;;8022:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;8115:8;;8102:9;:21;;8094:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;8156:9;;;;;;;;;;;:14;;;8179:4;8186:11;8199:17;8218:16;8236:5;8156:86;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;8275:1;8265:9;:11;;;;:::i;:::-;8249:12;;:27;;;;;;;:::i;:::-;;;;;;;;8323:1;8313:9;:11;;;;:::i;:::-;8300:9;:25;;;;:::i;:::-;8282:13;;:44;;;;;;;:::i;:::-;;;;;;;;1637:1:18::0;2562:7;:22;;;;7821:510:21;;;;:::o;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;6788:253:21:-;6895:7;1680:1:18;2259:7;;:19;;2251:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;1680:1;2389:7;:18;;;;3490:6:21::1;;;;;;;;;;;3468:29;;:10;:29;;;3460:52;;;;;;;;;;;;:::i;:::-;;;;;;;;;6909:35:::2;6919:7;6942:1;6928:13;:11;:13::i;:::-;:15;;;;:::i;:::-;6909:9;:35::i;:::-;6988:22;;;;;;;;6993:5;6988:22;;;;7000:9;6988:22;;::::0;6962:8:::2;:23;6971:13;:11;:13::i;:::-;6962:23;;;;;;;;;;;:48;;;;;;;;;;;;;;;;;;;7023:13;:11;:13::i;:::-;7016:20;;1637:1:18::0;2562:7;:22;;;;6788:253:21;;;;;:::o;2349:98:5:-;2403:13;2435:5;2428:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2349:98;:::o;2467:32:21:-;;;;:::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;2432:31:21:-;;;;;;;;;;;;;:::o;1535:111:6:-;1596:7;1622:10;:17;;;;1615:24;;1535:111;:::o;10651:168:21:-;1189:12:17;:10;:12::i;:::-;1178:23;;:7;:5;:7::i;:::-;:23;;;1170:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;10770:17:21::1;10741:9;;:47;;;;;;;;;;;;;;;;;;10805:9;10794:8;;:20;;;;;;;;;;;;;;;;;;10651:168:::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;7314:188:21:-;7439:58;7444:11;7457:17;7476:16;7439:58;;;;;;;;;;;;:4;:58::i;:::-;7314:188;;;:::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;5120:179:5:-;5253:39;5270:4;5276:2;5280:7;5253:39;;;;;;;;;;;;:16;:39::i;:::-;5120:179;;;:::o;2380:21:21:-;;;;;;;;;;;;;:::o;2347:28::-;;;;;;;;;;;;;:::o;10261:166::-;10340:12;10367:9;;;;;;;;;;;:27;;;10403:4;10410:11;10367:55;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10360:62;;10261:166;;;:::o;3311:41::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::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;1790:205::-;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;8865:413:21:-;1680:1:18;2259:7;;:19;;2251:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;1680:1;2389:7;:18;;;;8992:9:21::1;;;;;;;;;;;:26;;;9027:4;9034:11;8992:54;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8976:70;;:12;:10;:12::i;:::-;:70;;;8968:102;;;;;;;;;;;;:::i;:::-;;;;;;;;;9097:8;;9084:9;:21;;9076:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;9138:9;;;;;;;;;;;:16;;;9163:4;9170:11;9183:5;9138:51;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;9222:1;9212:9;:11;;;;:::i;:::-;9196:12;;:27;;;;;;;:::i;:::-;;;;;;;;9270:1;9260:9;:11;;;;:::i;:::-;9247:9;:25;;;;:::i;:::-;9229:13;;:44;;;;;;;:::i;:::-;;;;;;;;1637:1:18::0;2562:7;:22;;;;8865:413:21;;:::o;966:85:17:-;1012:7;1038:6;;;;;;;;;;;1031:13;;966:85;:::o;2511:102:5:-;2567:13;2599:7;2592:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2511:102;:::o;8528:94:21:-;8594:23;8601:11;8594:23;;;;;;;;;;;;:6;:23::i;:::-;8528:94;:::o;4144:290:5:-;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;3976:304:21:-;4039:13;4135:7;:16;4152:8;:18;4161:8;4152:18;;;;;;;;;;;:27;;;4135:45;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4210:7;:16;4227:8;:18;4236:8;4227:18;;;;;;;;;;;:27;;;4210:45;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4074:200;;;;;;;;;:::i;:::-;;;;;;;;;;;;;4060:215;;3976:304;;;:::o;10898:336::-;1680:1:18;2259:7;;:19;;2251:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;1680:1;2389:7;:18;;;;10981:7:21::1;:5;:7::i;:::-;10965:23;;:12;:10;:12::i;:::-;:23;;;10962:268;;;10997:9;11009:12;;10997:24;;11044:1;11029:12;:16;;;;11061:12;:10;:12::i;:::-;11053:30;;:33;11084:1;11053:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;10989:104;10962:268;;;11117:6;;;;;;;;;;;11101:22;;:12;:10;:12::i;:::-;:22;;;11098:132;;;11132:9;11144:13;;11132:25;;11181:1;11165:13;:17;;;;11198:12;:10;:12::i;:::-;11190:30;;:33;11221:1;11190:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;11124:106;11098:132;10962:268;1637:1:18::0;2562:7;:22;;;;10898:336:21:o;2405: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;9901:159:21:-;9979:7;10001:9;;;;;;;;;;;:26;;;10036:4;10043:11;10001:54;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9994:61;;9901:159;;;:::o;2503:31::-;;;;:::o;9537:168::-;9615:7;9624;9646:9;;;;;;;;;;;:26;;;9681:4;9688:11;9646:54;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9639:61;;;;9537:168;;;:::o;11353:180::-;1189:12:17;:10;:12::i;:::-;1178:23;;:7;:5;:7::i;:::-;:23;;;1170:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;11431:11:21::1;;;;;;;;;;;11430:12;11422:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;11489:14;11472:6;;:32;;;;;;;;;;;;;;;;;;11524:4;11510:11;;:18;;;;;;;;;;;;;;;;;;11353:180:::0;:::o;4498:2020::-;4564:13;4586:15;:20;;;;;;;;;;;;;;4617:17;4625:8;4617:7;:17::i;:::-;4614:628;;;4644:24;;:::i;:::-;4689:6;;;;;;;;;;;:14;;;4704:8;:18;4713:8;4704:18;;;;;;;;;;;:27;;;4733:8;:18;4742:8;4733:18;;;;;;;;;;;:23;;;4689:68;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4677:80;;;;;;;4767:28;4798:10;:20;4819:5;4826:6;;;;;;;;;;;:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4798:47;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4767:78;;4859:7;4855:341;4876:1;4872;:5;;;4855:341;;;4898:7;4894:236;4915:1;4911;:5;;;4894:236;;;4977:1;4993:10;:19;5013:9;5023:1;5013:12;;;;;;;;;:::i;:::-;;;;;;5026:1;5013:15;;;;;;;;;:::i;:::-;;;;;;5030:3;5035:12;5049:13;5064:11;4993:83;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5091:13;4946:171;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;4935:183;;4918:3;;;;;:::i;:::-;;;;4894:236;;;;5168:1;5171:13;5151:34;;;;;;;;;:::i;:::-;;;;;;;;;;;;;5140:46;;4879:3;;;;;:::i;:::-;;;;4855:341;;;;4635:568;;4614:628;;;5216:18;;;;;;;;;;;;;;;;;;;4614:628;5249:20;:397;;;;;;;;;;;;;;;;;;;5654:21;:54;;;;;;;;;;;;;;;;;;;5716:20;5763:6;5771:1;5774:7;5746:36;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;5716:67;;5791:18;5812:622;5937:7;:16;5954:8;5937:26;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6268:24;6283:8;6268:14;:24::i;:::-;6360:28;6380:6;6360:13;:28::i;:::-;5869:538;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;5812:13;:622::i;:::-;5791:643;;6506:4;6456:55;;;;;;;;:::i;:::-;;;;;;;;;;;;;6442:70;;;;;;;4498:2020;;;:::o;4500:162:5:-;4597:4;4620:18;:25;4639:5;4620:25;;;;;;;;;;;;;;;:35;4646:8;4620:35;;;;;;;;;;;;;;;;;;;;;;;;;4613:42;;4500:162;;;;:::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;587:96:2:-;640:7;666:10;659:17;;587:96;:::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;8114:108::-;8189:26;8199:2;8203:7;8189:26;;;;;;;;;;;;:9;:26::i;:::-;8114:108;;:::o;7157:125::-;7222:4;7273:1;7245:30;;:7;:16;7253:7;7245:16;;;;;;;;;;;;;;;;;;;;;:30;;;;7238:37;;7157:125;;;:::o;11008:171::-;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;396:1557:1:-;454:13;479:11;493:4;:11;479:25;;525:1;518:3;:8;514:23;;;528:9;;;;;;;;;;;;;;;;;514:23;586:18;624:1;619;613:3;:7;;;;:::i;:::-;612:13;;;;:::i;:::-;607:1;:19;;;;:::i;:::-;586:40;;681:19;726:2;713:10;:15;;;;:::i;:::-;703:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;681:48;;740:18;761:5;;;;;;;;;;;;;;;;;740:26;;827:1;820:5;816:13;871:2;863:6;859:15;919:1;888:757;941:3;938:1;935:10;888:757;;;993:1;990;986:9;981:14;;1050:8;1045:1;1039:4;1035:12;1029:19;1025:34;1128:4;1120:5;1116:2;1112:14;1108:25;1098:8;1094:40;1088:47;1166:3;1163:1;1159:11;1152:18;;1256:4;1247;1239:5;1235:2;1231:14;1227:25;1217:8;1213:40;1207:47;1203:58;1198:3;1194:68;1187:75;;1293:3;1290:1;1286:11;1279:18;;1382:4;1373;1365:5;1362:1;1358:13;1354:24;1344:8;1340:39;1334:46;1330:57;1325:3;1321:67;1314:74;;1419:3;1416:1;1412:11;1405:18;;1500:4;1491;1484:5;1480:16;1470:8;1466:31;1460:38;1456:49;1451:3;1447:59;1440:66;;1539:3;1534;1530:13;1523:20;;1579:3;1568:9;1561:22;1629:1;1618:9;1614:17;1601:30;;963:682;;888:757;;;892:42;1675:1;1670:3;1666:11;1695:1;1690:82;;;;1790:1;1785:80;;;;1659:206;;1690:82;1750:6;1745:3;1741:16;1737:1;1726:9;1722:17;1715:43;1690:82;;1785:80;1845:4;1840:3;1836:14;1832:1;1821:9;1817:17;1810:41;1659:206;;1894:10;1886:6;1879:26;786:1129;;1939:6;1925:21;;;;;;396:1557;;;;:::o;763:155:4:-;848:4;886:25;871:40;;;:11;:40;;;;864:47;;763:155;;;:::o;8443:311:5:-;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;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;9076:372::-;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;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;-1:-1:-1:-;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::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:419::-;2967:5;2992:65;3008:48;3049:6;3008:48;:::i;:::-;2992:65;:::i;:::-;2983:74;;3080:6;3073:5;3066:21;3118:4;3111:5;3107:16;3156:3;3147:6;3142:3;3138:16;3135:25;3132:2;;;3163:79;;:::i;:::-;3132:2;3253:39;3285:6;3280:3;3275;3253:39;:::i;:::-;2973:325;;;;;;:::o;3304:421::-;3393:5;3418:66;3434:49;3476:6;3434:49;:::i;:::-;3418:66;:::i;:::-;3409:75;;3507:6;3500:5;3493:21;3545:4;3538:5;3534:16;3583:3;3574:6;3569:3;3565:16;3562:25;3559:2;;;3590:79;;:::i;:::-;3559:2;3680:39;3712:6;3707:3;3702;3680:39;:::i;:::-;3399:326;;;;;;:::o;3731:139::-;3777:5;3815:6;3802:20;3793:29;;3831:33;3858:5;3831:33;:::i;:::-;3783:87;;;;:::o;3876:143::-;3933:5;3964:6;3958:13;3949:22;;3980:33;4007:5;3980:33;:::i;:::-;3939:80;;;;:::o;4044:403::-;4145:5;4194:3;4187:4;4179:6;4175:17;4171:27;4161:2;;4202:79;;:::i;:::-;4161:2;4306:4;4328:113;4437:3;4429:6;4421;4328:113;:::i;:::-;4319:122;;4151:296;;;;;:::o;4469:405::-;4561:5;4610:3;4603:4;4595:6;4591:17;4587:27;4577:2;;4618:79;;:::i;:::-;4577:2;4728:6;4722:13;4753:115;4864:3;4856:6;4849:4;4841:6;4837:17;4753:115;:::i;:::-;4744:124;;4567:307;;;;;:::o;4896:357::-;4974:5;5023:3;5016:4;5008:6;5004:17;5000:27;4990:2;;5031:79;;:::i;:::-;4990:2;5135:4;5157:90;5243:3;5235:6;5227;5157:90;:::i;:::-;5148:99;;4980:273;;;;;:::o;5259:133::-;5302:5;5340:6;5327:20;5318:29;;5356:30;5380:5;5356:30;:::i;:::-;5308:84;;;;:::o;5398:137::-;5443:5;5481:6;5468:20;5459:29;;5497:32;5523:5;5497:32;:::i;:::-;5449:86;;;;:::o;5541:141::-;5597:5;5628:6;5622:13;5613:22;;5644:32;5670:5;5644:32;:::i;:::-;5603:79;;;;:::o;5701:338::-;5756:5;5805:3;5798:4;5790:6;5786:17;5782:27;5772:2;;5813:79;;:::i;:::-;5772:2;5930:6;5917:20;5955:78;6029:3;6021:6;6014:4;6006:6;6002:17;5955:78;:::i;:::-;5946:87;;5762:277;;;;;:::o;6058:353::-;6124:5;6173:3;6166:4;6158:6;6154:17;6150:27;6140:2;;6181:79;;:::i;:::-;6140:2;6291:6;6285:13;6316:89;6401:3;6393:6;6386:4;6378:6;6374:17;6316:89;:::i;:::-;6307:98;;6130:281;;;;;:::o;6431:355::-;6498:5;6547:3;6540:4;6532:6;6528:17;6524:27;6514:2;;6555:79;;:::i;:::-;6514:2;6665:6;6659:13;6690:90;6776:3;6768:6;6761:4;6753:6;6749:17;6690:90;:::i;:::-;6681:99;;6504:282;;;;;:::o;6792:139::-;6838:5;6876:6;6863:20;6854:29;;6892:33;6919:5;6892:33;:::i;:::-;6844:87;;;;:::o;6937:143::-;6994:5;7025:6;7019:13;7010:22;;7041:33;7068:5;7041:33;:::i;:::-;7000:80;;;;:::o;7086:139::-;7141:5;7172:6;7166:13;7157:22;;7188:31;7213:5;7188:31;:::i;:::-;7147:78;;;;:::o;7231:329::-;7290:6;7339:2;7327:9;7318:7;7314:23;7310:32;7307:2;;;7345:79;;:::i;:::-;7307:2;7465:1;7490:53;7535:7;7526:6;7515:9;7511:22;7490:53;:::i;:::-;7480:63;;7436:117;7297:263;;;;:::o;7566:351::-;7636:6;7685:2;7673:9;7664:7;7660:23;7656:32;7653:2;;;7691:79;;:::i;:::-;7653:2;7811:1;7836:64;7892:7;7883:6;7872:9;7868:22;7836:64;:::i;:::-;7826:74;;7782:128;7643:274;;;;:::o;7923:474::-;7991:6;7999;8048:2;8036:9;8027:7;8023:23;8019:32;8016:2;;;8054:79;;:::i;:::-;8016:2;8174:1;8199:53;8244:7;8235:6;8224:9;8220:22;8199:53;:::i;:::-;8189:63;;8145:117;8301:2;8327:53;8372:7;8363:6;8352:9;8348:22;8327:53;:::i;:::-;8317:63;;8272:118;8006:391;;;;;:::o;8403:619::-;8480:6;8488;8496;8545:2;8533:9;8524:7;8520:23;8516:32;8513:2;;;8551:79;;:::i;:::-;8513:2;8671:1;8696:53;8741:7;8732:6;8721:9;8717:22;8696:53;:::i;:::-;8686:63;;8642:117;8798:2;8824:53;8869:7;8860:6;8849:9;8845:22;8824:53;:::i;:::-;8814:63;;8769:118;8926:2;8952:53;8997:7;8988:6;8977:9;8973:22;8952:53;:::i;:::-;8942:63;;8897:118;8503:519;;;;;:::o;9028:943::-;9123:6;9131;9139;9147;9196:3;9184:9;9175:7;9171:23;9167:33;9164:2;;;9203:79;;:::i;:::-;9164:2;9323:1;9348:53;9393:7;9384:6;9373:9;9369:22;9348:53;:::i;:::-;9338:63;;9294:117;9450:2;9476:53;9521:7;9512:6;9501:9;9497:22;9476:53;:::i;:::-;9466:63;;9421:118;9578:2;9604:53;9649:7;9640:6;9629:9;9625:22;9604:53;:::i;:::-;9594:63;;9549:118;9734:2;9723:9;9719:18;9706:32;9765:18;9757:6;9754:30;9751:2;;;9787:79;;:::i;:::-;9751:2;9892:62;9946:7;9937:6;9926:9;9922:22;9892:62;:::i;:::-;9882:72;;9677:287;9154:817;;;;;;;:::o;9977:468::-;10042:6;10050;10099:2;10087:9;10078:7;10074:23;10070:32;10067:2;;;10105:79;;:::i;:::-;10067:2;10225:1;10250:53;10295:7;10286:6;10275:9;10271:22;10250:53;:::i;:::-;10240:63;;10196:117;10352:2;10378:50;10420:7;10411:6;10400:9;10396:22;10378:50;:::i;:::-;10368:60;;10323:115;10057:388;;;;;:::o;10451:474::-;10519:6;10527;10576:2;10564:9;10555:7;10551:23;10547:32;10544:2;;;10582:79;;:::i;:::-;10544:2;10702:1;10727:53;10772:7;10763:6;10752:9;10748:22;10727:53;:::i;:::-;10717:63;;10673:117;10829:2;10855:53;10900:7;10891:6;10880:9;10876:22;10855:53;:::i;:::-;10845:63;;10800:118;10534:391;;;;;:::o;10931:507::-;11010:6;11018;11067:2;11055:9;11046:7;11042:23;11038:32;11035:2;;;11073:79;;:::i;:::-;11035:2;11193:1;11218:64;11274:7;11265:6;11254:9;11250:22;11218:64;:::i;:::-;11208:74;;11164:128;11331:2;11357:64;11413:7;11404:6;11393:9;11389:22;11357:64;:::i;:::-;11347:74;;11302:129;11025:413;;;;;:::o;11444:619::-;11521:6;11529;11537;11586:2;11574:9;11565:7;11561:23;11557:32;11554:2;;;11592:79;;:::i;:::-;11554:2;11712:1;11737:53;11782:7;11773:6;11762:9;11758:22;11737:53;:::i;:::-;11727:63;;11683:117;11839:2;11865:53;11910:7;11901:6;11890:9;11886:22;11865:53;:::i;:::-;11855:63;;11810:118;11967:2;11993:53;12038:7;12029:6;12018:9;12014:22;11993:53;:::i;:::-;11983:63;;11938:118;11544:519;;;;;:::o;12069:441::-;12183:6;12232:4;12220:9;12211:7;12207:23;12203:34;12200:2;;;12240:79;;:::i;:::-;12200:2;12360:1;12385:108;12485:7;12476:6;12465:9;12461:22;12385:108;:::i;:::-;12375:118;;12331:172;12190:320;;;;:::o;12516:980::-;12683:6;12691;12699;12748:4;12736:9;12727:7;12723:23;12719:34;12716:2;;;12756:79;;:::i;:::-;12716:2;12876:1;12901:108;13001:7;12992:6;12981:9;12977:22;12901:108;:::i;:::-;12891:118;;12847:172;13079:4;13068:9;13064:20;13058:27;13112:18;13104:6;13101:30;13098:2;;;13134:79;;:::i;:::-;13098:2;13239:99;13330:7;13321:6;13310:9;13306:22;13239:99;:::i;:::-;13229:109;;13029:319;13387:4;13415:64;13471:7;13462:6;13451:9;13447:22;13415:64;:::i;:::-;13405:74;;13358:131;12706:790;;;;;:::o;13502:327::-;13560:6;13609:2;13597:9;13588:7;13584:23;13580:32;13577:2;;;13615:79;;:::i;:::-;13577:2;13735:1;13760:52;13804:7;13795:6;13784:9;13780:22;13760:52;:::i;:::-;13750:62;;13706:116;13567:262;;;;:::o;13835:349::-;13904:6;13953:2;13941:9;13932:7;13928:23;13924:32;13921:2;;;13959:79;;:::i;:::-;13921:2;14079:1;14104:63;14159:7;14150:6;14139:9;14135:22;14104:63;:::i;:::-;14094:73;;14050:127;13911:273;;;;:::o;14190:522::-;14269:6;14318:2;14306:9;14297:7;14293:23;14289:32;14286:2;;;14324:79;;:::i;:::-;14286:2;14465:1;14454:9;14450:17;14444:24;14495:18;14487:6;14484:30;14481:2;;;14517:79;;:::i;:::-;14481:2;14622:73;14687:7;14678:6;14667:9;14663:22;14622:73;:::i;:::-;14612:83;;14415:290;14276:436;;;;:::o;14718:524::-;14798:6;14847:2;14835:9;14826:7;14822:23;14818:32;14815:2;;;14853:79;;:::i;:::-;14815:2;14994:1;14983:9;14979:17;14973:24;15024:18;15016:6;15013:30;15010:2;;;15046:79;;:::i;:::-;15010:2;15151:74;15217:7;15208:6;15197:9;15193:22;15151:74;:::i;:::-;15141:84;;14944:291;14805:437;;;;:::o;15248:329::-;15307:6;15356:2;15344:9;15335:7;15331:23;15327:32;15324:2;;;15362:79;;:::i;:::-;15324:2;15482:1;15507:53;15552:7;15543:6;15532:9;15528:22;15507:53;:::i;:::-;15497:63;;15453:117;15314:263;;;;:::o;15583:619::-;15660:6;15668;15676;15725:2;15713:9;15704:7;15700:23;15696:32;15693:2;;;15731:79;;:::i;:::-;15693:2;15851:1;15876:53;15921:7;15912:6;15901:9;15897:22;15876:53;:::i;:::-;15866:63;;15822:117;15978:2;16004:53;16049:7;16040:6;16029:9;16025:22;16004:53;:::i;:::-;15994:63;;15949:118;16106:2;16132:53;16177:7;16168:6;16157:9;16153:22;16132:53;:::i;:::-;16122:63;;16077:118;15683:519;;;;;:::o;16208:943::-;16303:6;16311;16319;16327;16376:3;16364:9;16355:7;16351:23;16347:33;16344:2;;;16383:79;;:::i;:::-;16344:2;16503:1;16528:53;16573:7;16564:6;16553:9;16549:22;16528:53;:::i;:::-;16518:63;;16474:117;16630:2;16656:53;16701:7;16692:6;16681:9;16677:22;16656:53;:::i;:::-;16646:63;;16601:118;16758:2;16784:53;16829:7;16820:6;16809:9;16805:22;16784:53;:::i;:::-;16774:63;;16729:118;16914:2;16903:9;16899:18;16886:32;16945:18;16937:6;16934:30;16931:2;;;16967:79;;:::i;:::-;16931:2;17072:62;17126:7;17117:6;17106:9;17102:22;17072:62;:::i;:::-;17062:72;;16857:287;16334:817;;;;;;;:::o;17157:652::-;17234:6;17242;17291:2;17279:9;17270:7;17266:23;17262:32;17259:2;;;17297:79;;:::i;:::-;17259:2;17417:1;17442:53;17487:7;17478:6;17467:9;17463:22;17442:53;:::i;:::-;17432:63;;17388:117;17572:2;17561:9;17557:18;17544:32;17603:18;17595:6;17592:30;17589:2;;;17625:79;;:::i;:::-;17589:2;17730:62;17784:7;17775:6;17764:9;17760:22;17730:62;:::i;:::-;17720:72;;17515:287;17249:560;;;;;:::o;17815:347::-;17883:6;17932:2;17920:9;17911:7;17907:23;17903:32;17900:2;;;17938:79;;:::i;:::-;17900:2;18058:1;18083:62;18137:7;18128:6;18117:9;18113:22;18083:62;:::i;:::-;18073:72;;18029:126;17890:272;;;;:::o;18168:281::-;18287:10;18308:96;18400:3;18392:6;18308:96;:::i;:::-;18436:6;18431:3;18427:16;18413:30;;18298:151;;;;:::o;18455:187::-;18528:10;18549:50;18595:3;18587:6;18549:50;:::i;:::-;18631:4;18626:3;18622:14;18608:28;;18539:103;;;;:::o;18648:118::-;18735:24;18753:5;18735:24;:::i;:::-;18730:3;18723:37;18713:53;;:::o;18806:886::-;18992:73;19059:5;18992:73;:::i;:::-;19081:113;19187:6;19182:3;19081:113;:::i;:::-;19074:120;;19218:75;19287:5;19218:75;:::i;:::-;19316:7;19347:1;19332:353;19357:6;19354:1;19351:13;19332:353;;;19433:6;19427:13;19460:113;19569:3;19554:13;19460:113;:::i;:::-;19453:120;;19596:79;19668:6;19596:79;:::i;:::-;19586:89;;19392:293;19379:1;19376;19372:9;19367:14;;19332:353;;;19336:14;18968:724;;;;;:::o;19726:682::-;19856:50;19900:5;19856:50;:::i;:::-;19922:80;19995:6;19990:3;19922:80;:::i;:::-;19915:87;;20026:52;20072:5;20026:52;:::i;:::-;20101:7;20132:1;20117:284;20142:6;20139:1;20136:13;20117:284;;;20218:6;20212:13;20245:67;20308:3;20293:13;20245:67;:::i;:::-;20238:74;;20335:56;20384:6;20335:56;:::i;:::-;20325:66;;20177:224;20164:1;20161;20157:9;20152:14;;20117:284;;;20121:14;19832:576;;;;;:::o;20414:109::-;20495:21;20510:5;20495:21;:::i;:::-;20490:3;20483:34;20473:50;;:::o;20529:360::-;20615:3;20643:38;20675:5;20643:38;:::i;:::-;20697:70;20760:6;20755:3;20697:70;:::i;:::-;20690:77;;20776:52;20821:6;20816:3;20809:4;20802:5;20798:16;20776:52;:::i;:::-;20853:29;20875:6;20853:29;:::i;:::-;20848:3;20844:39;20837:46;;20619:270;;;;;:::o;20895:364::-;20983:3;21011:39;21044:5;21011:39;:::i;:::-;21066:71;21130:6;21125:3;21066:71;:::i;:::-;21059:78;;21146:52;21191:6;21186:3;21179:4;21172:5;21168:16;21146:52;:::i;:::-;21223:29;21245:6;21223:29;:::i;:::-;21218:3;21214:39;21207:46;;20987:272;;;;;:::o;21265:377::-;21371:3;21399:39;21432:5;21399:39;:::i;:::-;21454:89;21536:6;21531:3;21454:89;:::i;:::-;21447:96;;21552:52;21597:6;21592:3;21585:4;21578:5;21574:16;21552:52;:::i;:::-;21629:6;21624:3;21620:16;21613:23;;21375:267;;;;;:::o;21672:818::-;21765:3;21802:5;21796:12;21831:36;21857:9;21831:36;:::i;:::-;21883:79;21955:6;21950:3;21883:79;:::i;:::-;21876:86;;21993:1;21982:9;21978:17;22009:1;22004:135;;;;22153:1;22148:336;;;;21971:513;;22004:135;22088:4;22084:9;22073;22069:25;22064:3;22057:38;22124:4;22119:3;22115:14;22108:21;;22004:135;;22148:336;22215:38;22247:5;22215:38;:::i;:::-;22275:1;22289:154;22303:6;22300:1;22297:13;22289:154;;;22377:7;22371:14;22367:1;22362:3;22358:11;22351:35;22427:1;22418:7;22414:15;22403:26;;22325:4;22322:1;22318:12;22313:17;;22289:154;;;22472:1;22467:3;22463:11;22456:18;;22155:329;;21971:513;;21769:721;;;;;;:::o;22520:845::-;22623:3;22660:5;22654:12;22689:36;22715:9;22689:36;:::i;:::-;22741:89;22823:6;22818:3;22741:89;:::i;:::-;22734:96;;22861:1;22850:9;22846:17;22877:1;22872:137;;;;23023:1;23018:341;;;;22839:520;;22872:137;22956:4;22952:9;22941;22937:25;22932:3;22925:38;22992:6;22987:3;22983:16;22976:23;;22872:137;;23018:341;23085:38;23117:5;23085:38;:::i;:::-;23145:1;23159:154;23173:6;23170:1;23167:13;23159:154;;;23247:7;23241:14;23237:1;23232:3;23228:11;23221:35;23297:1;23288:7;23284:15;23273:26;;23195:4;23192:1;23188:12;23183:17;;23159:154;;;23342:6;23337:3;23333:16;23326:23;;23025:334;;22839:520;;22627:738;;;;;;:::o;23371:366::-;23513:3;23534:67;23598:2;23593:3;23534:67;:::i;:::-;23527:74;;23610:93;23699:3;23610:93;:::i;:::-;23728:2;23723:3;23719:12;23712:19;;23517:220;;;:::o;23743:366::-;23885:3;23906:67;23970:2;23965:3;23906:67;:::i;:::-;23899:74;;23982:93;24071:3;23982:93;:::i;:::-;24100:2;24095:3;24091:12;24084:19;;23889:220;;;:::o;24115:366::-;24257:3;24278:67;24342:2;24337:3;24278:67;:::i;:::-;24271:74;;24354:93;24443:3;24354:93;:::i;:::-;24472:2;24467:3;24463:12;24456:19;;24261:220;;;:::o;24487:366::-;24629:3;24650:67;24714:2;24709:3;24650:67;:::i;:::-;24643:74;;24726:93;24815:3;24726:93;:::i;:::-;24844:2;24839:3;24835:12;24828:19;;24633:220;;;:::o;24859:366::-;25001:3;25022:67;25086:2;25081:3;25022:67;:::i;:::-;25015:74;;25098:93;25187:3;25098:93;:::i;:::-;25216:2;25211:3;25207:12;25200:19;;25005:220;;;:::o;25231:402::-;25391:3;25412:85;25494:2;25489:3;25412:85;:::i;:::-;25405:92;;25506:93;25595:3;25506:93;:::i;:::-;25624:2;25619:3;25615:12;25608:19;;25395:238;;;:::o;25639:366::-;25781:3;25802:67;25866:2;25861:3;25802:67;:::i;:::-;25795:74;;25878:93;25967:3;25878:93;:::i;:::-;25996:2;25991:3;25987:12;25980:19;;25785:220;;;:::o;26011:366::-;26153:3;26174:67;26238:2;26233:3;26174:67;:::i;:::-;26167:74;;26250:93;26339:3;26250:93;:::i;:::-;26368:2;26363:3;26359:12;26352:19;;26157:220;;;:::o;26383:366::-;26525:3;26546:67;26610:2;26605:3;26546:67;:::i;:::-;26539:74;;26622:93;26711:3;26622:93;:::i;:::-;26740:2;26735:3;26731:12;26724:19;;26529:220;;;:::o;26755:366::-;26897:3;26918:67;26982:2;26977:3;26918:67;:::i;:::-;26911:74;;26994:93;27083:3;26994:93;:::i;:::-;27112:2;27107:3;27103:12;27096:19;;26901:220;;;:::o;27127:404::-;27287:3;27308:86;27390:3;27385;27308:86;:::i;:::-;27301:93;;27403;27492:3;27403:93;:::i;:::-;27521:3;27516;27512:13;27505:20;;27291:240;;;:::o;27537:366::-;27679:3;27700:67;27764:2;27759:3;27700:67;:::i;:::-;27693:74;;27776:93;27865:3;27776:93;:::i;:::-;27894:2;27889:3;27885:12;27878:19;;27683:220;;;:::o;27909:366::-;28051:3;28072:67;28136:2;28131:3;28072:67;:::i;:::-;28065:74;;28148:93;28237:3;28148:93;:::i;:::-;28266:2;28261:3;28257:12;28250:19;;28055:220;;;:::o;28281:366::-;28423:3;28444:67;28508:2;28503:3;28444:67;:::i;:::-;28437:74;;28520:93;28609:3;28520:93;:::i;:::-;28638:2;28633:3;28629:12;28622:19;;28427:220;;;:::o;28653:402::-;28813:3;28834:85;28916:2;28911:3;28834:85;:::i;:::-;28827:92;;28928:93;29017:3;28928:93;:::i;:::-;29046:2;29041:3;29037:12;29030:19;;28817:238;;;:::o;29061:366::-;29203:3;29224:67;29288:2;29283:3;29224:67;:::i;:::-;29217:74;;29300:93;29389:3;29300:93;:::i;:::-;29418:2;29413:3;29409:12;29402:19;;29207:220;;;:::o;29433:400::-;29593:3;29614:84;29696:1;29691:3;29614:84;:::i;:::-;29607:91;;29707:93;29796:3;29707:93;:::i;:::-;29825:1;29820:3;29816:11;29809:18;;29597:236;;;:::o;29839:366::-;29981:3;30002:67;30066:2;30061:3;30002:67;:::i;:::-;29995:74;;30078:93;30167:3;30078:93;:::i;:::-;30196:2;30191:3;30187:12;30180:19;;29985:220;;;:::o;30211:366::-;30353:3;30374:67;30438:2;30433:3;30374:67;:::i;:::-;30367:74;;30450:93;30539:3;30450:93;:::i;:::-;30568:2;30563:3;30559:12;30552:19;;30357:220;;;:::o;30583:366::-;30725:3;30746:67;30810:2;30805:3;30746:67;:::i;:::-;30739:74;;30822:93;30911:3;30822:93;:::i;:::-;30940:2;30935:3;30931:12;30924:19;;30729:220;;;:::o;30955:366::-;31097:3;31118:67;31182:2;31177:3;31118:67;:::i;:::-;31111:74;;31194:93;31283:3;31194:93;:::i;:::-;31312:2;31307:3;31303:12;31296:19;;31101:220;;;:::o;31327:400::-;31487:3;31508:84;31590:1;31585:3;31508:84;:::i;:::-;31501:91;;31601:93;31690:3;31601:93;:::i;:::-;31719:1;31714:3;31710:11;31703:18;;31491:236;;;:::o;31733:366::-;31875:3;31896:67;31960:2;31955:3;31896:67;:::i;:::-;31889:74;;31972:93;32061:3;31972:93;:::i;:::-;32090:2;32085:3;32081:12;32074:19;;31879:220;;;:::o;32105:366::-;32247:3;32268:67;32332:2;32327:3;32268:67;:::i;:::-;32261:74;;32344:93;32433:3;32344:93;:::i;:::-;32462:2;32457:3;32453:12;32446:19;;32251:220;;;:::o;32477:402::-;32637:3;32658:85;32740:2;32735:3;32658:85;:::i;:::-;32651:92;;32752:93;32841:3;32752:93;:::i;:::-;32870:2;32865:3;32861:12;32854:19;;32641:238;;;:::o;32885:366::-;33027:3;33048:67;33112:2;33107:3;33048:67;:::i;:::-;33041:74;;33124:93;33213:3;33124:93;:::i;:::-;33242:2;33237:3;33233:12;33226:19;;33031:220;;;:::o;33257:366::-;33399:3;33420:67;33484:2;33479:3;33420:67;:::i;:::-;33413:74;;33496:93;33585:3;33496:93;:::i;:::-;33614:2;33609:3;33605:12;33598:19;;33403:220;;;:::o;33629:366::-;33771:3;33792:67;33856:2;33851:3;33792:67;:::i;:::-;33785:74;;33868:93;33957:3;33868:93;:::i;:::-;33986:2;33981:3;33977:12;33970:19;;33775:220;;;:::o;34001:366::-;34143:3;34164:67;34228:2;34223:3;34164:67;:::i;:::-;34157:74;;34240:93;34329:3;34240:93;:::i;:::-;34358:2;34353:3;34349:12;34342:19;;34147:220;;;:::o;34373:366::-;34515:3;34536:67;34600:2;34595:3;34536:67;:::i;:::-;34529:74;;34612:93;34701:3;34612:93;:::i;:::-;34730:2;34725:3;34721:12;34714:19;;34519:220;;;:::o;34745:402::-;34905:3;34926:85;35008:2;35003:3;34926:85;:::i;:::-;34919:92;;35020:93;35109:3;35020:93;:::i;:::-;35138:2;35133:3;35129:12;35122:19;;34909:238;;;:::o;35153:402::-;35313:3;35334:85;35416:2;35411:3;35334:85;:::i;:::-;35327:92;;35428:93;35517:3;35428:93;:::i;:::-;35546:2;35541:3;35537:12;35530:19;;35317:238;;;:::o;35561:118::-;35648:24;35666:5;35648:24;:::i;:::-;35643:3;35636:37;35626:53;;:::o;35685:126::-;35780:24;35798:5;35780:24;:::i;:::-;35775:3;35768:37;35758:53;;:::o;35817:135::-;35910:35;35939:5;35910:35;:::i;:::-;35905:3;35898:48;35888:64;;:::o;35958:120::-;36049:22;36065:5;36049:22;:::i;:::-;36044:3;36037:35;36027:51;;:::o;36084:110::-;36165:22;36181:5;36165:22;:::i;:::-;36160:3;36153:35;36143:51;;:::o;36200:595::-;36428:3;36450:95;36541:3;36532:6;36450:95;:::i;:::-;36443:102;;36562:95;36653:3;36644:6;36562:95;:::i;:::-;36555:102;;36674:95;36765:3;36756:6;36674:95;:::i;:::-;36667:102;;36786:3;36779:10;;36432:363;;;;;;:::o;36801:589::-;37026:3;37048:95;37139:3;37130:6;37048:95;:::i;:::-;37041:102;;37160:95;37251:3;37242:6;37160:95;:::i;:::-;37153:102;;37272:92;37360:3;37351:6;37272:92;:::i;:::-;37265:99;;37381:3;37374:10;;37030:360;;;;;;:::o;37396:429::-;37573:3;37595:95;37686:3;37677:6;37595:95;:::i;:::-;37588:102;;37707:92;37795:3;37786:6;37707:92;:::i;:::-;37700:99;;37816:3;37809:10;;37577:248;;;;;:::o;37831:1233::-;38314:3;38336:148;38480:3;38336:148;:::i;:::-;38329:155;;38501:95;38592:3;38583:6;38501:95;:::i;:::-;38494:102;;38613:148;38757:3;38613:148;:::i;:::-;38606:155;;38778:95;38869:3;38860:6;38778:95;:::i;:::-;38771:102;;38890:148;39034:3;38890:148;:::i;:::-;38883:155;;39055:3;39048:10;;38318:746;;;;;:::o;39070:541::-;39303:3;39325:148;39469:3;39325:148;:::i;:::-;39318:155;;39490:95;39581:3;39572:6;39490:95;:::i;:::-;39483:102;;39602:3;39595:10;;39307:304;;;;:::o;39617:1659::-;40249:3;40271:148;40415:3;40271:148;:::i;:::-;40264:155;;40436:95;40527:3;40518:6;40436:95;:::i;:::-;40429:102;;40548:148;40692:3;40548:148;:::i;:::-;40541:155;;40713:95;40804:3;40795:6;40713:95;:::i;:::-;40706:102;;40825:148;40969:3;40825:148;:::i;:::-;40818:155;;40990:95;41081:3;41072:6;40990:95;:::i;:::-;40983:102;;41102:148;41246:3;41102:148;:::i;:::-;41095:155;;41267:3;41260:10;;40253:1023;;;;;;:::o;41282:222::-;41375:4;41413:2;41402:9;41398:18;41390:26;;41426:71;41494:1;41483:9;41479:17;41470:6;41426:71;:::i;:::-;41380:124;;;;:::o;41510:640::-;41705:4;41743:3;41732:9;41728:19;41720:27;;41757:71;41825:1;41814:9;41810:17;41801:6;41757:71;:::i;:::-;41838:72;41906:2;41895:9;41891:18;41882:6;41838:72;:::i;:::-;41920;41988:2;41977:9;41973:18;41964:6;41920:72;:::i;:::-;42039:9;42033:4;42029:20;42024:2;42013:9;42009:18;42002:48;42067:76;42138:4;42129:6;42067:76;:::i;:::-;42059:84;;41710:440;;;;;;;:::o;42156:332::-;42277:4;42315:2;42304:9;42300:18;42292:26;;42328:71;42396:1;42385:9;42381:17;42372:6;42328:71;:::i;:::-;42409:72;42477:2;42466:9;42462:18;42453:6;42409:72;:::i;:::-;42282:206;;;;;:::o;42494:751::-;42717:4;42755:3;42744:9;42740:19;42732:27;;42769:71;42837:1;42826:9;42822:17;42813:6;42769:71;:::i;:::-;42850:72;42918:2;42907:9;42903:18;42894:6;42850:72;:::i;:::-;42932;43000:2;42989:9;42985:18;42976:6;42932:72;:::i;:::-;43014;43082:2;43071:9;43067:18;43058:6;43014:72;:::i;:::-;43134:9;43128:4;43124:20;43118:3;43107:9;43103:19;43096:49;43162:76;43233:4;43224:6;43162:76;:::i;:::-;43154:84;;42722:523;;;;;;;;:::o;43251:529::-;43418:4;43456:2;43445:9;43441:18;43433:26;;43469:71;43537:1;43526:9;43522:17;43513:6;43469:71;:::i;:::-;43550:72;43618:2;43607:9;43603:18;43594:6;43550:72;:::i;:::-;43669:9;43663:4;43659:20;43654:2;43643:9;43639:18;43632:48;43697:76;43768:4;43759:6;43697:76;:::i;:::-;43689:84;;43423:357;;;;;;:::o;43786:528::-;43999:4;44037;44026:9;44022:20;44014:28;;44052:167;44216:1;44205:9;44201:17;44192:6;44052:167;:::i;:::-;44229:78;44301:4;44290:9;44286:20;44277:6;44229:78;:::i;:::-;44004:310;;;;;:::o;44320:210::-;44407:4;44445:2;44434:9;44430:18;44422:26;;44458:65;44520:1;44509:9;44505:17;44496:6;44458:65;:::i;:::-;44412:118;;;;:::o;44536:309::-;44647:4;44685:2;44674:9;44670:18;44662:26;;44734:9;44728:4;44724:20;44720:1;44709:9;44705:17;44698:47;44762:76;44833:4;44824:6;44762:76;:::i;:::-;44754:84;;44652:193;;;;:::o;44851:313::-;44964:4;45002:2;44991:9;44987:18;44979:26;;45051:9;45045:4;45041:20;45037:1;45026:9;45022:17;45015:47;45079:78;45152:4;45143:6;45079:78;:::i;:::-;45071:86;;44969:195;;;;:::o;45170:419::-;45336:4;45374:2;45363:9;45359:18;45351:26;;45423:9;45417:4;45413:20;45409:1;45398:9;45394:17;45387:47;45451:131;45577:4;45451:131;:::i;:::-;45443:139;;45341:248;;;:::o;45595:419::-;45761:4;45799:2;45788:9;45784:18;45776:26;;45848:9;45842:4;45838:20;45834:1;45823:9;45819:17;45812:47;45876:131;46002:4;45876:131;:::i;:::-;45868:139;;45766:248;;;:::o;46020:419::-;46186:4;46224:2;46213:9;46209:18;46201:26;;46273:9;46267:4;46263:20;46259:1;46248:9;46244:17;46237:47;46301:131;46427:4;46301:131;:::i;:::-;46293:139;;46191:248;;;:::o;46445:419::-;46611:4;46649:2;46638:9;46634:18;46626:26;;46698:9;46692:4;46688:20;46684:1;46673:9;46669:17;46662:47;46726:131;46852:4;46726:131;:::i;:::-;46718:139;;46616:248;;;:::o;46870:419::-;47036:4;47074:2;47063:9;47059:18;47051:26;;47123:9;47117:4;47113:20;47109:1;47098:9;47094:17;47087:47;47151:131;47277:4;47151:131;:::i;:::-;47143:139;;47041:248;;;:::o;47295:419::-;47461:4;47499:2;47488:9;47484:18;47476:26;;47548:9;47542:4;47538:20;47534:1;47523:9;47519:17;47512:47;47576:131;47702:4;47576:131;:::i;:::-;47568:139;;47466:248;;;:::o;47720:419::-;47886:4;47924:2;47913:9;47909:18;47901:26;;47973:9;47967:4;47963:20;47959:1;47948:9;47944:17;47937:47;48001:131;48127:4;48001:131;:::i;:::-;47993:139;;47891:248;;;:::o;48145:419::-;48311:4;48349:2;48338:9;48334:18;48326:26;;48398:9;48392:4;48388:20;48384:1;48373:9;48369:17;48362:47;48426:131;48552:4;48426:131;:::i;:::-;48418:139;;48316:248;;;:::o;48570:419::-;48736:4;48774:2;48763:9;48759:18;48751:26;;48823:9;48817:4;48813:20;48809:1;48798:9;48794:17;48787:47;48851:131;48977:4;48851:131;:::i;:::-;48843:139;;48741:248;;;:::o;48995:419::-;49161:4;49199:2;49188:9;49184:18;49176:26;;49248:9;49242:4;49238:20;49234:1;49223:9;49219:17;49212:47;49276:131;49402:4;49276:131;:::i;:::-;49268:139;;49166:248;;;:::o;49420:419::-;49586:4;49624:2;49613:9;49609:18;49601:26;;49673:9;49667:4;49663:20;49659:1;49648:9;49644:17;49637:47;49701:131;49827:4;49701:131;:::i;:::-;49693:139;;49591:248;;;:::o;49845:419::-;50011:4;50049:2;50038:9;50034:18;50026:26;;50098:9;50092:4;50088:20;50084:1;50073:9;50069:17;50062:47;50126:131;50252:4;50126:131;:::i;:::-;50118:139;;50016:248;;;:::o;50270:419::-;50436:4;50474:2;50463:9;50459:18;50451:26;;50523:9;50517:4;50513:20;50509:1;50498:9;50494:17;50487:47;50551:131;50677:4;50551:131;:::i;:::-;50543:139;;50441:248;;;:::o;50695:419::-;50861:4;50899:2;50888:9;50884:18;50876:26;;50948:9;50942:4;50938:20;50934:1;50923:9;50919:17;50912:47;50976:131;51102:4;50976:131;:::i;:::-;50968:139;;50866:248;;;:::o;51120:419::-;51286:4;51324:2;51313:9;51309:18;51301:26;;51373:9;51367:4;51363:20;51359:1;51348:9;51344:17;51337:47;51401:131;51527:4;51401:131;:::i;:::-;51393:139;;51291:248;;;:::o;51545:419::-;51711:4;51749:2;51738:9;51734:18;51726:26;;51798:9;51792:4;51788:20;51784:1;51773:9;51769:17;51762:47;51826:131;51952:4;51826:131;:::i;:::-;51818:139;;51716:248;;;:::o;51970:419::-;52136:4;52174:2;52163:9;52159:18;52151:26;;52223:9;52217:4;52213:20;52209:1;52198:9;52194:17;52187:47;52251:131;52377:4;52251:131;:::i;:::-;52243:139;;52141:248;;;:::o;52395:419::-;52561:4;52599:2;52588:9;52584:18;52576:26;;52648:9;52642:4;52638:20;52634:1;52623:9;52619:17;52612:47;52676:131;52802:4;52676:131;:::i;:::-;52668:139;;52566:248;;;:::o;52820:419::-;52986:4;53024:2;53013:9;53009:18;53001:26;;53073:9;53067:4;53063:20;53059:1;53048:9;53044:17;53037:47;53101:131;53227:4;53101:131;:::i;:::-;53093:139;;52991:248;;;:::o;53245:419::-;53411:4;53449:2;53438:9;53434:18;53426:26;;53498:9;53492:4;53488:20;53484:1;53473:9;53469:17;53462:47;53526:131;53652:4;53526:131;:::i;:::-;53518:139;;53416:248;;;:::o;53670:419::-;53836:4;53874:2;53863:9;53859:18;53851:26;;53923:9;53917:4;53913:20;53909:1;53898:9;53894:17;53887:47;53951:131;54077:4;53951:131;:::i;:::-;53943:139;;53841:248;;;:::o;54095:419::-;54261:4;54299:2;54288:9;54284:18;54276:26;;54348:9;54342:4;54338:20;54334:1;54323:9;54319:17;54312:47;54376:131;54502:4;54376:131;:::i;:::-;54368:139;;54266:248;;;:::o;54520:419::-;54686:4;54724:2;54713:9;54709:18;54701:26;;54773:9;54767:4;54763:20;54759:1;54748:9;54744:17;54737:47;54801:131;54927:4;54801:131;:::i;:::-;54793:139;;54691:248;;;:::o;54945:419::-;55111:4;55149:2;55138:9;55134:18;55126:26;;55198:9;55192:4;55188:20;55184:1;55173:9;55169:17;55162:47;55226:131;55352:4;55226:131;:::i;:::-;55218:139;;55116:248;;;:::o;55370:238::-;55471:4;55509:2;55498:9;55494:18;55486:26;;55522:79;55598:1;55587:9;55583:17;55574:6;55522:79;:::i;:::-;55476:132;;;;:::o;55614:222::-;55707:4;55745:2;55734:9;55730:18;55722:26;;55758:71;55826:1;55815:9;55811:17;55802:6;55758:71;:::i;:::-;55712:124;;;;:::o;55842:332::-;55963:4;56001:2;55990:9;55986:18;55978:26;;56014:71;56082:1;56071:9;56067:17;56058:6;56014:71;:::i;:::-;56095:72;56163:2;56152:9;56148:18;56139:6;56095:72;:::i;:::-;55968:206;;;;;:::o;56180:1048::-;56459:4;56497:3;56486:9;56482:19;56474:27;;56511:77;56585:1;56574:9;56570:17;56561:6;56511:77;:::i;:::-;56635:9;56629:4;56625:20;56620:2;56609:9;56605:18;56598:48;56663:83;56741:4;56732:6;56663:83;:::i;:::-;56655:91;;56793:9;56787:4;56783:20;56778:2;56767:9;56763:18;56756:48;56821:83;56899:4;56890:6;56821:83;:::i;:::-;56813:91;;56951:9;56945:4;56941:20;56936:2;56925:9;56921:18;56914:48;56979:83;57057:4;57048:6;56979:83;:::i;:::-;56971:91;;57110:9;57104:4;57100:20;57094:3;57083:9;57079:19;57072:49;57138:83;57216:4;57207:6;57138:83;:::i;:::-;57130:91;;56464:764;;;;;;;;:::o;57234:129::-;57268:6;57295:20;;:::i;:::-;57285:30;;57324:33;57352:4;57344:6;57324:33;:::i;:::-;57275:88;;;:::o;57369:75::-;57402:6;57435:2;57429:9;57419:19;;57409:35;:::o;57450:270::-;57546:4;57636:18;57628:6;57625:30;57622:2;;;57658:18;;:::i;:::-;57622:2;57708:4;57700:6;57696:17;57688:25;;57551:169;;;:::o;57726:321::-;57813:4;57903:18;57895:6;57892:30;57889:2;;;57925:18;;:::i;:::-;57889:2;57975:4;57967:6;57963:17;57955:25;;58035:4;58029;58025:15;58017:23;;57818:229;;;:::o;58053:247::-;58126:4;58216:18;58208:6;58205:30;58202:2;;;58238:18;;:::i;:::-;58202:2;58288:4;58280:6;58276:17;58268:25;;58131:169;;;:::o;58306:307::-;58367:4;58457:18;58449:6;58446:30;58443:2;;;58479:18;;:::i;:::-;58443:2;58517:29;58539:6;58517:29;:::i;:::-;58509:37;;58601:4;58595;58591:15;58583:23;;58372:241;;;:::o;58619:308::-;58681:4;58771:18;58763:6;58760:30;58757:2;;;58793:18;;:::i;:::-;58757:2;58831:29;58853:6;58831:29;:::i;:::-;58823:37;;58915:4;58909;58905:15;58897:23;;58686:241;;;:::o;58933:119::-;59019:4;59042:3;59034:11;;59024:28;;;:::o;59058:96::-;59121:4;59144:3;59136:11;;59126:28;;;:::o;59160:141::-;59209:4;59232:3;59224:11;;59255:3;59252:1;59245:14;59289:4;59286:1;59276:18;59268:26;;59214:87;;;:::o;59307:125::-;59393:6;59421:4;59411:14;;59400:32;;;:::o;59438:102::-;59501:6;59529:4;59519:14;;59508:32;;;:::o;59546:98::-;59597:6;59631:5;59625:12;59615:22;;59604:40;;;:::o;59650:99::-;59702:6;59736:5;59730:12;59720:22;;59709:40;;;:::o;59755:132::-;59844:4;59876;59871:3;59867:14;59859:22;;59849:38;;;:::o;59893:109::-;59959:4;59991;59986:3;59982:14;59974:22;;59964:38;;;:::o;60008:172::-;60134:11;60171:3;60156:18;;60146:34;;;;:::o;60186:139::-;60279:11;60316:3;60301:18;;60291:34;;;;:::o;60331:168::-;60414:11;60448:6;60443:3;60436:19;60488:4;60483:3;60479:14;60464:29;;60426:73;;;;:::o;60505:169::-;60589:11;60623:6;60618:3;60611:19;60663:4;60658:3;60654:14;60639:29;;60601:73;;;;:::o;60680:177::-;60772:11;60806:6;60801:3;60794:19;60846:4;60841:3;60837:14;60822:29;;60784:73;;;;:::o;60863:148::-;60965:11;61002:3;60987:18;;60977:34;;;;:::o;61017:305::-;61057:3;61076:20;61094:1;61076:20;:::i;:::-;61071:25;;61110:20;61128:1;61110:20;:::i;:::-;61105:25;;61264:1;61196:66;61192:74;61189:1;61186:81;61183:2;;;61270:18;;:::i;:::-;61183:2;61314:1;61311;61307:9;61300:16;;61061:261;;;;:::o;61328:185::-;61368:1;61385:20;61403:1;61385:20;:::i;:::-;61380:25;;61419:20;61437:1;61419:20;:::i;:::-;61414:25;;61458:1;61448:2;;61463:18;;:::i;:::-;61448:2;61505:1;61502;61498:9;61493:14;;61370:143;;;;:::o;61519:348::-;61559:7;61582:20;61600:1;61582:20;:::i;:::-;61577:25;;61616:20;61634:1;61616:20;:::i;:::-;61611:25;;61804:1;61736:66;61732:74;61729:1;61726:81;61721:1;61714:9;61707:17;61703:105;61700:2;;;61811:18;;:::i;:::-;61700:2;61859:1;61856;61852:9;61841:20;;61567:300;;;;:::o;61873:191::-;61913:4;61933:20;61951:1;61933:20;:::i;:::-;61928:25;;61967:20;61985:1;61967:20;:::i;:::-;61962:25;;62006:1;62003;62000:8;61997:2;;;62011:18;;:::i;:::-;61997:2;62056:1;62053;62049:9;62041:17;;61918:146;;;;:::o;62070:96::-;62107:7;62136:24;62154:5;62136:24;:::i;:::-;62125:35;;62115:51;;;:::o;62172:90::-;62206:7;62249:5;62242:13;62235:21;62224:32;;62214:48;;;:::o;62268:149::-;62304:7;62344:66;62337:5;62333:78;62322:89;;62312:105;;;:::o;62423:126::-;62460:7;62500:42;62493:5;62489:54;62478:65;;62468:81;;;:::o;62555:77::-;62592:7;62621:5;62610:16;;62600:32;;;:::o;62638:86::-;62673:7;62713:4;62706:5;62702:16;62691:27;;62681:43;;;:::o;62730:109::-;62778:9;62811:22;62827:5;62811:22;:::i;:::-;62798:35;;62788:51;;;:::o;62845:154::-;62929:6;62924:3;62919;62906:30;62991:1;62982:6;62977:3;62973:16;62966:27;62896:103;;;:::o;63005:307::-;63073:1;63083:113;63097:6;63094:1;63091:13;63083:113;;;63182:1;63177:3;63173:11;63167:18;63163:1;63158:3;63154:11;63147:39;63119:2;63116:1;63112:10;63107:15;;63083:113;;;63214:6;63211:1;63208:13;63205:2;;;63294:1;63285:6;63280:3;63276:16;63269:27;63205:2;63054:258;;;;:::o;63318:320::-;63362:6;63399:1;63393:4;63389:12;63379:22;;63446:1;63440:4;63436:12;63467:18;63457:2;;63523:4;63515:6;63511:17;63501:27;;63457:2;63585;63577:6;63574:14;63554:18;63551:38;63548:2;;;63604:18;;:::i;:::-;63548:2;63369:269;;;;:::o;63644:281::-;63727:27;63749:4;63727:27;:::i;:::-;63719:6;63715:40;63857:6;63845:10;63842:22;63821:18;63809:10;63806:34;63803:62;63800:2;;;63868:18;;:::i;:::-;63800:2;63908:10;63904:2;63897:22;63687:238;;;:::o;63931:167::-;63968:3;63991:22;64007:5;63991:22;:::i;:::-;63982:31;;64035:4;64028:5;64025:15;64022:2;;;64043:18;;:::i;:::-;64022:2;64090:1;64083:5;64079:13;64072:20;;63972:126;;;:::o;64104:180::-;64152:77;64149:1;64142:88;64249:4;64246:1;64239:15;64273:4;64270:1;64263:15;64290:180;64338:77;64335:1;64328:88;64435:4;64432:1;64425:15;64459:4;64456:1;64449:15;64476:180;64524:77;64521:1;64514:88;64621:4;64618:1;64611:15;64645:4;64642:1;64635:15;64662:180;64710:77;64707:1;64700:88;64807:4;64804:1;64797:15;64831:4;64828:1;64821:15;64848:180;64896:77;64893:1;64886:88;64993:4;64990:1;64983:15;65017:4;65014:1;65007:15;65034:180;65082:77;65079:1;65072:88;65179:4;65176:1;65169:15;65203:4;65200:1;65193:15;65220:117;65329:1;65326;65319:12;65343:117;65452:1;65449;65442:12;65466:117;65575:1;65572;65565:12;65589:117;65698:1;65695;65688:12;65712:117;65821:1;65818;65811:12;65835:102;65876:6;65927:2;65923:7;65918:2;65911:5;65907:14;65903:28;65893:38;;65883:54;;;:::o;65943:169::-;66083:21;66079:1;66071:6;66067:14;66060:45;66049:63;:::o;66118:230::-;66258:34;66254:1;66246:6;66242:14;66235:58;66327:13;66322:2;66314:6;66310:15;66303:38;66224:124;:::o;66354:237::-;66494:34;66490:1;66482:6;66478:14;66471:58;66563:20;66558:2;66550:6;66546:15;66539:45;66460:131;:::o;66597:225::-;66737:34;66733:1;66725:6;66721:14;66714:58;66806:8;66801:2;66793:6;66789:15;66782:33;66703:119;:::o;66828:178::-;66968:30;66964:1;66956:6;66952:14;66945:54;66934:72;:::o;67012:214::-;67152:66;67148:1;67140:6;67136:14;67129:90;67118:108;:::o;67232:223::-;67372:34;67368:1;67360:6;67356:14;67349:58;67441:6;67436:2;67428:6;67424:15;67417:31;67338:117;:::o;67461:175::-;67601:27;67597:1;67589:6;67585:14;67578:51;67567:69;:::o;67642:231::-;67782:34;67778:1;67770:6;67766:14;67759:58;67851:14;67846:2;67838:6;67834:15;67827:39;67748:125;:::o;67879:243::-;68019:34;68015:1;68007:6;68003:14;67996:58;68088:26;68083:2;68075:6;68071:15;68064:51;67985:137;:::o;68128:803::-;68268:66;68264:1;68256:6;68252:14;68245:90;68369:34;68364:2;68356:6;68352:15;68345:59;68438:34;68433:2;68425:6;68421:15;68414:59;68507:34;68502:2;68494:6;68490:15;68483:59;68577:34;68571:3;68563:6;68559:16;68552:60;68647:34;68641:3;68633:6;68629:16;68622:60;68717:34;68711:3;68703:6;68699:16;68692:60;68787:34;68781:3;68773:6;68769:16;68762:60;68857:66;68851:3;68843:6;68839:16;68832:92;68234:697;:::o;68937:169::-;69077:21;69073:1;69065:6;69061:14;69054:45;69043:63;:::o;69112:229::-;69252:34;69248:1;69240:6;69236:14;69229:58;69321:12;69316:2;69308:6;69304:15;69297:37;69218:123;:::o;69347:228::-;69487:34;69483:1;69475:6;69471:14;69464:58;69556:11;69551:2;69543:6;69539:15;69532:36;69453:122;:::o;69581:255::-;69721:66;69717:1;69709:6;69705:14;69698:90;69822:6;69817:2;69809:6;69805:15;69798:31;69687:149;:::o;69842:171::-;69982:23;69978:1;69970:6;69966:14;69959:47;69948:65;:::o;70019:214::-;70159:66;70155:1;70147:6;70143:14;70136:90;70125:108;:::o;70239:182::-;70379:34;70375:1;70367:6;70363:14;70356:58;70345:76;:::o;70427:231::-;70567:34;70563:1;70555:6;70551:14;70544:58;70636:14;70631:2;70623:6;70619:15;70612:39;70533:125;:::o;70664:182::-;70804:34;70800:1;70792:6;70788:14;70781:58;70770:76;:::o;70852:228::-;70992:34;70988:1;70980:6;70976:14;70969:58;71061:11;71056:2;71048:6;71044:15;71037:36;70958:122;:::o;71086:145::-;71222:5;71218:1;71210:6;71206:14;71199:29;71192:39;:::o;71233:154::-;71369:14;71365:1;71357:6;71353:14;71346:38;71339:48;:::o;71389:208::-;71525:34;71521:1;71513:6;71509:14;71502:58;71590:3;71585:2;71577:6;71573:15;71566:28;71495:102;:::o;71599:171::-;71735:31;71731:1;71723:6;71719:14;71712:55;71705:65;:::o;71772:224::-;71908:34;71904:1;71896:6;71892:14;71885:58;71973:19;71968:2;71960:6;71956:15;71949:44;71878:118;:::o;71998:159::-;72134:19;72130:1;72122:6;72118:14;72111:43;72104:53;:::o;72159:219::-;72295:34;72291:1;72283:6;72279:14;72272:58;72360:14;72355:2;72347:6;72343:15;72336:39;72265:113;:::o;72380:173::-;72516:33;72512:1;72504:6;72500:14;72493:57;72486:67;:::o;72555:152::-;72691:12;72687:1;72679:6;72675:14;72668:36;72661:46;:::o;72709:206::-;72845:66;72841:1;72833:6;72829:14;72822:90;72815:100;:::o;72917:206::-;73053:66;73049:1;73041:6;73037:14;73030:90;73023:100;:::o;73125:114::-;73194:24;73212:5;73194:24;:::i;:::-;73187:5;73184:35;73174:2;;73233:1;73230;73223:12;73174:2;73168:71;:::o;73241:108::-;73307:21;73322:5;73307:21;:::i;:::-;73300:5;73297:32;73287:2;;73343:1;73340;73333:12;73287:2;73281:68;:::o;73351:112::-;73419:23;73436:5;73419:23;:::i;:::-;73412:5;73409:34;73399:2;;73457:1;73454;73447:12;73399:2;73393:70;:::o;73465:114::-;73534:24;73552:5;73534:24;:::i;:::-;73527:5;73524:35;73514:2;;73573:1;73570;73563:12;73514:2;73508:71;:::o;73581:110::-;73648:22;73664:5;73648:22;:::i;:::-;73641:5;73638:33;73628:2;;73685:1;73682;73675:12;73628:2;73622:69;:::o

Swarm Source

ipfs://92e9988b2565cb2c31880566e86082c195bcf63e54fa43a54a30cad604b543ed
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.