ERC-721
Overview
Max Total Supply
367 XEN0
Holders
204
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 XEN0Loading...
Loading
Loading...
Loading
Loading...
Loading
# | 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 Name:
Xe_ntity
Compiler Version
v0.8.6+commit.11564f7e
Contract Source Code (Solidity Multiple files format)
// 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; } }
// 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); } } } }
// 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); } }
// 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; } }
// 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; } }
// 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); } }
// 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; } }
// 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 {} }
// 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(); } }
// 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))); } }
// 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); }
// 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; }
// 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; }
// 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); }
// 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); }
// 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); }
// 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)); } }
// 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; } }
// 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); } }
// 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; } }
// 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; } }
// 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
- No Contract Security Audit Submitted- Submit Audit Here
[{"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"}]
Contract Creation Code
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.