ERC-721
Overview
Max Total Supply
229 DM
Holders
82
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
2 DMLoading...
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:
DungeonMiners
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "./Libraries/Strings.sol"; import "./Structs/Attempt.sol"; import "./Structs/Class.sol"; import "./Structs/Miner.sol"; import "./Structs/Item.sol"; import "./Libraries/Calcs.sol"; import "./Libraries/Counters.sol"; import "./Libraries/Metadata.sol"; /* /@@@@@@@ /@@ /@@ /@@ /@@ /@@@@@@ /@@@@@@@@ /@@@@@@ /@@ /@@ | @@__ @@| @@ | @@| @@@ | @@ /@@__ @@| @@_____/ /@@__ @@| @@@ | @@ | @@ \ @@| @@ | @@| @@@@| @@| @@ \__/| @@ | @@ \ @@| @@@@| @@ | @@ | @@| @@ | @@| @@ @@ @@| @@ /@@@@| @@@@@ | @@ | @@| @@ @@ @@ | @@ | @@| @@ | @@| @@ @@@@| @@|_ @@| @@__/ | @@ | @@| @@ @@@@ | @@ | @@| @@ | @@| @@\ @@@| @@ \ @@| @@ | @@ | @@| @@\ @@@ | @@@@@@@/| @@@@@@/| @@ \ @@| @@@@@@/| @@@@@@@@| @@@@@@/| @@ \ @@ |_______/ \______/ |__/ \__/ \______/ |________/ \______/ |__/ \__/ /@@ /@@ /@@@@@@ /@@ /@@ /@@@@@@@@ /@@@@@@@ /@@@@@@ | @@@ /@@@|_ @@_/| @@@ | @@| @@_____/| @@__ @@ /@@__ @@ | @@@@ /@@@@ | @@ | @@@@| @@| @@ | @@ \ @@| @@ \__/ | @@ @@/@@ @@ | @@ | @@ @@ @@| @@@@@ | @@@@@@@/| @@@@@@ | @@ @@@| @@ | @@ | @@ @@@@| @@__/ | @@__ @@ \____ @@ | @@\ @ | @@ | @@ | @@\ @@@| @@ | @@ \ @@ /@@ \ @@ | @@ \/ | @@ /@@@@@@| @@ \ @@| @@@@@@@@| @@ | @@| @@@@@@/ |__/ |__/|______/|__/ \__/|________/|__/ |__/ \______/ */ contract DungeonMiners { using Strings for *; using Counters for Counters.Counter; /** * * DUNGEON MINER CUSTOM VARS * */ // Address of the creator of the contract address CREATOR; // Address of the treasury contract address payable TREASURY; // The current supply Counters.Counter private TOKEN_SUPPLY; // Token id of the most recent token to redeem the prize pool uint256 private LAST_WITHDRAWN = 0; // Configure floating difficulty target to make it harder for people to hunt for difficulty solutions in advance // Set initial difficulty target as middle of potential hash value range uint256 private DIFFICULTY_TARGET = uint256(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); // Difficulty target range is 0x00000033216c94739703b2e9ffd940abb780678f326aac1d5cfddef0b1857bcb // Difficulty radius is half of difficulty target range uint256 private DIFFICULTY_RADIUS = uint256(0x0000001990b64a39cb81d974ffeca055dbc033c79935560eae7eef7858c2bde5); // Difficulty limit is the potential hash value range minus the difficulty target range uint256 private DIFFICULTY_LIMIT = uint256(0xffffffccde936b8c68fc4d160026bf54487f9870cd9553e2a302210f4e7a8434); // Array of character classes Class[4] public CLASSES; // Array of shop items Item[8] public SHOP_ITEMS; /** * * DUNGEON MINER EVENTS * */ // Let the world know that a token has been mined event Mined(uint256 indexed tokenId, address indexed minter, bytes32 indexed hash, uint256 startTokenId, uint256 difficultyTarget, uint256 difficultyRadius, uint256 itemId, uint256 classId, uint256 genderId); // Let the world know that ETH from the prize pool has been redeemed event Redeemed(uint256 indexed tokenId, address indexed primaryWinner, uint256 payout, address indexed secondaryWinner, uint256 secondaryPayout); // Let the world know that an attempt has been started event AttemptStarted(uint256 indexed tokenId, uint256 indexed startTokenId); /** * * ERC-721 EVENTS * */ event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); /** * * ERC-721 VARS * */ // Mapping of tokens mapping(uint256 => Attempt) TOKENS; // Mapping of owners mapping(uint256 => address) OWNERS; // How many tokens a particular address owns mapping(address => uint256) internal BALANCES; // Addresses allowed to manage specific tokens mapping(uint256 => address) internal ALLOWANCE; // Addresses allowed to control all assets of other addresses in this smart contract mapping(address => mapping(address => bool)) internal AUTHORIZED; /** * * ERC-165 VARS * */ // Map of supported interfaces mapping (bytes4 => bool) internal supportedInterfaces; /** * * CONSTRUCTOR * */ /** * @notice construct function * @param treasuryAddress the address of the treasury contract */ constructor(address treasuryAddress) payable { // Ensure that the contract has been seeded with enough ETH to cover 50 mints require(msg.value == 3 ether); // Define supported interfaces supportedInterfaces[0x80ac58cd] = true; // ERC-721 supportedInterfaces[0x5b5e139f] = true; // ERC-721 Metadata supportedInterfaces[0x01ffc9a7] = true; // ERC-165 // Define creator of contract CREATOR = address(0x79ac53F63728684F5B21B6302FC5Cef5A8E8b7e9); // Define treasury address TREASURY = payable(treasuryAddress); // Define classes CLASSES[0] = Class({baseHealth: 200, baseArmor: 75, baseAttack: 40, baseSpeed: 40}); // 0 | Warrior CLASSES[1] = Class({baseHealth: 195, baseArmor: 85, baseAttack: 35, baseSpeed: 40}); // 1 | Mage CLASSES[2] = Class({baseHealth: 175, baseArmor: 80, baseAttack: 35, baseSpeed: 50}); // 2 | Ranger CLASSES[3] = Class({baseHealth: 225, baseArmor: 90, baseAttack: 30, baseSpeed: 50}); // 3 | Assassin // Define shop items SHOP_ITEMS[0] = Item({cost: 0, healthMod: 0, armorMod: 0, attackMod: 0, speedMod: 0}); // 0 | No Item SHOP_ITEMS[1] = Item({cost: 0.005 ether, healthMod: 15, armorMod: 0, attackMod: 0, speedMod: 0}); // 1 | Health Potion SHOP_ITEMS[2] = Item({cost: 0.005 ether, healthMod: 0, armorMod: 15, attackMod: 0, speedMod: 0}); // 2 | Simple Bracers SHOP_ITEMS[3] = Item({cost: 0.005 ether, healthMod: 0, armorMod: 0, attackMod: 10, speedMod: 0}); // 3 | Strength Potion SHOP_ITEMS[4] = Item({cost: 0.005 ether, healthMod: 0, armorMod: 0, attackMod: 0, speedMod: 10}); // 4 | Strong Coffee SHOP_ITEMS[5] = Item({cost: 0.0075 ether, healthMod: 15, armorMod: 0, attackMod: 0, speedMod: 10}); // 5 | Cooked Dinner SHOP_ITEMS[6] = Item({cost: 0.0075 ether, healthMod: 0, armorMod: 15, attackMod: 10, speedMod: 0}); // 6 | Soldier Training SHOP_ITEMS[7] = Item({cost: 0.01 ether, healthMod: 15, armorMod: 15, attackMod: 10, speedMod: 10}); // 7 | Ancient Blessing // Mint 50 inactive Miners for drops, rewards, etc. for(uint8 i = 0; i < 50; i++){ // Increase TOKEN_SUPPLY by one TOKEN_SUPPLY.increment(); // Generate and define token hash bytes32 hash = keccak256(abi.encodePacked( CREATOR, i, (i == 0 ? bytes32(0) : TOKENS[i].hash), block.timestamp )); // Define alternating gender id uint256 genderId = (i % 2); // Define class id uint256 classId = (uint256(hash) % 4); // Mint the token with the token ID and new hash with rotating class/gender _mint(TOKEN_SUPPLY.current(),hash,uint256(hash),0,0,classId,genderId); // Let the world know emit Mined(TOKEN_SUPPLY.current(),msg.sender,hash,0,DIFFICULTY_TARGET,DIFFICULTY_RADIUS,0,classId,genderId); } } /** * * METADATA METHODS * */ /** * @notice return the starting stats for a miner * @param attempt the escape attempt struct * @return array of the miner as it entered the dungeon (struct -> array) */ function _getStartingMiner(Attempt memory attempt) internal view returns(Miner memory) { // Get class data from storage for provided class id Class memory class = CLASSES[attempt.classId]; // Get starting item data from storage for provided item id Item memory item = SHOP_ITEMS[attempt.itemId]; // Define the miner and its base stats Miner memory miner = Miner({ baseHealth: int16(uint16((uint8(attempt.hash[0]) % 48))) + class.baseHealth + item.healthMod, baseArmor: int16(uint16((uint8(attempt.hash[1]) % 24))) + class.baseArmor + item.armorMod, health: 0, armor: 0, attack: int16(uint16((uint8(attempt.hash[2]) % 24))) + class.baseAttack + item.attackMod, speed: int16(uint16((uint8(attempt.hash[3]) % 24))) + class.baseSpeed + item.speedMod, genderId: attempt.genderId, classId: attempt.classId, skintoneId: uint8(attempt.hash[21]) < 250 ? (uint8(attempt.hash[21]) % 10) : ((uint8(attempt.hash[21]) % 6) + 10), hairColorId: uint8(attempt.hash[27]) % 8, hairTypeId: uint8(attempt.hash[26]) % 8, eyeColorId: (uint8(attempt.hash[23]) < 252 ? (uint8(attempt.hash[23]) % 9) : ((uint8(attempt.hash[23]) % 4) + 9)), eyeTypeId: uint8(attempt.hash[24]) % 4, mouthId: uint8(attempt.hash[25]) % 8, headgearId: (Calcs.gType(uint8(attempt.hash[16])) > 8 ? uint8(((Calcs.gType(uint8(attempt.hash[16])) - 9) * 4) + 9 + attempt.classId) : Calcs.gType(uint8(attempt.hash[16]))), armorId: (Calcs.gType(uint8(attempt.hash[17])) > 8 ? uint8(((Calcs.gType(uint8(attempt.hash[17])) - 9) * 4) + 9 + attempt.classId) : Calcs.gType(uint8(attempt.hash[17]))) + 17, pantsId: (Calcs.gType(uint8(attempt.hash[18])) > 8 ? uint8(((Calcs.gType(uint8(attempt.hash[18])) - 9) * 4) + 9 + attempt.classId) : Calcs.gType(uint8(attempt.hash[18]))) + 34, footwearId: (Calcs.gType(uint8(attempt.hash[19])) > 8 ? uint8(((Calcs.gType(uint8(attempt.hash[19])) - 9) * 4) + 9 + attempt.classId) : Calcs.gType(uint8(attempt.hash[19]))) + 51, weaponId: (Calcs.gType(uint8(attempt.hash[20])) > 4 ? uint8(((Calcs.gType(uint8(attempt.hash[20])) - 5) * 4) + 5 + attempt.classId) : Calcs.gType(uint8(attempt.hash[20]))) + 68, gold: 0, curseTurns: 0, buffTurns: 0, debuffTurns: 0, revives: 0, currentChamber: 0 }); // Define empty gearItem int16[6] memory gearItem; // Loop through gear types for(uint256 i = 0; i < 5; i++){ if(i == 0){ gearItem = Calcs.headgearStats(miner.headgearId); } else if(i == 1){ gearItem = Calcs.armorStats(miner.armorId); } else if(i == 2){ gearItem = Calcs.pantsStats(miner.pantsId); } else if(i == 3){ gearItem = Calcs.footwearStats(miner.footwearId); } else if(i == 4){ gearItem = Calcs.weaponStats(miner.weaponId); } // Add gear health buff to baseHealth miner.baseHealth = miner.baseHealth + gearItem[0]; // Add gear armor buff to baseArmor miner.baseArmor = miner.baseArmor + gearItem[1]; // Add gear attack buff to attack miner.attack = miner.attack + gearItem[2]; // Add gear speed buff to speed miner.speed = miner.speed + gearItem[3]; } // Set current miner health to base health miner.health = miner.baseHealth; // Set current miner armor to base armor miner.armor = miner.baseArmor; // Return the miner return miner; } /** * @notice return the stats for a miner given a chamber number * @param tokenId the token id of the miner * @param chamberCount how many chambers to return * @return array of the miner in its current state (struct -> array) */ function getMiner(uint256 tokenId, uint8 chamberCount) public view returns (Miner memory) { // Ensure that the token id has been minted require(_isValidToken(tokenId),'invalid token'); // Get the starting attempt data for this token from storage Attempt memory attempt = TOKENS[tokenId]; // Get all potential chamber hashes for this token bytes32[47] memory chambers = _getChambers(tokenId,attempt.startTokenId); // Define the starting miner struct Miner memory miner = _getStartingMiner(attempt); // Set the miner's current chamber to 1 to skip calculating the spawn chamber miner.currentChamber = 1; // Loop through all chambers and calculate attempt data as long as it's < chamber 46, miner is alive and chamber hash is not empty while(miner.currentChamber < 46 && miner.currentChamber <= chamberCount && miner.health > 0 && chambers[miner.currentChamber] != bytes32(0)){ // Calculate and return the miner and stats after traversing this chamber miner = Calcs.chamberStats(keccak256(abi.encodePacked(chambers[0],chambers[miner.currentChamber])),miner); miner.currentChamber++; } return miner; } /** * @notice overload getMiner function to default to the current state of the miner * @param tokenId the token id of the miner * @return array of the miner in its current state (struct -> array) */ function getMiner(uint256 tokenId) public view returns (Miner memory) { return getMiner(tokenId,46); } /** * @notice return all potential chambers for a given miner * @param tokenId the token id of the miner * @param startTokenId the starting token id of the miner * @return array of chamber hashes */ function _getChambers(uint256 tokenId, uint256 startTokenId) internal view returns(bytes32[47] memory) { // Define array of hashes bytes32[47] memory hashes; // Set the first chamber as the mint chamber hashes[0] = TOKENS[tokenId].hash; // Loop through potential token ids starting from the start token id if(startTokenId != 0){ for(uint256 i = 1; i < 47; i++){ // Add hash value to hashes array. If the token is not valid, set the hash value to zero hashes[i] = TOKENS[startTokenId + i].hash; if(hashes[i] == bytes32(0)){ break; } } } return hashes; } /** * @notice generate and return the data for a miner * @param tokenId the token id of the miner * @return string representing a data uri */ function _tokenURI(uint256 tokenId) internal view returns (string memory) { // Get the json attributes and image data for a given token id (string memory attributes, string memory imageData) = _getData(tokenId); // Pack the metadata together in data URI format string memory metadata = string(abi.encodePacked( 'data:text/plain,{"name":"Miner %23', tokenId.toString(), '","description":"An escape attempt through the dark dungeon.","attributes":[', attributes, '],"image":"', imageData, '"}' )); // Return the metadata return metadata; } /** * @notice return json attribute data and image data URI for a miner * @param tokenId the token id of the miner * @return array of strings representing json attribute data and image data URI for a miner */ function _getData(uint256 tokenId) internal view returns (string memory,string memory) { // Get the starting attempt data for this token from storage Attempt memory attempt = TOKENS[tokenId]; // Get the miner for this attempt Miner memory miner = _getStartingMiner(attempt); // Get chambers bytes32[47] memory chambers = _getChambers(tokenId,attempt.startTokenId); // Return the data return Metadata.build(attempt,miner,chambers); } /** * @notice return whether or not an address can redeem from the prize pool for a given token id * @param owner the address of the owner * @param tokenId the token id of the miner * @return boolean representing whether or not the token can be redeemed at this time */ function canRedeem(address owner, uint256 tokenId) public view returns (bool) { // Ensure that the tokenId has been minted require(_isValidToken(tokenId),'invalid token'); // Ensure that the supplied address owns the held token being withdrawn from require(ownerOf(tokenId) == owner,"owner"); // Get the starting attempt data for this token from storage Attempt memory attempt = TOKENS[tokenId]; // Ensure that a token with a matching or higher id has not redeemed the prize pool already require(LAST_WITHDRAWN < attempt.startTokenId,"previously redeemed"); // Ensure that an attempt has started require(attempt.startTokenId > 0,"preparing"); // Get all potential chamber hashes for this token bytes32[47] memory chambers = _getChambers(tokenId,attempt.startTokenId); // Define the starting miner struct Miner memory miner = _getStartingMiner(attempt); // Set the miner's current chamber to 1 to skip calculating the spawn chamber miner.currentChamber = 1; // Loop through all chambers and calculate attempt data as long as it's < chamber 47, miner is alive and chamber hash is not empty while(miner.currentChamber < 46 && miner.health > 0 && chambers[miner.currentChamber] != bytes32(0)){ // Calculate and return the miner and stats after traversing this chamber miner = Calcs.chamberStats(keccak256(abi.encodePacked(chambers[0],chambers[miner.currentChamber])),miner); miner.currentChamber++; } // Check if a miner is still alive and has cleared all chambers to reach the exit (46) if(miner.health > 0 && miner.currentChamber == 46){ // Token can be redeemed! Return true return true; } // Nope, return false return false; } /** * @notice return the total supply of tokens * @return uint256 value of the total supply of tokens */ function totalSupply() external view returns(uint256) { // Return count of tokens counter return TOKEN_SUPPLY.current(); } /** * @notice return the total prize pool value * @return uint256 value of the balance of the prize pool */ function poolValue() external view returns(uint256) { // Return balance of prize pool in contract return address(this).balance; } /** * @notice return the potential redeemable value from the prize pool for a token id * @param tokenId the token id of the miner * @return uint256 value of the amount that will be eligible to be redeemed from the contract for the provided token upon escape */ function redeemableValue(uint256 tokenId) public view returns(uint256) { // Get the starting attempt data for this token from storage Attempt memory attempt = TOKENS[tokenId]; // Check if anyone has redeemed the prize pool yet if(LAST_WITHDRAWN == 0){ // First redemption! Add 46 to the token id to account for the chambers traversed to reach the exit return (attempt.startTokenId + 46) * 0.06 ether; } else if(LAST_WITHDRAWN < tokenId){ // Not the first redemption and the provided token id is higher than the last withdrawn token id, subtract the current token id from the last withdrawn token id to calculate how much ETH can be withdrawn for the given token return (attempt.startTokenId - LAST_WITHDRAWN) * 0.06 ether; } // Not the first redemption but the last withdrawn token id is equal to or more than the provided token id, so no ETH can be withdrawn return 0; } /** * @notice withdraw winnings from the prize pool * @param tokenId the token id of the escaped miner * @return boolean representing whether or not the prize was redeemed */ function redeem(uint256 tokenId) external returns(bool) { // Ensure that the tx sender can redeem the prize pool with the provided token id require(canRedeem(msg.sender, tokenId),"cannot redeem"); // Get the starting attempt data for this token Attempt memory attempt = TOKENS[tokenId]; // Define the total payout available to this token id uint256 payout = redeemableValue(tokenId); // Check if the payout available is greater than 0 if(payout > 0){ // Redeemable ETH available from prize pool! // Define secondary payout (1/10 of payout) uint256 secondaryPayout = payout / 10; // Remove secondary payout from payout amount payout = payout - secondaryPayout; // Define total supply uint256 supply = TOKEN_SUPPLY.current(); // Define empty secondary winner address secondaryWinner; // Select a secondary winner uint256 secondaryWinnerTokenId = uint256(keccak256(abi.encodePacked( tokenId, payout ))) % supply; secondaryWinner = ownerOf(secondaryWinnerTokenId); // Set last withdrawn token id to the provided token's starting chamber id LAST_WITHDRAWN = attempt.startTokenId; // Send payout amount to tx sender payable(msg.sender).transfer(payout); // Send secondaryPayout amount to secondary winner payable(secondaryWinner).transfer(secondaryPayout); // Let the world know that the prize pool has been redeemed emit Redeemed(tokenId,msg.sender,payout,secondaryWinner,secondaryPayout); // Prize redeemed, return success return true; } // No available funds, revert revert("no funds"); } /** * @notice start an escape attempt if the miner has not yet entered the dungeon * @param tokenId the token id of the pending miner * @return uint256 value of the starting token id */ function startAttempt(uint256 tokenId) external returns(uint256) { // Ensure the sender owns the token require(ownerOf(tokenId) == msg.sender,"owner"); // Ensure this attempt has not yet started Attempt memory attempt = TOKENS[tokenId]; require(attempt.startTokenId == 0,"started"); // Get total supply (this the most recent tokenId and will be the startTokenId) uint256 supply = TOKEN_SUPPLY.current(); // Set new value in struct and save to contract attempt.startTokenId = supply; TOKENS[tokenId] = attempt; // Let the world know emit AttemptStarted(tokenId,supply); // Return the starting token id return supply; } /** * * MINING & MINTING METHODS * */ /** * @notice return the current difficulty variables * @return array of the the current difficulty variables */ function getDifficulty() external view returns(uint256, uint256) { // Return difficulty variables (target and radius) return (DIFFICULTY_TARGET,DIFFICULTY_RADIUS); } /** * @notice mine a token and mint it if the difficulty target problem has been solved * @param nonce the nonce solving the difficulty target problem for the message sender * @param itemId the item id of the miner's starting item * @param classId the class id of the miner * @param genderId the gender id of the miner * @param startNow whether or not the miner should enter the dungeon right away */ function mine(uint256 nonce, uint256 itemId, uint256 classId, uint256 genderId, bool startNow) payable public { // Ensure the class is valid require(classId < 4,"class"); // Ensure the item is valid require(itemId < 8,"item"); // Ensure the gender is valid require(genderId < 2,"gender"); // Ensure the transaction contains enough ETH to mint require(msg.value >= (0.08 ether + SHOP_ITEMS[itemId].cost), "cost"); // Get current supply uint256 supply = TOKEN_SUPPLY.current(); // Get next token id uint256 tokenId = supply + 1; // Define hash var bytes32 hash; // Check if this is the first token to be minted if(supply > 0){ // Not first token hash = keccak256(abi.encodePacked( msg.sender, TOKENS[supply].hash, nonce )); } else { // First token hash = keccak256(abi.encodePacked( msg.sender, bytes32(0x0000000000000000000000000000000000000000000000000000000000000000), nonce )); } // Make sure the difficulty target problem has been solved require(uint256(hash) >= (DIFFICULTY_TARGET - DIFFICULTY_RADIUS) && uint256(hash) < (DIFFICULTY_TARGET + DIFFICULTY_RADIUS), "range"); // Create new hash to commit to blockchain by rehashing the calculated difficulty hash with the Miner's itemId, classId, genderId, the timestamp of the current block, the current coinbase, block difficulty and block number hash = keccak256(abi.encodePacked(hash,itemId,classId,genderId,block.timestamp,block.coinbase,block.difficulty,block.number)); // Store 0.06 of the base cost in the contract/prize pot and send the remainder to the treasury (bool sent, bytes memory data) = TREASURY.call{value: msg.value - 0.06 ether}(""); require(sent, "payment"); // Increase TOKEN_SUPPLY TOKEN_SUPPLY.increment(); // Mint the token with the token ID and new hash _mint(tokenId,hash,uint256(hash),(startNow ? tokenId : 0),itemId,classId,genderId); // Let the world know emit Mined(tokenId,msg.sender,hash,(startNow ? tokenId : 0),DIFFICULTY_TARGET,DIFFICULTY_RADIUS,itemId,classId,genderId); if(startNow){ emit AttemptStarted(tokenId,tokenId); } } /** * @notice overload mine function to default the startNow bool to TRUE if it is not set * @param nonce the nonce solving the difficulty target problem for the message sender * @param itemId the item id of the miner's starting item * @param classId the class id of the miner * @param genderId the gender id of the miner */ function mine(uint256 nonce, uint256 itemId, uint256 classId, uint256 genderId) payable public { mine(nonce,itemId,classId,genderId,true); } /** * @notice mint a new token and set new difficulty target values * @param tokenId the token id of the miner to be minted * @param tokenHash the hash of the token * @param hashVal the hash of the token cast to an unsigned integer * @param startTokenId the tokenId at which the miner entered the dungeon * @param itemId the item id of the miner's starting item * @param classId the class id of the miner * @param genderId the gender id of the miner */ function _mint(uint256 tokenId, bytes32 tokenHash, uint256 hashVal, uint256 startTokenId, uint256 itemId, uint256 classId, uint256 genderId) private { // Define the escape attempt stats based on provided data Attempt memory attempt = Attempt({ hash: tokenHash, startTokenId: startTokenId, genderId: uint8(genderId), classId: uint8(classId), itemId: uint8(itemId) }); // Set the owner of the token to the sender OWNERS[tokenId] = msg.sender; // Increment the balance of the sender BALANCES[msg.sender]++; // Set new difficulty target DIFFICULTY_TARGET = (hashVal % DIFFICULTY_LIMIT) + DIFFICULTY_RADIUS; // Push the attempt to the tokens array TOKENS[tokenId] = attempt; // Let the world know that a token has been minted emit Transfer(address(0),msg.sender,tokenId); } /** * @notice get the hash of a token * @param tokenId the token id of the miner * @return bytes32 value of the hash of the provided token */ function hashOf(uint256 tokenId) external view returns(bytes32) { require(_isValidToken(tokenId),"Invalid token."); return TOKENS[tokenId].hash; } /** * @notice check if a token is valid (has been minted and is owned by an address) * @param tokenId the token id of the miner * @return boolean representing whether or not the token is valid */ function _isValidToken(uint256 tokenId) internal view returns(bool) { return OWNERS[tokenId] != address(0); } /** * * ERC-721 * */ /** * @notice get the balance of an address * @param owner the address to be checked * @return uint256 value of the number of miners the address owns */ function balanceOf(address owner) external view returns(uint256) { return BALANCES[owner]; } /** * @notice get the owner of a miner * @param tokenId the token id of the miner * @return address of the owner */ function ownerOf(uint256 tokenId) public view returns(address) { require(_isValidToken(tokenId),"invalid"); return OWNERS[tokenId]; } /** * @notice transfer ownership of a miner from one address to another * @param from the address to transfer the miner from * @param to the address to transfer the miner to * @param tokenId the token id of the miner to transfer * @param data additional data to send in call to "to" */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public { // Call the transferFrom() function to transfer ownership of a token from one address to another transferFrom(from, to, tokenId); // Get size of "to" address, if 0 it's a wallet uint32 size; assembly { size := extcodesize(to) } // Check if the "to" address is not a wallet if(size > 0){ // Not a wallet! // Set up ERC-721 interface for accepting safe transfers ERC721TokenReceiver receiver = ERC721TokenReceiver(to); // Successful transfers will return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` - otherwise the transaction will be reversed require(receiver.onERC721Received(msg.sender,from,tokenId,data) == bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")),"receiver"); } } /** * @notice overload safeTransferFrom to transfer ownership of a miner from one address to another with blank data * @param from the address to transfer the miner from * @param to the address to transfer the miner to * @param tokenId the token id of the miner to transfer */ function safeTransferFrom(address from, address to, uint256 tokenId) external { safeTransferFrom(from,to,tokenId,""); } /** * @notice transfer ownership of a miner from one address to another * @notice make sure "to" is an actual address or this miner could be lost forever * @param from the address to transfer the miner from * @param to the address to transfer the miner to * @param tokenId the token id of the miner to transfer */ function transferFrom(address from, address to, uint256 tokenId) public { // Get the owner of the token address owner = ownerOf(tokenId); // Ensure that the message sender owns the token or the sender has been authorized for actions on this token or for all actions on behalf of the owner require (owner == msg.sender || ALLOWANCE[tokenId] == msg.sender || AUTHORIZED[owner][msg.sender],"permission"); // Ensure that the owner address specified matches the calculated owner address of the token require(owner == from,"owner"); // Ensure that the recipient address is a valid address require(to != address(0),"zero"); // let the world know emit Transfer(from, to, tokenId); // Set the owner of the token to the recipient address OWNERS[tokenId] = to; // Remove one token from the original owner's token ownership counter in the balances array BALANCES[from]--; // Add one token to the new owner's token ownership counter in the balances array BALANCES[to]++; // Check if there's been an access allowance made in the past for this token if(ALLOWANCE[tokenId] != address(0)){ // Allowance exists! // Delete the existing allowance to revoke token operation access from previously-allowed addresses delete ALLOWANCE[tokenId]; } } /** * @notice approve an address to take action on a specific miner * @param approved the address to approve * @param tokenId the token id of the miner */ function approve(address approved, uint256 tokenId) external { // Get the owner of the token address owner = ownerOf(tokenId); // Ensure that the message sender owns the token or the sender is authorized for this token require(owner == msg.sender || AUTHORIZED[owner][msg.sender],"permission"); // Let the world know emit Approval(owner, approved, tokenId); // Add the approved address to the allowance array ALLOWANCE[tokenId] = approved; } /** * @notice approve an address to take action on all miners owned by the sender * @param operator the address to approve * @param approved whether or not the operator address provided is approved */ function setApprovalForAll(address operator, bool approved) external { // Let the world know emit ApprovalForAll(msg.sender,operator, approved); // Set authorized boolean for an operator address on behalf of the message sender AUTHORIZED[msg.sender][operator] = approved; } /** * @notice return the approved an address for a specific miner * @param tokenId the token id of the miner * @return address of the approved wallet for a token */ function getApproved(uint256 tokenId) external view returns(address) { // Check that the token is valid require(_isValidToken(tokenId),"invalid"); // Return the address from the allowance array return ALLOWANCE[tokenId]; } /** * @notice check if an operator address has been approved to manage all tokens for another address * @param owner the address of the miner(s) owner * @param operator the address of the approved operator * @return boolean representing whether or not the operator is approved for all of owner's tokens */ function isApprovedForAll(address owner, address operator) external view returns(bool) { // Return a boolean if the operator address is found at the owner key in the authorized array return AUTHORIZED[owner][operator]; } /** * * ERC-721 METADATA * */ /** * @notice return the Dungeon Miners name * @return string representing the token name */ function name() external pure returns(string memory) { return "Dungeon Miners"; } /** * @notice return the abbreviated Dungeon Miners name * @return string representing the token abbreviation */ function symbol() external pure returns(string memory) { return "DM"; } /** * @notice return the data URI for a given token * @param tokenId the token id of the miner * @return string representing a data uri */ function tokenURI(uint256 tokenId) external view returns (string memory) { // Ensure the token id is valid require(_isValidToken(tokenId),"Invalid token"); // Return generated data from _tokenURI function return _tokenURI(tokenId); } /** * * CONTRACT-LEVEL METADATA * */ /** * @notice return the data URI for contract-level data * @return string representing a data uri */ function contractURI() external pure returns (string memory) { return 'data:text/plain,{"name":"Dungeon Miners","description":"Dungeon Miners is a fully on-chain, procedurally-generated dungeon crawler where players can mine for and mint NFTs that evolve as more and more NFTs are minted in an attempt to escape a 48-chamber dungeon and win ETH prizes.","image":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCA2NCA2NCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQgbWVldCI+PGRlZnM+PG1hc2sgaWQ9Im9tIiBtYXNrVW5pdHM9InVzZXJTcGFjZU9uVXNlIj48cmVjdCB3aWR0aD0iNiIgaGVpZ2h0PSI3IiBmaWxsPSIjZmZmIi8+PHJlY3QgeD0iMiIgeT0iMSIgd2lkdGg9IjIiIGhlaWdodD0iNSIgZmlsbD0iIzAwMCIvPjwvbWFzaz48bWFzayBpZD0icm0iIG1hc2tVbml0cz0idXNlclNwYWNlT25Vc2UiPjxyZWN0IHdpZHRoPSI2IiBoZWlnaHQ9IjciIGZpbGw9IiNmZmYiLz48cmVjdCB4PSIyIiB5PSIxIiB3aWR0aD0iMiIgaGVpZ2h0PSIzIiBmaWxsPSIjMDAwIi8+PC9tYXNrPjxwYXRoIGlkPSJkIiBkPSJNMCwwaDV2MWgxdjVoLTF2MWgtNXoiIHN0eWxlPSJtYXNrOnVybCgjb20pIi8+PHBhdGggaWQ9InUiIGQ9Ik0wLDBoMnY2aDJ2LTZoMnY3aC02eiIvPjxwYXRoIGlkPSJuIiBkPSJNMCwwaDF2MWgxdjFoMXYxaDF2LTNoMnY3aC0xdi0xaC0xdi0xaC0xdi0xaC0xdjNoLTJ6Ii8+PHBhdGggaWQ9ImciIGQ9Ik0wLDBoNnYyaC0ydi0xaC0ydjVoMnYtMmgtMXYtMWgzdjRoLTZ6Ii8+PHBhdGggaWQ9ImUiIGQ9Ik0wLDBoNnYxaC00djJoM3YxaC0zdjJoNHYxaC02eiIvPjxwYXRoIGlkPSJvIiBkPSJNMCwwaDZ2N2gtNnoiIHN0eWxlPSJtYXNrOnVybCgjb20pIi8+PHBhdGggaWQ9Im0iIGQ9Ik0wLDBoMXYxaDF2MWgxdjFoMXYtMWgxdi0xaDF2LTFoMXY3aC0ydi0zaC0xdjJoLTF2LTJoLTF2M2gtMnoiLz48cGF0aCBpZD0iaSIgZD0iTTAsMGg2djFoLTJ2NWgydjFoLTZ2LTFoMnYtNWgtMnoiLz48cGF0aCBpZD0iciIgZD0iTTAsMGg2djRoLTF2MWgxdjJoLTJ2LTJoLTJ2MmgtMnoiIHN0eWxlPSJtYXNrOnVybCgjcm0pIi8+PHBhdGggaWQ9InMiIGQ9Ik0wLDBoNnYyaC0ydi0xaC0ydjJoNHY0aC02di0yaDJ2MWgydi0yaC00eiIvPjxnIGlkPSJkdW5nZW9uIj48dXNlIGhyZWY9IiNkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDQpIi8+PHVzZSBocmVmPSIjdSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNywyKSIvPjx1c2UgaHJlZj0iI24iIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE0LDEpIi8+PHVzZSBocmVmPSIjZyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjEsMCkiLz48dXNlIGhyZWY9IiNlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyOCwxKSIvPjx1c2UgaHJlZj0iI28iIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM1LDIpIi8+PHVzZSBocmVmPSIjbiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDIsNCkiLz48L2c+PGcgaWQ9Im1pbmVycyI+PHVzZSBocmVmPSIjbSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMywyKSIvPjx1c2UgaHJlZj0iI2kiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDExLDEpIi8+PHVzZSBocmVmPSIjbiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTgsMCkiLz48dXNlIGhyZWY9IiNlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNSwwKSIvPjx1c2UgaHJlZj0iI3IiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMyLDEpIi8+PHVzZSBocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzksMikiLz48L2c+PC9kZWZzPjxyZWN0IGhlaWdodD0iNjQiIHdpZHRoPSI2NCIgZmlsbD0iIzA5MDgwYiIvPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDgsMTgpIj48Zz48cmVjdCB4PSIyMyIgd2lkdGg9IjIiIGhlaWdodD0iMjgiIGZpbGw9IiM3NTRjMjQiLz48cmVjdCB4PSIyMyIgd2lkdGg9IjEiIGhlaWdodD0iMjgiIGZpbGw9IiM4YzYyMzkiLz48cmVjdCB4PSIyMyIgeT0iNSIgd2lkdGg9IjIiIGhlaWdodD0iMSIgZmlsbD0icmdiYSgwLDAsMCwwLjIpIi8+PHBhdGggZD0iTTIsOGgxdi0yaDJ2LTFoM3YtMWg0di0xaDV2LTFoNXYtMWg0djFoNXYxaDV2MWg0djFoM3YxaDJ2MmgxdjFoLTF2LTFoLTJ2LTFoLTN2LTFoLTR2LTFoLTV2LTFoLTV2MWgtNHYtMWgtNXYxaC01djFoLTR2MWgtM3YxaC0ydjFoLTF6IiBmaWxsPSIjOTU5NTk1Ii8+PHBhdGggZD0iTTIsOGgxdi0yaDJ2LTFoM3YtMWg0di0xaDV2LTFoNXYtMWg0djFoLTR2MWgtNXYxaC01djFoLTR2MWgtM3YxaC0ydjJoLTF6IiBmaWxsPSJyZ2JhKDI1NSwyNTUsMjU1LDAuMikiLz48cGF0aCBkPSJNMjIsNGg0di0xaDV2MWg1djFoNHYxaDN2MWgydjFoMXYxaC0xdi0xaC0ydi0xaC0zdi0xaC00di0xaC01di0xaC01djFoLTR6IiBmaWxsPSJyZ2JhKDAsMCwwLDAuMikiLz48L2c+PHVzZSBocmVmPSIjZHVuZ2VvbiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCw4KSIgZmlsbD0iIzUyM2YyYyIvPjx1c2UgaHJlZj0iI21pbmVycyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwxOCkiIGZpbGw9IiM1MjNmMmMiLz48dXNlIGhyZWY9IiNkdW5nZW9uIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDcpIiBmaWxsPSIjZmZmIi8+PHVzZSBocmVmPSIjbWluZXJzIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDE3KSIgZmlsbD0iI2ZmZiIvPjwvZz48L3N2Zz4=","external_link":"https://dungeonminers.com","seller_fee_basis_points":250,"fee_recipient":"0x79ac53F63728684F5B21B6302FC5Cef5A8E8b7e9"}'; } /** * * ERC-165 * */ /** * @notice check if this contract implements an interface * @param interfaceID the interface identifier, as specified in ERC-165 * @return boolean representing whether or not the interface is supported */ function supportsInterface(bytes4 interfaceID) external view returns(bool) { return supportedInterfaces[interfaceID]; } } // Define the ERC721TokenReceiver interface interface ERC721TokenReceiver { function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns(bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // 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); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; struct Attempt { bytes32 hash; uint256 startTokenId; uint8 genderId; uint8 classId; uint8 itemId; }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; struct Class { int16 baseHealth; int16 baseArmor; int16 baseAttack; int16 baseSpeed; }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; struct Miner { int16 baseHealth; int16 baseArmor; int16 health; int16 armor; int16 attack; int16 speed; uint16 gold; uint8 genderId; uint8 classId; uint8 skintoneId; uint8 hairColorId; uint8 hairTypeId; uint8 eyeColorId; uint8 eyeTypeId; uint8 mouthId; uint8 headgearId; uint8 armorId; uint8 pantsId; uint8 footwearId; uint8 weaponId; uint8 curseTurns; uint8 buffTurns; uint8 debuffTurns; uint8 revives; uint8 currentChamber; }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; struct Item { uint256 cost; int16 healthMod; int16 armorMod; int16 attackMod; int16 speedMod; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "./Strings.sol"; import "../Structs/PackedVars.sol"; import "../Structs/Monster.sol"; import "../Structs/Miner.sol"; library Calcs { using Strings for *; /** * @notice return a headgear stats array * @param gearId the gear id of the headgear item * @return array of int16 values representing the HP buff, AP buff, ATK buff, SPD buff, small asset id and large asset id of the item */ function headgearStats(uint256 gearId) public pure returns (int16[6] memory) { int16[6][17] memory GEAR = [ [int16(0),0,0,0, 0,3], // 0 | C | none // uncommon = 8 total // Health & Attack [int16(3),0,5,0, 1,7], // 1 | U | bandana [int16(6),0,2,0, 2,10], // 2 | U | leather hat [int16(2),0,6,0, 3,11], // 3 | U | rusty helm [int16(4),0,4,0, 4,8], // 4 | U | feathered cap // rare = 14 total // Health & Armor & Attack [int16(7),5,2,0, 5,4], // 5 | R | enchanted crown [int16(5),5,4,0, 6,12], // 6 | R | bronze helm [int16(2),4,8,0, 7,0], // 7 | R | assassin's mask // epic = 24 total // Health & Armor & Attack [int16(6),12,6,0, 8,13], // 8 | E | iron helm [int16(9),6,9,0, 15,16], // 9 | E | skull helm [int16(9),6,9,0, 14,6], // 10 | E | charmed headband [int16(9),6,9,0, 12,9], // 11 | E | ranger cap [int16(9),6,9,0, 10,1], // 12 | E | misty hood // legendary = 42 total // Health & Armor & Attack & Speed [int16(13),10,13,6, 16,17], // 13 | L | phoenix helm [int16(13),10,13,6, 13,5], // 14 | L | ancient mask [int16(13),10,13,6, 11,15], // 15 | L | genesis helm [int16(13),10,13,6, 9,14] // 16 | L | soul shroud ]; return GEAR[gearId]; } /** * @notice return an armor stats array * @param gearId the gear id of the armor item * @return array of int16 values representing the HP buff, AP buff, ATK buff, SPD buff, small asset id and large asset id of the item */ function armorStats(uint256 gearId) public pure returns (int16[6] memory) { int16[6][17] memory GEAR = [ [int16(0),0,0,0, 0,0], // 17 | C | cotton shirt // uncommon = 8 total // Health & Armor [int16(3),5,0,0, 0,1], // 18 | U | thick vest [int16(4),4,0,0, 0,2], // 19 | U | leather chestplate [int16(2),6,0,0, 3,3], // 20 | U | rusty chainmail [int16(6),2,0,0, 0,4], // 21 | U | longcoat // rare = 14 total // Health & Armor & Attack [int16(6),4,4,0, 3,5], // 22 | R | chainmail [int16(5),6,3,0, 0,6], // 23 | R | bronze chestplate [int16(6),6,2,0, 0,7], // 24 | R | blessed armor // epic = 24 total // Health & Armor & Attack [int16(6),7,11,0, 0,8], // 25 | E | iron chestplate [int16(9),9,6,0, 2,9], // 26 | E | skull armor [int16(9),9,6,0, 1,10], // 27 | E | cape of deception [int16(9),9,6,0, 1,11], // 28 | E | mystic cloak [int16(9),9,6,0, 4,12], // 29 | E | shimmering cloak // legendary = 42 total // Health & Armor & Attack & Speed [int16(13),13,10,6, 0,13], // 30 | L | phoenix chestplate [int16(13),13,10,6, 0,14], // 31 | L | ancient robe [int16(13),13,10,6, 1,15], // 32 | L | genesis cloak [int16(13),13,10,6, 1,16] // 33 | L | soul cloak ]; return GEAR[gearId - 17]; } /** * @notice return a pants stats array * @param gearId the gear id of the pants item * @return array of int16 values representing the HP buff, AP buff, ATK buff, SPD buff, small asset id and large asset id of the item */ function pantsStats(uint256 gearId) public pure returns (int16[6] memory) { int16[6][17] memory GEAR = [ [int16(0),0,0,0, 0,0], // 34 | C | cotton pants // uncommon = 8 total // Armor & Speed [int16(0),6,0,2, 0,0], // 35 | U | thick pants [int16(0),4,0,4, 0,0], // 36 | U | leather greaves [int16(0),3,0,5, 3,0], // 37 | U | rusty chainmail pants [int16(0),2,0,6, 0,0], // 38 | U | reliable leggings // rare = 14 total // Health & Armor & Speed [int16(2),4,0,8, 0,0], // 39 | R | padding leggings [int16(3),5,0,6, 1,0], // 40 | R | bronze greaves [int16(5),5,0,4, 0,0], // 41 | R | enchanted pants // epic = 24 total // Health & Armor & Speed [int16(8),9,0,7, 1,0], // 42 | E | iron greaves [int16(6),9,0,9, 0,0], // 43 | E | skull greaves [int16(6),9,0,9, 0,0], // 44 | E | swift leggings [int16(6),9,0,9, 0,0], // 45 | E | forest greaves [int16(6),9,0,9, 0,0], // 46 | E | silent leggings // legendary = 42 total // Health & Armor & Attack & Speed [int16(10),13,6,13, 0,0], // 47 | L | phoenix greaves [int16(10),13,6,13, 2,0], // 48 | L | ancient greaves [int16(10),13,6,13, 0,0], // 49 | L | genesis greaves [int16(10),13,6,13, 0,0] // 50 | L | soul greaves ]; return GEAR[gearId - 34]; } /** * @notice return a footwear stats array * @param gearId the gear id of the footwear item * @return array of int16 values representing the HP buff, AP buff, ATK buff, SPD buff, small asset id and large asset id of the item */ function footwearStats(uint256 gearId) public pure returns (int16[6] memory) { int16[6][17] memory GEAR = [ [int16(0),0,0,0, 0,0], // 51 | C | none // uncommon = 8 total // Health & Speed [int16(3),0,0,5, 1,0], // 52 | U | sturdy cleats [int16(4),0,0,4, 1,0], // 53 | U | leather boots [int16(6),0,0,2, 2,0], // 54 | U | rusty boots [int16(2),0,0,6, 0,0], // 55 | U | lightweight shoes // rare = 14 total // Health & Attack & Speed [int16(2),0,3,9, 2,0], // 56 | R | bandit's shoes [int16(5),0,4,5, 2,0], // 57 | R | bronze boots [int16(6),0,5,3, 6,0], // 58 | R | heavy boots // epic = 24 total // Health & Attack & Speed [int16(9),0,10,5, 2,0], // 59 | E | iron boots [int16(9),0,6,9, 1,0], // 60 | E | skull boots [int16(9),0,6,9, 1,0], // 61 | E | enchanted boots [int16(9),0,6,9, 4,0], // 62 | E | jaguarpaw boots [int16(9),0,6,9, 3,0], // 63 | E | lightfoot boots // legendary = 42 total // Health & Armor & Attack & Speed [int16(13),6,10,13, 5,0], // 64 | L | phoenix boots [int16(13),6,10,13, 1,0], // 65 | L | ancient boots [int16(13),6,10,13, 1,0], // 66 | L | genesis boots [int16(13),6,10,13, 2,0] // 67 | L | soul boots ]; return GEAR[gearId - 51]; } /** * @notice return a weapon stats array * @param gearId the gear id of the weapon item * @return array of int16 values representing the HP buff, AP buff, ATK buff, SPD buff, small asset id and large asset id of the item */ function weaponStats(uint256 gearId) public pure returns (int16[6] memory) { int16[6][29] memory GEAR = [ [int16(0),0,0,0, 0,5], // 68 | C | fists // uncommon = 8 total // Attack & Speed [int16(0),0,4,4, 1,6], // 69 | U | rusty sword [int16(0),0,6,2, 8,20], // 70 | U | wooden club [int16(0),0,5,3, 7,1], // 71 | U | pickaxe [int16(0),0,2,6, 6,0], // 72 | U | brass knuckles // rare = 14 total // Armor & Attack & Speed [int16(0),2,6,6, 19,28], // 73 | R | weathered greataxe [int16(0),2,6,6, 5,18], // 74 | R | polished scepter [int16(0),2,6,6, 14,24], // 75 | R | poisoned spear [int16(0),2,6,6, 11,3], // 76 | R | kusarigama [int16(0),4,4,6, 1,7], // 77 | R | bronze sword [int16(0),4,4,6, 4,15], // 78 | R | bronze staff [int16(0),4,4,6, 13,23], // 79 | R | bronze shortsword [int16(0),4,4,6, 2,9], // 80 | R | bronze daggers [int16(0),2,4,8, 18,27], // 81 | R | dusty scmitar [int16(0),2,4,8, 15,25], // 82 | R | silver wand [int16(0),2,4,8, 12,22], // 83 | R | dual handaxes [int16(0),2,4,8, 10,21], // 84 | R | dual shortswords // epic = 24 total // Armor & Attack & Speed [int16(0),7,9,8, 1,8], // 85 | E | holy sword [int16(0),7,9,8, 4,16], // 86 | E | holy staff [int16(0),7,9,8, 3,12], // 87 | E | holy bow [int16(0),7,9,8, 2,10], // 88 | E | holy daggers [int16(0),5,9,10, 17,26], // 89 | E | soulcutter [int16(0),5,9,10, 4,17], // 90 | E | shadow staff [int16(0),5,9,10, 3,13], // 91 | E | shadow bow [int16(0),5,9,10, 9,2], // 92 | E | shadowblades // legendary = 42 total // Health & Armor & Attack & Speed [int16(6),10,13,13, 16,4], // 93 | L | phoenix blade [int16(6),10,13,13, 5,19], // 94 | L | ancient scepter [int16(6),10,13,13, 3,14], // 95 | L | genesis bow [int16(6),10,13,13, 2,11] // 96 | L | soul daggers ]; return GEAR[gearId - 68]; } /** * @notice return a uint16 value from a bytes32 hash, given an offset * @param hash the bytes32 hash to retrieve a uint16 from * @param offset the offset from 0 to grab the data from * @return uint16 value cast to a uint256 */ function _hashToUint16(bytes32 hash, uint256 offset) internal pure returns (uint256) { require(30 >= offset, "oob"); return uint256((hash << (offset * 8)) >> 240); } /** * @notice calculate a gear type * @param typeVal a uint value between 0-255 * @return uint8 value of gear type for an item */ function gType(uint8 typeVal) public pure returns (uint8) { /* 0 | common | 0-127 | 1/2 | 128 | 50% | 0% 1 | uncommon 1 | 128-151 | 3/32 | 24 | 9.375% | 18.75% 2 | uncommon 2 | 152-175 | 3/32 | 24 | 9.375% | 18.75% 3 | uncommon 3 | 176-199 | 3/32 | 24 | 9.375% | 18.75% 4 | uncommon 4 | 200-223 | 3/32 | 24 | 9.375% | 18.75% 5 | rare 1 | 224-232 | 9/256 | 9 | 3.516% | 7.031% 6 | rare 2 | 233-241 | 9/256 | 9 | 3.516% | 7.031% 7 | rare 3 | 242-250 | 9/256 | 9 | 3.516% | 7.031% 8 | epic 1 | 251-252 | 1/32 | 2 | 0.781% | 1.563% 9 | epic 2 | 253-254 | 1/32 | 2 | 0.781% | 1.563% 10 | legendary | 255 | 1/256 | 1 | 0.391% | 0.781% */ // Sorting from middle-out (reduce gas by probability) if(typeVal < 128){ return 0; } else { if(typeVal < 224) { if(typeVal < 176){ return typeVal < 152 ? 1 : 2; } else { return typeVal < 200 ? 3 : 4; } } else { if(typeVal < 251){ if(typeVal < 233){ return 5; } else { return typeVal < 242 ? 6 : 7; } } else { if(typeVal < 253){ return 8; } else { return typeVal < 255 ? 9 : 10; } } } } } /** * @notice calculate a chamber type * @param hash the bytes32 hash value of a chamber * @return uint256 value of chamber type */ function _cType(bytes32 hash) internal pure returns (uint256) { return (uint256(uint8(hash[4])) / 32); } /** * @notice calculate a chamber type and return as a string * @param hash the bytes32 hash value of a chamber * @return string of chamber type */ function ctString(bytes32 hash) external pure returns (string memory) { return _cType(hash).toString(); } /** * @notice calculate an encounter type * @param hash the bytes32 hash value of a chamber * @return uint8 value of the encounter type */ function _eType(bytes32 hash) internal pure returns (uint8) { uint256 typeVal = uint256(_hashToUint16(hash,14)); /* # | type | value range | size | probability ---+------------+-------------+------+------------------- 0 | slime | 0-6143 | 6144 | 9.375% 1 | crawler | 6144-12287 | 6144 | 9.375% 2 | poison bat | 12288-18431 | 6144 | 9.375% 3 | skeleton | 18432-24575 | 6144 | 9.375% 4 | trap | 24576-28475 | 3900 | 5.950927734375% 5 | curse | 28476-32375 | 3900 | 5.950927734375% 6 | buff | 32376-36275 | 3900 | 5.950927734375% 7 | debuff | 36276-40175 | 3900 | 5.950927734375% 8 | gold | 40176-44075 | 3900 | 5.950927734375% 9 | thief | 44076-47975 | 3900 | 5.950927734375% 10 | empty | 47976-51875 | 3900 | 5.950927734375% 11 | rest | 51876-55775 | 3900 | 5.950927734375% 12 | gear | 55776-58780 | 3005 | 4.58526611328125% 13 | merchant | 58781-61785 | 3005 | 4.58526611328125% 14 | treasure | 61786-63600 | 1815 | 2.76947021484375% 15 | heal | 63601-65415 | 1815 | 2.76947021484375% 16 | revive | 65416-65495 | 80 | 0.1220703125% 17 | armory | 65496-65535 | 40 | 0.06103515625% */ // Sorting from middle-out (reduce gas by probability) if(typeVal < 32376){ if(typeVal < 18432){ if(typeVal < 12288){ return typeVal < 6144 ? 0 : 1; } else { return 2; } } else { if(typeVal < 24576){ return 3; } else { return typeVal < 28476 ? 4 : 5; } } } else { if(typeVal < 47976){ if(typeVal < 40176){ return typeVal < 36276 ? 6 : 7; } else { return typeVal < 44076 ? 8 : 9; } } else { if(typeVal < 55776){ return typeVal < 51876 ? 10 : 11; } else { if(typeVal < 61786){ return typeVal < 58781 ? 12 : 13; } else { if(typeVal < 63601){ return 14; } else { if(typeVal < 65416){ return 15; } else { return typeVal < 65496 ? 16 : 17; } } } } } } } /** * @notice calculate an encounter type and return as a string * @param hash the bytes32 hash value of a chamber * @return string of the encounter type */ function etString(bytes32 hash) external pure returns (string memory) { return _eType(hash).toString(); } /** * @notice calculate an encounter outcome * @param hash chamber hash * @param miner the current Miner instance * @return array representing the post-encounter miner struct */ function chamberStats(bytes32 hash, Miner memory miner) external pure returns (Miner memory) { // Define chamberData PackedVars memory chamberData; // Define encounter type for this chamber chamberData.var_uint8_1 = _eType(hash); // Pre-encounter calcuations // Check Miner's class if(miner.classId == 0){ // Miner is a warrior! Restore 2 armor miner.armor = miner.armor + 2; // Check if armor is greater than baseArmor if(miner.armor > miner.baseArmor){ // Set armor to baseArmor miner.armor = miner.baseArmor; } } else if(miner.classId == 2){ // Miner is a ranger! Restore 3 health and add 2 to baseHealth // Restore health miner.health = miner.health + 3; // Check if health is greater than baseHealth if(miner.health > miner.baseHealth){ // Set health to baseHealth miner.health = miner.baseHealth; } // Add 2 to baseHealth miner.baseHealth = miner.baseHealth + 2; } // Check if Miner is cursed and make sure this isn't a curse chamber to avoid doing double damage if(miner.curseTurns > 0 && chamberData.var_uint8_1 != 5){ // Miner is cursed! // Calculate curse damage taken (10 percent of current health or 5 if Miner has less than 50 health) chamberData.var_int16_1 = miner.health < 50 ? int16(5) : (miner.health / 10); // Set Miner health miner.health = miner.health - chamberData.var_int16_1; // Check if Miner is dead but has a revive if(miner.health < 1 && miner.revives > 0){ // Revive with 1/4 health and 1/4 armor IF current armor is less than current armor miner.health = miner.baseHealth / 4; miner.armor = miner.armor < (miner.baseArmor / 4) ? (miner.baseArmor / 4) : miner.armor; // Remove revive from inventory miner.revives--; } // Remove curse turn miner.curseTurns--; } // Encounter calculations // Check if Miner is still alive after potential curse damage has been calculated if(miner.health > 0){ // Miner is alive! Loop through potential encounter types to calculate results if(chamberData.var_uint8_1 < 4){ // MONSTER // Define monster Monster memory monster; // Check what kind of monster we've encountered and adjust stats if(chamberData.var_uint8_1 == 0){ // SLIME monster.health = int16(int8(uint8(hash[0]) % 48)) + 70 + (10 * int16(uint16(miner.currentChamber / 8))); monster.attack = int16(int8(uint8(hash[2]) % 24)) + 15 + (5 * int16(uint16(miner.currentChamber / 8))); monster.speed = int16(int8(uint8(hash[3]) % 24)) + 35; monster.mtype = chamberData.var_uint8_1; } else if(chamberData.var_uint8_1 == 1){ // CRAWLER monster.health = int16(int8(uint8(hash[0]) % 48)) + 65 + (10 * int16(uint16(miner.currentChamber / 8))); monster.attack = int16(int8(uint8(hash[2]) % 24)) + 25 + (5 * int16(uint16(miner.currentChamber / 8))); monster.speed = int16(int8(uint8(hash[3]) % 24)) + 50; monster.mtype = chamberData.var_uint8_1; } else if(chamberData.var_uint8_1 == 2){ // POISON BAT monster.health = int16(int8(uint8(hash[0]) % 48)) + 60 + (10 * int16(uint16(miner.currentChamber / 8))); monster.attack = int16(int8(uint8(hash[2]) % 24)) + 15 + (5 * int16(uint16(miner.currentChamber / 8))); monster.speed = int16(int8(uint8(hash[3]) % 24)) + 55; monster.mtype = chamberData.var_uint8_1; } else { // SKELETON monster.health = int16(int8(uint8(hash[0]) % 48)) + 80 + (10 * int16(uint16(miner.currentChamber / 8))); monster.attack = int16(int8(uint8(hash[2]) % 24)) + 30 + (5 * int16(uint16(miner.currentChamber / 8))); monster.speed = int16(int8(uint8(hash[3]) % 24)) + 40; monster.mtype = chamberData.var_uint8_1; } // Define turn counter chamberData.var_uint8_2 = 0; // Loop through battle turns until someone dies while(miner.health > 0 && monster.health > 0){ // Check variable monster turn speed vs. variable Miner turn speed if((monster.speed + int16(int8(uint8(keccak256(abi.encodePacked(hash,chamberData.var_uint8_2))[7]) % 24))) > (miner.speed + int16(int8(uint8(keccak256(abi.encodePacked(hash,chamberData.var_uint8_2))[6]) % 24)))){ // Monster goes first // Get random offset from monster's base attack for this turn chamberData.var_int16_4 = int16(int8(uint8(keccak256(abi.encodePacked(hash,chamberData.var_uint8_2))[14]) % 8)); // Adjust monster's attack modifier to be a range of -4 to 4, no zero (positive numbers will be a buff, negative will be debuff) chamberData.var_int16_4 = chamberData.var_int16_4 - (chamberData.var_int16_4 < 4 ? int16(4) : int16(3)); // Calculate total damage taken chamberData.var_int16_2 = monster.attack + chamberData.var_int16_4; // Sub 1/3 of total damage from total damage for armor damage (do this instead of dmg / 3 * 2 because of integer floor rounding - would favor health damage instead of armor) // Value is 1/2 instead of 1/3 for Warriors chamberData.var_int16_3 = chamberData.var_int16_2 - (chamberData.var_int16_2 / (miner.classId == 0 ? int16(2) : int16(3))); // Sub armor damage from armor miner.armor = miner.armor - chamberData.var_int16_3; // Sub health damage from health miner.health = miner.health - (chamberData.var_int16_2 - chamberData.var_int16_3); // If armor has been broken, pass excess damage to health and set armor to zero if(miner.armor < 0){ miner.health = miner.health + miner.armor; miner.armor = 0; } // Check if Miner is dead if(miner.health < 1){ // Check if Miner has a revive if(miner.revives > 0){ // Revive with 1/4 health and 1/4 armor IF current armor is less than current armor miner.health = miner.baseHealth / 4; miner.armor = miner.armor < (miner.baseArmor / 4) ? (miner.baseArmor / 4) : miner.armor; // Remove revive from inventory miner.revives--; } else { // He/she dead, bro break; } } // Get random offset from Miner's base attack for this turn chamberData.var_int16_1 = int16(int8(uint8(keccak256(abi.encodePacked(hash,chamberData.var_uint8_2))[13]) % 8)); // Adjust Miner's attack modifier to be a range of -4 to 4, no zero (negative numbers will be a buff, positive will be debuff) chamberData.var_int16_1 = chamberData.var_int16_1 - (chamberData.var_int16_1 < 4 ? int16(4) : int16(3)); // Attack monster monster.health = monster.health - miner.attack - chamberData.var_int16_1 - (miner.buffTurns > 0 ? int16(4) : int16(0)) + (miner.debuffTurns > 0 ? int16(4) : int16(0)); } else { // Miner goes first // Get random offset from Miner's base attack for this turn chamberData.var_int16_1 = int16(int8(uint8(keccak256(abi.encodePacked(hash,chamberData.var_uint8_2))[13]) % 8)); // Adjust Miner's attack modifier to be a range of -4 to 4, no zero (negative numbers will be a buff, positive will be debuff) chamberData.var_int16_1 = chamberData.var_int16_1 - (chamberData.var_int16_1 < 4 ? int16(4) : int16(3)); // Attack monster monster.health = monster.health - miner.attack - chamberData.var_int16_1 - (miner.buffTurns > 0 ? int16(4) : int16(0)) + (miner.debuffTurns > 0 ? int16(4) : int16(0)); // Check if monster is dead if(monster.health < 1){ // It dead, bro break; } else { // Get random offset from monster's base attack for this turn chamberData.var_int16_4 = int16(int8(uint8(keccak256(abi.encodePacked(hash,chamberData.var_uint8_2))[14]) % 8)); // Adjust monster's attack modifier to be a range of -4 to 4, no zero (positive numbers will be a buff, negative will be debuff) chamberData.var_int16_4 = chamberData.var_int16_4 - (chamberData.var_int16_4 < 4 ? int16(4) : int16(3)); // Calculate total damage taken chamberData.var_int16_2 = monster.attack + chamberData.var_int16_4; // Sub 1/3 of total damage from total damage for armor damage (do this instead of dmg / 3 * 2 because of integer floor rounding - would favor health damage instead of armor) // Value is 1/2 instead of 1/3 for Warriors chamberData.var_int16_3 = chamberData.var_int16_2 - (chamberData.var_int16_2 / (miner.classId == 0 ? int16(2) : int16(3))); // Sub armor damage from armor miner.armor = miner.armor - chamberData.var_int16_3; // Sub health damage from health miner.health = miner.health - (chamberData.var_int16_2 - chamberData.var_int16_3); // If armor has been broken, pass excess damage to health and set armor to zero if(miner.armor < 0){ miner.health = miner.health + miner.armor; miner.armor = 0; } // Check if Miner is dead but has a revive if(miner.health < 1 && miner.revives > 0){ // Revive with 1/4 health and 1/4 armor IF current armor is less than current armor miner.health = miner.baseHealth / 4; miner.armor = miner.armor < (miner.baseArmor / 4) ? (miner.baseArmor / 4) : miner.armor; // Remove revive from inventory miner.revives--; } } } // Add one to loop/turn count chamberData.var_uint8_2++; } } else if(chamberData.var_uint8_1 == 4){ // TRAP // Calculate trap damage chamberData.var_int16_2 = int16(int8(uint8(hash[2]) % 16) + 32); // Check if Miner is an assassin if(miner.classId == 3){ // // Miner is an assassin! Cut trap damage in half chamberData.var_int16_2 = (chamberData.var_int16_2 / 2); } // Sub 1/3 of total damage from total damage for armor damage (do this instead of dmg / 3 * 2 because of integer floor rounding - would favor health damage instead of armor) // Value is 1/2 instead of 1/3 for Warriors chamberData.var_int16_3 = chamberData.var_int16_2 - (chamberData.var_int16_2 / (miner.classId == 0 ? int16(2) : int16(3))); // Sub armor damage from armor miner.armor = miner.armor - chamberData.var_int16_3; // Sub health damage from health miner.health = miner.health - (chamberData.var_int16_2 - chamberData.var_int16_3); // If armor has been broken, pass excess damage to health and set armor to zero if(miner.armor < 0){ miner.health = miner.health + miner.armor; miner.armor = 0; } // Check if Miner is dead but has a revive if(miner.health < 1 && miner.revives > 0){ // Revive with 1/4 health and 1/4 armor IF current armor is less than current armor miner.health = miner.baseHealth / 4; miner.armor = miner.armor < (miner.baseArmor / 4) ? (miner.baseArmor / 4) : miner.armor; // Remove revive from inventory miner.revives--; } } else if(chamberData.var_uint8_1 == 5){ // CURSE // Check if the Miner IS NOT a mage if(miner.classId != 1){ // Miner is not a mage! Curse this mf // Calculate curse damage taken (10 percent of current health or 5 if Miner has less than 50 health) chamberData.var_int16_1 = miner.health < 50 ? int16(5) : (miner.health / 10); // Sub curse damage from health miner.health = miner.health - chamberData.var_int16_1; // Check if Miner is dead but has a revive if(miner.health < 1 && miner.revives > 0){ // Revive with 1/4 health and 1/4 armor IF current armor is less than current armor miner.health = miner.baseHealth / 4; miner.armor = miner.armor < (miner.baseArmor / 4) ? (miner.baseArmor / 4) : miner.armor; // Remove revive from inventory miner.revives--; } // Add curse for 4 more chambers miner.curseTurns = 4; } } else if(chamberData.var_uint8_1 == 6){ // BUFF // Add buff for 3 chambers (adding one extra because it will be removed at the end of loop) miner.buffTurns = miner.buffTurns + 4; } else if(chamberData.var_uint8_1 == 7){ // DEBUFF // Add debuff for 3 chambers (adding one extra because it will be removed at the end of loop) miner.debuffTurns = miner.debuffTurns + 4; } else if(chamberData.var_uint8_1 == 8){ // GOLD // Add gold to inventory miner.gold = miner.gold + uint16(uint8(hash[8]) % 24) + 2; } else if(chamberData.var_uint8_1 == 9){ // THIEF // Check if the Miner is an assassin if(miner.classId == 3){ // Miner is an assassin! Give a low-tier item (uncommon or rare) // Gear type (0 == headgear, 1 == armor, 2 == pants, 3 == footwear, 4 == weapon) chamberData.var_uint8_2 = uint8(hash[13]) % 5; // Gear rarity // Add 128 to modulo 123 to get item from uncommon or rare rarity tiers chamberData.var_uint8_3 = gType((uint8(hash[16 + chamberData.var_uint8_2]) % 123) + 128); // Gear ID chamberData.var_uint8_4 = (chamberData.var_uint8_2 < 4 ? chamberData.var_uint8_3 : (chamberData.var_uint8_3 > 4 ? (((chamberData.var_uint8_3 - 5) * 4) + 8) : chamberData.var_uint8_3)) + (17 * chamberData.var_uint8_2); // Define array for gearItem stats int16[6] memory gearItem; // Check which gear type and add values appropriately if(chamberData.var_uint8_2 == 0){ // Get headgear stats gearItem = headgearStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.headgearId){ miner.headgearId = chamberData.var_uint8_4; } } else if(chamberData.var_uint8_2 == 1){ // Get armor stats gearItem = armorStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.armorId){ miner.armorId = chamberData.var_uint8_4; } } else if(chamberData.var_uint8_2 == 2){ // Get pants stats gearItem = pantsStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.pantsId){ miner.pantsId = chamberData.var_uint8_4; } } else if(chamberData.var_uint8_2 == 3){ // Get footwear stats gearItem = footwearStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.footwearId){ miner.footwearId = chamberData.var_uint8_4; } } else { // Get weapon stats gearItem = weaponStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.weaponId){ miner.weaponId = chamberData.var_uint8_4; } } // Add gear health buff to baseHealth miner.baseHealth = miner.baseHealth + gearItem[0]; // Add gear health buff to health miner.health = miner.health + gearItem[0]; // Add gear armor buff to baseArmor miner.baseArmor = miner.baseArmor + gearItem[1]; // Add gear armor buff to armor miner.armor = miner.armor + gearItem[1]; // Add gear attack buff to attack miner.attack = miner.attack + gearItem[2]; // Add gear speed buff to speed miner.speed = miner.speed + gearItem[3]; } else { // Miner IS NOT an assassin, let's steal some gold // uint16 goldStolen chamberData.var_uint16_1 = uint16(uint8(hash[8]) % 16) + 1; // Remove stolen gold from Miner miner.gold = miner.gold > chamberData.var_uint16_1 ? (miner.gold - chamberData.var_uint16_1) : 0; } // } else if(chamberData.var_uint8_1 == 10){ // EMPTY // Nothing happens here } else if(chamberData.var_uint8_1 == 11){ // REST // Restore health miner.health = miner.health + int16(int8(uint8(hash[9]) % 24)) + 7; // Check if health is greater than baseHealth if(miner.health > miner.baseHealth){ // Miner is way too healthy, set health to baseHealth miner.health = miner.baseHealth; } } else if(chamberData.var_uint8_1 == 12){ // GEAR // Gear type (0 == headgear, 1 == armor, 2 == pants, 3 == footwear, 4 == weapon) chamberData.var_uint8_2 = uint8(hash[13]) % 5; // Gear rarity // If less than 128, add 128 to the hash val (rarity tiers start at uncommon and double chance for each tier) chamberData.var_uint8_3 = gType((uint8(hash[16 + chamberData.var_uint8_2]) < 128 ? uint8(hash[16 + chamberData.var_uint8_2]) + 128 : uint8(hash[16 + chamberData.var_uint8_2]))); // Gear ID chamberData.var_uint8_4 = (chamberData.var_uint8_2 < 4 ? (chamberData.var_uint8_3 > 8 ? (((chamberData.var_uint8_3 - 9) * 4) + 9 + miner.classId) : chamberData.var_uint8_3) : (chamberData.var_uint8_3 > 4 ? (((chamberData.var_uint8_3 - 5) * 4) + 5 + miner.classId) : chamberData.var_uint8_3)) + (17 * chamberData.var_uint8_2); // Define array for gearItem stats int16[6] memory gearItem; // Check which gear type and add values appropriately if(chamberData.var_uint8_2 == 0){ // Get headgear stats gearItem = headgearStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.headgearId){ miner.headgearId = chamberData.var_uint8_4; } } else if(chamberData.var_uint8_2 == 1){ // Get armor stats gearItem = armorStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.armorId){ miner.armorId = chamberData.var_uint8_4; } } else if(chamberData.var_uint8_2 == 2){ // Get pants stats gearItem = pantsStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.pantsId){ miner.pantsId = chamberData.var_uint8_4; } } else if(chamberData.var_uint8_2 == 3){ // Get footwear stats gearItem = footwearStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.footwearId){ miner.footwearId = chamberData.var_uint8_4; } } else { // Get weapon stats gearItem = weaponStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.weaponId){ miner.weaponId = chamberData.var_uint8_4; } } // Add gear health buff to baseHealth miner.baseHealth = miner.baseHealth + gearItem[0]; // Add gear health buff to health miner.health = miner.health + gearItem[0]; // Add gear armor buff to baseArmor miner.baseArmor = miner.baseArmor + gearItem[1]; // Add gear armor buff to armor miner.armor = miner.armor + gearItem[1]; // Add gear attack buff to attack miner.attack = miner.attack + gearItem[2]; // Add gear speed buff to speed miner.speed = miner.speed + gearItem[3]; } else if(chamberData.var_uint8_1 == 13){ // MERCHANT // Check if Miner has enough gold for item (min 25) if(miner.gold > 24){ // Miner can afford to purchase some gear, assign gear type // Gear type (0 == headgear, 1 == armor, 2 == pants, 3 == footwear, 4 == weapon) chamberData.var_uint8_2 = uint8(hash[13]) % 5; // Check what the Miner can afford if(miner.gold < 50){ // Buy uncommon item // Gear rarity - assign 1-4 for uncommon chamberData.var_uint8_3 = (uint8(hash[16 + chamberData.var_uint8_2]) % 4) + 1; // Pay the merchant miner.gold = miner.gold - 25; } else if (miner.gold < 75){ // Buy rare item // Gear rarity - assign 5-7 for rare chamberData.var_uint8_3 = (uint8(hash[16 + chamberData.var_uint8_2]) % 3) + 5; // Pay the merchant miner.gold = miner.gold - 50; } else if (miner.gold < 100){ // Buy epic item // Gear rarity - assign 8-9 for epic chamberData.var_uint8_3 = (uint8(hash[16 + chamberData.var_uint8_2]) % 2) + 8; // Pay the merchant miner.gold = miner.gold - 75; } else { // Buy legendary item // Gear rarity - assign 10 for legendary chamberData.var_uint8_3 = 10; // Pay the merchant miner.gold = miner.gold - 100; } // Determine Gear ID chamberData.var_uint8_4 = (chamberData.var_uint8_2 < 4 ? (chamberData.var_uint8_3 > 8 ? (((chamberData.var_uint8_3 - 9) * 4) + 9 + miner.classId) : chamberData.var_uint8_3) : (chamberData.var_uint8_3 > 4 ? (((chamberData.var_uint8_3 - 5) * 4) + 5 + miner.classId) : chamberData.var_uint8_3)) + (17 * chamberData.var_uint8_2); // Define array for gearItem stats int16[6] memory gearItem; // Check which gear type and add values appropriately if(chamberData.var_uint8_2 == 0){ // Get headgear stats gearItem = headgearStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.headgearId){ miner.headgearId = chamberData.var_uint8_4; } } else if(chamberData.var_uint8_2 == 1){ // Get armor stats gearItem = armorStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.armorId){ miner.armorId = chamberData.var_uint8_4; } } else if(chamberData.var_uint8_2 == 2){ // Get pants stats gearItem = pantsStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.pantsId){ miner.pantsId = chamberData.var_uint8_4; } } else if(chamberData.var_uint8_2 == 3){ // Get footwear stats gearItem = footwearStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.footwearId){ miner.footwearId = chamberData.var_uint8_4; } } else { // Get weapon stats gearItem = weaponStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.weaponId){ miner.weaponId = chamberData.var_uint8_4; } } // Add gear health buff to baseHealth miner.baseHealth = miner.baseHealth + gearItem[0]; // Add gear health buff to health miner.health = miner.health + gearItem[0]; // Add gear armor buff to baseArmor miner.baseArmor = miner.baseArmor + gearItem[1]; // Add gear armor buff to armor miner.armor = miner.armor + gearItem[1]; // Add gear attack buff to attack miner.attack = miner.attack + gearItem[2]; // Add gear speed buff to speed miner.speed = miner.speed + gearItem[3]; } } else if(chamberData.var_uint8_1 == 14){ // TREASURE // Add found gold to gold miner.gold = miner.gold + uint16(uint8(hash[8]) % 48) + 28; // Gear type (0 == headgear, 1 == armor, 2 == pants, 3 == footwear, 4 == weapon) chamberData.var_uint8_2 = uint8(hash[13]) % 5; // Gear rarity // Modulo of 32, add 224 to the hash val to get a value between 224-255 (rarity tiers start at rare) chamberData.var_uint8_3 = gType((uint8(hash[16 + chamberData.var_uint8_2]) % 32) + 224); // Determine Gear ID chamberData.var_uint8_4 = (chamberData.var_uint8_2 < 4 ? (chamberData.var_uint8_3 > 8 ? (((chamberData.var_uint8_3 - 9) * 4) + 9 + miner.classId) : chamberData.var_uint8_3) : (((chamberData.var_uint8_3 - 5) * 4) + 5 + miner.classId)) + (17 * chamberData.var_uint8_2); // Define array for gearItem stats int16[6] memory gearItem; // Check which gear type and add values appropriately if(chamberData.var_uint8_2 == 0){ // Get headgear stats gearItem = headgearStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.headgearId){ miner.headgearId = chamberData.var_uint8_4; } } else if(chamberData.var_uint8_2 == 1){ // Get armor stats gearItem = armorStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.armorId){ miner.armorId = chamberData.var_uint8_4; } } else if(chamberData.var_uint8_2 == 2){ // Get pants stats gearItem = pantsStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.pantsId){ miner.pantsId = chamberData.var_uint8_4; } } else if(chamberData.var_uint8_2 == 3){ // Get footwear stats gearItem = footwearStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.footwearId){ miner.footwearId = chamberData.var_uint8_4; } } else { // Get weapon stats gearItem = weaponStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.weaponId){ miner.weaponId = chamberData.var_uint8_4; } } // Add gear health buff to baseHealth miner.baseHealth = miner.baseHealth + gearItem[0]; // Add gear health buff to health miner.health = miner.health + gearItem[0]; // Add gear armor buff to baseArmor miner.baseArmor = miner.baseArmor + gearItem[1]; // Add gear armor buff to armor miner.armor = miner.armor + gearItem[1]; // Add gear attack buff to attack miner.attack = miner.attack + gearItem[2]; // Add gear speed buff to speed miner.speed = miner.speed + gearItem[3]; } else if(chamberData.var_uint8_1 == 15){ // HEAL // Restore health by 1/2 baseHealth miner.health = miner.health + (miner.baseHealth / 2); // Check if health is greater than baseHealth if(miner.health > miner.baseHealth){ // Miner is way too healthy, set health to baseHealth miner.health = miner.baseHealth; } // Restore armor by 1/2 baseArmor miner.armor = miner.armor + (miner.baseArmor / 2); // Check if armor is greater than baseArmor if(miner.armor > miner.baseArmor){ // Miner is way too tanky, set armor to baseArmor miner.armor = miner.baseArmor; } } else if(chamberData.var_uint8_1 == 16){ // REVIVE // Add revive to inventory miner.revives++; } else if(chamberData.var_uint8_1 == 17){ // ARMORY // Oh baby, this Miner is about to get BROLIC // Loop through gear types to add all to gear stats for(chamberData.var_uint8_2 = 0; chamberData.var_uint8_2 < 5; chamberData.var_uint8_2++){ // Gear rarity // 3/4 chance of epic, 1/4 chance of legendary chamberData.var_uint8_3 = (uint8(hash[16 + chamberData.var_uint8_2]) % 4) < 3 ? 9 : 10; // Determine Gear ID chamberData.var_uint8_4 = (chamberData.var_uint8_2 < 4 ? (((chamberData.var_uint8_3 - 9) * 4) + 9 + miner.classId) : (((chamberData.var_uint8_3 - 5) * 4) + 5 + miner.classId)) + (17 * chamberData.var_uint8_2); // Define array for gearItem stats int16[6] memory gearItem; // Check which gear type and add values appropriately if(chamberData.var_uint8_2 == 0){ // Get headgear stats gearItem = headgearStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.headgearId){ miner.headgearId = chamberData.var_uint8_4; } } else if(chamberData.var_uint8_2 == 1){ // Get armor stats gearItem = armorStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.armorId){ miner.armorId = chamberData.var_uint8_4; } } else if(chamberData.var_uint8_2 == 2){ // Get pants stats gearItem = pantsStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.pantsId){ miner.pantsId = chamberData.var_uint8_4; } } else if(chamberData.var_uint8_2 == 3){ // Get footwear stats gearItem = footwearStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.footwearId){ miner.footwearId = chamberData.var_uint8_4; } } else { // Get weapon stats gearItem = weaponStats(chamberData.var_uint8_4); // If gearId is higher than Miner's current gearId, reassign visible gear if(chamberData.var_uint8_4 > miner.weaponId){ miner.weaponId = chamberData.var_uint8_4; } } // Add gear health buff to baseHealth miner.baseHealth = miner.baseHealth + gearItem[0]; // Add gear armor buff to baseArmor miner.baseArmor = miner.baseArmor + gearItem[1]; // Add gear attack buff to attack miner.attack = miner.attack + gearItem[2]; // Add gear speed buff to speed miner.speed = miner.speed + gearItem[3]; } // Set current Miner health to base health miner.health = miner.baseHealth; // Set current Miner armor to base armor miner.armor = miner.baseArmor; } } // Post-encounter calculations // If the Miner has at least one buff turn remaining, remove a buff turn if(miner.buffTurns > 0){ miner.buffTurns--; } // If the Miner has at least one debuff turn remaining, remove a debuff turn if(miner.debuffTurns > 0){ miner.debuffTurns--; } // Return the Miner return miner; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "./Strings.sol"; import "../Structs/Attempt.sol"; import "../Structs/Miner.sol"; import "../Structs/PackedVars.sol"; import "./AssetRenderer1.sol"; import "./AssetRenderer2.sol"; import "./AssetRenderer3.sol"; import "./AssetRenderer4.sol"; import "./AssetRenderer5.sol"; import "./Calcs.sol"; import "./LgSVG.sol"; import "./SmSVG.sol"; library Metadata { using Strings for *; /** * @notice build metadata strings for a miner * @param attempt the attempt struct for this miner * @param minerIn the miner struct to ingest * @param chambers an array of chamber hashes * @return array of strings (first json metadata, second image data) */ function build(Attempt memory attempt, Miner memory minerIn, bytes32[47] memory chambers) external pure returns(string memory,string memory) { // Define a PackedVars struct to efficiently assign/reassign values during calculation PackedVars memory packedData; // Check if an attempt has started yet if(attempt.startTokenId == 0){ // Attempt has not started - generate miner (Miner memory miner, string memory metaAttributes) = _initCodeGen( minerIn, packedData ); // Set svgBody to large miner render string memory svgBody = _lgRender(miner); // Return the metadata and image data return ( metaAttributes, LgSVG.render( Calcs.ctString(attempt.hash), svgBody, 1, 7 ) ); } else { (Miner memory miner, string memory svgBody, string memory metaAttributes) = _codeGen( minerIn, chambers, packedData ); if(miner.health <= 0 || miner.currentChamber == 46){ // Miner is dead or won! // Set svgBody to large miner render svgBody = _lgRender(miner); if(miner.currentChamber == 46){ // Winner winner, chicken dinner! // Set background value to 2 packedData.var_uint8_2 = 2; // Set frame value to 6 packedData.var_uint8_1 = 6; } else { // Miner es muerto; // Set frame value to current floor packedData.var_uint8_1 = (miner.currentChamber / 8); } // Return the metadata and image data return ( metaAttributes, LgSVG.render( Calcs.ctString(attempt.hash), svgBody, packedData.var_uint8_2, packedData.var_uint8_1 ) ); } else { // Miner is alive! // Define string var for bottom stats attributes based on attempt stats string memory minerStats; // Loop through all gear types to generate style tags for miner for(packedData.var_uint8_1 = 0; packedData.var_uint8_1 < 5; packedData.var_uint8_1++){ // Generate and append color defs to the minerStats var if(packedData.var_uint8_1 == 0){ minerStats = string(abi.encodePacked( minerStats, AssetRenderer1.cssSkinVar(miner.skintoneId) )); } else if(packedData.var_uint8_1 == 1){ minerStats = string(abi.encodePacked( minerStats, // AssetRenderer1.cssVar(GEAR[miner.armorId]) AssetRenderer1.cssVar(miner.armorId) )); } else if(packedData.var_uint8_1 == 2){ minerStats = string(abi.encodePacked( minerStats, // AssetRenderer1.cssVar(GEAR[miner.pantsId]) AssetRenderer1.cssVar(miner.pantsId) )); } else if(packedData.var_uint8_1 == 3){ minerStats = string(abi.encodePacked( minerStats, // AssetRenderer1.cssVar(GEAR[miner.footwearId]) AssetRenderer1.cssVar(miner.footwearId) )); } else if(packedData.var_uint8_1 == 4){ minerStats = string(abi.encodePacked( minerStats, // AssetRenderer1.cssVar(GEAR[miner.weaponId]) AssetRenderer1.cssVar(miner.weaponId) )); } } for(packedData.var_uint8_2 = 0; packedData.var_uint8_2 < 7; packedData.var_uint8_2++){ // Generate and append avatar image data to the minerStats var if(packedData.var_uint8_2 == 0){ minerStats = string(abi.encodePacked( minerStats, AssetRenderer4.renderCape(uint16(Calcs.armorStats(miner.armorId)[4])) )); } else if(packedData.var_uint8_2 == 1){ minerStats = string(abi.encodePacked( minerStats, AssetRenderer4.renderPants(uint16(Calcs.pantsStats(miner.pantsId)[4])) )); } else if(packedData.var_uint8_2 == 2){ minerStats = string(abi.encodePacked( minerStats, AssetRenderer4.renderFootwear(uint16(Calcs.footwearStats(miner.footwearId)[4])) )); } else if(packedData.var_uint8_2 == 3){ minerStats = string(abi.encodePacked( minerStats, AssetRenderer4.renderArmor(uint16(Calcs.armorStats(miner.armorId)[4])) )); } else if(packedData.var_uint8_2 == 4){ minerStats = string(abi.encodePacked( minerStats, '%253Cg fill=\'var(--dms)\'%253E%253Cpath d=\'M8,4h5v5h-5z\'/%253E%253Cpath d=\'M4,14h3v3h-3zM16,14h3v3h-3z\'/%253E%253C/g%253E' )); } else if(packedData.var_uint8_2 == 5){ minerStats = string(abi.encodePacked( minerStats, AssetRenderer4.renderHeadgear(uint16(Calcs.headgearStats(miner.headgearId)[4])) )); } else if(packedData.var_uint8_2 == 6){ minerStats = string(abi.encodePacked( minerStats, AssetRenderer1.weapon(uint16(Calcs.weaponStats(miner.weaponId)[4])), '%253C/g%253E' )); } } // Loop through all miner stats to generate image data for bottom stats bar for(packedData.var_uint8_3 = 0; packedData.var_uint8_3 < 6; packedData.var_uint8_3++){ // Generate and append miner stats image data to the minerStats var minerStats = string(abi.encodePacked( minerStats, AssetRenderer1.smMinerStat(packedData.var_uint8_3,miner) )); } // Return the metadata and image data return ( metaAttributes, SmSVG.render( svgBody, minerStats ) ); } } } /** * @notice render a miner portrait * @param miner the miner struct * @return string of miner portrait image data */ function _lgRender(Miner memory miner) internal pure returns(string memory) { PackedVars memory packedData; string memory svgBody; // Loop through all gear types to generate style tags for miner for(packedData.var_uint8_1 = 0; packedData.var_uint8_1 < 11; packedData.var_uint8_1++){ // Generate and append color defs to the svgBody var if(packedData.var_uint8_1 == 0){ svgBody = string(abi.encodePacked( svgBody, AssetRenderer1.cssSkinVar(miner.skintoneId) )); } else if(packedData.var_uint8_1 == 1){ svgBody = string(abi.encodePacked( svgBody, AssetRenderer1.cssHairVar(miner.hairColorId) )); } else if(packedData.var_uint8_1 == 2){ svgBody = string(abi.encodePacked( svgBody, AssetRenderer1.cssEyeVar(miner.eyeColorId) )); } else if(packedData.var_uint8_1 == 3){ svgBody = string(abi.encodePacked( svgBody, LgSVG.renderBase(miner.genderId,miner.classId,miner.eyeTypeId,miner.mouthId) )); } else if(packedData.var_uint8_1 == 4){ svgBody = string(abi.encodePacked( svgBody, AssetRenderer3.renderArmor(uint16(Calcs.armorStats(miner.armorId)[5])) )); } else if(packedData.var_uint8_1 == 5){ svgBody = string(abi.encodePacked( svgBody, AssetRenderer2.renderHairDefs(uint16(Calcs.headgearStats(miner.headgearId)[5]),miner.hairTypeId,miner.genderId) )); } else if(packedData.var_uint8_1 == 6){ svgBody = string(abi.encodePacked( svgBody, // AssetRenderer3.renderHair(miner.hairTypeId,GEAR[miner.headgearId].lgAssetId) AssetRenderer3.renderHair(miner.hairTypeId,uint16(Calcs.headgearStats(miner.headgearId)[5])) )); } else if(packedData.var_uint8_1 == 7){ svgBody = string(abi.encodePacked( svgBody, LgSVG.renderMod((miner.genderId * 4) + miner.classId) )); } else if(packedData.var_uint8_1 == 8){ svgBody = string(abi.encodePacked( svgBody, // AssetRenderer2.renderHeadgear(GEAR[miner.headgearId].lgAssetId,miner.genderId) AssetRenderer2.renderHeadgear(uint16(Calcs.headgearStats(miner.headgearId)[5]),miner.genderId) )); } else if(packedData.var_uint8_1 == 9 && miner.classId == 2){ svgBody = string(abi.encodePacked( svgBody, AssetRenderer2.renderEarMod(miner.headgearId) )); } else if(packedData.var_uint8_1 == 10){ svgBody = string(abi.encodePacked( svgBody, AssetRenderer5.renderWeapon(uint16(Calcs.weaponStats(miner.weaponId)[5])) )); } } return svgBody; } /** * @notice return the name of a gear item * @param gearId the gear id of the gear item * @return string of quotation mark-wrapped gear item */ function _gearName(uint8 gearId) internal pure returns(string memory) { if(gearId < 17){ // Headgear return ['"None"','"Bandana"','"Leather Hat"','"Rusty Helm"','"Feathered Cap"','"Enchanted Crown"','"Bronze Helm"','"Assassin\'s Mask"','"Iron Helm"','"Skull Helm"','"Charmed Headband"','"Ranger Cap"','"Misty Hood"','"Phoenix Helm"','"Ancient Mask"','"Genesis Helm"','"Soul Shroud"'][gearId]; } else if(gearId < 34){ // Armor - 17 return ['"Cotton Shirt"','"Thick Vest"','"Leather Chestplate"','"Rusty Chainmail"','"Longcoat"','"Chainmail"','"Bronze Chestplate"','"Blessed Armor"','"Iron Chestplate"','"Skull Armor"','"Cape of Deception"','"Mystic Cloak"','"Shimmering Cloak"','"Phoenix Chestplate"','"Ancient Robe"','"Genesis Cloak"','"Soul Cloak"'][gearId - 17]; } else if(gearId < 51){ // Pants - 34 return ['"Cotton Pants"','"Thick Pants"','"Leather Greaves"','"Rusty Chainmail Pants"','"Reliable Leggings"','"Padded Leggings"','"Bronze Greaves"','"Enchanted Pants"','"Iron Greaves"','"Skull Greaves"','"Swift Leggings"','"Forest Greaves"','"Silent Leggings"','"Phoenix Greaves"','"Ancient Greaves"','"Genesis Greaves"','"Soul Greaves"'][gearId - 34]; } else if(gearId < 68){ // Footwear - 51 return ['"None"','"Sturdy Cleats"','"Leather Boots"','"Rusty Boots"','"Lightweight Shoes"','"Bandit\'s Shoes"','"Bronze Boots"','"Heavy Boots"','"Iron Boots"','"Skull Boots"','"Enchanted Boots"','"Jaguarpaw Boots"','"Lightfoot Boots"','"Phoenix Boots"','"Ancient Boots"','"Genesis Boots"','"Soul Boots"'][gearId - 51]; } else { // Weapons - 68 return ['"Fists"','"Rusty Sword"','"Wooden Club"','"Pickaxe"','"Brass Knuckles"','"Weathered Greataxe"','"Polished Scepter"','"Poisoned Spear"','"Kusarigama"','"Bronze Sword"','"Bronze Staff"','"Bronze Shortsword"','"Bronze Daggers"','"Dusty Scmitar"','"Silver Wand"','"Dual Handaxes"','"Dual Shortswords"','"Holy Sword"','"Holy Staff"','"Holy Bow"','"Holy Daggers"','"Soulcutter"','"Shadow Staff"','"Shadow Bow"','"Shadowblades"','"Phoenix Blade"','"Ancient Scepter"','"Genesis Bow"','"Soul Daggers"'][gearId - 68]; } } /** * @notice calculate the result of an escape attempt and return miner, metadata and image data * @param minerIn the miner struct to ingest * @param chambers an array of chamber hashes * @param packedData a packed struct of variables * @return array of miner struct, metadata string and image data string */ function _codeGen(Miner memory minerIn, bytes32[47] memory chambers, PackedVars memory packedData) internal pure returns (Miner memory, string memory, string memory) { // Define string var for all chambers image data starting with the initial chamber Miner memory miner = minerIn; // Define string var for all chambers image data starting with the initial chamber string memory svgBody = string(abi.encodePacked( AssetRenderer1.smChamber( 'a', Calcs.ctString(chambers[0]), 'x', 0 ) )); // Loop through all chambers and calculate attempt data for(packedData.var_uint8_1 = 1; packedData.var_uint8_1 < 47; packedData.var_uint8_1++){ // Check if the miner is alive if(miner.health > 0){ // The miner lives! Do chambery shit // Check if the current chamber has been mined yet if(chambers[packedData.var_uint8_1] != bytes32(0)){ // This chamber has been mined! Do more chambery shit // Set the current chamber to current loop value miner.currentChamber = packedData.var_uint8_1; // Calculate and return the miner and stats after traversing this chamber miner = Calcs.chamberStats(keccak256(abi.encodePacked(chambers[0],chambers[packedData.var_uint8_1])),miner); // Generate and append chamber image data to the svgBody var svgBody = string(abi.encodePacked( svgBody, AssetRenderer1.smChamber( 'a', Calcs.ctString(chambers[packedData.var_uint8_1]), Calcs.etString(keccak256(abi.encodePacked(chambers[0],chambers[packedData.var_uint8_1]))), packedData.var_uint8_1 ) )); } else { // This chamber hasn't been mined yet // Generate and append pending chamber image data to the svgBody var svgBody = string(abi.encodePacked( svgBody, chambers[packedData.var_uint8_1 - 1] != bytes32(0) ? AssetRenderer1.smNext(packedData.var_uint8_1) : '', AssetRenderer1.smChamber('u','x','x',packedData.var_uint8_1) )); } } else { // Break the loop break; } } // Append status elements to the svgBody var svgBody = string(abi.encodePacked( svgBody, '%253Cg class=\'se\' transform=\'translate(4,88)\'%253E' )); if(miner.buffTurns > 0){ // Add buff indicator svgBody = string(abi.encodePacked( svgBody, '%253Cpath d=\'M10,10h2v2h-2z\' fill=\'var(--dm18)\'/%253E' )); } if(miner.debuffTurns > 0){ // Add buff indicator svgBody = string(abi.encodePacked( svgBody, '%253Cpath d=\'M10,10h2v2h-2z\' fill=\'var(--dm6)\'/%253E' )); } if(miner.curseTurns > 0){ // Add buff indicator svgBody = string(abi.encodePacked( svgBody, '%253Cpath d=\'M10,10h2v2h-2z\' fill=\'var(--dm3)\'/%253E' )); } svgBody = string(abi.encodePacked( svgBody, '%253C/g%253E' )); // Define string var for JSON attributes based on attempt stats string memory metaAttributes; // Check if miner is still alive after all chambers have been calculated if(miner.health > 0){ // Still alive! // Check if the miner has reached the exit if(miner.currentChamber == 46){ // Winner winner, chicken dinner! metaAttributes = '{"trait_type":"Miner Status","value":"Escaped"}'; } else { // Attempt is in progress metaAttributes = '{"trait_type":"Miner Status","value":"Exploring"}'; // Generate and append exit image data to the svgBody var svgBody = string(abi.encodePacked( svgBody, AssetRenderer1.smExit() )); } } else { metaAttributes = '{"trait_type":"Miner Status","value":"Dead"}'; } // Loop through all miner attributes to be calculated for metadata for(packedData.var_uint8_1 = 0; packedData.var_uint8_1 < 21; packedData.var_uint8_1++){ // Generate and append miner attribute data to the metaAttributes var metaAttributes = string(abi.encodePacked( metaAttributes, _minerAttribute(packedData.var_uint8_1,miner) )); } // Return miner, svg body and metadata return (miner, svgBody, metaAttributes); } /** * @notice calculate the initial status of an escape attempt and return miner and metadata * @param miner the miner struct * @param packedData a packed struct of variables * @return array of miner struct and metadata string */ function _initCodeGen(Miner memory miner, PackedVars memory packedData) internal pure returns (Miner memory, string memory) { // Define string var for JSON attributes based on attempt stats string memory metaAttributes = '{"trait_type":"Miner Status","value":"In Village"}'; // Loop through all miner attributes to be calculated for metadata for(packedData.var_uint8_2 = 0; packedData.var_uint8_2 < 19; packedData.var_uint8_2++){ // Generate and append miner attribute data to the metaAttributes var metaAttributes = string(abi.encodePacked( metaAttributes, _minerAttribute(packedData.var_uint8_2,miner) )); } // Append blank values to end of metaAttributes metaAttributes = string(abi.encodePacked( metaAttributes, ',{"trait_type":"Chambers Cleared","value":0},{"trait_type":"Gold","value":0}' )); // Return miner and metadata return (miner,metaAttributes); } /** * @notice render the attributes for json metadata * @param index name of stat * @param miner number of string * @return string of a single attribute key/value pair in json object key/value format */ function _minerAttribute(uint256 index, Miner memory miner) internal pure returns (string memory) { string memory stat; string memory value; if(index == 0){ stat = 'Class'; if(miner.classId == 0){ value = '"Warrior"'; } else if(miner.classId == 1){ value = '"Mage"'; } else if(miner.classId == 2){ value = '"Ranger"'; } else { value = '"Assassin"'; } } else if(index == 1){ stat = 'Gender'; value = miner.genderId == 0 ? '"Male"' : '"Female"'; } else if(index == 2){ stat = 'HP'; value = (miner.health < 0 ? 0 : uint16(miner.health)).toString(); } else if(index == 3){ stat = 'AP'; value = (miner.armor < 0 ? 0 : uint16(miner.armor)).toString(); } else if(index == 4){ stat = 'Base HP'; value = (miner.baseHealth < 0 ? 0 : uint16(miner.baseHealth)).toString(); } else if(index == 5){ stat = 'Base AP'; value = (miner.baseArmor < 0 ? 0 : uint16(miner.baseArmor)).toString(); } else if(index == 6){ stat = 'Base ATK'; value = (miner.attack < 0 ? 0 : uint16(miner.attack)).toString(); } else if(index == 7){ stat = 'Base SPD'; value = (miner.speed < 0 ? 0 : uint16(miner.speed)).toString(); } else if(index == 8){ stat = 'Headgear'; value = _gearName(miner.headgearId); } else if(index == 9){ stat = 'Armor'; value = _gearName(miner.armorId); } else if(index == 10){ stat = 'Pants'; value = _gearName(miner.pantsId); } else if(index == 11){ stat = 'Footwear'; value = _gearName(miner.footwearId); } else if(index == 12){ stat = 'Weapon'; value = _gearName(miner.weaponId); } else if(index == 13){ stat = 'Skin Tone'; value = AssetRenderer2.skintoneName(miner.skintoneId); } else if(index == 14){ stat = 'Hair Type'; value = AssetRenderer2.hairTypeName(miner.hairTypeId); } else if(index == 15){ stat = 'Hair Color'; value = AssetRenderer2.hairColorName(miner.hairColorId); } else if(index == 16){ stat = 'Eye Type'; value = AssetRenderer2.eyeTypeName(miner.eyeTypeId); } else if(index == 17){ stat = 'Eye Color'; value = AssetRenderer2.eyeColorName(miner.eyeColorId); } else if(index == 18){ stat = 'Mouth Type'; value = AssetRenderer2.mouthTypeName(miner.mouthId); } else if(index == 19){ stat = 'Gold'; value = miner.gold.toString(); } else if(index == 20){ stat = 'Chambers Cleared'; value = miner.currentChamber.toString(); } return string(abi.encodePacked( ',{"trait_type":"', stat, '","value":', value, '}' )); } }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; struct PackedVars { int8 var_int8_1; int8 var_int8_2; int8 var_int8_3; int8 var_int8_4; int8 var_int8_5; int8 var_int8_6; uint8 var_uint8_1; uint8 var_uint8_2; uint8 var_uint8_3; uint8 var_uint8_4; uint8 var_uint8_5; uint8 var_uint8_6; int16 var_int16_1; int16 var_int16_2; int16 var_int16_3; int16 var_int16_4; uint16 var_uint16_1; uint16 var_uint16_2; uint16 var_uint16_3; uint16 var_uint16_4; uint32 var_uint32_1; }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; struct Monster { int16 health; int16 attack; int16 speed; uint8 mtype; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; import "./Strings.sol"; import "../Structs/Miner.sol"; library AssetRenderer1 { using Strings for *; /** * @notice generate CSS color variables * @param colorId color id of skintone * @return string of css */ function cssSkinVar(uint256 colorId) external pure returns (string memory) { // Array of potential color values string[16] memory COLORS = [ 'var(--dm59)', // 0 | porcelain 'var(--dm58)', // 1 | creme 'var(--dm57)', // 2 | sienna 'var(--dm56)', // 3 | sand 'var(--dm55)', // 4 | beige 'var(--dm54)', // 5 | honey 'var(--dm53)', // 6 | almond 'var(--dm52)', // 7 | bronze 'var(--dm51)', // 8 | espresso 'var(--dm50)', // 9 | ebony 'var(--dm5)', // 10 | demon 'var(--dm17)', // 11 | orc 'var(--dm26)', // 12 | djinn 'var(--dm39)', // 13 | spectre 'var(--dm2)', // 14 | mystic 'var(--dm34)' // 15 | golem ]; return string(abi.encodePacked( '%253Cstyle%253E:root{--dms:', COLORS[colorId], ';' )); } /** * @notice generate CSS color variables * @param colorId color id of hair color * @return string of css */ function cssHairVar(uint256 colorId) external pure returns (string memory) { // Array of potential color values string[8] memory COLORS = [ 'var(--dm48)', // 0 | light brown 'var(--dm46)', // 1 | dark brown 'var(--dm41)', // 2 | dirty blonde 'var(--dm13)', // 3 | blonde 'var(--dm36)', // 4 | gray 'var(--dm43)', // 5 | dark brownish/gray 'var(--dm24)', // 6 | black 'var(--dm11)' // 7 | orange/red ]; return string(abi.encodePacked( '--dmh:', COLORS[colorId], ';' )); } /** * @notice generate CSS color variables * @param colorId color id of eye color * @return string of css */ function cssEyeVar(uint256 colorId) external pure returns (string memory) { // Array of potential color values string[13] memory COLORS = [ 'black', // 0 | black 'var(--dm29)', // 1 | gray 'var(--dm20)', // 2 | light green 'var(--dm17)', // 3 | green 'var(--dm41)', // 4 | amber 'var(--dm45)', // 5 | light brown 'var(--dm47)', // 6 | brown 'var(--dm28)', // 7 | light blue 'var(--dm26)', // 8 | blue 'var(--dm11)', // 9 | orange 'var(--dm2)', // 10 | purple 'var(--dm5)', // 11 | red 'transparent' // 12 | none ]; return string(abi.encodePacked( '--dmi:', COLORS[colorId], '}%253C/style%253E' )); } /** * @notice generate CSS color variables for gear items * @param gearId gear id of gear item * @return string of css */ function cssVar(uint256 gearId) external pure returns (string memory) { // Array of potential color values string[46] memory COLORS = [ 'var(--dm14)', // 0 | BRIGHT YELLOW 'var(--dm42)', // 1 | LIGHT DULL YELLOW 'var(--dm44)', // 2 | DULL BROWN 'var(--dm48)', // 3 | BRIGHT BROWN 'var(--dm43)', // 4 | DARK DULL BROWN 'var(--dm37)', // 5 | GRAY 'var(--dm36)', // 6 | DARK GRAY 'var(--dm38)', // 7 | LIGHT GRAY 'var(--dm41)', // 8 | DARK ORANGE 'var(--dm11)', // 9 | ORANGE 'var(--dm12)', // 10 | BRIGHT YELLOW 'var(--dm2)', // 11 | BRIGHT PURPLE & skintone 14 'var(--dm17)', // 12 | GREEN && skintone 12 'var(--dm46)', // 13 | DARK BROWN 'var(--dm49)', // 14 | MID BRIGHT BROWN 'var(--dm32)', // 15 | LIGHT BLUE 'var(--dm10)', // 16 | LIGHT PINK 'white', // 17 | WHITE 'var(--dm15)', // 18 | LIGHT YELLOW 'var(--dm35)', // 19 | DARK GRAY 'var(--dm37)', // 20 | MID GRAY 'var(--dm1)', // 21 | DARK PURPLE 'var(--dm25)', // 22 | DARK BLUE 'var(--dm26)', // 23 | LIGHT BLUE 'var(--dm19)', // 24 | LIGHT GREEN 'var(--dm52)', // 25 | DARK BROWN & skintone 8 'var(--dm21)', // 26 | SLIME GREEN 'var(--dm20)', // 27 | LIGHT GREEN 'var(--dm59)', // 28 | skintone 1 'var(--dm58)', // 29 | skintone 2 'var(--dm57)', // 30 | skintone 3 'var(--dm56)', // 31 | skintone 4 'var(--dm55)', // 32 | skintone 5 'var(--dm54)', // 33 | skintone 6 'var(--dm53)', // 34 | skintone 7 'var(--dm51)', // 35 | skintone 9 'var(--dm50)', // 36 | skintone 10 'var(--dm5)', // 37 | skintone 11 'var(--dm26)', // 38 | skintone 13 'var(--dm39)', // 39 | skintone 14 'var(--dm2)', // 40 | skintone 15 'url(%2523ch)', // 41 | chain 'url(%2523ch2)', // 42 | chain2 'url(%2523ch3)', // 43 | chain3 'var(--dms)', // 44 | skintone 'transparent' // 45 | transparent ]; if(gearId < 17){ return ''; } else if(gearId < 34){ uint8[4] memory gear = [ [0,1,0,45], [2,1,0,45], [3,1,0,45], [8,1,0,43], [2,4,2,45], [7,5,7,42], [8,5,7,9], [9,5,10,10], [5,5,7,7], [7,7,17,6], [3,3,3,11], [3,3,3,12], [6,7,17,9], [8,5,9,9], [3,3,8,8], [3,3,13,14], [15,15,16,16] ][gearId - 17]; return string(abi.encodePacked( '--dmpa1:', COLORS[gear[0]], ';--dmpa2:', COLORS[gear[1]], ';--dmpa3:', COLORS[gear[2]], ';--dmpa4:', COLORS[gear[3]], ';' )); } else if(gearId < 51){ uint8[3] memory gear = [ [0,18,45], [4,2,45], [2,3,45], [3,3,41], [19,20,45], [2,18,45], [2,8,9], [21,11,45], [2,5,7], [2,17,45], [22,23,45], [2,24,45], [20,19,45], [8,9,45], [2,8,3], [35,14,45], [15,16,45] ][gearId - 34]; return string(abi.encodePacked( '--dmpp1:', COLORS[gear[0]], ';--dmpp2:', COLORS[gear[1]], ';--dmpp3:', COLORS[gear[2]], ';' )); } else if(gearId < 68){ uint8[3] memory gear = [ [44,45,45], [2,45,45], [3,45,45], [3,8,45], [7,5,45], [19,20,45], [8,9,45], [45,45,45], [5,7,45], [7,17,45], [21,11,45], [45,45,45], [45,45,45], [45,45,45], [3,8,45], [35,45,14], [15,16,45] ][gearId - 51]; return string(abi.encodePacked( '--dmpf1:', COLORS[gear[0]], ';--dmpf2:', COLORS[gear[1]], ';--dmpf3:', COLORS[gear[2]], ';' )); } else { uint8[4] memory gear = [ [44,45,45,45], [7,5,45,45], [3,8,45,45], [3,8,7,45], [5,7,45,45], [7,3,8,45], [9,8,45,45], [3,8,27,26], [7,8,3,45], [9,8,45,45], [8,9,3,45], [9,8,45,45], [9,8,45,45], [5,7,45,45], [7,5,45,45], [7,8,3,45], [7,5,45,45], [10,9,45,45], [9,10,9,45], [10,9,10,45], [10,9,45,45], [15,16,45,45], [19,20,19,45], [20,19,20,45], [20,19,45,45], [8,9,45,45], [8,3,45,45], [26,14,27,45], [16,15,45,45] ][gearId - 68]; return string(abi.encodePacked( '--dmpw1:', COLORS[gear[0]], ';--dmpw2:', COLORS[gear[1]], ';--dmpw3:', COLORS[gear[2]], ';--dmpw4:', COLORS[gear[3]], ';%253C/style%253E%253Cg class=\'h\' transform=\'translate(4,88)\'%253E' )); } } /** * @notice render a weapon asset * @param smAssetId the small asset id of the gear item * @return string of svg */ function weapon(uint256 smAssetId) external pure returns (string memory) { string[20] memory GEAR = [ // START WEAPONS // 0 empty '%253Cg%253E%253C/g%253E', // 1 sword '%253Cg%253E%253Cpath d=\'M17,9h2v2h-1v1h-1v1h-2v1h-2v1h-2v1h-2v1h-2v-3h2v-1h2v-1h2v-1h2v-1h2z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M18,10h1v1h-1v1h-1v1h-2v1h-2v1h-2v1h-2v1h-2v-1h2v-1h2v-1h2v-1h2v-1h2v-1h1z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M17,9h2v2h-1v1h-1v1h-1v-1h1v-1h1v-1h-1v1h-2v-1h2zM13,11h1v1h-1zM11,12h1v1h-1v1h-1v1h1v1h-2v1h-1v-3h1v-1h2zM12,14h1v1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 2 daggers '%253Cg%253E%253Cpath d=\'M15,10h2v1h1v1h1v2h-3v-2h-1zM8,14h2v-1h2v2h-1v1h-1v1h-2z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M16,10h1v1h1v1h1v2h1v1h-5v-1h3v-2h-1v-1h-1zM7,13h1v3h2v-1h1v-1h1v1h-1v1h-1v1h-2v1h-1z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M15,11h1v1h1v3h-2v-1h1v-2h-1zM10,13h2v1h-2v1h-2v1h2v-1h1v-1h1v1h-1v1h-1v1h-2v1h-1v-3h1v-1h2zM18,13h1v1h1v1h-2z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 3 bow '%253Cg%253E%253Cpath d=\'M11,9h1v1h-1v1h-2v1h-1v1h-2v1h-2v1h-1v-1h1v-1h2v-1h2v-1h1v-1h2zM7,15h1v1h1v1h1v1h1v1h-1v-1h-1v-1h-1v-1h-1z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M13,8h1v1h-1v1h-1v-1h1zM2,14h1v1h-1z\' fill=\'var(--dmpw3)\'/%253E%253Cpath d=\'M14,7h1v3h-1v2h-1v1h-1v1h-1v1h-1v1h-2v1h-1v-1h1v-1h2v-1h1v-1h1v-1h1v-2h1zM1,15h1v1h2v1h-2v-1h-1zM11,18h1v2h-2v-1h1z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M14,7h1v2h-2v1h1v-1h1v1h-1v2h-1v1h-1v-1h1v-2h-1v-1h1v-1h1zM2,14h1v1h-1v1h2v1h-2v-1h-1v-1h1zM7,15h1v1h1v1h-2zM11,18h1v1h-1v1h-1v-1h1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 4 staff '%253Cg%253E%253Cpath d=\'M6,5h1v1h1v4h-1v2h-1v-2h-1v-4h1z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M6,6h1v2h1v1h-1v2h-1v-2h-1v-1h1z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M6,12h1v2h-1zM5,17h1v5h-1z\' fill=\'var(--dmpw3)\'/%253E%253Cpath d=\'M5,8h1v1h1v-1h1v2h-1v2h-1v-2h-1zM6,13h1v1h-1zM5,17h1v3h-1zM5,21h1v1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 5 scepter '%253Cg%253E%253Cpath d=\'M15,10h3v2h-1v1h-4v1h-2v1h-2v1h-2v-1h2v-1h2v-1h2v-1h1v-1h1z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M18,9h1v1h-1zM15,11h1v1h1v-1h1v1h-1v1h-1v-1h-1v1h-1v-1h1zM12,13h1v1h-1zM7,15h1v1h-1z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M18,9h1v1h-1v2h-1v1h-3v-1h2v-1h1v-1h1zM9,14h1v1h-1v1h-2v-1h2z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 6 knuckles '%253Cg%253E%253Cpath d=\'M5,14h3v3h-1v1h-2v-1h1v-2h-1zM17,14h3v3h-1v1h-2v-1h1v-2h-1z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M5,13h2v1h1v2h-1v-1h-1v-1h-1zM17,13h2v1h1v2h-1v-1h-1v-1h-1z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M6,13h1v1h-1zM5,15h1v1h1v2h-2zM17,15h1v1h1v2h-2z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 7 pickaxe '%253Cg%253E%253Cpath d=\'M9,13h4v1h-2v1h-2v1h-2v-2h2zM3,16h1v1h1v1h-2z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M11,12h2v1h-2v1h-2v1h-1v-1h1v-1h2z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M11,7h2v1h1v1h1v2h1v4h-1v2h-1v1h-1v1h-1v-1h1v-8h-1v-2h-1z\' fill=\'var(--dmpw3)\'/%253E%253Cpath d=\'M11,7h2v1h1v1h1v1h-1v-1h-1v1h1v5h1v-4h1v4h-1v2h-1v1h-1v1h-1v-2h1v-3h-2v1h-2v1h-2v-2h3v-1h2v-1h1v-2h-1v-2h-1zM3,17h2v1h-2z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 8 club '%253Cg%253E%253Cpath d=\'M13,9h3v1h1v3h-1v1h-2v1h-3v1h-4v-2h1v-1h1v-1h1v-1h2v-1h1z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M13,10h3v1h-1v1h-2v1h-1v1h-2v1h-2v-1h1v-1h1v-1h2v-1h1z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M13,9h1v1h-1zM10,11h1v1h-1v1h-1v1h-1v2h-1v-2h1v-1h1v-1h1zM16,11h1v2h-1v1h-2v1h-3v1h-2v-1h2v-1h2v-1h2v-1h1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 9 shadowblades '%253Cg%253E%253Cpath d=\'M17,9h2v1h1v1h1v5h-3v-5h-1zM11,15h1v2h-1v1h-1v1h-5v-3h6z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M18,9h1v1h1v1h1v1h-1v-1h-1v-1h-1v1h-1v-1h1zM18,12h1v2h-1v1h1v1h1v-2h1v2h-1v1h-1v1h-2v-1h1v-2h-1v-1h1zM3,15h1v1h2v-1h1v1h2v1h-2v-1h-1v1h-1v1h2v1h-2v-1h-1v-1h-1zM10,15h1v1h1v1h-1v1h-1v1h-1v-1h1v-1h1v-1h-1z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M18,13h1v1h-1zM3,15h1v1h2v-1h1v1h-1v1h1v1h1v1h-3v-1h-1v-1h-1zM19,15h2v1h-1v1h-1v1h-2v-1h1v-1h1zM8,16h2v1h-2z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 10 shortswords '%253Cg%253E%253Cpath d=\'M14,8h2v1h1v1h1v4h-2v-2h-1v-2h-1zM11,12h2v2h-1v1h-1v1h-4v-2h2v-1h2z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M15,8h1v1h1v1h1v2h1v2h-1v-2h-1v-2h-1v-1h-1zM12,13h1v1h-1v1h-1v1h-2v1h-2v-1h2v-1h2v-1h1z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M14,8h2v1h-1v1h1v-1h1v1h1v1h-1v-1h-1v2h-1v-2h-1zM11,12h2v1h-2v1h1v-1h1v1h-1v1h-1v1h-1v-1h1v-1h-2v-1h2zM16,13h1v1h-1zM7,14h1v1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 11 kusarigama '%253Cg%253E%253Cpath d=\'M14,9h3v1h2v1h1v1h1v1h-1v-1h-2v-1h-2v1h-2v-1h-1v-1h1zM3,17h1v1h1v2h-1v1h-1v-1h-1v-2h1zM7,17h1v1h1v1h6v-1h1v-1h1v1h-1v1h-1v1h-6v-1h-1v-1h-1z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M15,12h2v2h1v2h-2v-2h-1z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M16,12h1v2h1v2h-1v-2h-1z\' fill=\'var(--dmpw3)\'/%253E%253Cpath d=\'M16,9h1v1h-1zM13,10h1v1h2v1h1v2h1v2h-2v-2h-1v-1h1v-1h-2v-1h-1zM18,11h1v1h-1zM20,12h1v1h-1zM3,17h1v1h-1zM7,17h1v1h1v1h1v1h-1v-1h-1v-1h-1zM16,17h1v1h-1v1h-1v1h-1v-1h1v-1h1zM2,19h1v1h1v-1h1v1h-1v1h-1v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 12 handaxes '%253Cg%253E%253Cpath d=\'M16,8h3v1h1v1h1v2h-1v1h-1v-1h-3v-2h1v-1h-1zM9,14h2v1h1v-1h1v3h-1v1h-1v1h-2v-1h-1v-1h1z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M14,10h2v2h1v4h-1v-2h-1v-2h-1zM9,12h2v2h-2v1h-3v-1h1v-1h2z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M14,10h2v2h1v2h1v2h-1v-2h-1v-2h-1v-1h-1zM10,12h1v2h-2v1h-2v1h-1v-1h1v-1h2v-1h1z\' fill=\'var(--dmpw3)\'/%253E%253Cpath d=\'M17,9h1v1h1v-1h1v1h1v1h-1v-1h-1v2h1v1h-1v-1h-2v2h1v2h-2v-2h-1v-1h1v-3h1zM7,13h1v2h-1v1h-1v-2h1zM10,13h1v2h1v-1h1v3h-1v1h-1v1h-2v-1h-1v-1h1v1h2v-1h1v-1h-1v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 13 shortsword '%253Cg%253E%253Cpath d=\'M13,11h2v2h-1v1h-1v1h-2v1h-4v-2h2v-1h2v-1h2z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M14,12h1v1h-1v1h-1v1h-2v1h-2v1h-2v-1h2v-1h2v-1h2v-1h1z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M13,11h2v1h-2v1h1v-1h1v1h-1v1h-1v1h-1v-1h1v-1h-2v-1h2zM9,13h1v1h-1zM7,14h1v1h-1zM8,16h1v1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 14 poison spear '%253Cg%253E%253Cpath d=\'M5,5h1v9h-1zM5,17h1v5h-1z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M4,3h2v3h-1v-1h-1z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M5,1h1v2h1v3h-1v-1h-1zM6,7h1v1h-1z\' fill=\'var(--dmpw3)\'/%253E%253Cpath d=\'M5,3h1v1h1v1h-1v-1h-1z\' fill=\'var(--dmpw4)\'/%253E%253Cpath d=\'M5,1h1v1h-1zM5,6h1v1h-1zM5,8h1v4h-1zM5,17h1v2h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 15 wand '%253Cg%253E%253Cpath d=\'M13,11h2v1h-2v1h-2v1h-2v1h-2v-1h2v-1h2v-1h2z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M15,10h2v1h-2v1h-1v-1h1zM7,14h1v1h-1z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M16,10h1v1h-1zM9,13h1v1h-1v1h-2v-1h2z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 16 phoenix '%253Cg%253E%253Cpath d=\'M5,11h5v1h2v1h1v1h1v1h1v2h-2v1h-3v-1h1v-1h-4v-2h1v-1h-1v-1h-2z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M6,11h3v1h2v1h1v1h1v1h1v1h1v1h-2v-1h-1v-1h-1v-1h-2v1h1v1h-1v-1h-1v-1h1v-1h-1v-1h-2z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M5,11h2v1h2v1h1v1h1v1h2v-1h1v1h-1v1h1v-1h1v2h-4v1h-1v-1h1v-1h-4v-2h1v-1h-1v-1h-2z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 17 cutter '%253Cg%253E%253Cpath d=\'M20,3h1v3h-1v2h-1v3h-1v1h-1v1h-2v1h-2v1h-2v1h-2v1h-2v-3h2v-1h2v-1h2v-1h2v-1h-3v-1h1v-1h1v-1h1v-1h1v-1h2v-1h2z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M19,4h1v3h-1v1h-1v2h-1v1h-1v1h-1v1h-2v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h-1v1h-1v1h-1v1h-2v-1h1v-1h1v-1h2v-1h1z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M16,5h1v1h-1zM20,5h1v1h-1zM17,7h1v1h-1v2h-1v1h-1v1h-2v1h-2v1h-2v1h-1v1h1v-1h2v-1h2v1h-2v1h-2v1h-2v-3h2v-1h2v-1h2v-1h2v-1h-1v-1h-1v1h-1v-1h1v-1h1v1h1v-1h2zM18,10,h1v1h-1v1h-1v1h-1v-1h1v-1h1zM14,13h1v1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 18 scmitar '%253Cg%253E%253Cpath d=\'M16,8h3v3h-1v1h-1v1h-1v1h-2v1h-3v1h-2v1h-2v-2h2v-1h2v-1h1v-1h1v-1h1v-1h2z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M17,5h1v1h1v2h-1v2h-1v1h-1v1h-1v1h-2v1h-2v1h-2v1h-2v-1h2v-1h2v-1h2v-1h1v-1h1v-2h1v-2h1z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M17,5h1v2h-1v2h-1v1h-1v1h-1v1h-1v1h-1v1h-1v2h-2v1h-2v-2h2v-1h2v-1h1v-1h1v-1h1v-1h1v-1h1v-2h1zM18,9h1v2h-1v1h-1v1h-1v1h-1v-1h1v-1h1v-1h1zM13,14h1v1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 19 greataxe '%253Cg%253E%253Cpath d=\'M17,11h2v1h1v-1h1v3h-1v1h-2v1h-4v-1h1v-3h2z\' fill=\'var(--dmpw1)\'/%253E%253Cpath d=\'M17,9h2v2h-2v1h-2v1h-2v1h-2v1h-2v1h-2v-2h2v-1h2v-1h2v-1h2v-1h2zM3,16h1v1h1v1h-2v1h-2v-2h2z\' fill=\'var(--dmpw2)\'/%253E%253Cpath d=\'M17,9h1v1h-1v1h-2v1h-2v1h-2v1h-2v1h-1v-1h1v-1h2v-1h2v-1h2v-1h2z\' fill=\'var(--dmpw3)\'/%253E%253Cpath d=\'M18,10h1v2h1v-1h1v3h-1v1h-1v-1h1v-1h-1v-1h-1zM15,12h1v2h1v1h1v1h-4v-1h1zM7,14h3v1h-1v1h-2zM1,17h1v1h1v-1h2v1h-2v1h-2z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E' // END WEAPONS ]; return GEAR[smAssetId]; } /** * @notice render a chamber with an encounter * @param ct chamber type * @param et encounter type * @param index chamber index * @return string of svg */ function smChamber(string memory ut, string memory ct, string memory et, uint256 index) external pure returns (string memory) { return string(abi.encodePacked( '%253Cg transform=\'translate(', // Calculate the starting x position of the chamber (((index % 8) * 14) + 2).toString(), ',', // Calculate the starting y position of the chamber (((index / 8) * 14) + 2).toString(), ')\'%253E%253Cuse href=\'%2523', ut, '\' class=\'c', ct, '\'/%253E%253Cuse href=\'%2523e', et, '\'/%253E%253C/g%253E' )); } /** * @notice render the next upcoming chamber * @param index next chamber index * @return string of svg */ function smNext(uint256 index) external pure returns (string memory) { return string(abi.encodePacked( '%253Cg transform=\'translate(', // Calculate the starting x position of the chamber (((index % 8) * 14) + 2).toString(), ',', // Calculate the starting y position of the chamber (((index / 8) * 14) + 2).toString(), ')\'%253E%253Cuse href=\'%2523u\' class=\'n\'/%253E%253C/g%253E' )); } /** * @notice render the exit chamber * @return string of svg */ function smExit() external pure returns (string memory) { return '%253Cg transform=\'translate(100,72)\'%253E%253Cimage href=\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAMAAABhq6zVAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABhQTFRF2dnZ/NYXG4YtIJ41YDEU////HcDtgEIb7MtdQwAAADdJREFUeNpcysERACAIA0FQif13bBxRkPvtJDJTUgAYANUDMwl4AY5+k7JcdNbYwyYxUh+WAAMAA0sDCBfICVcAAAAASUVORK5CYII=\'/%253E%253C/g%253E'; } /** * @notice render portions of the bottom stats block * @param index index to render * @param miner current miner instance * @return string of svg */ function smMinerStat(uint256 index, Miner memory miner) external pure returns (string memory) { if(index == 0){ // health return string(abi.encodePacked( '%253Ctext x=\'39\' y=\'90.75\' font-family=\'txt\' font-size=\'10\' dominant-baseline=\'hanging\' fill=\'white\'%253E', (miner.health < 0 ? 0 : uint16(miner.health)).toString(), '%253C/text%253E' )); } else if(index == 1){ // attack return string(abi.encodePacked( '%253Ctext x=\'67\' y=\'90.75\' font-family=\'txt\' font-size=\'10\' dominant-baseline=\'hanging\' fill=\'white\'%253E', (miner.attack < 0 ? 0 : uint16(miner.attack)).toString(), '%253C/text%253E' )); } else if(index == 2){ // gold return string(abi.encodePacked( '%253Ctext x=\'95\' y=\'90.75\' font-family=\'txt\' font-size=\'10\' dominant-baseline=\'hanging\' fill=\'white\'%253E', miner.gold.toString(), '%253C/text%253E' )); } else if(index == 3){ // armor return string(abi.encodePacked( '%253Ctext x=\'39\' y=\'101.75\' font-family=\'txt\' font-size=\'10\' dominant-baseline=\'hanging\' fill=\'white\'%253E', (miner.armor < 0 ? 0 : uint16(miner.armor)).toString(), '%253C/text%253E' )); } else if(index == 4){ // speed return string(abi.encodePacked( '%253Ctext x=\'67\' y=\'101.75\' font-family=\'txt\' font-size=\'10\' dominant-baseline=\'hanging\' fill=\'white\'%253E', (miner.speed < 0 ? 0 : uint16(miner.speed)).toString(), '%253C/text%253E' )); } else { // chamber count return string(abi.encodePacked( '%253Ctext x=\'95\' y=\'101.75\' font-family=\'txt\' font-size=\'10\' dominant-baseline=\'hanging\' fill=\'white\'%253E', miner.currentChamber.toString(), '%253C/text%253E' )); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; library AssetRenderer2 { /** * @notice render defs tag * @param lgHeadgearAssetId the lgHeadgearAssetId of the gear item * @param genderId the gender of the miner (0 == male, 1 == female) * @return string of svg */ function renderHairDefs(uint256 lgHeadgearAssetId, uint256 lgHairAssetId, uint256 genderId) external pure returns (string memory) { return string(abi.encodePacked( '%253Cdefs%253E%253Cmask id=\'hm\'%253E%253Cpath d=\'M0,0h57v57h-57z\' fill=\'white\'/%253E', (lgHeadgearAssetId < 7 ? '' : '%253Cpath d=\'M0,0h57v22h-57z\' fill=\'black\'/%253E'), (lgHairAssetId == 5 ? '%253C/mask%253E%253C/defs%253E%253Cg mask=\'url(%2523hm)\'%253E' : (genderId == 0 ? '%253Cpath d=\'M0,57v-5h1v-1h2v-1h2v-1h4v-1h3v-1h2v-1h2v-1h2v-1h1v-7h-1v-1h-1v-1h-1v-1h-1v-5h28v9h-1v5h-1v3h-1v1h-1v1h2v1h2v1h4v1h2v1h4v1h2v1h1v1h1v2z\' fill=\'black\'/%253E%253C/mask%253E%253C/defs%253E%253Cg mask=\'url(%2523hm)\'%253E' : '%253Cpath d=\'M0,57v-5h1v-1h2v-1h2v-1h4v-1h3v-1h2v-1h3v-1h2v-8h-1v-1h-1v-1h-1v-1h-1v-5h28v9h-1v2h-1v1h-1v2h-1v2h-1v1h-1v2h4v1h2v1h4v1h2v1h4v1h2v1h1v1h1v2z\' fill=\'black\'/%253E%253C/mask%253E%253C/defs%253E%253Cg mask=\'url(%2523hm)\'%253E')) )); } /** * @notice render a headgear asset * @param lgAssetId the large asset id of the gear item * @return string of base64-encoded image */ function renderHeadgear(uint256 lgAssetId, uint256 genderId) external pure returns (string memory) { string[18] memory HEADGEAR = [ // START HEADGEAR // 0 assassin's mask 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAylJREFUeNrsmsFv0zAUxu2qRw5dDxPHZqtAAs5w4cJf3h64wA0JkEAb3RHtMHZg57LPyxc9PWwnWZzG22wpchunyfv5e355tmv3+7157GVmnkApkAWyQBbIAlkgC+QTh5wP+bG1tvms00PZhrKqToP548Xu3OpzvF/sGQeBjD0Y56uTddO4WCzN4mhprv9cuRrl+Pi5ubz87S7ndbtfZ5ZwuIcP9uCQoQJAgDnAGg5QOFBqOFfevnvvvqNNdIzNwl1DcFo5gvmKbltV68YZ7gS0ZuhMaT6Weo2bHi07wflg6w4brOhsLPf0Ga7dtE1d3I8Ba4iasxRBx6dgV/eMtYe84OBKhgC1gb6A01VNGaUnTwZibnof2DbVs8t4CMW6DaCr4qND0lX7jB2tZAhGdoKItHko2QYcgtLns1FyTLdOGWEfxCxkaACaT6ES658/vjdtofQP53FkBekzllAXu7PoOJadgGtD12er5J3R5x8CzRsmFE6566v/rr1N7zZZj8m2MQUggDlID2CWgadn+N8mumY6d5U56Os3zzbfvn6xfeFjSydZjUkEFwDf3Pz1GszJcl1vdNuQIDQapI6y/AyDubajax/00NdHsjEZMsQ3NrvMULDmQ+WyznhonHzh+zoBHZQyT00OifVShv6YWrGZBjuDsKg/f/ooF7TyTAZ8c0YoyuAT6hTWL16+au4h12kng4Saq8q4eWVobMJ4tgEWELJAOZn2scbYTBF4kqygY3GUoH0V75ruTR54uGonx6dWQLqcTNhrwK3vkOleNtEVwSJmlAw0HVO2bQq70i9/3LoXx1SfVwM3d+SRdXR1QUgo6tsSQAcgsJh6R6s6WXs847TpNN/23uRpnQTl6yPk4r60ri2bOjikXkXnbpbMP+UyRtdkIZv5JABD2Yl8uUsloWwsnePvxCqBnRQSO8Ndp0ESFsZTXamsTO9SAKLYIVGMG6SoObGVLqq3zXXd1jkE5DMm+8+ANsiI/f+2nBPRNTRLYdBK8SpJAqkMseJPDHudk+rxK2chDFgpAZO4a/+sqH29JjQO72urLX/PLpAFskAWyBHKPwEGAAnHFCRzB+E2AAAAAElFTkSuQmCC', // 1 misty hood male 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA6BJREFUeNrsmj2O4kAQhW1ETEZIQDITIIHECTg0B+AESCARDAkBIRkZEctD80ZFTfWP222b3XVJIwZj4/761U9Xm/J+vxf/ug2K/8B6yB6yh+whe8geMtGGVU4uy7LWzebzeXDlsd/vo28Su5AZpg44dIPFYnE3jhXX6/Xl2Gg0er6K48/rdrtdmWuyyyrLOvnlrusIByDLAAOw5XJZbLfbl2NyAk6nU+GC5Thix54VEoAaTsPMZrPifD6/qIdj4/H45TwfbGeQAJxOpz/uBzgYBw6bTCY/MARZrVa/ztOghCVoVchhjuxFQKmeNWAASiOgvO5yuRSHw+GpLq/ZbDbvU0IYa1YMctBUke9dgIAjIL3DSmatKKlVjDWtKtUioLSHmxa4B1w2pYxlVVKryEFDOQ7cUpGAcF8JCGWpIl4BGlNrG4PkYEKfaaUkoITDH7IwVETGtiawNXf1AWKgUmG+pzGjakAYYhPuWRewNqSsi3ogHKxUTf7PBBQLqEtM60pWNcBoQBpcFICIP5zDyeCxziBd7qSzpK9GyhiUKx0Y4Kx1b+dK6izJ9zoueYwu+uhCPr87li/AyUSV6rK1IWNmVwPqCQCg0XIB9guQnCThMfcqLdmg6djTsC4XlipKwwRYk/AW7ipd1HeOD4Bqwm0tNbFWb01JrZgLUMaUBHSpSFB8jnOteG5dSWZItFQWnGtREGuyO2l9WQfVOHD2jJZ6uuBbKj56xKNLzVDJasVdtYtKQDkwj5seXaBvkXhkH2i5qAass/tWtV4mKyn7SA6cgOgsQvUz5KY51aytpNyYkq2TtUtABRTgscq92ES3uhiQtYsQLkBD3WNgwyyLmllXPHJPVatHQKsmBmLxGBvTjUMSwpfeY92U0Ba8bweilRLCAVA9vAIaceoCDGXUHD/cGOQAhAtJQK2mmv3Kcca2K3Wh3thuHWHx+p0NPzVgVZUwWVUzazZIK9mEll4pgKk7A7UhpQtZZcJSMSXOrP3aRiGxwctdOqsm+nbYqgI+auYH/1+v197nltmV1Io5ir1eeHexOVjPXfXD1NxGFW+3W7Kr1lq76poYKtapborygdBIddUkSMYj90dp7Ei4ISzjNNVNWR9b7UL4RAmAelZl60XQOm4q911ll5P0fbkep+Mz/ViNGdialNhelbHI3XV8TyeP03nD8vcT0uDPVWLrcMrCvLaSTZvvYSuXdY38+uNvtf4HhD1kD9lDtm5/BBgAJ3vz25dUcNcAAAAASUVORK5CYII=', // 2 misty hood female 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA49JREFUeNrsmjGO8jAQhRNETUdJQbUFEkicgENzAE6ABBLF0lBQ0nGB/DzEQ8Ps2I4dJ7D7Z6QVSwhkPr/xzNhJWVVV8ddtUPwH1kP2kD1kD9lD9pCJNow5uSzLRhebz+fBzmO/39e+SN1GZpjqcOgCi8WiMo4V1+v15dhoNLq/iuP37+12uzLXYJcxbZ38cdf3CAcgywADsOVyWWy325djcgBOp1PhgqUfdX3PCglADadhZrNZcT6fX9TDsfF4/HKeD/ZtkACcTqfP8AMcjI7DJpPJE4Ygq9Xqx3kalLAEjYUc5sheBJTqWQ4DUBoB5fcul0txOBzu6vI7m83mc0oI55o1B+k0VeR7FyDgCMjosJJZJ0pqFeuaVpVqEVDaLUwLXAMhm1LGsiqpVaTTUI6OWyoSEOErAaEsVcQrQOvU2tYg6UzoM62UBJRw+EMWhorI2NYAdhauPkA4KhXmexozqgaEYW4iPJsCNoaUdVE7QmelavJ/JqC6gLrEdK5krAFGA9IQogDE/MM5HAweexukK5x0lvTVSDkHZacDA5zV975dSZ0l+V7PSx5jiN5WIV+PFcs34GSiSg3ZxpB1RlcD6gEAoLHkAuw3IDlIImKqmCXZoO25p2FdISxVlIYBsAbhI8JVhqjvHB8A1UTYWmqiV+9MSa2YC1DOKQnoUpGg+BznWvO5cyWZIbGksuBcTUFdk6uTzts6qEbHuWa01NMF31LxtkY8utQMlaxOwlWHqASUjnnC9OgC/YjEI9eBVohqwCa7b7H1MllJuY6k4wTEyiJUP0NhmlPNxkrKjSm5dLJ2CaiAAjzGXIuL6E6bAVm7COECNNQ9BjbMsqiZteORe6paPQJaNTEwF49153TrkITwpfe6YUpoC963A9FJCaEDVA+vgMY8dQGGMmqOBzcGOQARQhJQq6lGP3qecdmV2qi3tltHWLw+suGXBoxVCYMVm1mzQVrJJtR6pQCm7gw0hpQhZJUJS8UYQDYd1n5tq5DY4OUunVUTfTtsTRLJer323rfMrqRWzFHsdeOd3Dq+Lbvqm6ltWmqoNoLUNTFUrJuoiN9MDdWkBp3zkfujNDrEDWE5T98VpkmQvKMEQD2q0jGC5gpTucppHdJXhB+fVQqcf1VqqHFLhQOZ8jvZdgYQkuXPO6TBx1Xq1uGUxvy5dEt9MKJt891sZUS18vTHb7X+AcIesofsITu3fwIMAGcE6Bijid9KAAAAAElFTkSuQmCC', // 3 none '', // 4 enchanted crown 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAblJREFUeNrsmDFuwjAUhu0KqUywdWPkGEWtVHWgF+jEBXqEsjU9Qi/QiRMwoA5ROEZGNrZmol3cvFAHK7KTWHET0/xPinDC48Wf//eeQ7gQgv13u2A9MEACsi+QnPPKY/kwFq58vFbyeT4SLnw6g6QtyHTQxGfTYakf+dw9JZU+3tfkcj4uTbeba49rsu4KDxe78+6uTRoC/VamM6WsLpbqc7ZbyGx66b+SJgWk3b/sa8XR1SXFlU2pU8jvzVUOSvuZKc2KzYfGdE21YHWM06QEWktXCaiqSM1H12WLTSkD/fWjsQsbuAhCagarFOgx67bcVGsZKJtoVSz6BQt3iz5wFejwPklBd7mKpm1Dgra5tThN1yNokqlIY5OPbZZ4AxnFX1b+dVS0XZDWGk/ZxOR3ZYDh9vRpu3B/XpM2ChIApWEUH7Q+H2/5svgPKZWTikTxJ2PrUQ7wuk5uLcKFgQ+QJxi9AgpU2Gb28CavJE1PJgWFQnkP9YmIrqnndf+7dqJkClQ5Ux2MLWBnSvbiRRYgAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEpCABCQgAQlIV/YjwACgM+38l8jvfwAAAABJRU5ErkJggg==', // 5 ancient mask 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAhpJREFUeNrsmj1LxEAQhrOiKFEQO9HKQ60ED8RWYu3vtb70h3C2Kmel2ImFQbGImSOj42bzcckku4kzEHKX7C377MzuzryciuPYG7qteP/ABFIgBVIgBVIgBVIgBXIQtsrVkVIq8+z0wGfN/mfzd2UVEo1WNePRpre7s7a4wM4O/Vp9Xk/fvJfXLwlXgRRIgRRIgextMlBkeMbdPES5bfQztKitk5BgkBAUJQMAhe/pZ/zeJBlggUwymzhJ4X6ynMGG63jkZ2Z/No9qhSB4jbZt4kU2yNvHCBLnOC8/hVBddqBNwVrxJILq3qOgRe+ch4TKA0qtFDQgpdbEMBmX2R78ycXJ1h9AvZ2pL5u7a5jeg5L3VfvpzxEClnqrUiHNWXC3VjSblIKjvY3FxbFT9z6t49x0OoPkHrSTkKYjYpBViE1vdhauNr3ZWbiKJ4ndP3/0s2guW5MgHh/vr/dbGcjbYQEOn989fWbKMpiYq/PtxqFudXdFtQDuAEPv+JzjCOo046m73nrjSRNoVzuuSJLcRjeXKtUIl6db96RpoBS2bJ1ynJuK66+gWD9q9WRApQvTLgnnI0Dn3YkcUnusnYTrr16ThdXPR1MkpNqRe2syFbdQpwnKYE0hbRK0nArXHAkk0HScDCyGKQEMdWnFKci6sAiY9BXS3zoNuSysDoi6rnXIOhOSB8vlQauQRbDcgNYhB6UM2LZvAQYAsylEU82de7EAAAAASUVORK5CYII=', // 6 charmed headband 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAg9JREFUeNrs2b9Lw0AUB/CLRCgpYoWC4haxk0IL4q6Dk3+Bs39XN8G/wMnB7iK0g4NUzCYKBetgKDjEvNjXvl4usSQpJfX7QK7NJeY+9+5HolYQBGrVY039gwASSCCBBBJIIIEEEkgggUyO6mErsCxrdZEErF9cKuegWSjUWsZL8161Fbvpu6sUATkG12217U3rPb+Xua32MnCu05oc23eOovJKtWPnn9V/0c/+AxV0rVUoUu/tl6+ulTdrhGOUKUZeX1XcRlTKoGs8v5u5c+2khnEv6o2dF8vn19Z31Fb4w7hxVqL4+H6bXrChIqCM11Ff7VYa6nbQzjWCbFPjqGH3nzfRd2ogDx1qINUnQWXW6Hccb55P6iSOwPRd1j+Fw5UzyUFAHgGFZZKBQ9HD/Jl7nW5oWjhMc41hMxkLgztQwimTevB5eSOWSULRShYHRBM/quehTMOoNs60DELJBg41ZNpxOR+TrsuFlDhermm/cp1mwEOW58dMFrQ5pjfO1GmG+5yExR0f9x97p+EO0il8nySQvhfJRYhgBKF5SmVST5tQf+1xY6QeHdnZWffJ1A2WgXJuZcnSXA1JeMIp4mHFngcoh6GOKsO/GVKfeBjI2WPgImCL7KxUJANNC1LpX7Xkfll2YOqr1qoAl/aqhT9/AAkkkEACCSSQQAIJJJBAAgkkkEACCSSQQJY7fgQYADSdKGHvFBOyAAAAAElFTkSuQmCC', // 7 bandana 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAf1JREFUeNrsmU1OwzAQhW0aVbSUFQvELVj1FrDhAtyFO7DmAmzoLbgIQqISqD+RkKqQkZho6o6bEDvglDerKj+OP7+ZzHNqi6Iwhx5H5h8EIAEJSEACEpAtI/utB12PJ7WuY5avbBfmxHbleFyo6XBkzgcDczM+3bn2cb0wr5uNef7Mq2NP66VNFpLhCIrDB+cLgp7ly2igUSEJMBSOglSlIGVjgEaDlIAER/ETQC19GTS0VrPUAOW9BPs9bmHLaAsatYXEAHRTN4kW4tZhDEA5zv3ivVKTyutP+ySryCqEwEoVaVyuz2TMQF2auee1xXCPhaZu1rSZN3mV0+S0CVHKhdQr3UN9MyokAT6cXajQElbWI6UUA8p6cvulXARfGvKCXA6Pzd3HW3wzoDV0qRI7Ec3ZsC2jY/RbLpSE47GaqhrqgLYgGVB6SOk9GdqXOlejiZq6dYrVKRvqfjJtMHIYyrXVarBCt/OXLSXlZDlVpcJJbLUkHCtcGo1SoZOC4QjM98aTVsw37s7KiUyiZ3UR1n2IVqOsHHtK7l0+hTSoUI+szS2KQWdAWVttVUryy4AEdHcEKYK0djzujp0B+/b/yV5IBtReSL3/Wif7Zd8B9+4nDwWw0691vVASkIAEJCABCUhAAhKQgAQkIAEJSEACEpCABCQgAdkqvgQYAOQdZ2oZpwBLAAAAAElFTkSuQmCC', // 8 feathered cap 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAc5JREFUeNrs2LFOwzAQBmC76pIFJBgJY9jISFbEIzCSiDfgFRh4Bd4AKYyMGRGsHcNGRsIIEizdMDkLFzdNWmonboH/pKpulTr6HPvuVC6EYH89BuwfBJBAAgmk8xja/DhJkpn6k6Yp90+CpetSeV3wvsrZ0AYYRRELgkB+LopCju/FSGyGWzPXb+xvN87z/vDyNQrEbrzHntJH3jXSaPUIWL2mcPo4z3N2JW7m4tqwb/mrfO8Sa4wMw/B7q5XlZExIhb74uFx67j6wRkjOOYvjWEIV0Pf9KbTC2kAV1hZqjKQgaHUGJ9+rs3jKj9cKapXRCEuZtCnREJTC8zxjaH37mkKt6uS8BaLEQ09zPB7LhHQ+ODO6h0pctJBV9hXOkXTTtnJBr9udkcQSksIU2nRUVtrx6CVDjQmbZZn1nLSgJo1G722d/lQJ2sXTdJp46meEVpoSRH0LE1IlkKPnAwluaxToOv16NZ+qm3r8NBFZI5tAfUe9YVjU9w7ZLwy1kNqCkpA7Q+pFfF2i0zO5qli0XW07nkOHljuTpqSTtq4Kp1CjXht/LgMJJJBAAgkkkEACCSSQQAIJJJBAAgkkkEACCSSQQAIJJJCO4lOAAQCEf/kz0iBcCgAAAABJRU5ErkJggg==', // 9 ranger cap 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAXxJREFUeNrs2LFOAjEcx/HWNDHRCWMc1IHECRJG9RF8BJ+VR1B3nEwYlMGYMGHidFLkL1y56921BQG//+XgUsp9+Pd6v6CzLFP7XgfqHxRIkCBBbrzMOifXNxfxz6enkY59zJm1ou6u8gO6p/UnG3zIKzunjrquVGFgBnRRoUAX2n9R2eOb/tNOeoEhODaefUMmWgW70cnprRCzUyfZeLpnR7+T3F4eq4fXyexoq906VMPxV+61Pbol52WsW3bOwftn0OZjUgAFJHXfO1kZtwwsgsp7d9xWLlf34t0LLutk2Q+SW3Y67CliUnaxCrh8vmi873Pz7wkKBkH3pGwCneE4d969H2NL5rJHqed26ycGNQgHjZG1ko1NKilDwCLiLWqagupiK5GVedQHTI0tws+xviDvRa50bQsimg9b1lUTvWxSpxfpfsx3Neqk3bKvz3fjP8vQ5UpABwkSJEiQIEGCBAkSJEiQIEGCBAkSJEiQIEGCBAkSJMhm9S3AAKKYsH+jEASqAAAAAElFTkSuQmCC', // 10 leather hat 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAfZJREFUeNrsmsFKw0AQhneliATai4J6rBcv4jPUB9CX3Qewz6BevNhjLbSXFqKIEDPBaYeFbNLd2WaNM1DSkKbZr/+fnT9JdVEUqu91pP5BCaRACqRACqRAetbgUAe6uxo1po7pbKNjhBMdK/HYUJfD42o533ypyXikXpef223XZyfVOmzDenxb62QhEQ6gXha5ujnPttsQsK4oOHyWC5QVEgBRMRsQ1GpTMUDZIF2ATQq6gDlAWSA5FIwJGrWFwOCo/Xwq9EdigaQqxhokfH+bFnQQJW2rclXoDxUEeXuRFS5gl8L71ir/VlrrbpWsUzH0nOy0T7pUpHWaDYIVpPX0nu8tZ9AIAMC2JMdEQ11AIyC4JYkWggOybdpkW7ofvuz9fF0R5SoEBoahG/slXdbZEpQCEHhPgWzLJnVO4kDLS6gHj0OY3+U9XfcZr7eSz4sPPRkPnUEAlPMErOBKIOPbNtjPSbAmTjicE08JiCpWCvq6zltJOGAZtdrOrEbu8fTlHk+XD5bYlZzO1rZtTddKskOG9rQ/YVc7laTw/JNFSRq9MGtij+Toc51Cwn0XO6qlcGnFFutIw1Z28iFJx6Rg2eBzEgBK0Cri7WbYHWAvlKyJYialiUfLvz8EUiAFUiAFUiAFUiAFUiAFUiAFUiAFst/1I8AAx7MirNZCeJoAAAAASUVORK5CYII=', // 11 rusty helm 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAn9JREFUeNrsms9Kw0AQxndjW5QqFdFLQTyJF28K0kdQ0Ie1oI/Qi968iCcRerGIIqLUP7Ff5IvTmLTBbJutzkDYZrub7i/f7OzsUhuGofnrFph/YAqpkAqpkAqpkL+0yrR+6GB3eWzWcXr+YCeRnNhJZTxJqL3GYlRe9l7MffXNLL9+vd+lZmBubvvRPeppJ2f31ltIwhFia3U+Klc25+I2nc5TDNpq1b9UPHsw62u16PNj9yP63hVo4BoQA5eAgCPg3dV7VAKMyrFuf7cRKUp18X0eF58qJAEJR4VoF9fPQ7AAofvSCLq9sRC/CBegwSQAAQMQljAMnIb6Zr/2Q02CwnWl4ni+tdYPd00DlHNRGuo5X6WaEljO6VKVpIp0PxlksgClJdVEH6km7tFmf6cRlqokAOF+eQ3zM+9LcKGmE0iE/DSjOoSiYX6yLo/LerWEJJXhvQw6hJageZ9TCqSMqlSAV5qCSSVRSgWz3Nrr3DVNwTSXHQdX1H0rLl01bTCy7rH3PXc73adMQLwAJAWY63G7qgeQck0kGHJUWJx4V8dHXQBG/apmKGH30l0xYA5ysIU6Gtd+sA4eL5la3C+lT9uL6CoXdLFHPMrTF+3gorjy9pmqknKta23Wfx0VR8EV2RI6ddcRmUnblGjOz3hcZyveQObJSOBuRa7SIZPqJZL19swrKbdYDD5QNitpn0lIwtBlEXyksi7czQslu7X+UMbDY0csCUWOLbyAxGEwT9iYu47aVZRlhc5dqRKOJuSWS6Rl7aILeekZDwc/gLXyDEYCzrySGeoeSkAf/nhh9d8fCqmQCqmQCqmQCqmQCqmQCqmQCqmQCvm37VOAAQBcRKGlaSUs1AAAAABJRU5ErkJggg==', // 12 bronze helm 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAcRJREFUeNrsmrFOwzAQhu1SBHTp2hdAwFYkZlR2Blh4HAZegndgoQMPUHYk2BreoGuFVJAQCj2EI+M6IfgusYH/pChDYzuf73z3243O81z9deuof2CABCQgAQlIQAZal9NYa1372ZPh1reqY/zwXNlhqHDpcmepbODT/d6XH/YG62p3eZ0d9FaevbpbqGz2qtRQFW2u7xc6dEJXnMGRdTSw297AEZSxMrgyu7iZq+kS2gb1jRUFkgBtuBDAMlAOpFjicQFHO5sFIIXjT+38uP8RDdQvJ1TFIH2As/lbARjiSRu0TtJqtYRIAdrhHrWE+LwoCUhGfViZVyfhSRswZC024c2OdKjagBKeTE7WTR5f1KC/Jg7I7YtVJ11V07S5Kqi1xOMWfwpZ8ijdyQ63N9hwRhhEy66+kPXdQ5JHxgAThaw7w1OhF44ariY8bbu8fTJbqCOJIImeXSksSQjQRevQrEUhwLiebNoLOP5IzJOK+58LZ7uF07pQkxLmSUNK7kDgyRiQWURV02p2TRGUfSRZdcj0qXYmUiUkyrmrU79GVUon5rcJGh9GABKQgAQkIAEJSEACEpCABCQgAQlIQP56exdgAFsb1LS8gb46AAAAAElFTkSuQmCC', // 13 iron helm 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAf5JREFUeNrsmsGNgzAQRTFKBRRACRF3OLCNUAnV0Eg4wD2ihBSQFlg+wshiYSGecUx2ZySHS+zkecYz3zaq7/vgr1sY/AMTSIEUSIEUSIG0tMu7fijLsl3V0batciFOlCvFs4SK43hseZ7/+G5d18Hj8RibtqZp1GkhNRyATMA1uC2rqmoE5gJlhQSgCWcD6AI0dAWYJMkMiHB81YqiGPtjXKWUf8g1wOfzOQPaeNIETdOUBMpeQrgAzXD3XkKWXuQEhGGMKevCm1Y5hN2TJqDNWnThzZA7VE1ADk/CzPrpHfJ+vwdRFJEBu66bn2iYPG918ohU4zRb2XfhXi+YdXhUz/71eiWND09iPErIsgt0/CGAI8tqXeprLTqBNBUOnlqaHe2L4q8nZpBz59tqITx1aOqkowGHtfT1W99B0dzWvL7oV3uHRJjqEDUz6x7g0TBFwrGVdu/YNNcEuHoJeuqTgZ3SAG/fPvb448jsIwy3wppjv3sKT1KSiheBTq2NHxOur+5AXF8fOvfkdHyRU48wKDqZFXJZAsqyHJsu9hTAoVmDsntSg+LJuTYpWzcn4WqCcq07yoQ5vwuBSPdtJEgc/HJth05bQqaMiQ/nJwSUrRf7XQjKxday8vU6zbvuJ71KICUvKwmkQAqkQAqkQAqkQAqkQAqkQAqkhX0LMACoRR6lieJO6AAAAABJRU5ErkJggg==', // 14 soul shroud 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA19JREFUeNrsm71u2zAQgMkiQJB36JLBWxGgDToEyGBnq7f0HdytS/ocLdBmS96ho7tFGQx0CJwAQTcPWfoORifVZ+vs84WURPJIJq0OEAwblsWP93+SdVmW6l+XF+o/kA6yg+wgO8gOMobsSP7YyfBDY9Itflzq1Ll5RxJqv/dGbb8/NJ1WLs579OHV+ELHgnTaVROUBeSRfOztLV/PZ/Otzx9m0+r1NhqwMyRqi8IhQIggPEAjsBSsNyTIl+FxFPNC4KvxpQisE6TWWg3ejUruezGAuWZDQJ0hQWyg0sBSoM7hnII2RVUJXwU5G0/WwcknBTkXA3ABOOBiFBAWAHBwAJwUoIRleFc8fDdPhiNR7ZlAYUOpBSWveMBvQIs8D5py5bMt62gypz4J0BJw4Jfok0pdpIVEuDpzlQLNpkkaWSkINVsw5bMZBqftignN3GbS8Dv4HWotyc0VggIsBkM9LhorFtS0qc7lnyEUlfcvd5Wa/1IPyw1aBh6dHJLmsbYmXCu97ZQxub/Ja67UhGKlkeODt5X5T/P6ZF2V4xN40KfxvNdgrilqV5dJAMBjoKFBhmvfVXzKOtHoagsoNABVCx24XmdR6RRYSmad8XBA1JgPlK2UxAYhKyRNH1JwdTVzcsgawGuVUbwDjy3oYMBp6z+uXUWywMNnPaa82XbxnwZHyzzYJtWcfv2WLk/CGIKDoqmGNrgUlI4/2o4+RZtmMJuQfNem36TveT2bJPBU4VxDwbzyw9UiztVhUKMcoyULiq4clO84nRT4Lh7Om8x31ffff/IV6Bw0xHe4YPcRAhilGEBN4tQuFPBu75V39yEKaTJbPh1wNdlNe7VJTU+qdjVFQx//xO/B6ORJmKtNmyYfdekvqTZ9qzNRTVagi5p1VPCKyMc/62a4SYqBhkJhsJn3TNcLpkfKnCl+/77q9/rY6DbdYm8CgSj7ufgZ9KxBrKc/rrlGaUDCo41JhubIKJBkt62gXKM2UCmfjJJCyJgCQPurBnpU0JkQaNKlYwlxq2h50gwKsoGFobStMpLSYpTAYwlEKH0yESjozNZ2D8T37nJSSAOoMfry230UMNRckz4CZtKqCZQMw7SET+ocz6AT2DWoafIgAZgNkgH3eY4VL1C6fxN0kM9H/gowAL65SgCwf/y4AAAAAElFTkSuQmCC', // 15 genesis helm 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAwtJREFUeNrsms9u00AQxr2Vq6LQSvSWHpB65hRuHMsb8Ki8ATlyoyeuVOLQ3FpBKVQFgr9tvmg8Xa9jrxuvyKxkJY3dnfnNny+TOG65XBb/+9ordmDtBGS5yUWvT57Xavp8cevGKnPnXDGbTmrGP13+cL0hCffu1bE+tayMbR2UgPTn4uqu5mcTbBkDnJ1M/POPX2+Kxfd7/xyvrYxgY7dNSAIC7vzy1r82Pdp/OA73vc8h0GA2CLi4uV/DsURxjpF8//mqtVSGWrRLQOkPYbHgr/apbAJkpLCZvgaZffPyMAtRoX+zYrKG1RkNlisjVWtCkXFECxFFZJtK5CmzqP1Cr2rY1p7kPxAMRqqjkCLEpu/iaNs1sWDB3unxgT/IR58qPx2FCb5r9X3Uk7hQRkn2oAQTxoK9qaEoYtHSE1niftiH/QZxgV3th7YPBskVhaSaoQdZprLJ2ZcwQse0EMAxHZRYtrwdIXhyL+7HYFAc+RpBNeSjcpUlyj6QCivrHvAwwEzr7DHymy59LexKQPwt1VPaAzD1QSeubItsSIQ0LKKpIw5nUhSYFfDr99/iWbnn99N+AMgPCAGx6T27IkI8CMvoyoPZnX/51gtQZrQJMKT6ut02gpRZ1JsRlufXPXhUL9GuKixBmU1tM6TKsoe7QTYA6lFLC0NfsKayxf76baHJ106za59PGnDm4vquuP75xz+evjjoJDyhbG4asJWvrlMmOwOuSgs95Es2ETDbD81QU19eqpdS1hCBSoLkNEIoPYkM2ZtZfv3BWZOgeOTRVXVTK6N8KkgJyLFwPSishgeOZG2L148KGXLWj4OEibyHxc5t9YuspAA8TCtvU/ep1H6eXU/yk8QQgNlkkiUb6bP5WJCDZVICBoQiGRCDd2j4Hi2TqhfnfaeoLN8nY1I/5o2lrdwLGfvOmd3VMshdhwwpq2UyZ0hkSw/YOos5/CYh6UZqNYGc4XE2nXyQ4DkMAENC8ulZaITL5Zclzn7iYpAGaZAGaZAGaZAGaZAGaZAGaZAGucOQ/wQYAFKtQwRx1IOxAAAAAElFTkSuQmCC', // 16 skull helm 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAvtJREFUeNrsmt2t4jAQhcMqVVzxnO2AZ65EGaygDgqgDlAoAyk800HyjGgjm4NyomFkm4Dzt3s9koVFEsOXM57MDMzKsoz+d/sV/QALkAEyQAbIABkgA+QPh4yH+qDtdmvNH4/H46zP9DIeCmy1WkWLxeLpeJIknJbVuY/J4XCYdf09eruDAAQYTQIKONN1nasb96WeBFyv162vr5SMiqJ4qAsRKou8YbFAV2Oz2ZRpmjZDWpZlpclM7+d5/hhYr4vvGPflnlK9y+US3W63Zk5bLpePoQ3uDDXr9UrI6aNm3DcgYQB3Op1auy737fl8Hn9PugIMDXCEB6xJPZt1oWanyYANcD6fNwpSVZvVQadR07TmoJCIfC5AGAC1cgQ1wdoeLz570gsS0U+6qjaXa8qgI9WTc+myroxpEHc1qWgDBIQGYTSFXa9X63mTSQbobjYFeRwABKJJQOm2mPtE2bgPFdveDFd6N7kEHQrYYF37kmryWgndlat2AqldTrqaBMQceWkbhbHGfr+fXqnlUpOJd1VZ/LEcThmlCajPrSJ5Ovmi2WU1UIqEAaWW42aMm/FIFVvsp6sYPucMp+SbEZZfWt4J2wLFi+PDKamDj8xqDICFAvzCfmNQwmu9/4pJBh6pqn6g122NvNpvv2uAZQWTEYznYL7b7dgZwP78nlzGI6MsQO/3e5On1srmMuKaejwCFJaN3sjS9aTJbIWyDFD6ucheDz0Ead2nnTzvPYkPfpVXoqbE0KVVm9RuMvWkDRTvccDQ57HBwuCiwk07y2293JWQXEPXfHWQYcaSqyD0VE8SCDcB6slqBa7s03T2DjwAFLBoxSSG59wTMIIPQbViev8icPGGfiyITz9TXv+qRVEfSzjQVWDPFa+2Oc7Tn/Xu6Cytk4o6ejM6EYjEbyBPlYpUelLPSa2k3rPa2HB+9Tp64Hnnep7PfSuDkaNCYYb08Z6cjfG3s1rhts8HL8DRIIe28J+BABkgA2SADJABMkAGyAD5r9hfAQYAS+f6+Tif5loAAAAASUVORK5CYII=', // 17 phoenix helm 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAqNJREFUeNrsmr9KA0EQxm8logbE1hcQky6CtZreQhvBR/AlLHwOn8BGC3uDtWA6I76AhU2aqIic+Y6bsBlnL7u3J/njDASjxt353fft7OyiSdM0WfRYSv5BKKRCKuRsRW0akx7v1EuV9Jvuu6H3IbtCrcokpLh+HBg+dnNzOXt/sL366/N7WyviOFcPg4yNjxelJBJBEp3nDzEZKXiCSAxQlNgkQMT9y6c41sluffSQQkGNJLuUDCZFAq4n7QqAXncHXp+lOSkaw+8Jjo8H6/paVvygMSY5aq2lfFJ7clfwpChOL99G7uBKIfHe61fyNHxxYA6a2zYD9VXUCYkAaKj/JTsSEEDP9tcnuuLitp8Bu0Dp976Q4poEOEBhCa5orH2xxosKDOL8cGMMFCqXmatQSUlRX+u67GrbEhA+SXNF6e/woEKUnLh4fa0rqc0Vs9elryoclCp+tF25dXPYMesWJUoqUZEYVe1WPVMyxOpwCl4oNM2CgldJx5PDGt4oSIkSoMu6IesLY0BNPCDaiqCi3f1U3taNBm8lqV1I7CpIgDYobfLkgBDQRkkFvddk0VqVKi91SFKnZP8spFJSweIq+uZe+hSCCTCZvYGHAJKyvpaNUTPqFCJVXF/AECXx+Z71MEPdF33Ugl1tNclSvNHnRScE1F73UztPTirtPEn6Hl+LbNhjD28mDs1UOamq0kZeFE8BIH++T/oA8taOAIYFqh07/nD93039jgfWe+1//+pyqgCclzuejt7WLQok9raYlyo5DUhefBYSkk4gquS8QtptWH432p4FyMr3yar6zZlREhdJUu+ZH2zbVTcCodce0TcD/IbA0cp1yp4BXXOVGcvoP0YopEIqpEIqpEIqpEIqpEIqpEIqpEIqpELOffwIMABPLOUxc/z/CAAAAABJRU5ErkJggg==' // END HEADGEAR ]; return string(abi.encodePacked( '%253Cimage href=\'data:image/png;base64,', HEADGEAR[(lgAssetId == 1 ? (lgAssetId + genderId) : lgAssetId)], '\'/%253E' )); } /** * @notice renders the ear modifier for the ranger class * @param headgearId the id of the headgear item * @return string of svg */ function renderEarMod(uint8 headgearId) external pure returns (string memory) { if(headgearId == 0 || headgearId == 1 || headgearId == 4 || headgearId == 5 || headgearId == 10 || headgearId == 11 || headgearId == 14){ return '%253Cg%253E%253Cpath d=\'M15,20h1v2h1v1h1v1h1v2h1v3h-1v-1h-1v-1h-1v1h-2z\' fill=\'var(--dms)\'/%253E%253Cpath d=\'M15,20h1v2h1v1h1v1h1v2h1v2h-1v-2h-1v-2h-1v-1h-1v5h-1z\' fill=\'var(--dmb5)\'/%253E%253Cpath d=\'M15,20h1v2h1v1h1v1h1v2h1v3h-1v-1h-1v-1h-1v-1h1v-1h-1v-1h-1v4h-1z\' fill=\'var(--dmb15)\'/%253E%253C/g%253E'; } return ''; } /** * @notice return skintone color name * @param colorId colorId of skintone * @return string of quotation mark-wrapped skintone value */ function skintoneName(uint256 colorId) external pure returns (string memory) { // Array of potential color values string[16] memory SKINTONE_COLORS = [ '"Porcelain"', // 0 '"Cream"', // 1 '"Sienna"', // 2 '"Sand"', // 3 '"Beige"', // 4 '"Honey"', // 5 '"Almond"', // 6 '"Bronze"', // 7 '"Espresso"', // 8 '"Ebony"', // 9 '"Demonic"', // 10 '"Orc"', // 11 '"Djinn"', // 12 '"Spectre"', // 13 '"Mystic"', // 14 '"Golem"' // 15 ]; return SKINTONE_COLORS[colorId]; } /** * @notice return hair color name * @param colorId colorId of hair color * @return string of quotation mark-wrapped hair color value */ function hairColorName(uint256 colorId) external pure returns (string memory) { // Array of potential color values string[8] memory HAIR_COLORS = [ '"Light Brown"', // 0 '"Dark Brown"', // 1 '"Dirty Blonde"', // 2 '"Blonde"', // 3 '"Gray"', // 4 '"Gray-Brown"', // 5 '"Black"', // 6 '"Red"' // 7 ]; return HAIR_COLORS[colorId]; } /** * @notice return eye color name * @param colorId colorId of eyes * @return string of quotation mark-wrapped eye color value */ function eyeColorName(uint256 colorId) external pure returns (string memory) { // Array of potential color values string[13] memory EYE_COLORS = [ '"Black"', // 0 '"Gray"', // 1 '"Light Green"', // 2 '"Green"', // 3 '"Amber"', // 4 '"Light Brown"', // 5 '"Brown"', // 6 '"Light Blue"', // 7 '"Blue"', // 8 '"Orange"', // 9 '"Purple"', // 10 '"Red"', // 11 '"Transparent"' // 12 ]; return EYE_COLORS[colorId]; } /** * @notice return hair type name * @param assetId assetId of hair * @return string of quotation mark-wrapped hair type value */ function hairTypeName(uint256 assetId) external pure returns (string memory) { // Array of potential color values string[8] memory HAIR_TYPES = [ '"Bald"', // 0 '"Buzzed"', // 1 '"Spiked"', // 2 '"Mohawk"', // 3 '"Short"', // 4 '"Braided"', // 5 '"Long"', // 6 '"Ponytail"' // 7 ]; return HAIR_TYPES[assetId]; } /** * @notice return eye type name * @param assetId assetId of eyes * @return string of quotation mark-wrapped eye type value */ function eyeTypeName(uint256 assetId) external pure returns (string memory) { // Array of potential color values string[4] memory EYE_TYPES = [ '"Normal"', // 0 '"Angry"', // 1 '"Sad"', // 2 '"Surprised"' // 3 ]; return EYE_TYPES[assetId]; } /** * @notice return mouth type name * @param assetId assetId of mouth * @return string of quotation mark-wrapped mouth type value */ function mouthTypeName(uint256 assetId) external pure returns (string memory) { // Array of potential color values string[8] memory MOUTH_TYPES = [ '"Toothy Smile"', // 0 '"Small Smile"', // 1 '"Smile"', // 2 '"Frown"', // 3 '"Stoic"', // 4 '"Sewn"', // 5 '"Small Smile Fangs"', // 6 '"Stoic Fangs"' // 7 ]; return MOUTH_TYPES[assetId]; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; library AssetRenderer3 { /** * @notice render hair asset * @param lgHairAssetId the lgHairAssetId of the gear item * @param lgHeadgearAssetId the large headgear asset id of the gear item * @return string of svg */ function renderHair(uint256 lgHairAssetId, uint256 lgHeadgearAssetId) external pure returns (string memory) { string[11] memory HAIR = [ // START HAIR // 0 bald '%253C/g%253E', // 1 buzzed '%253Cpath d=\'M26,10h7v1h3v1h2v1h1v1h1v1h1v1h1v2h1v6h-1v-3h-1v-2h-2v-1h-11v1h-2v1h-1v1h-1v3h-1v1h-1v2h-1v1h-1v1h-1v-2h-2v1h-2v-7h1v-3h1v-2h1v-1h1v-1h1v-1h2v-1h1v-1h3z\' fill=\'var(--dmh)\'/%253E%253Cimage href=\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAZZJREFUeNrs2dGtgyAUBmBsXOKu0BF8MnEKhvGJYZzCxCdH6Ap3DCs355i/NN7bi1Bt+5MYEgT0K3BQW0zTZN49ncwHJCKJJJJIIokkcj2Vz7pQURT9L6ebnE9eRdbOb2Gj5BcoO0teacF8P83LIAU4QpHHdfNh52t2Ugeb1H5EFZwSmxwJozcGo/YD9LleM0BqsjLCVappnBS5Mno6LRFsdDShbdidSwU9ZQTimrsDzvWttLNSthzQxvfXH2ILWQHe4aC+VSiCgym7jKjvf2VqP2+6AvLyR9UzRtIHkoNgFD1tNyMB6PMvDDAaSec6DnDuH923EMSq6IiLayHmEFwNU8xK+ZJDndjk2/fR95gI6TIC90UCsH4UuOVasW1TRNdegkMXRk05PyDwld9CdMQU9i3BxuwNzPGqVcN+VulaTQRsjoLUB+1WgMM7vTS3sKeZcC2mSFtmQ5kI2MDavNnwj/A3RLnx121W3h6GowCzfxnghywiiSSSSCKJJJJIIokkkkgiiSSSSCKJJJJIIokkcud0FWAAiOX1bCeUzIsAAAAASUVORK5CYII=\'/%253E%253C/g%253E', // 2 spiked '%253Cpath d=\'M13,13h4v-1h1v-2h1v-1h2v-1h1v1h1v1h1v-1h3v-1h2v-1h1v2h1v1h2v-1h1v-2h1v1h2v-1h1v1h1v1h4v-1h1v3h1v1h2v1h-1v1h-1v1h-1v1h-1v6h-1v-1h-1v-2h-13v1h-1v1h-1v3h-1v1h-1v1h-2v1h-1v1h-1v-1h-1v-1h-2v1h-1v1h-1v-9h-1v-4h-1z\' fill=\'var(--dmh)\'/%253E%253Cimage href=\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAkFJREFUeNrsmcuNgzAQhk2UJtICJXCy5Cq4bxs5uY29U4UlTimBFigja0cz0b+zZhMMJLvJWEIYg/F88/KEVOfz2bx625k3aAqpkAqpkO8BWVVViMfkWO7+n4OcEpLGwy9T+b6j/l3vvdX2a8OlcywwHAuLUGkcnmOYyzXN8fFyiIcF6G9rlBQv+0KYHwuyoNRvAeaUBI/3OhrzNMWjAmhOuj4wfGyfMC/d/yiRd7+BqyZhahaSzgjYEHhqLimKFNTFs6VnLVm0g/c1oDg3x6JVifmlJWlhBhrBEkeYxi7Yi2tHz3myJI4hoOM1MSy2tGRAWHYr0jovPIBQHGudeA8De4xR6vuMojys6R7hruxqLQAaIRgLdRRzbQbUASj3e6GAZi7g1eXmHqBtFLYF7XPfZjKjnRDFwnwr5lvhzrNkXxKTnDmlmx1IgA7TP8SvEYoZpYtTqzE0yBtcyVayRjGAroOALUFcLJEypwD0AjAAGLq4y3nfLKOsYMmpNsC2gLEXSrV5bzZdNfHcAB0B0GSy5r2tX6KYLYoBjE9HMTaCoD5ao1+z+H50gR4y8VNTnF4BS2Kq1E0XWZL2RyNibEqQGmMyV/duDbpbkARMpiIxsBUMU+Xgo9taMcmgp4zbNpxsnvWNd+3E02T6HraP/wtJP3gxPhvYKp4KWFy7Qg0b5DsyNe3idZYe1ZI4mfhCYKX1nv1/S6V/+CikQiqkQiqkQiqkQiqkQiqkQiqkQiqkQiqkQiqkQiqkQirkC7cvAQYAWS7RDIfHvMcAAAAASUVORK5CYII=\'/%253E%253C/g%253E', // 3 mohawk '%253Cpath d=\'M37,7h4v2h-1v1h-1v1h-1v1h-1v3h-1v1h-1v1h-1v-1h-1v-1h-13v1h-1v1h-2v-4h1v-2h1v-1h1v-1h3v-1h14z\' fill=\'var(--dmh)\'/%253E%253Cimage href=\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAARNJREFUeNrs190NgjAQwHFKWIIFXIRHJ2AEX53H907AI4u4AGPUq6GmVCAI5UP9X0L4CK33y5VDlDEm+fVIkz8IkCBBgtw8srV/QCnVOZ/yypIxdTCmOCwyTLYPPRA3gWm59yrH58NVMoBV3nHjVUZPmMcBi8U5xfzH0wKrkVua8EIIljlK2eUWaJeprfzSHLONgbkH1WHyfcBv6665B7VRDjynnQrGWGnpRlX0oa+9rVxbvTnNadfuOrcbaoeP/WWUrQC8SJL3T1dCW73n+BjN5u3lvHSTsMu1nvsMeXOc3PgYeblN8dEMEiRIkCBBggQJEiRIkCBBggQJEiRIkCBBggQJEiRIkCBBggQJEuTu8RBgAGYWyYhxyBs+AAAAAElFTkSuQmCC\'/%253E%253C/g%253E', // 4 short '%253Cpath d=\'M26,10h4v1h3v1h1v-1h4v1h1v1h2v1h1v3h1v7h-1v-3h-1v-2h-2v-1h-1v-2h-2v1h-1v1h-1v1h-2v1h-1v1h-1v1h-2v1h-2v1h-1v1h-1v1h-2v1h-1v1h-1v-1h-1v-1h-2v1h-1v1h-1v-8h1v-4h1v-2h1v-1h2v-1h2v-1h4zM15,34h1v1h1v1h1v1h1v4h-1v-2h-1v-2h-1v-2h-1z\' fill=\'var(--dmh)\'/%253E%253Cimage href=\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAe9JREFUeNrsmk1uwyAQhe0ql+hVWFli2RN4n2t45WWlnqD7nKBLJFY+Qq6QY7hQDdVkAm78k0CTNxJSbMDm4w3DYKUex7F6dHupnsAACUhAAhKQgARk2nZrOtd1Pae5Edd67vuWZme7tbOUerGbACPaaXevYXBG1F20XziZl2NZk7v6l8v+bLCfru4woXzDFFWuDK50/nmuXe/vBdDQL5uSEbghUtfSTw5tRTMP2ru2Rw/rSsueqbMqyVxvEOvPQ/R03UUUl6oGRauYqr4+u5ICUFMxEcXOXI9grVA0qKpK2UK4ikYEFvuHJ7QE6935NcBRUTHXL2Gf5IAfNPgfd/SRlbsoAR7Yet1Tf5uYHJNln5wwD/hOgabhgSZAMcA91ffiGT0FoLzJQMLeXPly5cQAg/2qxwB7PglsrVp23+SElFFVEWBw3SPBdrTmTpQQVDHAiFmKsFmTAb43pgKFEq7YMXe0U9lTSDYI0vAsKAdklUgEOLgSa89em5cWk/FE3LYSgLPhSjxqKaFeEYC3iK5Xuee9P2hvAslOC6YU9bZ2Vy1giwK81Xmy2RpubXTd6qh1F1s6VnytAyQgHwvSPAOk/g+gW7mreXRIXTooAs+S/BVKZrIaf1YCJCABCUhAAhKQgAQkIAEJSEAusG8BBgC8BuDSh5XbAAAAAABJRU5ErkJggg==\'/%253E%253C/g%253E', // 5 braided '%253Cpath d=\'M26,10h4v1h3v1h1v-1h4v1h1v1h2v1h1v3h1v7h-1v-3h-1v-2h-2v-1h-1v-2h-2v1h-1v1h-1v1h-2v1h-1v1h-1v1h-2v1h-2v1h-1v1h-1v1h-2v1h-1v1h-1v-1h-1v-1h-2v1h-1v1h-1v6h1v2h-1v3h1v2h1v1h1v4h1v2h1v2h1v5h-1v1h-1v-1h-1v-2h-1v-1h-1v-2h-1v-1h-1v-1h-1v-2h-1v-3h-1v-2h-1v-2h-1v-5h1v-1h1v-5h1v-1h1v-2h1v-2h1v-3h1v-4h1v-2h1v-1h2v-1h2v-1h4z\' fill=\'var(--dmh)\'/%253E%253Cimage href=\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAutJREFUeNrsmk1uqzAUhU2UHTypUrfADp5HSFkFsw66DUZsI/OswpJHWUK2UKmbSG3p3vbkPtNgYgL2w5JFCSb4y7l/Nq2u16sqve3Uf9A2yA1yg9wgN8gNcoMcbvsxg6qqSvEsI84PsV8wtTrbz/UA98MYcf/BfdYAnBHX/hmf6keuxkzeP2QsJEz26O45/WIRDSiqXT+73vnnuHG9/4xB+b7ZlYyAOweutfQnQlsxzIP2buzFw7rewnceFlWSfmUj4AxB9HTeyfsDqrKiKqSqv764kgLwQN0EFLsxPYK1QlFWVa8lhaCKRgQWi8oFOpuxP74yHHUdMv015EkE7GjybI6NGNuSj/KYd7rfDqhvZs2TE5oHPBJEIwINBqGW4BT4r4Lz7mnFQGRjM/u4ox4D9gPR1sLRLAZJIR795gXOveldCLYjn0Pw3wC/QSnCLlcMiNw4FCi0MMUOzNGOqbQ4TWEVtASkGigEEFwL37NjJohKPj1P3gHU4jMdC5eyTVYyAMlQ3i8/B8w1GjCFkrupKpJ/hMzzU1YuSymYOoXI5dMq4G7M4V7HcQRiCOLGZN/+/uHroQpn8vxi5hqcfwwkAbQA+g0HY5vUIjwKWcU4MwWbo6g11dwvjRYJPCn2XXIIPCcq0crZrQu09UTOlObKuZE2py4qo7YbC+gDDqzklYywRZgrby/SxpIq0ie9imCqJ7GfU4ZPulaTuZ5UZi02utZU8dS55MiopZYwz57M9n3qan3NFQ9H10tOZhtbu7KCNRz13Go+qmTckuVniSWVNVNXCGNXQY+sQmLNFV/KtLnkyn2s6mQ6HGFrDkYx7zDXnCdlKulUom381UFSkNGkJu8CHNdcx47+x4iAKdZ07GCnIF8lA4D8/rAmNb2q54G92CT7PI/4+9RFswUV+aXOB0TefIsBmZxJRX4Xye0ppd7s0RUSrRX+WZeUQob8U5UKaQG0WEgMRGVCQuBiNftE/3C4bHTNrX0JMADsD3hOWpkfdAAAAABJRU5ErkJggg==\'/%253E%253C/g%253E', // 6 long - NEEDS MASK '%253Cpath d=\'M26,10h4v1h3v1h1v-1h4v1h1v1h2v1h1v3h1v7h-1v-3h-1v-2h-2v-1h-1v-2h-2v1h-1v1h-1v1h-2v1h-1v1h-1v1h-2v1h-2v1h-1v1h-1v1h-2v1h-1v1h-1v-1h-1v-1h-2v1h-1v1h-1v6h1v1h1v1h1v1h1v12h-14v-7h1v-3h1v-2h1v-1h1v-3h1v-4h1v-3h1v-3h1v-1h1v-1h1v-2h1v-3h1v-2h1v-1h2v-1h2v-1h4zM37,29h7v3h1v10h1v4h1v3h1v2h-11z\' fill=\'var(--dmh)\'/%253E%253Cimage href=\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAvBJREFUeNrsms2NpDAQhQ0iiU6BEDhZchTcJw1OpDF3orDEiRCcQofRi1fl3aK2oDG2gZ61JURDM9Af79WPYYrX6yV++ijFfzAyZIbMkBkyQ2bIDLk+Km5nURQprqXJtvI9wdHurOD+0EKGtnvzOTT5gWreJxFcQ7775/hYdzc6JPqx3/M5hg2HSKSoBZ7mpbPXnY/r7b5YoFW0u/UXbmK+a+Ejhh7JYRa0n481FnZeWnfOUNhgJUEdTeA0QPSw3dHzMaoqZOGoqlaJEoyCRTOKLZIIwI5EUadqc5cSglXUKLEsAC0Mszgb2/XDwcHScNa/Q53EgB38eGdHSY5tIUbdMV/w9yOnPs2+V9tVAOA3QEiSaHASagFOoPgVaLu7PLvC3Z2YLGn3Pd+o5wD7lWw7orW+DJIZOI6s9QzAdhBzGHwL8A8oZNhrmgFGxbVE0RArdsiO495Wzl7vaBmpItp0S1lcA9+pd06DvqUiAbR2rHEfSj5PjJqnwcWISbPx3bRi18OAV3U8NaqJDROXl9kzCBJZ1SBIgWqivoM9Y3c8DmqwcQyWuhXgUbualaItfErDmaPwmFJRqy4a8JgvjmB6xZakIwnI164dmfhGB7xLTLZ4xvEJr/7KnfbBM/ghtGEOGNORKddeJTUzFRIwe7+9kkeyqyTlI24mTHDTfGNSkfVv2BPV1EkgIQZ6mA8KtFaoT9V3tmu5ZRsEqMhcUMd8BnPASXEgmdLwRM9mFLHQ9JF2RSpiBTG8RtaNpmKKuuvdDKAn5rh3VScpOaaCHFdKiGIKdUpAE1VJJuHItYuCvcwJsfjEXY/PDS097t7IfB7gUX+dOtnMN3NMGZNSLJ9+K6ZZTzkeoTH/DrKGC7RkutWS5zwmoWVr6Krk0dgsdwY8fjHTxkgGnnZVSM3BdVl743JvCdlly8g1ziC7GoCVZ02azxiGrOuQtq7a6hFDMloC6AfZNmL50vfjlNyC9c7oRf737AyZITNkhkwwfgkwAOKsJLPTk5emAAAAAElFTkSuQmCC\'/%253E%253C/g%253E', // 7 ponytail '%253Cpath d=\'M26,10h4v1h3v1h1v-1h4v1h1v1h2v1h1v3h1v7h-1v-3h-1v-2h-2v-1h-1v-2h-2v1h-1v1h-1v1h-2v1h-1v1h-1v1h-2v1h-2v1h-1v1h-1v1h-2v1h-1v1h-1v-1h-1v-1h-2v1h-1v1h-1v4h-1v3h-1v2h-1v4h-1v2h-1v2h-1v1h-1v1h-2v1h-2v-10h1v-3h1v-2h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-2h1v-2h1v-3h1v-4h1v-2h1v-1h2v-1h2v-1h4z\' fill=\'var(--dmh)\'/%253E%253Cimage href=\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAlxJREFUeNrsmkGOgyAUhrHxDJPMFTwCKxNO4X6uwcpruJ9TkLDyCL3CJL1EB5LH5PUNVK1YCoWEtCqCn//P42nbXK9XVno5sTcoFbJCVsgKWSErZIUMl5buaJrmqLEU2RZbO3g0O2tjdkZuliJ9CrOvR3CKHPvXPtaNbyiQ7XAPJLrYyfTzfcclPVKUmzqbKu3Ypt1o9zlQd15UJXfCzZ5jA3zF0Jo0s6CjaXu2sKYOqE+RVEm4y4rAKYAYYVv6xiGqOkWZT1V7PLmSBFBAVR7FbqwHsJoo6lTlr7KEYBUVCSwaK+epzsb289PBQeU+67/COokBJVy8s2NP2g4wR12bLzhfB9RX0dbJSMUCTgDRk0CDg9AAcAzNX4a25SHJQITibPazoJ4DHAPRVqNPlQwSQjyeNx9o21rvDLAS5hwGvwf4BwoRNl0yQNbGUKDgxIoS2VGvSeXcMoWzoBSQLJAIYHBO5p5eMwZW8unr5AIgJ/v4VriY5WElPZAOys7LS8CumwFjKHnaoeIYsOeFZi6pFIy6hKCnBfUK9txtV09EvUmckcpRAGPYdROkZx4KOjg8GEdT76nRNRBofBeV3J4PQYYAc/lF7BRLwWwhPbnp7HvRlC1kAFAVpyRJ0SRE0zk3yHYho9HwaETfwYhSlNSeh95i7arRciFzUzEEadWaAEqTTCar9XFJyY68clC5Aq6xq1NvytGmayAHAsZzBV1SkgNsV2pa15Wg4hIkh7mYtYpr7NphFXP9s6HvzcDu3/aPKke8GRCskNLU/7tWyApZIStkhayQ7w35K8AAbRsZgzu5pK4AAAAASUVORK5CYII=\'/%253E%253C/g%253E', // 8 MODIFIED braided (helmeted) '%253Cpath d=\'M18,39h1v6h-1v1h-1v4h1v2h1v3h1v2h-4v-2h-1v-1h-1v-2h-1v-2h-1v-3h1v-2h1v-2h1v-1h1v-1h1v-1h1z\' fill=\'var(--dmh)\'/%253E%253Cimage href=\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPtJREFUeNrs2ssJwzAMgOG4W3SVnAqeosP0lDV6zxSBnjpCVsgYrgQy+FawW1DV3yAaXwIfeqBAUyllin5O0x8ckCBBggQJEiRIkCBBggQJEiRIkCBBggQJEiRIkCBBggQJEiRIkO9OSmmTiItUoPw8w2bSO3AYacAlbE8a8C6RJbawmSylrM119opMPX8gbPpwV6jds8FDZXKXcA/sQipKMNmu16Z0Y/WkQOtEPbwDh8rVhk6OutYpbJZsaqnedABZX4bN5G8c7aeesAVgaQbQ1vuub8cnFnQFrlHLNduWo8BL5O/JureetXS9DqDR3bU+HvL88JrJlwADAD8o5HEwnUYAAAAAAElFTkSuQmCC\'/%253E%253C/g%253E', // 9 MODIFIED long (helmeted) - NEEDS MASK '%253Cpath d=\'M16,35h1v1h1v1h1v10h-7v-2h1v-2h1v-1h1v-3h1zM37,40h5v4h1v4h1v2h-7z\' fill=\'var(--dmh)\'/%253E%253Cimage href=\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAR9JREFUeNrs2sENgjAUgGFKXMBjV3AETySdgjW8e2IYpjBhG8bANnk1jZqItoUK/0saDQd4X99rgQQ1TVO19airHQRIkCBBggQJEiRIkCBBggQJEiRIkCBBggQJEiRIkCBBgiwJqZS65UjMnvcxiqikTaTdQ7v2JUPr2JaSaOwYU7SWD/dVih9vrrdoJd167OT/sIfdtcmVZOzmlgppfItlAHarVVJm1yWg5ZDeVLsGQCOHrpnatJFzH9du19H/ptxdn+LiJvbX5VBHVNFXUMvFhwxVTHLOQ8R9zCfQZ2rTcNfWi7arxZkA+HLz/vDQ8G20su6jJlKV+L1rOCkuP3lkPNlxdpNcHHJuFefkIZuP2UQleWkGCRIkyH+IuwADANsRUZnVIli4AAAAAElFTkSuQmCC\'/%253E%253C/g%253E', // 10 MODIFIED ponytail - NEEDS MASK '%253Cpath d=\'M16,35h1v1h1v1h1v10h-7v-5h1v-3h1v-1h1v-2h1z\' fill=\'var(--dmh)\'/%253E%253Cimage href=\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALlJREFUeNrs2rENwjAQBdAYsRmrsBtTWHKVEajYxaQBRRYNcYF9vJNSpLClp2/7mku11iV6nZY/KEhISEhISEhISEhISEhISEhISEhISEhISEhISEjIXyJTSu1/Hh2Zvp0ZaJBv4LbPJfxxHTnRHmQOeydnAx5CfrjDa/QWss6Q6pEWknfp3bdky+hp9iT52L5r2zcjPjyv3phH7pPnjrW33UNUoh7XMsuEZTIKCgkJCQkJCRm+ngIMABnbKuzQgeCHAAAAAElFTkSuQmCC\'/%253E%253C/g%253E' // END HAIR ]; if(lgHairAssetId == 0 || lgHeadgearAssetId < 3){ return '%253C/g%253E'; } else if(lgHairAssetId > 4 && lgHeadgearAssetId > 8){ return HAIR[lgHairAssetId + 3]; } else { return HAIR[lgHairAssetId]; } } /** * @notice render an armor asset * @param lgAssetId the large asset id of the gear item * @return string of base64-encoded image */ function renderArmor(uint256 lgAssetId) external pure returns (string memory) { string[17] memory ARMOR = [ // 0 cotton shirt 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAYlJREFUeNrs2j1SwzAQBWDL4wNAQ28ahooOSs5ADuAU9NQcgZqeAg4AZ6AkHRVDlZ4GbiBYMeu8mLVsocB44G0jZ2PJ+0U/buK898Vfj7L4B0EkkUQSSSSRRBJJJJFEEkkkkUQSSSSRRBJJJJFEEkkkkUQSSSSRRBJJJJFEEkkkkb+JnM92vXNu0sgqByftwf5W0RS1QN1U/3GZXBjiMB6f3kJ7c7ecHHZUQQqzcKv89ifydtnmcsH63NxxzM6I6oMpajWTryF3fLjT5k7PH770GyoYn93M6jBu7ipZ64RLUQaO4RCjcXn9PHiPBce4ujhqr+8XLwHZ3RKpKyXcFNtnmsOZs4q3QorEwH7yg5zN99Yw3c8SmNMVk3oOuOak9n37TAeSZZMKHIuWnLaIUJzVPza7Froa2m84SA6w218Lxpxcx56B3ynU2lrySvtYnS226jtIcPPLiYmzucnQmUwNrRdntXtQ6vu7jAF/MrS47wCxj9Sus2lhZTuWY4G5S3XTMbYegb4LMAA6uttKyO8nkgAAAABJRU5ErkJggg==', // 1 thick vest 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAZ1JREFUeNrs2rFKA0EQBuDdI4VaeYHYaCNYxSIgouA7WMZOO0ufI72WYqWdbyFoIXKlNopiqaC+wZo5nLvd2Y25ywY59R84lhy7e/PtzIUU0cYY9dcjUf8ggAQSSCCBBBJIIIEEEkgggQQSSCCBBBJIIIEEEkgggQQSSCCBBBJIIIEEEkgggQTyJ5HdlWWjtW40shWDo7HTTmkgqG7qPy5rJyZwRby+vefj3cNT47CVEmJYCCeDsdMA83Nj9wku3tvZNDfZi7JhlLwN7LTnBe7Du3d7/+jtPS7h0IHGdomziHA09rpL6uQsKx5CyROCoRJTJ0JwgfQOL9QlddD5JBtnxyioTGSSkJUPdYKE2s/mXKpg9W5/w0hcCMoJUCViq2mj5Pjd/FHQ9bUFZ+7p+bWDboWAvdVF61M29qRjouqe5UGk+UETlNdeXD6rg/2tcnJfmWF3FtjEhvFlx+Fg23kXaHP5bsRWdJID4XV0b252xi3SsHB0UZfSD5XEr1y1hOokN41K2vP5276Epuro+MrvyC9oUhX4W4OgnwIMAOZZ5/3FwvtMAAAAAElFTkSuQmCC', // 2 leather chestplate 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAa5JREFUeNrs2r9Lw0AUB/BLiEgMCIqtoA4SnSqlY110cNLJ0T9AJwX/GEEn/QP8C9xcnDpncDI4iFAiCkIponDmBZPeXc/84FCCft9y/XHv8j69d+kSi3PO/nrY7B8EkEACCSSQQAIJJJBAAgkkkEACCSSQQAIJJJBAAgkkkEACCSSQQAIJJJBAAgkkkED+JrLVnOKWZdUa6ZjgaGx4tIRLUKuuT1xWLkzGjSIafCTjbTSsHbZUQSlMh0vDn5lMxt7DIPvMFJxe13QdbfLm+ip/Ch9ZHqzhTSg7+Z5Al7+wFJfB81heUcHiD9pd8lj48mbcJVIS4Wjc3e6wi7OrXFx73h377jp8LZyjg4ux157NXt/HQEKqR6JqpySTRJwYIlTcOV3xugj6Q+l92TwRt+VPS2tRx1S9D1gb3RWu4lRoq+lWLrQMWi1ajBSny1ehc/6CNO+mdyehHR2ws7aovbAJ8Pt8t3J+0B9BqdOi+P6xf7gjTuVxd2ZYpwh2cnrAjo/Opd2sQ6THR9cJwsYl/992HrCuIXYEYWk36VjpsHQc7bJA01b9SWheEPRTgAEA57jAd/wBs+kAAAAASUVORK5CYII=', // 3 rusty chainmail 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAehJREFUeNrs2s1OAjEQB/B21WA0KH6ciAcw8gAa4hmP+hS+pVfPRn0BTPRgSDwoItFIiK5McZahO/shmxii/yZk3KXtzq/TLRdtGIbmr7fA/IMGJJBAAgkkkEACCSSQQAIJJJBAAgkkkEACCSSQQAIJJJBAAgkkkEACCSSQQAIJJJC/iTzaXQuttXONXCyCo1irlEyrbghq5/U/Ln+cmMTJ9hAMXTy76s0dNldCDNNw3Mo7451/0xlE94qC+bnnt/1C86iDJSoNpkEb1eUJ8rIX65MFP2lWoi/3qiXTv/80d8/jhZsVOzVIbkWaWMPVNib3NhsL5qn9YR5Xhy4Zvw99H0MqcNmOm+vR3+3O+9S8jOWWF+06Jb1nEqrhKF5fvLkKUjJ+1MblaRJH4/l5LqfuIIbOwtpWvRymbUcfKoGzxNj83UHi1t96XVLHa9C0CgdJW5I/2irTQyjK67TE5TVXk+PB4Yp7Dkc+wPxx/DwaJ/OKCjCK/KHCyd9ve7q/HfrbKr4yL24wry69gxzl9qRE+R2VVZD9tOr4/XiepPH+AiadH3SfqhpkAbXGJyhFHsuRV9+PMqm06vu5aP0ILfvzQRnbkd9VDfICuVpaFWR1qAp0zdWQ1zLSfP7hpVWZ72vz5GkE/RJgAPKbdC9Pa9uUAAAAAElFTkSuQmCC', // 4 longcoat 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAbRJREFUeNrs2stLw0AQBvBsKFSsilTaKlYFvXjw4NH//+SxBz2JHnwgtVhErdfoLHxhsk7XrBEp+g2ENN1H5revXuqKosj+euTZPwgiiSSSSCKJJJJIIokkkkgiiSSSSCKJJJJIIokkkkgiiSSSSCKJJJJIIokkkkgiifxN5HCzXzjnFhrZaoKT+2pnOdse9ATqFvUfl8mJAQcg4mX25u9348nCYWslFIPhub/R9ffL69uyvCkY723aj9lYo0IYYm2lA0hZR6C97npZ53R09qndVwnrdx/sDrOHx2njVVJppPeZniULt7M1KL+bTJ/8DKK+VScG13FyfFTpV5B6O6QMWAWpcTo0FInPSx5QHR8HUuVZtzu/uPL9h7MlSI2T1YEBlByeX2fJ54CTk9GaMd2RTtYCWmC9PwUiIYljsJbabV+OMnwGCDi0l21wcz/2zxY0NsPucH+vmLckseeArAOsM8N6zyFCsC7X+1xCsCE0dtK3LFi45DQ0NSRBuTC7GmV9r0EhzpoIjQ0PSvx+5zHgTwawuGKQsE4YekVJ7jgoLaxA87rA7yzVlAFIjbr5CPRdgAEASZD7DWDIBSwAAAAASUVORK5CYII=', // 5 chainmail 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAbxJREFUeNrsmj2Og0AMhRm0DXdISVruEc6QK3AruEJyD1pSUqelZOORHnIc85NFWkW7z1JkZmLP+ON5Jk3COI7JX7c0+QdGSEISkpCEJCQhCUlIQhKSkIQkJCEJSUhCEpKQhCQkIQlJSEISkpCEJCQhCUlIQhKSkIQk5G9ClmU5hhA+GvJrD5z4PM+T0+kkoOFT/3H5dmEaTtv9fo++aZqPg91UEMA8ONjhcIi+bdtpbi8w9r1er7vWcZM11BKYB1oUxTSu6/olZg38fD5PX8pafd8nt9st2QP7lKRbURb24I7H49Nz13XJMAyxGBujY5fADeT0LF2h1wUsbCt0DJo7ZxrUgxN/uVyiglKM9V7eFtNwkoP9xOA19BpskJtxqR0tqAb8ibfmzaH1syxz8z3QJYXTuZbEx3vLsgkuGIyXCtdj28qPLorP8LjAbB72s3WhfvH4iHD69ztUVTWutdLjzcRkvF05g/C6PaVQnFGtgo7z1LFxWGcu377AuftD5kXV9J2zom89eKuMbSlP1SX1bS1enEDreFyU1qBquhUQankqaHVEBRlDDT3WXtazl5enMua9dbaYgH4LMADf73a61aRdeAAAAABJRU5ErkJggg==', // 6 bronze chestplate 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAYtJREFUeNrs2rFOwzAQBmA7KqJkICsvUAFbkJgrRgQMdOFdkBBDBS/DAgPqjDozdKOoL8BahlLEYOqoZ51TJ3VkhCz4b0nqxJf75HOyVCqlxF+PRPyDABJIIIEEEkgggQQSSCCBBBJIIIEEEkgggQQSSCCBBBJIIIEEEkgggQQSSCCBBBLI30T2DlIlpYwa2QrB6eP+zoYQudBQGes/LhsXZuF4Syx74nbwHh3WqyCCuXAUR7vt4jiczM1YKJie+zD6CMrjnMxRVbC90tj47auAdjubZuxmMF2Ztw5+dZqZi91OWzy9zsXLIncI1prEW1EnrsNdHKYr1/qP07X3uOAW8iQz58PJZ4GkICyFL7q4qWqfcShfOVfxrrh7nlm/fedx3PVZZuUaM6jvCsvzfEtV7TNK1MvTxoX6oMtF8yCca74LWrfC8vJ4W9Xtt/vRzCBDgD8ZGluG8oUqr3Cr6kVi9ukCyKGxBNXr6gQDXn6/kzpgrME7StdOL0oXVm/HxBcYS6s2rUdDvwUYAOkWv84DyblmAAAAAElFTkSuQmCC', // 7 blessed armor 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAadJREFUeNrs2r9Lw0AUB/B3pWjRoVsHwTHZ3Wvp1CH5Hxz8C7JWKrSo5L9w8H8wQ6ei4uoeR8GhoyBEl9NLSXJ3OZqEiBz6fcvlcj/yPum7dinjnNNfjw79gwASSCCBBBJIIIEEEkgggQQSSCCBBBJIIIEEEkgggQQSSCCBBBJIIIEEEkgggQQSyN9Ezvw+Z4xZjey2wYl25PSIPBJQZus/LhsnpuCkeNxbp+0iJOuwtRLKYCZcFjuTDXL1UNxrC86eexW9tdrHuNj3fX5ERbYm2MjZVfp3zx8pdHxc3JuH5QdWwednLB8cD4k+l4PvvRNqg1UWCZxoXdel/fh6K6538lIaW54PKueY4Mr4tLhe3W+QxYtMlLl10ekkGSeHDJU/OVPypkhuDpV+3XUybnKxVvYSFaOjq7DM8zyu43TozOs3TrQOWk9ajgxnWq9Dn2iozIuiSEGzIAhKr8BxnPz69XaaI9sAfzIEVoe+u6d5P45jBds1weQ48EO6lKC2RHZ8TJUgVWb6+93ZBrQ15IoSWPG9IY6VCSuOY6cu0JZSbZqPgH4JMAABcr3iOf9YBgAAAABJRU5ErkJggg==', // 8 iron chestplate 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAZ9JREFUeNrs2rFOhDAYB3BKLnF0c5MnOAkuupAcuecgDE4O+ghqjK/g4OSA8BbGYCKDk+TiE+Dm5uiE92EKbWk4CMY0+v+SS4/Sr9cf/RqWY1VVWX89bOsfBJBAAgkkkEACCSSQQAIJJJBAAgkkkEACCSSQQAIJJJBAAgkkkEACCSSQQAIJJJBA/ibS9/2KMWY0cjYFR63jONQQlJn6j8vRC1NwbUnY30WRpqlx2EEL4jAdjofneXW7Wq2avqlg/rt5nk+aR5t8frpXPbxsW30wta8syxrqum7TlyRJJ28TPAzD5ibNVRRFPfcUrJREOGoXhzvWxc1nLy4Igs69OI43jtHBFWTznaqCkOKDFGMouh4k4sQQoSJYt3hdZFkmXQ/NE3FRFElzidChO8zOTuaVilOh67MxeqFD0Lrd4cFxunwVutz/kMZdXb9KaHZ/t+w8gsVBiw6O3hrkFOBPBmFV6OXxVnP9+PwuYWc6mDTh7e4a+iTtpgnBj4+uEtrKnNfvb7sPaGqIFUVY+tCx0mHpONpDgaaU6tj1EPRLgAEACjfFOwGC4DgAAAAASUVORK5CYII=', // 9 skull armor 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAVVJREFUeNrs2tFtgzAQgOG4YiBGYBMYBTaBSWAERmEDJ0Y65Lo+2wlJhdr/JOQIw5mPs4GHGGvt7a/H1+0fBEiQIEGCBAkSJEiQIEGCBAkSJEiQIEGCBAkSJEiQIEGCBAkSJEiQIEGCBPmbyK7rrDHm0sjqDM61dV27xkHNVf9x+fSFBbgjtm3b22EYLoctuiCBxXDh/mVZjn1nwTLuNE2n8kRP9lEaTMM2TXP87vv+R38O/jjH+rnWdd23M9hvJ/lT0SVO4XyMhFQx1peCa/2ST5DSSpSi94O0deZDY32pCI9PwbWblRuvtMKmbVurTT1J9LgJL13suyOsrIYP0VVuvflJBBgb7JlITfkUSMsVWVrWFUawVe5B4g4exzFazU9WNTWGP51jN8Gz7O/vKgUsWTOvVLNkvboxSnNrD8rjQ2We5+zjyVXSbVcLf0prbwMXdwEGAGMx1b1iXMhzAAAAAElFTkSuQmCC', // 10 cape of deception 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAkhJREFUeNrs2r9v00AUB/Bz5CqVUxKyBbI0VUMGBlxVXWFF4m/kz2DiT0BI6cCQBrUsRhmQoECjVpFq8uw8593z+UcyNBL9viWKfXd+n3t358VeHMfmf4+GeQQBJJBAAgkkkEACCSSQQAIJJJBAAgkkkEACCSSQQAIJJJBAAgkkkEACCSSQQAIJJJAbhF+nked5zuuD4FX29eHV/NzbFaLqI0h/24EJOAhC83MxM929XvKsXWMLi1TnU1BZSa7e0xRm+s0Xye/z/aH5Ov+8RI6tvg+BrjLUQh61wqwR43Ro7Bo53hrLE1rVd6vlevKspXoNLRyBCEPx6fpD8hvdXWTQ4+DUmYvrogTIPS4ndBCs+17ejL2iM6JWJRnXe7KXaziJDpOHdgWWMd9vpwmSg9q4oLLCutIpJrTu0X7niaPxaVzZvqzC0pUgy3ASqZPQUE6GoSVVzU2M7BM02tZ1OSaNx31/LSeh056a8WzulSLDXhCX4XoH6b3Z30UG5cS5MjzjvIQ12LXMuU1R6L5nnXfW/48/3ptR/1ua25+FdY/QFvLtsBMXwXQw9OXB6yxZCXUt1aIKc/s6IYGyiozM5blCM9avguXwy4G/ROuDhpYWg/kg4sOIkpP3rP1m0verxvIe5JPatcSpHyEpH5r4XJ6rlRmaIKZTyq8L1EEPmt//tpKkpHjWqcKM1XvOtXS50jSm3ssS11WvMJm7BhOWoP6mQGo/WS03fqjeP3x4BM12bpnKPacnSZ/E8p7sTyfsm1HkzM0F/SfAANbvOCIM8jKOAAAAAElFTkSuQmCC', // 11 mystic cloak 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAhlJREFUeNrs2rFOAkEQBuA9BRNPDBRHgjbYmEhssLC29TF8QB/A1jewMVhKRwIFRnImEnM6LMPNzu0eB4Uk+k9CCHe7e/Pt7G4oLsqyzPz12DP/IIAEEkgggQQSSCCBBBJIIIEEEkgggQQSSCCBBBJIIIEEEkgggQQSSCCBBBJIIIEEcoOoVWkURZH/xkWSv334Mol2hVj3EmRt65EJ2EuMmaTGJPHiWbvGBotU5VVQp5JcvXZsf5+17He3aczz2JjBxO38C+h1hmrIXjtvxDgdGsvB6G2wPKFr+m61XK9OjtxerdjFEYgwFI9D+/06zaGXbW8u3gwkQO5xZ0Lz69lgHAXPiCqVZFznuF5o+LBftw9NBJYxwzeL5KA2PqissK40Be1xGbTfeeJofBpXti+psHQtkGU4B6mT0FBOhqHhqhYnRvZpHLjX5Zg0Hvcdp6Y/Tc3TKI1Kkf1OnJXhOg17bzSb51BOnCvDM85LWIN9y5zbhEL3vem6v+8H5vZrbnN7nzu3CO0gb8+bWQimYwW9Ps2TlVDfUg1VmNtXCQkUVWRkIc8lmrErZAgWhNL+lCcqBx9EvuR0pQissTymHlcCl3vz7tDmE8z1B0vQ2ibAwv6ZfbpJUlIMowpLsKyib+lypWlMvZclLomDq06DaRv2TZzVNgUu2n+Y/J8OffT+4cODPnqZykrqSdInsbwn+y+r6MvNB/0WYABwgfXw0R+8SwAAAABJRU5ErkJggg==', // 12 shimmering cloak 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAm9JREFUeNrs2rFrU0EcB/B7UjXUQVySIhgkCQSHQIbWJRWypAgu2gSd4uAkmLgU/SOcxESQrpkUgoJVJEEyZWkdHiSgkSSIFGyyiIOidnjy++kd917vtY0PS6jfH4Tf9eXu3n3e7+5lqeU4jjjscUT8BwEkkEACCSSQQAIJJJBAAgkkkEACCSSQQAIJJJBAAgkkkEACCSSQQAIJJJBAAgkkkAeJTKVSjmVZU42cCYKjHIlEKBHUmtb/uJx4YR6citFoxLnb7U4ddl8LkjAv7vzRDc7r2wsikUhwu91uq++DguV9g85jHFwoFJxeryd2g304dck15uznFyKbDAn79Iq6VqvVdsy914L1B5rJZES/3w+8S1yDCEe5VCqJcrmscHrFwuEwt9PptLh9osrtB19LnBuNBufrZ2zOW+fu7rihCa5HsVh0zSvn1I/EpDuFO+k4GT+fXRMrr8MKKnEXjzfE1flZBZPhBVPYts39KV79WOIH4xfD4VAMBgMRj8dFLBbjsfrDfPLmG88xHo8nfg9Y+XzekTiCHbv8WGUKquid+U/GhZpgu12fe3tPzaPjO52OOha0cMprV94bH5o8GnJnUf9kMum6T71ed6GtVqvl6ECKbDbL+fvDqFh4dJLOie8W/VuwXzUpqKK5XM53HsLKitJRer4ZFZVKRfWtVqsurELqsNCtjyr/eRlwNb1nLChY/7vZbHKbtqvctvdTL/fcEYSlahJSLxS1VzcvMJSRXqDhjceff11Jv/NpmkduXdr277a2VTVNUCqns4/fK7Fx80tgmOm6X1+CLoee/gZpP0v6mBvtRc56NU3xS4ABAIDuiOkug0P6AAAAAElFTkSuQmCC', // 13 phoenix chestplate 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAaxJREFUeNrs2iFPw0AYBuC7ZQ1dxYpAVECCWYBgugS9IAlgZvg1BEHgz2BAkGkyjahjZAaBmEBQRFdScXCFa+/ay9amhFzgfc2t197te3Z3mxlljJG/nhb5BwESSCCBBBJIIIEEEkgggQQSSCCBBBJIIIEEEkgggQQSSCCBBBJIIIEEEkgggQQSyN9EDvsOo5QajWw3wfF2x7MI8QmHUlP/cVm7MAUnb4nvPXE5ejMOW6kgAdPhRPa37LQdT+OsrylYvO9NMG80j3Zwf8Nhm2v5tQ62XeibzJIUOuitZH0Xo7A0bhn89MjNbg56Nrl7jMnD59xNsMogjuOt51rEtpKFuJM9p3Tv/DZc+owOriAP3ez1ePqeIkUEVqQqOn1IxsmRofLK6YrX5eo+Uq6rjpNxZ8euMtdEglZdYeqvd1gRV4QOfad2oVXQxaLlCJxufBH69KI+FzyraHqw2y19BF43R7/OowzZBPiT4dgiNE7ymmdhomDbOpic1Y5DroNIWU0TIo6PbieInemTr9/v1iKgqZF3FMfy7w1+rHRYfhxbVYGmbNW69XDohwADAHv5uuS4OWuFAAAAAElFTkSuQmCC', // 14 ancient robe 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAdVJREFUeNrs2r9PwkAUB/BrwSAa+eVGHMDIposSZlxMcPQPdTVxcjbqohsmMhgSB36FKDSNnLySK6/lKMUSQvT7EtLrcb8+vXdlwZBSir8epvgHASSQQAIJJJBAAgkkkEACCSSQQAIJJJBAAgkkkEACCSSQQAIJJJBAAgkkkEACCSSQ60SeH6akYRgbjYxHwdG1kEmIalEQ1NjUf1wuvTCO4/Fh2s715rG3cdhQC1IwHU7F3sEk81+bllsXFazmvXvrRxpH2/mynJGD9kgEwQpZb12jYznQUn57inzozfRbBKe5VfkonxD995FodCcP7rdYTyc1AQ3+/DIIxOVKsZnvnu6/FrbRwXnUymm3XG8OHaT7ILuWp21YtNOI43hwKN853eJ10a5/e+7D9uO408qOZyzKGD96EdaonaWlH+eHVouppRcaBu1fNKX7/ueWaO3aztU/1zxoMmcGHom4DsjPFSFXAZzXv9WcnmNK91IlNq6znbaE4n3ccj3hQinTGm1LnBwnpykv0nKcnS42roPxuLrIiuvbjmc3Vxk0L6Wn7mUWFKot31X+wlJY+v02g4DrCpqfPmr3FFzdB2UEYWk3ecZxLB1HMywwaqquOsKuh6A/AgwA4k/bm7b7+74AAAAASUVORK5CYII=', // 15 genesis cloak 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAixJREFUeNrs281OwkAQB/BW+SogERIwJsYgepHEo/HuxWf1JXwJEjxJiDchQaMg8iGVbZkyO2xL4SCJ/ufS0O4u89vZXS7Fdl3X+uuxZ/2DABJIIIEEEkgggQQSSCCBBBJIIIEEEkgggQQSSCCBBBJIIIEEEkgggQQSSCCBBBLIDSIRp5Ft28b7l2UnePvwsTu0d4VY9xJkYtuBFbBecazuYGKVc0nvu3aNDS1SnFdBeSWpeuWcPz+1Ytq7VufXxsvQanaGWt/fQK8zxELWK9mgEeFkSCwFobfB0oSu67vVcr0oZrReqeSehlOg6gL10Hr3rq3XUQC9OnKMuZhucgDf4/qELu83O5922BkRq5KEKzn7Kw37U9f70sX+0zDtOVAhl8kljVBeYVlpf8XofdR+p4lT46txefuoCnOXh4zCcaRMQkIpGYJGVHVlYnifg5T+y8bHVONR3+5gao0nM+vpbWRHIs8P024UrpTxl0zvaxpAKXGqDM04LWEJNi3ztngmQ/a9rRW0z/eNnpVP+Lbe8Ft7ptAa8vo464bBZBD05iQXJMuhpqUaVmFqHyc4kFeRkCt5LtCEDZBhsDCo2p/8RKWgg8iUnKyUAktsjY3Fx+VA2pun+aSXT2iuc6yCJjYByv3zMZ5pSaqkCKYqzMG8ivrSdbT9qcaUe5nj+Bgydwn2t2Hate/OChv/MeS5P9FOWoLWxMyblik/OU2V5O34M36fqhi20mT8CDAAUE88AME8AowAAAAASUVORK5CYII=', // 16 soul cloak 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAlxJREFUeNrs27FLG1EcB/A7yeoiCk6BRMRNJCW4RNqKGeoQBwWhQ4aCmUTo2o62/QdaKNTNQRDaoQ46pFDFLBoaSjcRW8gkKF36B1z9veR3+b1f3l0uGRqo399y5O69d7/P+733posfBIH3v8eIdw8CSCCBBBJIIIEEEkgggQQSSCCBBBJIIIEEEkgggQQSSCCBBBJIIIEEEkgggQQSSCD7iFSSRr7vO++XCkvh14cHtS/+sBC9PoJMDTowAUuFonfR/OnNpLPmXcPGRhYpyaegspJcvZn0lPn9cG7eXAuzee/j8eEdsmr1/RfoXoZEyJWFYtiIcTo0toOsDozlCe3Vd6DlurhcsXqNKhyBCEPxeveduZ58Pwuha4+Wnbm4bkqA3ONyQkuFTt/Pp1U/6oxIVEnGZaZzXQ1vG5/MS9v7z8LUftQNspNc1gmVFdaVbmGK1jPa7zxxND6NK9vHVVi6DDIOJ5E6CQ3lZBgaU9WuiZF9JscmrPtyTBqP+140r7w/oxnv69GOH4t8/GQjiMNlph+Y66/LbyGUE+fK8IzzEtZg1zLnNlGh+74sb1q/y6+ee+O51XZuDesZoS3ks633QRRMB0MrpadhshLqWqpRFeb2SUICZRUZ2Z1nw8KmesFc+A8He+FBQ0uLwXwQ8WFEyclner8RWGN5D/JJ7VrirX5XJh+a+O48eWVuBHRKpZICddCLrn/fWElSUjzrVGHG6j3nWrpcaRpT72WJk2Po3DW4hb2Dbr897/uPIfX9F9YhxFBZBdehkaSSsp18Ju/TCZtffxO5pXT8FWAAwKc5BAY2wHQAAAAASUVORK5CYII=' ]; return string(abi.encodePacked( '%253Cimage href=\'data:image/png;base64,', ARMOR[lgAssetId], '\'/%253E' )); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; library AssetRenderer4 { /** * @notice render a headgear asset * @param smAssetId the small asset id of the gear item * @return string of svg */ function renderHeadgear(uint256 smAssetId) external pure returns (string memory) { string[17] memory GEAR = [ // START HEADGEAR // 0 none '%253Cg%253E%253C/g%253E', // 1 bandana '%253Cg%253E%253Cpath d=\'M9,3h3v1h1v2h-6v1h-1v1h-1v-2h1v-1h2v-1h1z\' fill=\'var(--dm6)\'/%253E%253Cpath d=\'M9,3h1v1h-1v1h-1v1h-1v1h-1v1h-1v-1h1v-1h1v-1h1v-1h1zM11,4h2v2h-1v-1h-1z\' fill=\'var(--dm5)\'/%253E%253Cpath d=\'M8,4h1v2h1v-1h3v2h-3v1h-1v1h-1v-3h-1v1h-1v1h-1v-2h2v-1h1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 2 leather hat '%253Cg%253E%253Cpath d=\'M8,2h4v1h1v1h1v2h-4v1h-3v-4h1z\' fill=\'var(--dm48)\'/%253E%253Cpath d=\'M8,2h4v1h1v1h1v2h-2v-1h1v-1h-1v-1h-3v2h2v1h2v1h-3v1h-1v1h-1v-2h-1v-4h1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 3 rusty helm '%253Cg%253E%253Cpath d=\'M8,2h5v1h1v4h-1v-2h-1v1h-1v-1h-2v2h-2v-4h1z\' fill=\'var(--dm48)\'/%253E%253Cpath d=\'M9,2h3v1h1v1h-1v1h-1v-1h-3v-1h1z\' fill=\'var(--dm41)\'/%253E%253Cpath d=\'M8,2h2v1h-1v2h2v1h1v-1h1v-1h1v3h-1v-1h-1v1h-1v-1h-1v1h-1v2h-1v-2h-1v-4h1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 4 feathered cap '%253Cg%253E%253Cpath d=\'M7,2h5v1h1v1h1v1h2v1h-9z\' fill=\'var(--dm20)\'/%253E%253Cpath d=\'M5,1h3v1h1v1h1v1h1v1h-2v-1h-2v-1h-2z\' fill=\'var(--dm38)\'/%253E%253Cpath d=\'M7,1h1v1h-1zM5,2h1v1h-1zM7,3h2v1h1v1h-1v-1h-2z\' fill=\'var(--dm37)\'/%253E%253Cpath d=\'M5,1h1v1h1v1h1v1h1v1h2v-1h-1v-1h-1v-1h1v1h1v1h3v1h-2v1h1v1h-4v2h-1v-3h-1v-3h-2z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 5 enchanted crown '%253Cg%253E%253Cpath d=\'M9,1h1v2h1v-2h1v2h1v-2h1v4h-7v-3h1v1h1z\' fill=\'var(--dm12)\'/%253E%253Cpath d=\'M9,1h1v1h-1zM13,1h1v1h-1zM7,3h1v1h1v1h2v1h-4zM13,4h1v1h-1z\' fill=\'var(--dm11)\'/%253E%253Cpath d=\'M11,1h1v1h-1zM13,3h1v2h-1v1h-2v1h-2v1h-1v-2h-1v-2h1v1h4v-1h1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 6 bronze helm '%253Cg%253E%253Cpath d=\'M8,2h5v1h1v5h-1v-3h-4v3h-2v-5h1z\' fill=\'var(--dm41)\'/%253E%253Cpath d=\'M9,2h3v1h1v1h-1v1h-2v-1h-2v-1h1z\' fill=\'var(--dm11)\'/%253E%253Cpath d=\'M9,2h3v1h-3v1h-1v2h1v-1h1v-1h1v1h-1v2h-1v1h1v1h-2v-1h-1v-4h1v-1h1zM13,4h1v4h-1v1h-1v-1h1v-1h-1v-2h1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 7 assassin's mask '%253Cg%253E%253Cpath d=\'M9,3h3v1h1v1h-4v1h2v-1h1v1h1v1h-3v1h2v-1h1v2h-5v-5h1z\' fill=\'var(--dm34)\'/%253E%253Cpath d=\'M9,3h1v1h3v3h-1v-1h-2v1h-1v1h1v1h-2v-5h1zM12,8h1v1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 8 iron helm '%253Cg%253E%253Cpath d=\'M8,2h5v1h1v6h-2v-2h1v-3h-1v1h-1v-1h-2v3h1v2h-3v-6h1z\' fill=\'var(--dm37)\'/%253E%253Cpath d=\'M9,2h4v1h1v1h-1v-1h-1v1h-1v-1h-2z\' fill=\'var(--dm38)\'/%253E%253Cpath d=\'M8,2h2v2h-2v1h1v-1h2v1h1v-1h1v1h1v1h-1v1h-1v-1h-1v-1h-1v2h-1v-1h-1v1h1v1h4v-1h1v2h-7v-6h1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 9 soul shroud '%253Cg%253E%253Cpath d=\'M7,2h6v1h1v2h-4v1h3v-1h1v3h-1v2h-1v1h-1v-1h-1v-1h-2v-1h-1v-1h1v-4h-1z\' fill=\'var(--dm32)\'/%253E%253Cpath d=\'M10,3h3v1h1v1h-5v-1h1zM10,6h4v1h-1v1h-1v1h-1v-2h-1z\' fill=\'var(--dm10)\'/%253E%253Cpath d=\'M7,2h3v1h1v1h-1v2h-1v-1h-1v-2h-1zM12,2h1v1h1v1h-1v-1h-1zM7,7h2v1h1v1h1v1h1v-1h1v1h-1v1h-1v-1h-1v-1h-2v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 10 misty hood '%253Cg%253E%253Cpath d=\'M9,2h4v1h1v6h-1v2h-1v-2h1v-4h-1v1h-1v2h-1v3h-1v-1h-1v-1h-1v-4h1v-2h1z\' fill=\'var(--dm35)\'/%253E%253Cpath d=\'M11,2h1v1h1v1h-1v-1h-1v1h1v1h-1v1h-1v1h-2v-1h1v-2h1v-1h1z\' fill=\'var(--dm37)\'/%253E%253Cpath d=\'M9,2h1v1h1v1h-1v2h-1v-1h-1v1h-1v-1h1v-2h1M12,2h1v1h1v1h-1v-1h-1zM12,5h2v1h-2v1h-1v-1h1zM7,7h2v1h4v-1h1v2h-3v1h-1v1h-1v-2h-2zM12,10h1v1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 11 genesis helm '%253Cg%253E%253Cpath d=\'M7,2h5v1h1v1h1v4h-1v-2h-3v2h-3z\' fill=\'var(--dm49)\'/%253E%253Cpath d=\'M4,1h3v1h1v2h1v1h-1v-1h-1v-1h-1v1h-1v1h-1v1h-1v-1h1v-1h1v-2h-1v1h-1v1h-1v-1h1v-1h1zM16,1h2v1h1v1h-1v-1h-1v2h1v1h-1v-1h-1v-1h-1v2h-1v-2h1v-1h1z\' fill=\'var(--dm52)\'/%253E%253Cpath d=\'M6,2h4v1h1v1h-1v2h1v-1h2v-1h2v1h-1v3h-1v1h-1v-1h1v-1h-3v-1h-3v-3h-1v1h-1v1h-1v1h-1v-1h1v-1h1v-1h1zM16,2h1v2h1v1h-1v-1h-1zM7,7h2v1h1v1h-2v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 12 ranger cap '%253Cg%253E%253Cpath d=\'M8,2h4v1h1v1h1v1h1v1h-9v-1h1v-2h1z\' fill=\'var(--dm19)\'/%253E%253Cpath d=\'M7,4h7v1h-7z\' fill=\'var(--dm48)\'/%253E%253Cpath d=\'M8,2h1v1h1v2h1v1h2v1h-3v1h-1v1h-1v-3h-2v-1h1v-2h1zM11,2h1v1h1v1h1v1h1v1h-1v-1h-1v-1h-1v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 13 ancient mask '%253Cg%253E%253Cpath d=\'M10,2h2v1h1v2h-4v1h2v-1h1v1h1v4h-1v1h-2v-1h-1v-1h-1v-6h2z\' fill=\'var(--dm41)\'/%253E%253Cpath d=\'M9,4h2v1h-2zM12,4h1v1h-1zM11,6h1v3h-2v-1h1z\' fill=\'var(--dm40)\'/%253E%253Cpath d=\'M12,3h1v1h-1v1h1v1h-5v-1h3v-1h1zM8,7h1v1h1v-1h3v3h-1v1h-2v-1h-1v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 14 charmed headband '%253Cg%253E%253Cpath d=\'M8,4h5v2h-6v1h-2v-1h1v-1h2z\' fill=\'var(--dm2)\'/%253E%253Cpath d=\'M5,4h1v1h-1zM7,5h1v1h-1v1h-1v-1h1zM11,5h1v1h-1z\' fill=\'var(--dm1)\'/%253E%253Cpath d=\'M11,3h1v2h-1z\' fill=\'var(--dm31)\'/%253E%253Cpath d=\'M8,4h1v1h1v1h-3v1h-2v-1h2v-1h1zM11,4h2v2h-2z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 15 skull helm '%253Cg%253E%253Cpath d=\'M8,2h5v1h1v2h-5v2h2v-2h1v2h1v-2h1v4h-1v1h-3v-1h-2v-1h-1v-5h1z\' fill=\'var(--dm38)\'/%253E%253Cpath d=\'M10,2h2v1h1v1h-1v3h-1v1h1v-1h2v1h-1v2h-2v-2h-1v-1h1v-3h-2v1h-1v-2h2z\' fill=\'white\'/%253E%253Cpath d=\'M8,2h1v2h1v1h1v1h-2v-2h-2v-1h1zM12,4h2v2h-2zM7,5h1v2h1v1h1v1h1v1h-1v-1h-2v-1h-1zM13,7h1v2h-1v2h-1v-2h1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 16 phoenix helm '%253Cg%253E%253Cpath d=\'M9,1h4v1h1v6h-1v-3h-4v3h-2v-6h2z\' fill=\'var(--dm41)\'/%253E%253Cpath d=\'M2,1h5v1h1v1h1v-1h3v-1h1v1h-1v1h1v-1h1v1h-1v1h-1v1h-2v-2h-1v2h-2v-1h-1v-1h-2v-1h-2z\' fill=\'var(--dm11)\'/%253E%253Cpath d=\'M9,1h2v1h-2v1h-1v1h4v1h1v-1h1v2h-6v1h1v1h1v1h-2v-1h-1v-4h-1v-1h-2v-1h3v1h1v-1h1zM13,7h1v1h-1v1h-1v-1h1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E' // END HEADGEAR ]; return GEAR[smAssetId]; } /** * @notice render an armor asset * @param smAssetId the small asset id of the gear item * @return string of svg */ function renderArmor(uint256 smAssetId) external pure returns (string memory) { string[5] memory GEAR = [ // START ARMOR // 0 standard armor '%253Cg%253E%253Cg%253E%253Cpath d=\'M12,9h1v1h1v2h1v3h-4v-3h-1v-2h1z\' fill=\'var(--dmpa2)\'/%253E%253Cpath d=\'M12,9h1v1h1v2h1v3h-4v-3h-1v-2h1z\' fill=\'var(--dmb35)\'/%253E%253Cpath d=\'M12,9h1v1h1v2h1v1h-1v2h-1v-2h1v-1h-1v-2h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M8,9h4v1h1v5h-6v-5h1z\' fill=\'var(--dmpa1)\'/%253E%253Cpath d=\'M9,10h4v1h-1v1h-1v2h-1v-3h-1z\' fill=\'var(--dmpa4)\'/%253E%253Cpath d=\'M9,9h1v2h-1v3h1v1h-3v-3h1v-1h1zM11,9h1v1h1v5h-2v-1h1v-4h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M6,9h3v2h-1v1h-1v1h-1v1h-1v-1h-1v-2h1v-1h1z\' fill=\'var(--dmpa2)\'/%253E%253Cpath d=\'M7,9h2v2h-1v1h-1v1h-1v-1h1v-1h1v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M3,12h2v1h1v2h1v1h-4zM15,13h2v3h-3v-2h1z\' fill=\'var(--dmpa3)\'/%253E%253Cpath d=\'M3,13h1v3h-1zM5,13h1v1h-1zM14,14h1v1h1v1h-2z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253C/g%253E', // 1 cape '%253Cg%253E%253Cg%253E%253Cpath d=\'M12,9h1v1h1v2h1v3h-4v-3h-1v-2h1z\' fill=\'var(--dmpa2)\'/%253E%253Cpath d=\'M12,9h1v1h1v2h1v3h-4v-3h-1v-2h1z\' fill=\'var(--dmb35)\'/%253E%253Cpath d=\'M12,9h1v1h1v2h1v1h-1v2h-1v-2h1v-1h-1v-2h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M8,9h4v1h1v5h-6v-5h1z\' fill=\'var(--dmpa1)\'/%253E%253Cpath d=\'M8,9h5v2h-1v1h-1v1h-2v1h-2v-1h1v-1h1v-2h-1z\' fill=\'var(--dmpa4)\'/%253E%253Cpath d=\'M12,9h1v1h-1zM7,13h1v1h-1z\' fill=\'var(--dmb4)\'/%253E%253Cpath d=\'M9,9h1v2h-1v3h1v1h-3v-3h1v-1h1zM11,9h1v1h1v5h-2v-1h1v-4h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M6,9h3v2h-1v1h-1v1h-1v1h-1v-1h-1v-2h1v-1h1z\' fill=\'var(--dmpa2)\'/%253E%253Cpath d=\'M7,9h2v2h-1v1h-1v1h-1v-1h1v-1h1v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M3,12h2v1h1v2h1v1h-4zM15,13h2v3h-3v-2h1z\' fill=\'var(--dmpa3)\'/%253E%253Cpath d=\'M3,13h1v3h-1zM5,13h1v1h-1zM14,14h1v1h1v1h-2z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253C/g%253E', // 2 skull '%253Cg%253E%253Cg%253E%253Cpath d=\'M12,9h1v1h1v2h1v3h-4v-3h-1v-2h1z\' fill=\'var(--dm37)\'/%253E%253Cpath d=\'M12,9h1v1h1v2h1v3h-4v-3h-1v-2h1z\' fill=\'var(--dmb35)\'/%253E%253Cpath d=\'M12,9h1v1h1v2h1v1h-1v2h-1v-2h1v-1h-1v-2h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M8,9h4v1h1v5h-6v-5h1z\' fill=\'var(--dm38)\'/%253E%253Cpath d=\'M9,10h4v1h-1v1h-1v2h-1v-3h-1z\' fill=\'white\'/%253E%253Cpath d=\'M9,10h2v2h1v-2h1v2h-1v1h-1v-1h-2z\' fill=\'var(--dm36)\'/%253E%253Cpath d=\'M9,9h1v2h-1v3h1v1h-3v-3h1v-1h1zM11,9h1v1h1v5h-2v-1h1v-4h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M6,9h3v2h-1v1h-1v1h-1v1h-1v-1h-1v-2h1v-1h1z\' fill=\'var(--dm38)\'/%253E%253Cpath d=\'M7,9h2v2h-1v1h-1v1h-1v-1h1v-1h1v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M3,12h2v1h1v2h1v1h-4zM15,13h2v3h-3v-2h1z\' fill=\'white\'/%253E%253Cpath d=\'M3,13h1v3h-1zM5,13h1v1h-1zM14,14h1v1h1v1h-2z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253C/g%253E', // 3 chain '%253Cg%253E%253Cg%253E%253Cpath d=\'M12,9h1v1h1v2h1v3h-4v-3h-1v-2h1z\' fill=\'var(--dmpa2)\'/%253E%253Cpath d=\'M12,9h1v1h1v2h1v3h-4v-3h-1v-2h1z\' fill=\'var(--dmb35)\'/%253E%253Cpath d=\'M12,9h1v1h1v2h1v1h-1v2h-1v-2h1v-1h-1v-2h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M8,9h4v1h1v5h-6v-5h1z\' fill=\'var(--dmpa1)\'/%253E%253Cpath d=\'M8,9h4v1h1v5h-6v-5h1z\' fill=\'var(--dmpa4)\'/%253E%253Cpath d=\'M9,9h1v2h-1v3h1v1h-3v-3h1v-1h1zM11,9h1v1h1v5h-2v-1h1v-4h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M6,9h3v2h-1v1h-1v1h-1v1h-1v-1h-1v-2h1v-1h1z\' fill=\'var(--dmpa2)\'/%253E%253Cpath d=\'M7,9h2v2h-1v1h-1v1h-1v-1h1v-1h1v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M3,12h2v1h1v2h1v1h-4zM15,13h2v3h-3v-2h1z\' fill=\'var(--dmpa3)\'/%253E%253Cpath d=\'M3,13h1v3h-1zM5,13h1v1h-1zM14,14h1v1h1v1h-2z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253C/g%253E', // 4 shimmering '%253Cg%253E%253Cg%253E%253Cpath d=\'M12,9h1v1h1v2h1v3h-4v-3h-1v-2h1z\' fill=\'var(--dm38)\'/%253E%253Cpath d=\'M14,13h1v1h-1z\' fill=\'var(--dm11)\'/%253E%253Cpath d=\'M12,9h1v1h1v2h1v3h-4v-3h-1v-2h1z\' fill=\'var(--dmb35)\'/%253E%253Cpath d=\'M12,9h1v1h1v2h1v1h-1v2h-1v-2h1v-1h-1v-2h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M8,9h4v1h1v5h-6v-5h1z\' fill=\'var(--dm36)\'/%253E%253Cpath d=\'M8,10h1v1h-1zM10,10h1v1h-1zM12,10h1v1h-1zM8,12h1v1h-1zM10,12h1v1h-1zM12,12h1v1h-1zM8,14h1v1h-1zM10,14h1v1h-1zM12,14h1v1h-1z\' fill=\'var(--dm11)\'/%253E%253Cpath d=\'M9,9h1v2h-1v3h1v1h-3v-3h1v-1h1zM11,9h1v1h1v5h-2v-1h1v-4h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M6,9h3v2h-1v1h-1v1h-1v1h-1v-1h-1v-2h1v-1h1z\' fill=\'var(--dm38)\'/%253E%253Cpath d=\'M8,9h1v1h-1zM6,10h1v1h-1zM5,12h1v1h-1z\' fill=\'var(--dm11)\'/%253E%253Cpath d=\'M7,9h2v2h-1v1h-1v1h-1v-1h1v-1h1v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M3,12h2v1h1v2h1v1h-4zM15,13h2v3h-3v-2h1z\' fill=\'white\'/%253E%253Cpath d=\'M3,13h1v3h-1zM5,13h1v1h-1zM14,14h1v1h1v1h-2z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253C/g%253E' // END ARMOR ]; return GEAR[smAssetId]; } /** * @notice render a pants asset * @param smAssetId the small asset id of the gear item * @return string of svg */ function renderPants(uint256 smAssetId) external pure returns (string memory) { string[4] memory GEAR = [ // START PANTS // 0 standard '%253Cg%253E%253Cg%253E%253Cpath d=\'M7,15h6v1h1v2h-3v-1h-2v1h-3v-2h1z\' fill=\'var(--dmpp1)\'/%253E%253Cpath d=\'M7,15h1v1h-1v2h-1v-2h1zM9,16h3v1h1v1h-2v-1h-2v1h-1v-1h1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M6,17h3v2h-1v1h-1v1h-3v-1h1v-2h1zM13,17h2v1h1v3h-3v-2h-1v-1h1z\' fill=\'var(--dmpp2)\'/%253E%253Cpath d=\'M6,17h1v1h1v-1h1v2h-1v1h-1v-2h-1v1h-1v-1h1zM14,17h1v1h1v1h-1v-1h-1zM12,18h1v1h1v1h-1v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253C/g%253E', // 1 shine '%253Cg%253E%253Cg%253E%253Cpath d=\'M7,15h6v1h1v2h-3v-1h-2v1h-3v-2h1z\' fill=\'var(--dmpp1)\'/%253E%253Cpath d=\'M7,15h1v1h-1v2h-1v-2h1zM9,16h3v1h1v1h-2v-1h-2v1h-1v-1h1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M6,17h3v2h-1v1h-1v1h-3v-1h1v-2h1zM13,17h2v1h1v3h-3v-2h-1v-1h1z\' fill=\'var(--dmpp2)\'/%253E%253Cpath d=\'M7,17h1v1h-1v1h-1v-1h1zM13,17h1v1h1v1h-1v-1h-1z\' fill=\'var(--dmpp3)\'/%253E%253Cpath d=\'M6,17h1v1h1v-1h1v2h-1v1h-1v-2h-1v1h-1v-1h1zM14,17h1v1h1v1h-1v-1h-1zM12,18h1v1h1v1h-1v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253C/g%253E', // 2 ancient '%253Cg%253E%253Cg%253E%253Cpath d=\'M7,15h6v1h1v2h-3v-1h-2v1h-3v-2h1z\' fill=\'var(--dm44)\'/%253E%253Cpath d=\'M7,15h1v1h-1v2h-1v-2h1zM9,16h3v1h1v1h-2v-1h-2v1h-1v-1h1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M6,17h3v2h-1v1h-1v1h-3v-1h1v-2h1zM13,17h2v1h1v3h-3v-2h-1v-1h1z\' fill=\'var(--dm41)\'/%253E%253Cpath d=\'M14,17h1v1h1v2h-1v-2h-1zM5,18h1v2h-1zM8,18h1v1h-1v1h-1v-1h1z\' fill=\'var(--dm48)\'/%253E%253Cpath d=\'M6,17h1v1h1v-1h1v2h-1v1h-1v-2h-1v1h-1v-1h1zM14,17h1v1h1v1h-1v-1h-1zM12,18h1v1h1v1h-1v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253C/g%253E', // 3 chain '%253Cg%253E%253Cg%253E%253Cpath d=\'M7,15h6v1h1v2h-3v-1h-2v1h-3v-2h1z\' fill=\'var(--dm48)\'/%253E%253Cpath d=\'M12,15h1v1h1v2h-3v-1h-2v1h-3v-2h6z\' fill=\'url(%2523ch1)\'/%253E%253Cpath d=\'M7,15h1v1h-1v2h-1v-2h1zM9,16h3v1h1v1h-2v-1h-2v1h-1v-1h1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M6,17h3v2h-1v1h-1v1h-3v-1h1v-2h1zM13,17h2v1h1v3h-3v-2h-1v-1h1z\' fill=\'var(--dm48)\'/%253E%253Cpath d=\'M6,17h3v2h-1v1h-3v-2h1zM13,17h2v1h1v2h-3v-1h-1v-1h1z\' fill=\'url(%2523ch1)\'/%253E%253Cpath d=\'M6,17h1v1h1v-1h1v2h-1v1h-1v-2h-1v1h-1v-1h1zM14,17h1v1h1v1h-1v-1h-1zM12,18h1v1h1v1h-1v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253C/g%253E' // END PANTS ]; return GEAR[smAssetId]; } /** * @notice render a footwear asset * @param smAssetId the small asset id of the gear item * @return string of svg */ function renderFootwear(uint256 smAssetId) external pure returns (string memory) { string[7] memory GEAR = [ // START FOOTWEAR // 0 tiny '%253Cg%253E%253Cpath d=\'M4,20h3v1h1v1h-4zM13,20h3v1h1v1h-4z\' fill=\'var(--dmpf1)\'/%253E%253Cpath d=\'M4,20h1v1h1v1h-2zM13,20h1v1h2v1h-3z\' fill=\'var(--dmpf2)\'/%253E%253Cpath d=\'M6,20h1v1h1v1h-1v-1h-1v1h-2v-1h2zM13,21h2v1h-2z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 1 medium '%253Cg%253E%253Cpath d=\'M4,19h3v2h1v1h-5v-2h1zM12,19h4v1h1v1h1v1h-6z\' fill=\'var(--dmpf1)\'/%253E%253Cpath d=\'M5,19h1v1h1v2h-2zM13,19h2v1h1v1h1v1h-2v-1h-1v-1h-1z\' fill=\'var(--dmpf2)\'/%253E%253Cpath d=\'M5,21h2v1h-2zM15,21h2v1h-2z\' fill=\'var(--dmpf3)\'/%253E%253Cpath d=\'M4,19h1v1h-1v2h-1v-2h1zM6,19h1v2h1v1h-1v-1h-1zM12,19h2v2h2v-1h-1v-1h1v1h1v1h1v1h-1v-1h-1v1h-4z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 2 medium_tongue '%253Cg%253E%253Cg%253E%253Cpath d=\'M6,18h3v1h-1v1h-4v-1h2zM13,18h3v2h-4v-1h1z\' fill=\'var(--dmpf1)\'/%253E%253Cpath d=\'M6,19h1v1h-1zM15,19h1v1h-1z\' fill=\'var(--dmpf2)\'/%253E%253Cpath d=\'M8,18h1v1h-1v1h-1v-1h1zM13,18h1v2h-2v-1h1zM15,18h1v2h-1zM4,19h1v1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M3,20h4v1h1v1h-5zM12,20h6v2h-6z\' fill=\'var(--dmpf1)\'/%253E%253Cpath d=\'M5,20h2v2h-1v-1h-1zM14,20h4v1h-1v1h-1v-1h-2z\' fill=\'var(--dmpf2)\'/%253E%253Cpath d=\'M3,20h1v1h2v-1h1v1h1v1h-1v-1h-1v1h-3zM12,20h1v1h2v1h-3zM17,20h1v2h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253C/g%253E', // 3 lightfoot '%253Cg%253E%253Cpath d=\'M4,20h3v1h1v1h-5v-1h1zM12,20h5v1h1v1h-6z\' fill=\'var(--dm35)\'/%253E%253Cpath d=\'M5,20h2v2h-1v-1h-1zM14,20h3v2h-1v-1h-2z\' fill=\'var(--dm37)\'/%253E%253Cpath d=\'M6,20h1v1h1v1h-1v-1h-1v1h-3v-1h3zM12,20h1v1h2v1h-3zM16,20h1v1h1v1h-1v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 4 jaguarpaw '%253Cg%253E%253Cpath d=\'M4,19h5v1h-1v2h-5v-2h1zM12,19h4v1h1v2h-5z\' fill=\'var(--dm11)\'/%253E%253Cpath d=\'M6,19h2v1h-1v1h1v1h-3v-2h1zM13,19h2v1h1v1h1v1h-3v-2h-1z\' fill=\'var(--dm12)\'/%253E%253Cpath d=\'M4,19h1v1h-1v1h4v1h-5v-2h1zM15,19h1v1h1v2h-5v-2h1v1h3v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253Cpath d=\'M6,21h1v1h-1zM8,21h1v1h-1zM15,21h1v1h-1zM17,21h1v1h-1z\' fill=\'white\'/%253E%253C/g%253E', // 5 phoenix '%253Cg%253E%253Cpath d=\'M2,19h5v2h1v1h-5v-2h-1zM10,19h6v1h1v1h1v1h-6v-1h-1v-1h-1z\' fill=\'var(--dm41)\'/%253E%253Cpath d=\'M3,19h1v1h1v-1h1v1h1v2h-2v-1h-1v-1h-1zM11,19h2v1h1v-1h1v1h1v1h1v1h-2v-2h-1v1h-2v-1h-1z\' fill=\'var(--dm11)\'/%253E%253Cpath d=\'M5,19h2v2h1v1h-1v-1h-1v-1h-1v1h1v1h-3v-1h1v-1h1zM10,19h1v1h2v1h3v-1h-2v-1h2v1h1v1h1v1h-1v-1h-1v1h-4v-1h-1v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E', // 6 heavy '%253Cg%253E%253Cg%253E%253Cpath d=\'M6,18h3v1h-1v1h-4v-1h2zM13,18h3v1h1v1h-5v-1h1z\' fill=\'var(--dm52)\'/%253E%253Cpath d=\'M6,19h1v1h-1zM15,19h1v1h-1z\' fill=\'var(--dm49)\'/%253E%253Cpath d=\'M8,18h1v1h-1v1h-1v-1h1zM13,18h1v2h-2v-1h1zM15,18h1v2h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M3,20h6v2h-6zM12,20h7v2h-7z\' fill=\'var(--dm52)\'/%253E%253Cpath d=\'M5,20h3v1h-1v1h-1v-1h-1zM14,20h4v1h-1v1h-1v-1h-2z\' fill=\'var(--dm49)\'/%253E%253Cpath d=\'M3,20h1v1h5v1h-6zM12,20h1v1h2v1h-3zM17,20h1v1h1v1h-2z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253C/g%253E' // END FOOTWEAR ]; return GEAR[smAssetId]; } /** * @notice render a cape asset * @param smAssetId the small asset id of the gear item * @return string of svg */ function renderCape(uint256 smAssetId) external pure returns (string memory) { if(smAssetId == 1){ return '%253Cg%253E%253Cpath d=\'M8,16h4v3h-1v1h-1v1h-1v-2h-1z\' fill=\'var(--dmpa4)\'/%253E%253Cpath d=\'M8,16h4v3h-1v1h-1v1h-1v-2h-1z\' fill=\'var(--dmb4)\'/%253E%253C/g%253E'; } else if (smAssetId == 4){ return '%253Cg%253E%253Cpath d=\'M8,16h4v3h-1v1h-1v1h-1v-2h-1z\' fill=\'var(--dm8)\'/%253E%253Cpath d=\'M8,16h4v3h-1v1h-1v1h-1v-2h-1z\' fill=\'var(--dmb4)\'/%253E%253C/g%253E'; } else { return '%253Cg%253E%253C/g%253E'; } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; library AssetRenderer5 { /** * @notice render a weapon asset * @param lgAssetId the large asset id of the gear item * @return string of base64-encoded image */ function renderWeapon(uint256 lgAssetId) external pure returns (string memory) { string[29] memory WEAPONS = [ // START WEAPONS // 0 brass knuckles 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAANhJREFUeNrs27sNwyAQgGEu8gS0NLCXx2MGWtcuPAEbsIQTpBg5rw6InfzXICgOfUJcdSfruqpfj4v6gwAJEiRIkCBBggQJEiRIkCBBggQJEiRIkCBBggQJEiRIkCBBggQJEiRIkCBBggR52hhqJhvH8aFD2HsvR0BKrc7lDHTOlb21Vk3TdAjs0CJpBhpjMvzlhb8Blpo96HvMBnyOG7I7VFo12m/gd9jeUGk9TbDHxhjL+TzP3aDSa2QiY/fQlJJalkWFEOSUhefDX5T7Wqqw1rrL3VcBBgAXRk2XfNaHnAAAAABJRU5ErkJggg==', // 1 pickaxe 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAX9JREFUeNrs2jFLw0AUB/B3V0ulUJG6FYdayJrBwVk/R/Jh/Ca65DOELtq5g4UMXQrSRRwUFcWhg5y+KwchLfRaB/PO/4OjR0tKfnnvLtdelDGGQg9N/yCABBJIIIEEEkgggQQSSCCBBBJIIIEEEkgggQQSSCCBBLL+sbfLQWma2k3NLMuUhP1NvQswjmPbF7OByyfq25IkMXmeG37d9ti/bHqbDP40KooizInHATkYKWUseiOrwKBvIWWgtCdGtG8Wg18MuCy68RgMUvJs+uvFgMQnuLRvFqWWqtfaNehyZRy35nRoG8f5SccEgazeNjrHmk7P2hQ9jqh/2KKLwYHhJr5cXYlyBj+40yPqRg3qUpv6sxbNXxfkoLf370r0mJy/LZad8TKjUW9fJHZloc3lWp5F+XOGcKm68mWsi5fZl8W6C1JH7ApSqfXn6CadTdiruycZyPJ7VfQ67NFnky5vHlRdFwsbfxf6ZPZ68my/p3qBxCBDCPzvCqSg+BZgALDGXYBnH6DbAAAAAElFTkSuQmCC', // 2 shadowblades 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAb5JREFUeNrsmTGOgzAQRTHiAjQgUdOGLieg5QZ03C03oOUEdKShSB0pnAGJzSA5GlkGAizgZf80FgmW5/l/2wOIruuss4dt/YMAJCABCUhAAhKQgAQkIAEJSEACEpCABCQgAQlIQAISkIAEJCABCci9wjlqYCFE314ul/5T9/1+F1t99XZMmOk3KDVEKE5lV1JNKvd6vXrQKIq6065J3/c/is4Fpfun+hgBSUpy684F9TxvtI9RSlJcr9dF/ccmxzgll6gp+w/1M+6cLMtytprcCTrQUxQD3Am6CTIWcs2Rova1TVTjt+2O2nVtDNmtqqrJ8o3UeNezs5yg24BoLGdLQDqk+Q4obSQH5/fwBP+EkjL5oig+isVx3NF6ociybLM6dVe7ckB+TUV5mqZdEARW27aDKsoJWXJWqnbfZOOhZ0Pd04aM2+0mns+ndndV2zlLYnclVTB+rSYnNw3ZPh6PVSruUgx8+4TfNI0WNAzD/j/uiCkVVQfkeX7cOcmTU622VMkpJxhXDLiuO+kI3VpUncAtbB+l4ljUdT3b7qoTaGeVdt9dSUpCTU7+niTJJ/mx9cjfCIzVwNIJPwIMANQO9dNShroWAAAAAElFTkSuQmCC', // 3 kusarigama 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAhJJREFUeNrsmr9PAjEUx9vzTESCRt2MCyZswmCMMy4aV1f4A5xcWRxd/A/8A2B1cJFNJwcHB1YSdVA2jZH4K0Yr77iSR3MHeCA0+H1J0165Nnz6fe+1l1QqpcS4myP+gQESkIAEJCABCUhAAhKQgAQkIAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhAjq25Nv0ZKaXQV26orU335fP50Ps4pVJJ8netheSwHFDDNepOw5Q/VpqgctSXlcLU05bL5VQXuDYrFostZfW8I1eSL7K54KRgL4CVSqXVzmQyXqHptKpWuuvG8oxHu727HwrTrd9fHJpHujYCpldiIrU4Jd58AFLGBOHPOulwB+G/S5suEJJ73l+ciJ3NOe/5sfolYlt7PYFxDjNxuTYBkosdNiAJbj41IR7in2KJwXUCM/s5qHXuSnF4enQg0vGmyx432uc3ddkNrFNCs+rEQ4pp1ep3314dm3fEbwGtPtb5qd9T7vbpo6ns2qzIJhOqn9zh9htHbBOWg1CS29Xlq1hdn25Tc6hKEiCtPCULqoNOK1GVJNW0mtXau6em3juHBqkzIa08HaMKhYIcVEya8RcUm3/urlpBggvYhPtWkoOSmtmkUIma01Lz7PpZDkVJ7la8DDomuZrktlHVdGxRUbu/Oa+ZaaPEphNVxbBPoyifWuVyWfGFoz5dtC28TLaNCStB9iPAAAMvFtd8U1D+AAAAAElFTkSuQmCC', // 4 phoenix blade 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAcBJREFUeNrs2rFOwzAQBuC4ilQmwtwZxk70JcJbMLDyPoh3YO1LwMQIE0P3bjCZ/lEuuFe7juUmRPCf1CFRYvvz2ZdUirHWFn89ZsU/CCKJJJJIIokkkkgiiSSSSCKJJJJIIokkkkgiiSSSSCKJJJJIIokkkkgiiZx4lCkX36wuol82rV+2ZmofQJUpsHpVdefvlj+Qx1fj3mJ390wKHRyA4ABzQSkB/Pp5++tgb6cAujiVqV7hy7SAx8YedCbAU8UUsN2eNMYU9XVlLxfz4m3z2buBq8VZdMkegqumj7qorEHH2MgDYjukAFPDNyEhuIAb7HK+O26us+0kD5bVver6vvlKujk0KRqu0XtYldUhoF2j7apJCmRfYzFRPnwou25xw17FPtXX5ML3kLHGfBMh0GOZjWFj0FzkLKUhXOP+ZB/jh4Ehi3rJ62PfHnaXLyq7O3GDvgz0eRN6uj1vBnj/8GFiyzgno7mZLHNu1kBn6TfnUExCWMmoi0V7gEpBQpO+PToqUgaqZxrHcMoAgRWoLkxoIwbNrbplMUIAK9BQVjXUfcS0z1KTXXhOHVKcXOix53CoIEkx6vM3LxTfAgwAuBAia6t2+pUAAAAASUVORK5CYII=', // 5 none '', // 6 rusty sword 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAASdJREFUeNrsmosJhDAQRN0jXViNdWh5WofVWEfOPVS8nJII52cnExBBEHy+bDKJive+QG+vIoNGSEISkpCEJCQhCUlIQhKSkIQ8F7JpGi8i+CbruoYDdeGFqqr0pKBJpBa2T9zWxbHbfp6/67ooaPgungi9O/AoqHZd+NEVBTQ6hSCAbkIOwwAFumsSCfQLUkfTvu/hQA/HOougP5Axm3NgsASa7yokZrMsS1M2szAp66wZ5lA1NQX2xWA4zajxlIx7Z7blzgBKbdIkik2aRLFJkyg2aTJsbduatOnujlyP7K4WazOLmnRHb9AuPX1CWFYoanO9QpltFom78DR5h0mLNmkSxSYTD8q8yZo8YjO1NsdDaPKEJv8M5fqLTMo+ra5mroR8CzAAlOHbWwh1ahQAAAAASUVORK5CYII=', // 7 bronze sword 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAVVJREFUeNrsmEEOwUAUhmdkdhK1cgNLKy6hDuAETsGSUzgBe1yitbHTE7BSiZ1kGDJoaVTS4r3+L5k0bSZNvn7zOm+e1FoL7lESBQhAAhKQgAQkIAEJSEACEpCABGS+kIOOo6WU/E323Qo7UBV/0G2VzcWApiKl0D6JmFxurlwD17kYTfMC8y0eB4nlOl1/Dkry7zpe8QJN3EI4gb6E3IZHVqCJJi3obQ8lDBqBXPih9INDBNTapAz6cVlHEfQJ8p1NWzBQAi3uKeSdzXpNkbJZCJPyscCO157tpqOb9fLtvuYo0Wvc5wfbo5h4BzGa71MXrb8o6NEZ4JKbMMnFJkxysQmTXGzCZDzm3o6kTfXrkusvlyvF3EROJp0iqNmESS42YZKLTZjksm8WwqTK4iXGpklT29m72rx39qxNM+c8JEzmEDLLotxtVVP1aYez8Ks2TwIMANdQ/b4gmemwAAAAAElFTkSuQmCC', // 8 holy sword 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAW1JREFUeNrsmc1qwkAURu8tWQgF3RW66K76BH2Kui6Ci76HtVAFf96ji0Lpppv6FN24VXfduVMQWhCmTnWCiRVnoGrvzTcQQkISODlzM99M2BhD2tsJZaABEpCABCQgAQlIQAISkIAEJCD3C9m4Y8PM+k0+1EgdaJQ+Ub352VlQL1IJyycJk/N+ftlta0ujPg+w72J9E9Fdv17Pg0FFfl0/Hy9UgW4dQjSB/go5HM9VgW416UDjMVQwaAKy3Zvy8/ssAepsSgYNjnUSQTcgd9l0gUESaHZnIbtsli5l2cyESV4P2OnsWb/Om8rVaXxcPIsod/sRHw9GRE8vRM0ueYfWYwR6rAxoqU2Y1GITJrXYhEktNmEy3VpvE5E2o2NHrn/ZXSXWZiZqMgq9wXbp1S+EeIZibRYXNt0Mxdm014TMUGDykCYl2oRJLTaReLSMm6jJEJu+tbnYGCb30PgvQ/l9ueC1TtvomIPa/BZgAE9a8+L8u4WmAAAAAElFTkSuQmCC', // 9 bronze daggers 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAaNJREFUeNrsmrFuwjAURW2rUtjSmbGCkanMXRFVf6M/wy/wGwj2zu3Ukaojc7vB5PISHB4IWttxXlS4liIYIj8f3+PElqKtterSm1FX0AAJSEACEpCABCQgAQlIQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEpCABOR1Qt743vg4vK0+E1m8fev/9NVIUJK9blZc4/vccuiLSdK1pzulZiqr0p2/fmmpwfKJDanrnSQp+rHaqNlnCToZlalKJ+psorq+tYN05aAvy80BqNZigRaTzGGTQZ570DhQWqdNw5GiMTYFJUmgPM1jUIlEY2yq9Z6kIqcSlVTXxyaTYjYlW4xNpokHgmSaPjYlhXzoZ2KJhthUG/K4SL/baXV3c8omk6JTvjaeB1bsleJrk0mhC4FO33Vr6f1lUzAkPd3cxYtQgm0p+5tNpKxJVYQnSUXGw7zxfa2vTUGnkHODLmdxraZqn+Byta51cvDdYm77r8YwGR3aRBMQddQiDVwnXNFd+f3fQbad2U4F6wo2qSwl6cZU/ubFoIIhQ9ebuz8VZIxNPwIMAM/39ASfB+UaAAAAAElFTkSuQmCC', // 10 holy daggers 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAc1JREFUeNrsmjFOwzAUhp+jiHaiWzbGHoOIqUO4A1fgAJSpcBHuUCRYisIxOrJ1I1PLYvJcObhRC3biOKL9nxQpkaz8+fx+Pz9LEVJKOvaI6AQCkIAEJCABCUhAAhKQgAQkIAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhAniZkbDtwej2qfhN5fC7Ef/prJHYZnI6H25uMZAlND/NPcXSQHGeTFaWUVNkNCWq6yUXXek2yRfPlmr5eEwU6ma1UZk3hEMGaWtdW26nwmKBv77QDKkQ45yo3GbDeIA8VGg16l513nlG2aCM38ce7XBwM9HKbSFlQdfGzBnV9Z1P9xdxOO24zs2zZq8ufjNJ9oipvad2gW4ypXT4KL81AfW2GDJ48U7++bPbVh9h7QaCw2bRxk9e2TouFCBc3tYasi6TjQa/djd5euBBp20Y+XmqujeHNR7AtxdZNkQ+7MOj66aK37P3lJmfI+p6lRTiDfVn2NzexZSNfImYmWWSajTrva23d5LSFHPpoFslpQ6khki83rU4Oti0mH/kqN8123cQT0Gif1GdKfsnWosX+LoTHlNAaVgt2aVnOpF42yk2kJl02gBw0Gu8LsombvgUYAEB2jLqBBdg1AAAAAElFTkSuQmCC', // 11 soul daggers 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAbxJREFUeNrsmr1OwzAUhW0rEuIdWDpkZWjEloVuzcg7hI2FB+nSDd6hY9lgYUPtwJqhC++AmEJuisNtS8F2HEe050pVO1g9/u458Y8UWZalOPRS4ggKkIAEJCABCUhAAhKQgAQkIAEJSEACEpCABCQgAQlIQAISkIAEJCABCUhAHidkZDpwlF03r4k8PdzL//TWSGQzeBAPv37lZQUtHud38uAgqa7OTsRMDBt3Q4LyNNnoGj+TFNFVsRSzt48adJKltbNcOESRptY11bZaeDjo8+vLBqiU4ZJLTeaw3iD3LTQa9HKcd+4oRdQlTVZOEih3cxs0hKMuaWq1T5LIT46GjK5JmpSPboYslzRFvheE9fZSuxnkwEBNTs8vGtDbudjR93qs02IhyiZNrSG3RQZx0uvpRm8vfG1QXiLKno2b+DTYlmKaJuUjLgQ6Ld57c++vNFlD0sOsP1yEHOwrsr+liSKrfIlwJ0lklOWdn2tN02S1heyb9LqLCzEV3w6uikWrm4PpEZOufHoOk2wzTdQAp31S3ynpT3hEdypOq84mDawW7DKy5KSeU/1dpYl64gCZOI33BemSpk8BBgBS2xHKk2R9CQAAAABJRU5ErkJggg==', // 12 holy bow 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAbZJREFUeNrsmr1Ow0AMx++iSAxIdGNj42NEQn2KsLDxMGQAiY9n4QHoU/AE0B2JjUpsSEcc5Cq9XpO0dyi2Y0s3ROryy9/+2+fUOueM9MjMCEIhFVIhFVIhFVIhRw6ZNx/Ky0k94z3MFjb0Y64j4JqSZTExN8WBE6skKJifL1xZHNXCbVKUNSTG++dPrSiA3r98sQfNQjW3d/WxBMU6Femuz6/fK6DWWuMf9pBVba6kLmczau2ToKYE0FZIcFcE5dxeOiceBAU1RbWQECiY7/V0f9laOPXQoJKnx4JnV4y3eT81q2NFK8lpUNjqquWbEBfQre+THN12p0tzs39yULMVEgb2TQcnIdHrD05qRu94OKi5M6S/76GsZpJtHXU1oyBDtxSKakZBNlOWsprR6eqrKbYmqRtQNCSHlNUPPn0DFtCUXVaVTGFAFJbQWd/1B+fpJ9kiy69L8pAxSnYN8uKMp97sEXDZf4HEujw5zOmma6p+Oao+OXQbCebT2cXfZvz2MU1dgv9UoHYoE1pT8u7JiPgzRKeSKd84mA+qaQb6dpKlBkTzoTT56ICeMmVVSYWMj18BBgBBAfIoY/ffzAAAAABJRU5ErkJggg==', // 13 shadow bow 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAZFJREFUeNrsmjESgkAMRQljS0lDxQXgmNyJa8AF6BkqDoDGmTi4rojuKklMZrbQsXn+5CcbgGVZEu2RJn8QBmmQBmmQBmmQBvnnkKf1h7qurzNe3/fg+7HUEfBByaqq8Cxq0xUVnKZJHejJ9+U8z1dQzNCu60CVklRzCEigVKcq3XUYhjtQAEjcIx6yKIq71JVco5t9EtXUALoJiW5LoJLby8uJh0BRTVUtxAeK5luW5a21PJuKxCiZ57ne2ZViHMddal4OqFZS0qDw1lXLNSEpoG/fJyW67UeX5nX/lKDmJiQO7M8OTUKq1x+S1Aze8UhQ82NId9/DWc0o2zruagZB+m4pHNUMglynLGc1g9PVVVNtTXI3oGBICSlrD3z2Bi6gObusKRnDgDgsodO96w/J00+0RZZbl+whQ5R8NcirMx7c7HFw2a9AUl1mWabPXbnW5U/65NFtxLtBb5oGYtYl+s8FFI4yoQcl27YV/47ALiVj/uNoPqRmctCzkzQ2IJkPp8nHBvSYKWtKGmR4nAUYAM9Y8XxdtZLpAAAAAElFTkSuQmCC', // 14 genesis bow 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAcBJREFUeNrsmrFOAkEQhnfJmZAckZIYrZHe+BIEa9/A3nfwQWy0NtEXoKaAUqXFGEsNJBYmJ4MZchzLcbBrbmZuNrkCQsHHP/PPf3PYJEmM9FMzFTgKqZAKqZAKqZAKWXHIKP3iotNcZLynly/r+jDXCLimZK/TNL3Tw0RsuYKCN3FdHGjkevNj+rMAhQp9fP60opTEnnu4bC9BsU9FuutgMlsBtdaa7MUecnTWWildzj2aOydBTQmguZDgtgjKebxsTTwICmqKGiEuUDDf85N4OVo2pSI2StaPY7nZFc/326yQmvPLilaSU1DY6VYra0JcQJ2Q190DUW67101zen5yUDMXEgL7pguTkOj1Byc1vXc8HNTcGzK776GsZpBtHXU1vSBddykU1fSCTJcsZTW9yzWrptiepG5A3pAcSlYf+BQ9sICm7LKqZAgDorCEdkK+v05FpR8n5FG74d2X5CF9lNwW5MlA3vbDlBxs9ii47L8YD/ZlqxHRLddQ87JSc7LsMeKsp+FV/+9b3YXpS/CfOagty4TWlJzcj9n/R6CQkiF/cTAfVNOU9OykFhoQzYdS8tGAHrJkVUmF9D+/AgwAs5/02YmME18AAAAASUVORK5CYII=', // 15 bronze staff 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAXBJREFUeNrs2TFuwkAQBdBdZKUgAiMhJTXpXcEBnNKU1LQ5Q+7AFbgBF0jLBVzRQUENEgVCuLKy8SxsMEQCO4mQZvynsZHdPM3uzKzRxhglPWqqAgEkkEACeffwyrzc77Vsv/mIt5pT6/HKAKOe734anQUX6E1kZlFR17fAt8ChfFbQm8ifQHW85wMtVHjyQPGF5xK+3j7abNKqZos8FZvzTI5nOgOmcvukAz75nszlulinGVBboOhMYqzjiqRlSfuQYjLXMpGcCsyfMlmZPemWLMfMFkbShMOtdfwqk24I4AYt1UIckNuSvYqkLwDxYv+ductM0jN6R0wm81BRR63jYVi/vjRN8FxX7bqnNskBOVslarrcaVF7koDvg5q9VubQnMs0BnQggQQSSCArj3STDsco/Ulyk3yyQxb+s8bNr/m5VdTEQ8Cw01Sj4YOdXek+7DSM6D3JbX+iugIJJJBAAgkkkEACCSSQQP57fAkwABKgngHgRL4dAAAAAElFTkSuQmCC', // 16 holy staff 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAVhJREFUeNrs2TsOgkAQBuDFUJiYaGdiYekNPAUegM6LSKkXsbOz0VN4ArGzo5PERBMTZNBV2UJYSIwz/FOB0nyZ3Zl9OEmSKOnRUg0IIIEEEsifh2vzcTDpZf1msY0dTq3HtQEGXk+/Jk4aXKCFyNSiZl43A7anxwdYDVlBC5EmkIKeOUFLFZ5PoPjCY8L9aJBlk0Y1W+S72MS53y/LoQqjm9w+qYGjvitzuO4PSl2fQNGZxLKOK5KGJc1Diut6IBPJqcDUymRj5qQeshwzWxpJKxxuraNSJkOGPdK6hWggtyH7FUknAKvd+ZU5M5P0H30jJpOfUFFzkjbD880py6ZZWblk0SqTBNQVtjGbZp1pLNCBBBJIIIEEkvfmudKRJLcofVlDp+n+uJNbt4q5utNAfbNFm+fnPeXf34HUmpOiTwbQQoAEEkgggQQSSCCBBBJIIMvEXYABAPzeoLvJeT1tAAAAAElFTkSuQmCC', // 17 shadow staff 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAATVJREFUeNrs2bENgzAQBVCIaNmBBaBj/wHoYAF6SgZwOItDxIqCDRLKP/5ViaB5+rbPxrlzLrNer+wBRSSRRBJ5exUpLzdN4/vNMAw5UuspUoB1Xetfly+FAj1ELpZswXlg27b7RzDQQ+Q34O43BDRq4QkStL3whPB5nn2aMqphkcFis1XXdQq02ScVWJalTeQ0TRvQdJLc1qEiZVjKPFy3czaRSAvMpSQfMyd1yCImG42UHQ5a6ziVJGKPTG4hCkQbsj+R8gVgHMctuTBJeSbvmElyDzU1J+Uw3Pe9TzNcWVFSTEpSgLrCPubQrElzg04kkUQSSSSR2IfnU58k0Sr6ska+pldV9bFvNXN1p0C92ZLD83p18Pd3IJfmpOkvA2whRBJJJJFEEkkkkUQSSSSRMfUWYAAGQqCvXabbLAAAAABJRU5ErkJggg==', // 18 polished scepter 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAVdJREFUeNrs2jEOgkAQBdBd3c5ErLyBpRWUXgBLb2DhKTwKd7D1FFSU3sCOws5kZZCNqxEFpGDGPwkhUPnymd2RoK21SnqN1B8UkEACCSSQQAIJJJBAAgkkkEACCSSQQAIJJJBAAgmkhFpHM0vH630jBUfncDFR6ekiL0kCxlGgDtupmgdG3uPqgLulldmTTYFskQSk/vOBSabVOb/KSrKu/0Qg26bINsk2KbLdJym1JDNP16InHh9Ig8AxzTWrJLXWb28XR9mXftUBWSe5X43L3iTcJyC7nozDoFxSaYTzV1QHrPu6zHAC0oTjYHR2CX77dI5VkrQ30qqaZPdtpOpLW/UpfyQltilA9Kg+hoBmP5/V4+r3ovvf+GnBYT0MfFtNWW4hrym2rZH0FFkgf02RXZJdUhw8so8UWSXZNcVBI+kNQB8pskjSn1FFIf0U277qeFc3AQYAB7+0h6in7acAAAAASUVORK5CYII=', // 19 ancient scepter 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAVRJREFUeNrs2rEKwjAQBuCkCkLBgjo4KziKr1AXH8DHdfIdHDt0dtBBwUmJXmwllra2tYN3/geltNvHf0nOojbGKOnlqT8oIIEEEkgggQQSSCCBBBJIIIEEEkgggQQSSCCBBBJICbWcBoau7PuuFBzd52Nf7fYXJQ5JwHASqOGso47RTV67ukCRa7IqkC2SgLT+XCC16uFylZXkyK++nXjSU2SbZJ0U2R4hNrUo8yx54nGBNAhs47NmlaTWOvf147Lr0q0iIOuJZ7bo2Q1nG5/scxGQHTKc9O2Mul4N3nbUFFj077IuJyBNOCmM7mmLfvrrHKsk7dkYPc9FOkaSdWmSdcofaVtyowy16qsiYecktau7FtPfjWUbDuvdtey4YDsMZFOsW570FFkgv02RXZJNUvx5ZBspskqyaYo/jaQvAG2kyCJJd0YVhXRTrPupI6/uAgwAniy3YrjrwnkAAAAASUVORK5CYII=', // 20 club 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAeVJREFUeNrs2jlPw0AQBeC1AXEpEkeHKEKRDhoKav451BT8gUiQAtFxiAhEhCDoGT1r7Hh9NHgCb5rEjpTk8+zMjqMk8/k8/PVIwz8IIYUUUkghhRRSSCGFFFJIIYUUUkghhRRSSCGFFFJIIYUUUkghhRRyIVarTiZJUjg+PxpE/z1xeTtNunxgH3/ESKo+lEjiTo43C6+PDjbC9dVb9nzyPCtg6xB4X1dIAIc76/m5wWGa4RCP48/wsP2xgG2C9oVsXZMEIvZGK2H/dS2M79/DcPfnQuCCMPPl5e6y8dgsnp5tZRBmzEKnd1/ZI6FL212BA6QqcAGIzy6GyebSbSGoQSDwWA5kEfWJ11C3sQ7tHjl5muVLFJlDLZaXLevWYzZbNx7gmFGgLBTncCG8ZrPzxEMowkJtF/aWzTQ2xXCTt4HaK28phALO2rTd1kM2O2eSEDYhYAHFMfZOdmJP2UzrZtJyNtlgCOFAYM8R72nvrM1kDAoYUJx8uGwJZTdmNvteso3LNQblEGChPM5HPSfZbFWTsUZkRz27raBu2aQ8ZLN144lBuUyRtfL+6SWbnbprXY3G7lY8dNram+ZY8Avb+00bdupBvaIR8X7T3S8DTVGF5cBOIJ5z6wH04ubl14vzW4ABAN8HHrujN7U3AAAAAElFTkSuQmCC', // 21 dual shortswords 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAWJJREFUeNrsmkGKhDAQRZOQK7hwK+jSi3gEPZ4eQQ+j4NYLuM9QDhkaWjqJ3ZmUM79ADBJKX/38UlFpjBF/PZT4BwFIQAISkIAEJCABCUhAAhKQgAQkIAEJSEACEpCABCQgAQlIQAISkCwgm6YxXdcZKaW4unEI7ZqQZZlo2/b45t73vbyjktpnEoHmeS5I1TvCenmyLEtR1zVB2n2yvymshT4Oue/7z5ggU4PSyqLz+16DF+S2bafHUzYcArXFdsG+hJymSc7zfIzXdX1S0zakFBFiIe/75LIsrJpJiIWckFzVDLGQE/LxtzQOal4puoqV+DfCt+j6SuKiKJIpSStLfrdvU1XVUXR7PVRwO20YBhnceDipGWohFXOZcPGmim16Dt5UsU3PQU0Vc5lwUVO/mzhlp7VFd3VaHSsxPXykUPOs6Cq26Tl4U8VKnOp986zoKrbpOaj5FuQ4jrdQ80uAAQAbKgRqdtaMpAAAAABJRU5ErkJggg==', // 22 dual handaxes 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAnRJREFUeNrsmb8vg0EYx+89Er+iwViWim50EDGYajEYDNZ29KfYbCZ/QJuYDBZhYZIwGEpiaKIGbEraRIlwPC9P8/Z674/24t7D8ySXXt/m23w//d7d+97VEUKwv16c/YMiSIIkSIIkSIIkSIIkSIIkSIIkSIIkSIIkSIIkSIIkSIIkyD8B6ThOYMvn80K+xnXEQS3OyuVyAlqTDf/VAmNB/3ABJPYLhYJja9Lg87OxUqnkto4hZbFtsOAxk8m4fXwFr5Eg/cTQbAEF/zBE0R8WvOdRxN5COBBD8w7juOehChC8ch2xbaAqj13dQrxiBDVdy3MjAppqOske2yA7FXuvm0pzcTIhppJ9DBr0o3jsxU42NeyK8YvGF1ZYFMCwz36i6jfvbHZ+0O1XI/jgsjid7Gcz0wORIfC6qTQPr2rO9eMLK989u15vj3dDPTYhjyr1jsVy0iYLAoFaXRpt+bFVHrmOGBcek0NVDgTqcnsj0CPXEatuLSaGLD60YCA4P/08ch1xGLTJNBv7m75+uI5YXnxMlhzIWLrH1yPXEasATd4zMRAsCETlkeuI/R4MTKd5dvrUDETlkeuI/e6Zcay0WCcba21+uI7YhpIDUXnkOmJbyrtYwqjzBhK6CwkT25YmLpZHlVp0yDCxjWni09re1npzgx96/AHXYYeCj3k7Bw8Mdih+q2pcRyLoM5tKsPuhV3Z+0XDBW7ZaYVUtv7liqGKxqIIQcQ9Z5+usRsAu6nsnJWDX0qsjln5JB49L4h66ML2GJ3j7prkbsWr+Am/caWZTn4FMfAUCBwA8qtg7sVH8G1bajg6yVGJbC08PMJAPAQYAfd4Z6gyxGIoAAAAASUVORK5CYII=', // 23 bronze shortsword 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAATFJREFUeNrs2jEKwjAYhuE/Wmgn69xZcXJzdreew1O0o7fwGoqncHJUHLvXqU6RRCiCiKQJNH/8AoUOUnx4G2lihZSSQh8D+oMBJJBAAgkkkEACCSSQQAIJJJBAAgkkkEACCSSQQAIJJJBAAukdMl+MZblOpRCCuh59jcjkw/dhQkVO+v/37aE2+tZ9Io1vVwVdThNSVdUR5JycZgoZU5mnLTY45Cxp2nOF5QA1Ru5v3+ecbz84xsjjqRbX6qHPd2fxUbPIRzKYkmpcqibchwGuNY2Q76+ocappfLtyrGn17MqlZickt5rWqxAONTsjOdV0sp70vaYVkktNZzsDPteMbC+gaq4olZMs1jU3c9nWfG0p6EW2CKKkzzWdIH/Nzb7Xm85363ysGbm6kM9z8ynAAIAhhYiPD/6GAAAAAElFTkSuQmCC', // 24 poisoned spear 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAYVJREFUeNrsmb1KA1EQhedqJGKxYsRGELLCtRC0srOJIAipbINP4YOIrT5AbLQStBQrCxFB8Ae8hYEESxMISILoNbOwsgY02e1mcqa5P93HmTk7O9d470l7jNEIBCD7Y2FnyRtjxEHm0gBOrxZ6O8tFbNQqGazM6k3XWMXd8kRvb6OzSiWlqpjJXVlNdZAbi4HffGrS1t7dzx2nriSnHVrJgh2n/fMPkak7FGRxJk9v7pMqp/cRqLSUTaWk1MgNqsdSGPzxWbG8iGgMBipZa3Z/nTllpblspgY9NiBVvWt/Pa4d3NDDlNWh5OVL29RaXbq9fif32onueL1YD3UpyaClkHyR8uSoQ+3GF80dPtIJLetQkkcjGsYjqYzHzk+KbNgzjz/qVUeNI2dUQXJrl1zr1WejXknV/5PJDkiKKUHJ/+KYtr16SEn9a2bIq/IZ3BWQgAQkIAEJSEACEpCABCQgAQlIQGqDjF+21ELyvDX5FqISkp8HoCRqEu4KSEACcsQgvwUYAHt3cFOqYEgzAAAAAElFTkSuQmCC', // 25 silver wand 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAARhJREFUeNrs2ksKgzAUheEkZC0O3YJzXYvLU3ArCk5dRuoNVUpJQaMDz+25IKQOCh8/Plq1IQSjfZz5gyGSSCKJJJJIIokkkkgiiSSSSCKJJJJIIokkkkgiiSSSyOeP14BomiY+ZO373qaet3oNwLZtt4/BrvMN9ejAdYvreZ7Ney1Cq6rkNE3J9edY9HcGpGZRFHE9jqPpus5Cnl3Xwyy5CbCqqh0oJx7Zr+4SUpblDlR3nazrOlYchmHf9+vQc9oqpqBOS0WVt3VHjkVYpFSUO5yjFaFLHq0Ih8ypCFvyTEUoZG5FyJJnK8Igr1SEK5lTEQK5/dLIrQhVMrfi45FbxWVZLn2P017x0ci7Ksp4lIpX/ot6CTAAIumXDiDKUh4AAAAASUVORK5CYII=', // 26 soulcutter 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAfpJREFUeNrsmb9Sg0AQhw8mjY+RgtbCjIUzNLGT98BOnYnvYWNnHsIudrGxjS9AkcewRH53HLMqfy4TkFuyOwNkmJDJx7e7dxxBnudq6hGqEwiBFEiBFEiBFEiBFEiBFEiBFEiBFEiBPGXIYHmT/lnkeX9bB1Na+5lhN48ufp1O8+vkdjKwGnKffarH5ZWKzy/1yedsUZzbadigCO6gAXaAKMzlMDqPFuouOitAv/QXtpt1eXwJWJssZJXAZX1GsQbVkaTaKm4CV9iwLhWtRQRgn5K4gEx17VpYdkOIBYUl1Kepx58BWKQyYAFa2ueTrhSU2rS1aVOXpjAu4dKUZnVjJK1NWF1lqmpIFnavhx3TfZt+3JcbELb9sdXmQ9ejGWZ2Va3iCGjUaN1kgsW0ztamDfu5rlYnMXeFtdeH+wqU1igXm42QtNPSIYWjTaenEDMZSNnabIVEp6W1ydVmKyTttJxtdqbrFGwetDKAJxIKzcVmJ2TbrIWLTSeT1p6Z8il2Np3T1QJytOkEWZeynGz2siTpu82jILts+rKK0Nviss82j4bkYNMZEs2naWuyCVDE2OtBvaQrfcimNg2o6bQAtRvbmuyySeO/QXuDdLHJvrseapMtZFOnHdvmYC9hfbLZO6SPNgd9ne6LzUEgfbM5qMk6c2PY/BZgACwVbLFh8QNzAAAAAElFTkSuQmCC', // 27 dusty scmitar 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAZtJREFUeNrsmU2uREAQx7snlk4hYekK9tzX3hUsSWwdo19KtNDqaW80qvtVJRM9E8HPv6rrY6RSSoRuH/EPjCEZkiEZkiEZkiEZkiEZkiEZkiEZkiEZkiH9twj7saoq6wivrmvpy6Rv86AariiK6Xue55uT27Zd1k3TLLBHN6DwInZKZlkmxnGc1nEcT8ckSXbQsJ6h1RlYMkpKKUVZlgpATUvTdIHF1AVlMVCSSs4PugPt+36j6lrRNRNFRSPzrYOafwU1YMmBRke7ZyigX+VJAB2Gwe88eRbUEqNk1PzYEn7XdVbQYJXUBm57pCZkJu9rVx/UdFKgY5uQVhNSkvfuqtXEUspcAytpkD5dBTlrtSinlNOQsMvqz1kzuxjS7gpgRs5DKyHMZb1R8kpSh7iEzoY0JAb4W5FANS6dzniwnEkhLr+G9EnNR6Z1b8flJUhMTYpl3i1Kmi77dlw+Nlx+02VvgaTmspchbY110LsrpbiM7rowVsuuW68n2y0nSlJ3Wf5/MpS4dBaT2MT9KC7Fg1M8dtdQ7EeAAQB0N9nOgpmylgAAAABJRU5ErkJggg==', // 28 weathered greataxe 'iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAn9JREFUeNrsmrFOwzAQhp1QRBECAd2AoUXKBh0ZmOAFeIGWF2Fm4wV4gFaClYURJkaGLgxIwIDYQAgEAiEI/U1TJSZx7CaidyWWrERJOnz67uyzXcf3fTHqzRX/oBWQBWQBWUAWkAVkAfnPIUu6l81mU9Z87Xbb4Vz+pZqs1+ui0Wj4ATDHlmoIcABFb7Va8ln36oxMuAah2r34PeBIGHOBNcq1wGY4hHuQLMwaDygqKCfYUpYfdzodoYYxRdDc5kkAA5biKJwZEiEbGKUK6uYFSNmom2XQUQFZVTybyzM+uo1B9R0lm6U4wNWVyf794vqWUOfINEDVOimTgKrOTghvoSw77rMAUrHpqoBoD5ef8jq95LI2mJiTYTDYvDjYi0z8poDh7x3HoZWTz7dfojL3Y3PeG4tA2wCGByAU+F3Qoa1J+wSn18/OzeO7vL+f+oi1aQtIegqBTTU34wYgDoARSISSzubhzjZLQO0qBDa9tbFIbg4K2PseCekMPVxVm5d3b79s2gJSmFq0tStswmLcvEk9RFMhk2yiBbnJBdBoFRK2iZAdmVWIziZCFja5ABqvJ5Ns2u4FkYTU2YyrglibTLJ5vL9rZAnf9DapaRUDYZsbNSGXYbBZEeN9m1UxIW7OjtRJn0/Fk1YFeV5ZnN++yuchSz5FUKNw1eUmDG/UpvtHfBRHXestSduRdtj5aAXJ2eZAm8umNgOLKPyHeVJtBWlqk0qYZjJpYpMKoNxIU8PIZGcNxmAOBisv4xIWZgEO0zAeXqOyNZlHTUsa0iY3WeckJ5sDQ3KymctxOnWbvyBtJm4uNnP7YwRlm4mQgdG0fnL1pLWpO7H+q/YtwADFMTLO/0vp8QAAAABJRU5ErkJggg==' // END WEAPONS ]; return string(abi.encodePacked( (lgAssetId < 5 ? '%253Cg%253E%253Cpath d=\'M23,48h3v1h3v1h2v1h1v1h1v1h1v3h-1v1h-17v-4h1v-1h1v-1h2v-1h2v-1h1z\' fill=\'var(--dms)\'/%253E%253Cpath d=\'M25,49h1v1h-1v1h-1v1h-1v1h-1v-1h1v-1h1v-1h1zM28,50h1v1h-1v1h-1v1h-2v1h-1v-1h1v-1h2v-1h1zM30,51h1v2h-1v1h-2v1h-1v-1h1v-1h2zM18,52h2v1h-1v2h-1v1h-1v-1h1v-1h-1v-1h1zM31,55h1v1h-1z\' fill=\'var(--dmb35)\'/%253E%253Cpath d=\'M23,48h3v1h3v1h2v1h1v1h1v1h1v3h-1v1h-4v-1h1v-1h2v-1h-1v-2h-3v-1h-2v-1h-1v1h-1v-1h-2v1h-1v1h-2v1h1v1h1v1h2v1h4v1h-11v-4h1v1h1v1h1v-1h-1v-1h-1v-1h1v-1h2v-1h2v-1h1z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M23,48h3v1h3v1h2v1h1v1h1v1h1v3h-1v1h-2v-1h2v-3h-1v-1h-1v-1h-2v-1h-3v-1h-3v1h-1v1h-2v1h-2v1h-1v4h-1v-4h1v-1h1v-1h2v-1h2v-1h1z\' fill=\'var(--dmb5)\'/%253E%253Cimage href=\'data:image/png;base64,' : '%253Cg%253E%253Cimage href=\'data:image/png;base64,'), WEAPONS[lgAssetId], '\'/%253E%253C/g%253E' )); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; library LgSVG { /** * @notice render an eyes asset * @param lgAssetId the large asset id of the eyes item * @return string of svg */ function _eyes(uint256 lgAssetId) internal pure returns (string memory) { string[8] memory EYES = [ // 0 normal male '%253Cpath d=\'M29,29h3v1h-3zM38,29h3v1h-3z\' fill=\'var(--dme)\'/%253E%253Cpath d=\'M30,29zh1v1h-1zM39,29h1v1h-1z\' fill=\'var(--dmi)\'/%253E%253Cpath d=\'M28,24h6v1h1v2h-9v-1h1v-1h1zM38,24h4v3h-5v-2h1z\' fill=\'var(--dmh)\'/%253E%253Cpath d=\'M28,24h6v1h-3v1h2v-1h2v2h-1v1h1v1h-1v1h-2v-1h-3v1h-1v-1h-2v-1h1v-1h-1v-1h1v-1h1zM38,24h4v1h-3v1h2v-1h1v5h-1v-1h-3v1h-1v-2h1v-1h-1v-2h1z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M28,24h6v1h-6v1h6v-1h1v2h-9v-1h1v-1h1zM38,24h4v1h-4v1h4v1h-5v-2h1zM29,28h3v1h1v1h-1v-1h-3v1h-1v-1h1zM38,28h3v1h1v1h-1v-1h-3v1h-1v-1h1z\' fill=\'var(--dmb5)\'/%253E', // 1 angry male '%253Cpath d=\'M29,29h3v1h-3zM38,29h3v1h-3z\' fill=\'var(--dme)\'/%253E%253Cpath d=\'M30,29zh1v1h-1zM39,29h1v1h-1z\' fill=\'var(--dmi)\'/%253E%253Cpath d=\'M28,24h3v1h3v1h1v2h-4v-1h-5v-1h1v-1h1zM40,24h2v3h-2v1h-3v-2h1v-1h2z\' fill=\'var(--dmh)\'/%253E%253Cpath d=\'M28,24h3v1h3v1h-3v1h2v-1h2v3h-1v1h-1v-1h-3v1h-1v-1h-2v-1h1v-1h-2v-1h1v-1h1zM40,24h2v6h-1v-1h-3v1h-1v-4h1v-1h2v1h-1v1h1v-1h1v-1h-1v-1h1z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M28,24h3v1h3v1h1v2h-3v1h1v1h-1v-1h-3v1h-1v-1h1v-1h2v-1h-5v-1h1v-1h1v1h3v1h3v-1h-3v-1h-3zM40,24h2v1h-2v1h-2v1h2v-1h2v1h-2v1h1v1h1v1h-1v-1h-3v1h-1v-1h1v-1h-1v-2h1v-1h2z\' fill=\'var(--dmb5)\'/%253E', // 2 sad male '%253Cpath d=\'M29,29h3v1h-3zM38,29h3v1h-3z\' fill=\'var(--dme)\'/%253E%253Cpath d=\'M30,29zh1v1h-1zM39,29h1v1h-1z\' fill=\'var(--dmi)\'/%253E%253Cpath d=\'M31,24h3v1h1v2h-4v1h-5v-1h1v-1h1v-1h3zM38,24h2v1h2v3h-2v-1h-3v-2h1z\' fill=\'var(--dmh)\'/%253E%253Cpath d=\'M31,24h3v1h1v2h-1v1h1v1h-1v1h-2v-1h-3v1h-1v-1h-2v-2h1v-1h1v-1h3v1h2v-1h-2zM38,24h2v1h-1v1h1v1h1v-1h-1v-1h1v-1h1v6h-1v-1h-3v1h-1v-2h1v-1h-1v-2h1z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M31,24h3v1h1v2h-4v1h1v1h1v1h-1v-1h-3v1h-1v-1h1v-1h-3v-1h1v-1h1v-1h3v1h-3v1h3v-1h3v-1h-3zM38,24h2v1h2v1h-2v1h2v1h-1v1h1v1h-1v-1h-3v1h-1v-1h1v-1h2v-1h-3v-2h1v1h2v-1h-2z\' fill=\'var(--dmb5)\'/%253E', // 3 surprised male '%253Cpath d=\'M29,28h3v2h-3zM38,28h3v2h-3z\' fill=\'var(--dme)\'/%253E%253Cpath d=\'M30,29zh1v1h-1zM39,29h1v1h-1z\' fill=\'var(--dmi)\'/%253E%253Cpath d=\'M28,24h6v1h1v2h-9v-1h1v-1h1zM38,24h4v3h-5v-2h1z\' fill=\'var(--dmh)\'/%253E%253Cpath d=\'M28,24h6v1h-3v1h2v-1h2v2h-1v1h1v1h-1v1h-2v1h-3v-1h3v-1h-3v1h-1v-1h-2v-1h1v-1h-1v-1h1v-1h1zM38,24h4v1h-3v1h2v-1h1v5h-1v-1h-3v1h3v1h-3v-1h-1v-2h1v-1h-1v-2h1z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M28,24h6v1h-6v1h6v-1h1v2h-3v1h-3v-1h-3v-1h1v-1h1zM38,24h4v1h-4v1h4v1h-1v1h-3v-1h-1v-2h1zM28,29h1v1h-1zM32,29h1v1h-1zM37,29h1v1h-1zM41,29h1v1h-1z\' fill=\'var(--dmb5)\'/%253E', // 4 normal female '%253Cpath d=\'M29,29h3v1h-3zM38,29h3v1h-3z\' fill=\'var(--dme)\'/%253E%253Cpath d=\'M30,29zh1v1h-1zM39,29h1v1h-1z\' fill=\'var(--dmi)\'/%253E%253Cpath d=\'M29,25h4v1h1v1h-6v-1h1zM38,25h3v1h1v1h-5v-1h1z\' fill=\'var(--dmh)\'/%253E%253Cpath d=\'M28,25h3v1h2v-1h1v1h1v1h-1v1h1v2h-3v-1h-3v1h-2v-1h-1v-1h1v-2h1zM37,25h2v1h2v-1h1v5h-1v-1h-3v1h-2v-1h1v-1h1v-1h-1z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M27,26h8v1h-8zM37,26h5v1h-5zM29,28h5v1h-1v1h-1v-1h-3v1h-1v-1h1zM38,28h4v2h-1v-1h-3v1h-1v-1h1z\' fill=\'var(--dmb5)\'/%253E', // 5 angry female '%253Cpath d=\'M29,29h3v1h-3zM38,29h3v1h-3z\' fill=\'var(--dme)\'/%253E%253Cpath d=\'M30,29zh1v1h-1zM39,29h1v1h-1z\' fill=\'var(--dmi)\'/%253E%253Cpath d=\'M29,25h2v1h2v1h1v1h-3v-1h-3v-1h1zM40,25h1v1h1v1h-2v1h-3v-1h1v-1h2z\' fill=\'var(--dmh)\'/%253E%253Cpath d=\'M28,25h4v1h3v1h-1v1h1v2h-3v-1h-3v1h-2v-1h-1v-1h1v-2h1zM39,25h1v1h1v-1h1v5h-1v-1h-3v1h-2v-1h1v-1h1v-1h-1v-1h2z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M27,26h4v1h4v1h-1v1h-1v1h-1v-1h-3v1h-1v-1h1v-1h2v-1h-4zM40,26h2v1h-2v1h2v2h-1v-1h-3v1h-1v-1h1v-1h-1v-1h3z\' fill=\'var(--dmb5)\'/%253E', // 6 sad female '%253Cpath d=\'M29,29h3v1h-3zM38,29h3v1h-3z\' fill=\'var(--dme)\'/%253E%253Cpath d=\'M30,29zh1v1h-1zM39,29h1v1h-1z\' fill=\'var(--dmi)\'/%253E%253Cpath d=\'M31,25h2v1h1v1h-3v1h-3v-1h1v-1h2zM38,25h2v1h1v1h1v1h-2v-1h-3v-1h1z\' fill=\'var(--dmh)\'/%253E%253Cpath d=\'M28,25h3v1h2v-1h1v1h1v1h-1v1h1v2h-3v-1h-3v1h-2v-1h-1v-1h1v-2h1zM37,25h2v1h2v-1h1v5h-1v-1h-3v1h-2v-1h1v-1h1v-1h-1z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M31,26h4v1h-3v1h2v1h-1v1h-1v-1h-3v1h-1v-1h1v-1h-2v-1h4zM37,26h3v1h2v3h-1v-1h-3v1h-1v-1h1v-1h1v-1h-2z\' fill=\'var(--dmb5)\'/%253E', // 7 surprised female '%253Cpath d=\'M29,28h3v2h-3zM38,28h3v2h-3z\' fill=\'var(--dme)\'/%253E%253Cpath d=\'M30,29zh1v1h-1zM39,29h1v1h-1z\' fill=\'var(--dmi)\'/%253E%253Cpath d=\'M29,24h4v1h1v1h-6v-1h1zM38,24h3v1h1v1h-5v-1h1z\' fill=\'var(--dmh)\'/%253E%253Cpath d=\'M28,24h3v1h2v-1h1v1h1v1h-1v1h1v3h-3v-1h-3v1h-2v-1h-1v-2h1v-2h1zM37,24h2v1h2v-1h1v6h-1v-1h-3v1h-2v-1h1v-2h1v-1h-1z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M27,25h8v1h-8zM37,25h5v1h-5zM29,27h5v1h-1v2h-1v-2h-3v2h-1v-2h1zM38,27h4v3h-1v-2h-3v2h-1v-2h1z\' fill=\'var(--dmb5)\'/%253E' ]; return EYES[lgAssetId]; } /** * @notice render a mouth asset * @param lgAssetId the large asset id of the mouth item * @return string of svg */ function _mouth(uint256 lgAssetId) internal pure returns (string memory) { string[16] memory MOUTHS = [ // 0 toothy smile male '%253Cpath d=\'M33,40h5v1h-5z\' fill=\'white\'/%253E%253Cpath d=\'M32,40h2v1h-2zM38,41h1v1h-1z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M32,40h1v1h5v-1h1v1h-1v1h-5v-1h-1z\' fill=\'var(--dmb35)\'/%253E', // 1 small smile male '%253Cpath d=\'M34,40h3v1h-3z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M32,39h1v1h5v1h-5v-1h-1zM35,42h2v1h-2z\' fill=\'var(--dmb35)\'/%253E', // 2 large smile male '%253Cpath d=\'M33,40h5v1h-5z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M31,39h1v1h7v-1h1v1h-1v1h-7v-1h-1zM35,42h2v1h-2z\' fill=\'var(--dmb35)\'/%253E', // 3 frown male '%253Cpath d=\'M34,40h4v1h-4z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M33,40h6v1h1v1h-1v-1h-6v1h-1v-1h1zM35,42h2v1h-2z\' fill=\'var(--dmb35)\'/%253E', // 4 stoic male '%253Cpath d=\'M34,40h4v1h-4z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M33,40h6v1h-6zM35,42h3v1h-3z\' fill=\'var(--dmb35)\'/%253E', // 5 sewn male '%253Cpath d=\'M31,38h1v1h-1zM36,39h1v1h1v-1h1v2h-1v1h-3v-1h-1v-1h2zM32,40h1v2h-1zM37,43h1v1h-1z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M32,39h1v1h2v-1h1v1h1v-1h1v1h2v1h-1v1h-1v-1h-1v2h-1v-2h-1v1h-1v-1h-3v-1h1z\' fill=\'var(--dmb35)\'/%253E', // 6 small smile fangs male '%253Cpath d=\'M34,41h1v2h-1zM38,41h1v2h-1z\' fill=\'white\'/%253E%253Cpath d=\'M32,40h1v1h1v-1h4v1h1v1h-6v-1h-1z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M32,39h1v1h6v1h-6v-1h-1z\' fill=\'var(--dmb35)\'/%253E', // 7 stoic fangs male '%253Cpath d=\'M34,41h1v2h-1zM38,41h1v2h-1z\' fill=\'white\'/%253E%253Cpath d=\'M34,40h4v1h1v1h-6v-1h1z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M33,40h6v1h-6z\' fill=\'var(--dmb35)\'/%253E', // 8 toothy smile female '%253Cpath d=\'M32,40h5v1h-5z\' fill=\'white\'/%253E%253Cpath d=\'M31,40h2v1h-2z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M31,40h1v1h5v-1h1v1h-1v1h-5v-1h-1z\' fill=\'var(--dmb35)\'/%253E', // 9 small smile female '%253Cpath d=\'M33,41h3v1h-3z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M31,40h1v1h5v1h-5v-1h-1z\' fill=\'var(--dmb35)\'/%253E', // 10 large smile female '%253Cpath d=\'M32,41h5v1h-5z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M30,40h1v1h7v-1h1v1h-1v1h-7v-1h-1z\' fill=\'var(--dmb35)\'/%253E', // 11 frown female '%253Cpath d=\'M33,40h3v1h-3z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M32,40h4v1h1v1h-1v-1h-4v1h-1v-1h1z\' fill=\'var(--dmb35)\'/%253E', // 12 stoic female '%253Cpath d=\'M32,41h4v1h-4z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M31,41h6v1h-6z\' fill=\'var(--dmb35)\'/%253E', // 13 sewn female '%253Cpath d=\'M30,38h1v1h-1zM35,39h1v1h1v-1h1v2h-1v1h-3v-1h-1v-1h2zM31,40h1v2h-1zM36,43h1v1h-1z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M31,39h1v1h2v-1h1v1h1v-1h1v1h2v1h-1v1h-1v-1h-1v2h-1v-2h-1v1h-1v-1h-3v-1h1z\' fill=\'var(--dmb35)\'/%253E', // 14 small smile fangs female '%253Cpath d=\'M32,42h1v2h-1zM36,42h1v2h-1z\' fill=\'white\'/%253E%253Cpath d=\'M30,41h1v1h1v-1h4v1h1v1h-6v-1h-1z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M30,40h1v1h6v1h-6v-1h-1z\' fill=\'var(--dmb35)\'/%253E', // 15 stoic fangs female '%253Cpath d=\'M32,42h1v2h-1zM36,42h1v2h-1z\' fill=\'white\'/%253E%253Cpath d=\'M32,41h4v1h1v1h-6v-1h1z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M31,41h6v1h-6z\' fill=\'var(--dmb35)\'/%253E' ]; return MOUTHS[lgAssetId]; } /** * @notice render the miner base * @param classId class id (0 == warrior, 1 == mage, 2 == ranger, 3 == assassin) * @param genderId gender id (0 == male, 2 == female) * @return string of svg */ function renderBase(uint256 genderId, uint256 classId, uint256 eyesId, uint256 mouthId) external pure returns (string memory) { string[2] memory MINERS = [ // 0 base male '%253Cpath d=\'M0,57v-5h1v-1h2v-1h2v-1h4v-1h3v-1h2v-1h2v-1h2v-1h1v-7h-1v-1h-1v-1h-1v-1h-1v-13h1v-3h1v-1h1v-1h1v-1h1v-1h2v-1h1v-1h3v-1h7v1h3v1h2v1h1v1h1v1h1v2h1v3h1v17h-1v5h-1v3h-1v1h-1v1h2v1h2v1h4v1h2v1h4v1h2v1h1v1h1v2z\' fill=\'var(--dms)\'/%253E%253Cimage href=\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAApNJREFUeNrsm12OwiAQx0vjRfaF03gVXjyBJ9gXrtLT8LJHca0BM5JhGGCgVtukibak8uM/zFejut1u06cf8/QFxwF5QB6QB+QBeUAekF8OqQb+liXumT1D2gpIsycrWaG0PzlHGGszC/I2cLYALgVsP0W93YFCQC30TBHQWdhEw+GEnus+WUFRNU89qENLRSnFHovGNyUT4bpAhsmtAKmJjoDrZao6B7JeKzklTFZaSYdBQWUolSjl3zZBz004Uosa495uT5Y6maAg3MuSx2n0JqYcEdest4I0qQoiVoerUjxuS49rC8qpnvVod8djSjKd0hAisT9nQXPV3II3OJlggv7zBbn2OFtBJRP0HKDG9hb4vtzPS2bM5kq+wCCAuVjnMs/YFJJjpo65X3+5+e0WSurSJBx7BjDLs6Sas4CZmsj5nDvVlNspeVfLIGGktIDWkXqr2Z7vyooU4pJpxOph/7yXhIvgMt4xAC7IPXj9sZg1lYpk7mqwrMSrQTkg50EwM1/8/SY1RybojmiTOERJB+6bqaGzPhLyGSsTPSCHeePIEqoSg+FvtTDAVI7qU7rmtuRoSA0m/zxhnorktXpvkI9JQzUxRaU7A70hzylQAKfjFkh07xk6ahdhFtxn2Cu3hYCFgV4jDkUsrZPwrtZPkKpEYBxcClI3kRSxJeOxqb4OMD/OxBfC1H+CqXIbYlKQL3CpNAs4F12zbwPgSCVtokAmX+5EC1CzxwxlLa2Qlqj8yZoxhkWU5sI67tYohUw+jOu2GZA5h+OYFsWGVtyVaoGUaEZR0L6mTc5FTbxOWzUkU83WxbBxIf/yyqE0sa6BpBLzltBQG95IyJZuN2dsh382XDdXctDevapv+F/IvwADAGp6okFeqr7oAAAAAElFTkSuQmCC\'/%253E', // 1 base female '%253Cpath d=\'M0,57v-5h1v-1h2v-1h2v-1h4v-1h3v-1h2v-1h3v-1h2v-8h-1v-1h-1v-1h-1v-1h-1v-13h1v-3h1v-1h1v-1h1v-1h1v-1h2v-1h1v-1h3v-1h7v1h3v1h2v1h1v1h1v1h1v2h1v3h1v17h-1v2h-1v1h-1v2h-1v2h-1v1h-1v2h4v1h2v1h4v1h2v1h4v1h2v1h1v1h1v2z\' fill=\'var(--dms)\'/%253E%253Cimage href=\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAodJREFUeNrsm+1twyAQho2VRfqHBbJGFugQ7JAdGCILeI0uwDKuqUC6UA4OOIidGMlSZdOYh/c+iSLWdZ3efczTB4wT8oQ8IU/IE/KEPCE/HFIMfJdOPFNHhtQVkOpIVmKhpLsow8/VmQ3ZDZwugMOA9buodzhQCCiZPpMFdGY2UT8M0+ead1aQVc1LD2p/pCKEIM+N5jfBk+G6QPrFWQBsoSPgepmqzIHYeyUXh8lyK2liUFCZlEop5XdboOcWHKiVmmN255OlQcYrCH2Zc1xGO3EqEFHN+lWQCusgQnWoKoXzXhlxdUE71bMf7R54VEmlU5pCOPxzZjRXSW14fZDxJhjzRTinFZSzQFc1pV4KlMsfZ+bAM8VMt1eSHwmZNVMq4DZPQtPkypdcSsrSIhwZ1z0qqYIcaWFvNb0l8FlJ3cRhSm6LU1gaQRacUvxh1eQu65ohnb95UKviUqICrFsd3GP7+7umyR5Ru6pEVSKx8xq3Sfb5FQSon+DZsQp0xA9NphdVU8PJes9+8oaZrS/XYNVDNcuafNsTcomARisfrF51getPxZZgNPqrO+kBIRCsU8ElW810FGRWTUxRDjMdqeQTqFUo5ouBok8qtrZfLJCRFxsE9Iblzp4FvOAA3BaoQctlwH2JRN0lsSH/VIz1lCWb0gKpYWnngEwkx8lEelky9TCaTnpDauzQKpMqJCGX2vHl6mE2ExalqpWE9EizTCnRFPFeM6SmviTnKzWg9sQ8+B/dAiuopkgN2wRIDNQUWhQZWlB3qgWyY4rQoKdF1yIoJ20tkNSDrMbN0GEj/3T6V9oW1UCmCvNORUGdD7eedlPmdvhlw/3lSg7y3bv4hN+F/AowAGIWzHdTKpamAAAAAElFTkSuQmCC\'/%253E' ]; return string(abi.encodePacked( (genderId == 0 && classId == 1 ? '%253Cdefs%253E%253Cmask id=\'mhm\'%253E%253Cpath d=\'M0,0h57v57h-57z\' fill=\'white\'/%253E%253Cpath d=\'M31,37h10v19h-10z\' fill=\'black\'/%253E%253C/mask%253E%253C/defs%253E' : ''), MINERS[genderId], _eyes((genderId * 4) + eyesId), _mouth((genderId * 8) + mouthId) )); } /** * @notice render the miner mods * @param modId class id (0-3 male, 4-7 female) * @return string of svg */ function renderMod(uint256 modId) external pure returns (string memory) { string[8] memory CLASS_MODS = [ // 0 warrior male '', // 1 mage male '%253Cpath d=\'M20,33h1v1h1v1h2v1h1v1h2v1h2v1h2v-1h9v1h1v-1h1v-1h1v7h-1v4h-1v2h-1v2h-1v2h-1v1h-1v1h-2v-1h-2v-1h-2v-1h-1v-1h-1v-2h-1v-1h-2v-1h-2v-1h-1v-1h-1v-1h-1v-1h-1v-1h-1v-7h1z\' fill=\'var(--dmh)\'/%253E%253Cimage href=\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAdJJREFUeNrsm0GOgyAYhaWZ03gEViacwj3XmNVcw72nIJlVjzDX6UDy0/zzQm0TsTDtIyHWSg2f7/GgRs3lchlevZyGNyiEJCQhCUlIQhKSkIQkJCEJSUhCEpKQhCQkIQlJSEISkpCEJCQhXxPSGPMV6xTrWyjZDeiRkN+ibHPYU2WrznETCrBNQWsr6fWOeuhit6rxd6EnuzoFNcPTJX9gU8dF/aIr5Pi0u0epE7WqWHXKli0c1yUUjk9SB7UNt9o/Wj8OUjKVpNAqal63ynpOVErtLZzjUyu/txwBmTp8VkHkkzURNF3huJ8Blxvje1YXrCvIs1LmRwA8Bk5aNCjAVadyvABJ5QTp5XNXkE46i6CYA06l5Srj0ZXa5TaY3D2k69WysYxbY3fj2b4F5l7XDaRSxYKFvep0brfAQkKfZ/0Py7pSag5bUPq7PZP/oZDZesqCGdRq6+bURTBU+47d2ysJoE5NL7nTS1arkJ46Ve2e8Xj4n2YIFaeUHVW4eEjdqiq2ujOAoDgeq6r4FEhct4K644Ztxw1X9KkkwJaSd4Rgsg/Mpf3eyIK51MvYtCUVa7wIYFq9TQBr2VAIIlcL1LR8ZaJwlyDUBmwO+azyK8AAkbk+yZJBIeYAAAAASUVORK5CYII=\'/%253E', // 2 ranger male '%253Cpath d=\'M34,29h2v2h2v2h1v2h1v3h-2v1h-5v-1h-2v-3h1v-2h1v-1h1z\' fill=\'var(--dms)\'/%253E%253Cpath d=\'M36,30h1v2h1v4h1v3h-4v-1h-1v-1h1v1h3v-2h-1v-4h-1z\' fill=\'var(--dmb35)\'/%253E%253Cpath d=\'M36,29h1v1h-1zM37,33h1v2h1v1h-1v-1h-1zM32,36h1v1h1v1h1v1h-1v-1h-1v-1h-1zM37,37h2v1h-1v1h-2v-1h1z\' fill=\'var(--dmb15)\'/%253E', // 3 assassin male '%253Cimage href=\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAA5CAYAAACMGIOFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAARhJREFUeNrs2oENgyAQQFFwIkdgJEZxJEfoRjQaSK5U1MqRUP0k5GxSlZc7j5hoQwjm7mMwDxggQYIECRIkSJAgQYIECRIkSJAgQYIECRIkSJAgQYK8H9Jau0wXo9rsNZPuCeU6R6i7I9KJOPeS1aFBBseUyRDCCo0fXyy/za9TZVy58cGCXAIdxbPXrF5XA6TXhF6tADlbNJ5XLNl1O1lKditm287Hsca20bq7jkdQAXTimf2qCvnfqv1b84sskQGfZXa3WW2tQQJTA+sNmUNlGct4qmPXrrElcgu8Bx0L2a9Gqj+ThQVNGaQUmwz1TMrrFTLrz3bp2KhMd+VaaCJ7p/lCRUzpvK6QvDSDBAkSJEiQ/zfeAgwAaFfCwD9utk4AAAAASUVORK5CYII=\'/%253E', // 4 warrior female '', // 5 mage female '%253Cstyle%253E:root{--dme:var(--dm31)}%253C/style%253E', // 6 ranger female '%253Cpath d=\'M34,29h2v2h2v2h1v2h1v3h-2v1h-5v-1h-2v-3h1v-2h1v-1h1z\' fill=\'var(--dms)\'/%253E%253Cpath d=\'M35,30h1v2h1v4h1v3h-4v-1h-1v-1h1v1h3v-2h-1v-4h-1z\' fill=\'var(--dmb35)\'/%253E%253Cpath d=\'M35,29h1v1h-1zM36,33h1v2h1v1h-1v-1h-1zM31,36h1v1h1v1h1v1h-1v-1h-1v-1h-1zM36,37h2v1h-1v1h-2v-1h1z\' fill=\'var(--dmb15)\'/%253E', // 7 assassin female '%253Cpath d=\'M27,29h1v1h-1v1h1v1h-1v-1h-2v1h-2v-1h2v-1h2zM32,30h1v1h1v1h-1v-1h-1zM41,31h1v1h-1v1h-1v1h-1v-1h1v-1h1zM23,35h1v1h1v1h2v-1h1v1h-1v1h1v1h1v1h1v1h-1v-1h-1v-1h-1v-1h-2v1h-1v-1h1v-1h-1v-1h-1zM35,44h1v1h-1v1h-2v1h-1v-1h1v-1h2z\' fill=\'var(--dmb2)\'/%253E' ]; return CLASS_MODS[modId]; } /** * @notice return a background image * @param bgType background type * @return string of base64-encoded image */ function _background(uint256 bgType) internal pure returns (string memory) { string[3] memory backgrounds = [ // 0 Dungeon 'R0lGODlhOQA5AJEAABsbGwcHBxAQEAAAACH5BAAAAAAALAAAAAA5ADkAAAL/VCIAhid/onSqsrScg1OaB34b01HV8oUiwpUNB12wFSVqujXsRWtwGkKcMjsPK3cTni6jmiqgeB6dzREIirq6nJzsdNdyBaHX8Hai1Z3XVTVriPKQfun3MNzKw5fU4o23F9VX9hciOEX4VAhySFckpmBFCPbVgSEZU8clozgHVDL2B0Yy6hnkOIa5mbmomSrV6poWS8om12qbC0mku4YRyKtE9Dv8AEz6C5hl2HhHdtraQ5yxXFj8FMcazRkUB6olCu5mCZ6kuYmJ43MWal6rWqr+8l6ajri4mlmTnmRv5ttuXy9JOQaimWNQDAM4phTGqLGn4TdjDEdxqbcjosUD7oJo1YPWDl+SKEDMaEtAqV8qJNgS1SpDBWS5lw9ZngwX0yUykTm1bfFU8FEuoF9CMhHqMFSjNqA+MiXn7tRTNPd0gOsRT13Nq4fm2SzjDKnWkjHCcsqHBdbONiOrsRnjJc/KiQsnDZyVEKrADQzXFpTCDw9RYRr/3uRWaNBhFY3OhqMlo8k5iAD8lax0ELFPqJrlsaJruU6/j45FA44aK7MpOrhurU6c0GPeoZNnY2hNECNk18pSxyO9+3c1fL8nQWZ9xRvn0Ot+zgSZ1PI+euiK01Ppbvp1tZ0Cv9anIevp7LrU7u1lfnZR9XIOFAAAOw==', // 1 Village 'R0lGODlhOQA5AMQAAEw0NF5lj5WAdmBPZXpwYC1qRSopQFRTYjw8TklIVyEgMGZMSR1KQTs2Q1tKU0Y/Sx1ZSVc+OYRnXjl2Tx1uUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAAAAAALAAAAAA5ADkAAAX/YCCOoyQIZoqa6OK6URy9s2zLQG7nAFlKwBTwxALOFjUb7QbD6QARni8QLA5VwdgSKeMyvVEeNDcVVlfEk6DWTN7eO7GUdF6d72C4/i0n/4J2VYISe4V6fT1/g4tVho5xYoqMRHVvLY98kVSMgIGdNi1tmDFjPZynZzJBL6KPT6iwJqoSrEt7eWOxpwJcQLWsbw7Cww/FDVERBYLKuidIvqzQbg4DA8LW1APFDw0AEIIQzLC8LrTR0F7D6uvbDeFBBRDfuuXVDg/lSKzY2evq2/GYhZtXRdyZBRLYPUiCBJu9YQ/5FRtYoKI8ZeLeCVrw8Nq9Bsdi+LvGzyM2BuFQ/waEsIDlgngEfakr+TGkgZs4c+rUyaAng3gqC/zsGa+WR3/2QC4AybSp06c+IfiMKk/qzwU+d2q9GYFbA2HbHoD1ys2YVKtoq6pN20AsyJpMvUYAGVasgrsK2jWdurYqhbU9IbQNe1cvSAaDtznAizcs08Dy/kamQLkyZXkMxG5jDPaxZsKM894j2xeC5dOWEyR+wNhxAwSr7YZ27U7yZAoTTuemcCCBatCFi338LXZ06LzCvU7OvRv1gd6+YY9trRd2XdazDaPGzfu5b9/PEYinW0zBTdHtrI9dnH00SNy5n8uHnqC3eASQIZu2bbUneeF35VTXWw/I9x109+m3n/9aFBBAAH9VZZbYYjoVZ8xXoyVwn3gK+rXdBAQ0N4FafN0m2VQ9SYQfSqVtxx1lE8T4Yl+olYZZRxN5qJuML1YGooiX7QdfkDZCNBZqzblo2Y9Jwuegj9tVNZM1xujm4nwHiAffbjHyCOOSYFKjEDdfWjbffd/5tmWXMfb2nJLcTUDSP1VShiUC0YGHJgJrtgnefM55N5OY7jUgH55ppomAd1qyOYF3WSKqYXfegdfRnBeGhyeimm6IgDyO2qdonon6ttVOenqqKn6gsknBpvXZt+F8Gj711HcJshhhiRDEGOJuulIlVaz3XThYUw9Et+JpNvbqaI0m6sfAXU951QDCVWXC2eWvPcKpVmNxxcWikl7CuG2XO8JJQWPCIaujlTv6iq6627HbjnJC0uuoq/SCaW+7IL3r4r7PktskZf8aw824XCZJ8K/zbtmvAcGNxRSDSO7roIOuHjxwbuddd9ha5hLs68b8krsdTmF9pGtkJrOJMscR90sZy2Hpt6SjKMtMcLzw3nyTMFF9fDLEMddsM4ooaXt00kwqTS/GTpsMZczZImlZvupanTHWPpZrc7xif3hyymPr63HZW/bscboUhAAAOw==', // 2 Escaped 'R0lGODlhOQA5AMQAAB1BO3h3hTs2QyEgMHpwYGFgblRTYkdHWZqGNjw8Tkw0NCwsWWZMSVc+OZyUKjl2T4uKmCopQB1KQS1qRV5lj1JahB1ZSVhgih1uUwAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAAAAAALAAAAAA5ADkAAAX/YCWOZGmeaKquULu+cDwGreu+d4w4DgIHtJpQJaytdrykbwUMNgMqYO2JQiaVsmylBVxdvw6t6UIum89kkxXcU6Hf8PiZ/S3J7/g3/TrK+/9rYAh/hH97DoV+NXmBSmeLiWUthI2DkkUBkXAQmXJIlmYMRZwXk5qnoaKjkHcUrq8UqGQQDQ2qC0JAZ7C8vb69aKO1DBHFuE0Qv8rLy6u0w8URC77TzNbKXAEUnAHDDMTG1a7SuELb2tfprxHettEL09Hko+i84uv3y8W1tt/g8PLILZBirBe5de+sGWugoF8/gRPewVsQkCIFaQkvRphAEZ4vaRqlMfTmj5wFYwI7/6oMtxHgRgscJ1KYMA7lOwUNHfpbMAEmRnIRpcUMyhMmxQgSevKceBIlz2IccfL79hCmBXgRi0ZU2jOrVZ49JSS9qjVcV6VS2/mTYCFp141dLVjt+VJsz7ltObZtCs9q3rQkGdgaO/auXL8TCs9lK/ar3a2JYY7FmVNnv72PYYadELdx26RuxRamK9ezWMpTvykQ/G30Xs6bI4OOnHg0W82SE8NGnZOq6m95cecdO9y15NucFXe2QLmhv1qrGUTXLTduWLxW2dKmfn2zZtQMBogXPIwhg7CKP3NHzxlve7va4zLHGV78+H6CG55lDDt7dezo4dXYgBNIVZ99luH0Wf9uh3lnWnbxNaZbaD1JZd+FtpSnQGi3wRfgbNstSBuEMNEnD4LkQacAAABoxuKLAHQlwYvVefehaLBJYGJAEeQkFU4CCPBikAJIECSMR7JoAYxMNtkiAFIFlMCUgEFnpGhYilVkkaIFqaWRXG4J5pg7RjDlAQcYYACaaxqQ5WFwvvlZlnTWqWNDxZyZpgEFGJAAmgfAKeighBZq6HwN6clnAYyqKRcGh8IJaaGTVjqpoJQJ9qeajHZagAUYhAppqI8+aulhooIq6qqXomqgdAks2ikBrIr6QK245hrqramqGqpzGcbKKQEEPMCrrsgmm+ut/CTKJgbGRrvqscraWi17q6hJECioBWBQbLHGVkttsuNiuyFbCahqwK4PEBvutfDqeq6k1hoLbrnxxisaqrjaK624rOI77aqe+RpwtAgPnG+1numK8L0CL6xrY+QinLDEuyZ7W8DTPnyxwiDnu7HAD0Mccbz4mupwtMS6+y/GyKq8LMstfwxzriEAADs=' ]; return backgrounds[bgType]; } /** * @notice return a fill color for the frame * @param frameType frame type * @return string of css color variable */ function _frame(uint256 frameType) internal pure returns (string memory) { string[8] memory frames = [ 'black', 'var(--dm17)', 'var(--dm26)', 'var(--dm4)', 'url(%2523s)', 'url(%2523g)', 'url(%2523f)', 'url(%2523c)' ]; return frames[frameType]; } /** * @notice render a double-encoded data URI for the profile SVG * @param spawnType chamber type of spawn * @param body body of the SVG markup * @param bgType the background type of the image * @param frameType the frame type of the image * @return string of svg as a data uri */ function render(string memory spawnType, string memory body, uint256 bgType, uint256 frameType) external pure returns (string memory) { return string(abi.encodePacked( 'data:image/svg+xml,%253Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'100%\' height=\'100%\' viewBox=\'0 0 57 57\' preserveAspectRatio=\'xMidYMid meet\'%253E%253Cstyle%253E*{shape-rendering:crispedges;image-rendering:-webkit-crisp-edges;image-rendering:-moz-crisp-edges;image-rendering:crisp-edges;image-rendering:pixelated;-ms-interpolation-mode:nearest-neighbor}:root{--dm0:%25237a09fa;--dm1:%252337104f;--dm2:%2523661e92;--dm3:%2523db3ffd;--dm4:%2523630460;--dm5:%2523b0151a;--dm6:%2523ed1c24;--dm7:%2523f01343;--dm8:%2523876776;--dm9:%2523b48a9e;--dm10:%2523f0b8d3;--dm11:%2523f7941d;--dm12:%2523fff200;--dm13:%2523fcd617;--dm14:%2523fbd958;--dm15:%2523fae391;--dm16:%2523005d2e;--dm17:%2523007c3d;--dm18:%2523209e35;--dm19:%252300a651;--dm20:%252339b54a;--dm21:%2523aaff4f;--dm22:%25232d1c50;--dm23:%252309080b;--dm24:%25231b1a2c;--dm25:%25231e205e;--dm26:%25232e3192;--dm27:%25231452cc;--dm28:%25231dc0ed;--dm29:%2523393754;--dm30:%25232a4c69;--dm31:%25231e8492;--dm32:%25238393ca;--dm33:%2523404247;--dm34:%252356585f;--dm35:%25235a5a5a;--dm36:%2523707070;--dm37:%2523898989;--dm38:%2523b7b7b7;--dm39:%2523dddddd;--dm40:%25234f3810;--dm41:%252392671e;--dm42:%2523bbaa6d;--dm43:%25233e3531;--dm44:%2523534741;--dm45:%25237d5e52;--dm46:%252347210e;--dm47:%2523603114;--dm48:%252380421b;--dm49:%2523984f1d;--dm50:%25233e2309;--dm51:%2523522b0c;--dm52:%252376451d;--dm53:%252394623d;--dm54:%2523cf9768;--dm55:%2523efc088;--dm56:%2523f1c998;--dm57:%2523e4af8f;--dm58:%2523e9c4af;--dm59:%2523f0d0bd;--dmw15:rgba(255,255,255,.15);--dmw25:rgba(255,255,255,.25);--dmb15:rgba(0,0,0,.15);--dmb2:rgba(0,0,0,.2);--dmb25:rgba(0,0,0,.25);--dmb35:rgba(0,0,0,.35);--dmb4:rgba(0,0,0,.4);--dmb5:rgba(0,0,0,.5);--dmb6:rgba(0,0,0,.6);--dmb68:rgba(0,0,0,.68);--dmtl:rgba(255,215,0,.1);--dmc:var(--dm29);--dme:white;}.c0{fill:var(--dm6)}.c1{fill:var(--dm11)}.c2{fill:var(--dm12)}.c3{fill:var(--dm18)}.c4{fill:var(--dm28)}.c5{fill:var(--dm27)}.c6{fill:var(--dm0)}.c7{fill:var(--dm3)}%253C/style%253E%253Cdefs%253E%253Cpattern id=\'c\' width=\'2\' height=\'2\' viewBox=\'0 0 2 2\' patternUnits=\'userSpaceOnUse\'%253E%253Cpath d=\'M0,0h2v2h-2z\' fill=\'var(--dm38)\'/%253E%253Cpath d=\'M0,0h1v1h1v1h-1v-1h-1z\' fill=\'var(--dm33)\'/%253E%253C/pattern%253E%253ClinearGradient id=\'s\' x1=\'0\' x2=\'1\' y1=\'0\' y2=\'1\'%253E%253Cstop offset=\'0%2525\' stop-color=\'var(--dm38)\'/%253E%253Cstop offset=\'100%2525\' stop-color=\'var(--dm37)\'/%253E%253C/linearGradient%253E%253ClinearGradient id=\'g\' x1=\'0\' x2=\'1\' y1=\'0\' y2=\'1\'%253E%253Cstop offset=\'0%2525\' stop-color=\'var(--dm42)\'/%253E%253Cstop offset=\'100%2525\' stop-color=\'var(--dm41)\'/%253E%253C/linearGradient%253E%253ClinearGradient id=\'f\' x1=\'0\' x2=\'1\' y1=\'0\' y2=\'1\'%253E%253Cstop offset=\'0%2525\' stop-color=\'%25238393ca\'%253E%253Canimate attributeName=\'stop-color\' values=\'%25238393ca;%25231dc0ed;%2523aaff4f;%2523db3ffd;%25238393ca\' dur=\'6s\' repeatCount=\'indefinite\'%253E%253C/animate%253E%253C/stop%253E%253Cstop offset=\'33%2525\' stop-color=\'%25231dc0ed\'%253E%253Canimate attributeName=\'stop-color\' values=\'%25231dc0ed;%2523aaff4f;%2523db3ffd;%25238393ca;%25231dc0ed\' dur=\'6s\' repeatCount=\'indefinite\'%253E%253C/animate%253E%253C/stop%253E%253Cstop offset=\'66%2525\' stop-color=\'%2523aaff4f\'%253E%253Canimate attributeName=\'stop-color\' values=\'%2523aaff4f;%2523db3ffd;%25238393ca;%25231dc0ed;%2523aaff4f\' dur=\'6s\' repeatCount=\'indefinite\'%253E%253C/animate%253E%253C/stop%253E%253Cstop offset=\'100%2525\' stop-color=\'%2523db3ffd\'%253E%253Canimate attributeName=\'stop-color\' values=\'%2523db3ffd;%25238393ca;%25231dc0ed;%2523aaff4f;%2523db3ffd\' dur=\'6s\' repeatCount=\'indefinite\'%253E%253C/animate%253E%253C/stop%253E%253C/linearGradient%253E%253C/defs%253E%253Cimage href=\'data:image/gif;base64,', _background(bgType), '\'/%253E%253Cpath d=\'M0,0h57v57h-57z\' class=\'c', spawnType, (bgType == 0 ? '\' style=\'mix-blend-mode:color\'/%253E' : '\' style=\'display:none\'/%253E'), body, '%253Cpath d=\'M0,0h57v57h-57v-56h1v55h55v-55h-56z\' fill=\'', _frame(frameType), '\'/%253E%253C/svg%253E' )); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; library SmSVG { /** * @notice render a double-encoded data URI for the attempt SVG * @param body body of the SVG markup * @return string of svg as a data uri */ function render(string memory body, string memory minerStats) external pure returns (string memory) { return string(abi.encodePacked( 'data:image/svg+xml,%253Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'100%\' height=\'100%\' viewBox=\'0 0 114 114\' preserveAspectRatio=\'xMidYMid meet\'%253E%253Cstyle%253E*{shape-rendering:crispedges;image-rendering:-webkit-crisp-edges;image-rendering:-moz-crisp-edges;image-rendering:crisp-edges;image-rendering:pixelated;-ms-interpolation-mode:nearest-neighbor}:root{--dm0:%25237a09fa;--dm1:%252337104f;--dm2:%2523661e92;--dm3:%2523db3ffd;--dm4:%2523630460;--dm5:%2523b0151a;--dm6:%2523ed1c24;--dm7:%2523f01343;--dm8:%2523876776;--dm9:%2523b48a9e;--dm10:%2523f0b8d3;--dm11:%2523f7941d;--dm12:%2523fff200;--dm13:%2523fcd617;--dm14:%2523fbd958;--dm15:%2523fae391;--dm16:%2523005d2e;--dm17:%2523007c3d;--dm18:%2523209e35;--dm19:%252300a651;--dm20:%252339b54a;--dm21:%2523aaff4f;--dm22:%25232d1c50;--dm23:%252309080b;--dm24:%25231b1a2c;--dm25:%25231e205e;--dm26:%25232e3192;--dm27:%25231452cc;--dm28:%25231dc0ed;--dm29:%2523393754;--dm30:%25232a4c69;--dm31:%25231e8492;--dm32:%25238393ca;--dm33:%2523404247;--dm34:%252356585f;--dm35:%25235a5a5a;--dm36:%2523707070;--dm37:%2523898989;--dm38:%2523b7b7b7;--dm39:%2523dddddd;--dm40:%25234f3810;--dm41:%252392671e;--dm42:%2523bbaa6d;--dm43:%25233e3531;--dm44:%2523534741;--dm45:%25237d5e52;--dm46:%252347210e;--dm47:%2523603114;--dm48:%252380421b;--dm49:%2523984f1d;--dm50:%25233e2309;--dm51:%2523522b0c;--dm52:%252376451d;--dm53:%252394623d;--dm54:%2523cf9768;--dm55:%2523efc088;--dm56:%2523f1c998;--dm57:%2523e4af8f;--dm58:%2523e9c4af;--dm59:%2523f0d0bd;--dmw15:rgba(255,255,255,.15);--dmw25:rgba(255,255,255,.25);--dmb15:rgba(0,0,0,.15);--dmb2:rgba(0,0,0,.2);--dmb25:rgba(0,0,0,.25);--dmb35:rgba(0,0,0,.35);--dmb4:rgba(0,0,0,.4);--dmb5:rgba(0,0,0,.5);--dmb6:rgba(0,0,0,.6);--dmb68:rgba(0,0,0,.68);--dmtl:rgba(255,215,0,.1);--dmc:var(--dm29)}.n{animation:a 1s infinite}.c0{fill:var(--dm6)}.c1{fill:var(--dm11)}.c2{fill:var(--dm12)}.c3{fill:var(--dm18)}.c4{fill:var(--dm28)}.c5{fill:var(--dm27)}.c6{fill:var(--dm0)}.c7{fill:var(--dm3)}@keyframes a{from{opacity:1}50%25{opacity:0}to{opacity:1}}@keyframes b{from{transform:translate(0,0)}50%25{transform:translate(1px,0)}to{transform:translate(0,0)}}@keyframes c{from{transform:translate(0,0);opacity:1}10%25{transform:translate(0,-4px);opacity:0}to{transform:translate(0,-4px);opacity:0}}@keyframes d{from{transform:rotateX(0deg)}25%25{transform:rotateX(30deg)}50%25{transform:rotateX(0deg)}to{transform:rotateX(0deg)}}@keyframes e{from{opacity:0.8}25%25{opacity:0}to{opacity:0}}@keyframes f{from{transform:translate(0,0)}5%25{transform:translate(1px,0)}20%25{transform:translate(1px,0)}25%25{transform:translate(0,0)}to{transform:translate(0,0)}}@keyframes g{from{transform:translate(0,0)}25%25{transform:translate(0,-1px)}50%25{transform:translate(0,0)}75%25{transform:translate(0,0)}to{transform:translate(0,0)}}@keyframes h{from{transform:translate(0,0) rotateZ(0)}25%25{transform:translate(0,-1px) rotateZ(2deg)}50%25{transform:translate(0,0) rotateZ(0)}75%25{transform:translate(0,-1px) rotateZ(-2deg)}to{transform:translate(0,0) rotateZ(0)}}@keyframes i{from{transform:translate(0,0)}50%25{transform:translate(0,3px)}to{transform:translate(0,0)}}@keyframes j{from{transform:rotateY(-90deg) translateZ(1px);filter:brightness(150%25)}50%25{transform:rotateY(0) translateZ(1px);filter:brightness(100%25)}to{transform:rotateY(90deg) translateZ(1px);filter:brightness(50%25)}}@keyframes k{from{transform:translate(0,.5px) rotateZ(2deg)}25%25{transform:translate(0,0) rotateZ(0)}50%25{transform:translate(0,.5px) rotateZ(-2deg)}75%25{transform:translate(0,0) rotateZ(0)}to{transform:translate(0,.5px) rotateZ(2deg)}}@keyframes l{from{transform:translate(0,0)}50%25{transform:translate(0,.5px)}to{transform:translate(0,0)}}@keyframes m{from{transform:translate(0,0);opacity:1}5%25{transform:translate(0,3px);opacity:1}10%25{transform:translate(0,6px);opacity:0}to{transform:translate(0,6px);opacity:0}}@keyframes n{from{filter:invert(0)}50%25{filter:invert(1)}to{filter:invert(0)}}@keyframes o{from{transform:scale(1);opacity:1}20%25{transform:scale(11);opacity:0}to{transform:scale(1);opacity:0}}%2523e0{transform-origin:6px 10px;animation:d 4s infinite}.f path{animation:b 1s infinite}%2523e1 g:nth-of-type(1),%2523e1 g:nth-of-type(2){animation:g 2s infinite}%2523e1 g:nth-of-type(2){animation-delay:-1s}%2523e1 g:nth-of-type(3){transform-origin:6px 6px;animation:k 2s infinite}%2523e1 g:nth-of-type(1) path:nth-of-type(2),%2523e1 g:nth-of-type(2) path:nth-of-type(3){animation:a 2s infinite;animation-delay:-1s}%2523e1 g:nth-of-type(1) path:nth-of-type(3),%2523e1 g:nth-of-type(2) path:nth-of-type(2){animation:a 2s infinite}%2523e2{animation:h 4s infinite;transform-origin:6px 6px}%2523e2 g{animation:i 2s infinite}%2523e3 g:nth-of-type(1){animation:l 2s infinite}%2523e3 g:nth-of-type(2){animation:l 2s infinite;animation-delay:-1.9s}%2523e3 g:nth-of-type(5),%2523e3 g:nth-of-type(6){animation:l 2s infinite;animation-delay:-1.8s}%2523e3 g:nth-of-type(5) path:nth-of-type(3){animation:m 7s infinite linear}%2523e5{animation:l 4s infinite}%2523e5 path:first-of-type{animation:n 2.5s infinite}%2523e6 path:nth-of-type(2),%2523e6 path:nth-of-type(3),%2523e7 path:nth-of-type(2),%2523e7 path:nth-of-type(3){animation:j 3s infinite;transform-origin:6px 6px}%2523e6 path:nth-of-type(2),%2523e7 path:nth-of-type(2){animation-delay:-1.5s}%2523e8 %253E g path{animation:e infinite}%2523e8 %253E g path:nth-of-type(1){animation-duration:4s;animation-delay:-0.75s}%2523e8 %253E g path:nth-of-type(2){animation-duration:3s}%2523e8 %253E g path:nth-of-type(3){animation-duration:5s;animation-delay:-2.15s}%2523e8 %253E g path:nth-of-type(4){animation-duration:6s;animation-delay:-1s}%2523e9 path:nth-of-type(2){animation:f 8s infinite}%2523e15 path{animation:b 4s infinite}%2523e15 path:nth-of-type(2){animation-delay:-2s}%2523e16 rect,%2523e6 rect,%2523e7 rect{animation:c infinite}%2523e16 rect:nth-of-type(1){animation-duration:7s;animation-delay:-0.75s}%2523e16 rect:nth-of-type(2){animation-duration:4s}%2523e16 rect:nth-of-type(3){animation-duration:10s;animation-delay:-2.15s}%2523e16 rect:nth-of-type(4){animation-duration:5s;animation-delay:-1s}.h %253E g,.h %253E g:nth-of-type(3) %253E g:first-of-type,.h %253E g:nth-of-type(4) %253E g,.h %253E g:nth-of-type(5) path{animation:l 2s infinite}.h %253E g:nth-of-type(3),.h %253E g:nth-of-type(4),.h %253E g:nth-of-type(5){animation:none}.h %253E g:nth-of-type(4) %253E g:nth-of-type(1),.h %253E g:nth-of-type(4) %253E g:nth-of-type(3){animation-delay:-1.95s}.h %253E g:nth-of-type(4) %253E g:nth-of-type(4){animation-delay:-1.9s}.h %253E g:nth-of-type(5) path:nth-of-type(2),.h %253E g:nth-of-type(7){animation-delay:-1.85s}.se path{transform-origin:11px 11px;animation:o 6s infinite}.se path:nth-of-type(2){animation-delay:-2s}.se path:nth-of-type(3){animation-delay:-4s}@font-face{font-family:\'txt\';src:url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAAdsABAAAAAAC7AAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABbAAAABwAAAAcja3TXUdERUYAAAGIAAAAHAAAAB4AJwAWR1BPUwAAAaQAAACkAAAA+BVXIoxHU1VCAAACSAAAACwAAAAwuP+4/k9TLzIAAAJ0AAAAUQAAAGBaR5KLY21hcAAAAsgAAABXAAABUhJ0SA5jdnQgAAADIAAAAAQAAAAEACECeWdhc3AAAAMkAAAACAAAAAj//wADZ2x5ZgAAAywAAAHAAAADYIgAY9poZWFkAAAE7AAAADMAAAA2FUXaomhoZWEAAAUgAAAAHAAAACQGEAHsaG10eAAABTwAAAAnAAAANhH1AeNsb2NhAAAFZAAAACIAAAAiBsgGDG1heHAAAAWIAAAAHwAAACAAWQBNbmFtZQAABagAAAF6AAAC7iBFbQlwb3N0AAAHJAAAAEYAAABYUqv82AAAAAEAAAAA2odvjwAAAADVbK0RAAAAAN25trx42mNgZGBg4AFiMSBmYmAEQn4gZgHzGAAEQwA+eNpNjr0NwjAUhL/8kDjBZABKJkBUVKkQFWUWIBISEigFQszBAIiKeRiAXYg5OykoPt/5vTvZREDJkpp4s901VOf9tWNOqjnO4ff/PjodLh3Gu0BKHNSIV0haFjS0HEXLLZx38dQm6S1pXzP5fsikuTDyhSjlp8LKz6SVNCFxbzUshVvrBX8bZoV7YEU2JLwTuTDjZuyq57PqstJfvVbwAzvDOvV42mNgZGBg4GLQYdBjYHJx8wlh4MtJLMljkGBgAYoz/P8PJBAsIAAAnsoHa3jaY2BhfMI4gYGVgYWpi2k3AwNDD4RmvM9gyMjEwMDEwMrMAAPMAiABKPAOcMtkOMCgoPqHWeG/BVBSgdEBKMwIkmP8wrQHSCkwMAEAfGEMtAAAAHjaY2BgYGaAYBkGRgYQ8AHyGMF8FgYDIM0BhExAWoHBUvXP//9glj6I9f/x/6u3hKG6wICRjQHOZQTpYWJABYwQq5AACysbOwcnFzcPLx/DsAAAGUoM1AAAIQJ5AAAAAf//AAJ42nVTwUoDMRCdSVqXYkVCWUSkh2XBghSFXZZe6s1/sB8QPPdTeu4XeG3P9eKl+YAe/QAveupJ7OKbJF2raCDZJLvz5r03s6QoI+IrNSdNCV0vmG7Gy6RFb8XiqP0yXmqFLS20XLflepkc8ed4yXJfmswMSpNn3Hldr9V895CpCQGnIFLvauUxj+mUenRGF0RlVaa3/Pcs7P+DiFqCyc/qqcGkkSlNWo1SjXnOpSmsc85a3tZdrFbdY6m7ckQ8Szx9gFNC1KvAxORGcvLW2t0db/FWxxwr6tAJpZ4vGOdplnJkHqKc42E9tUjmbITAqDc8pHaDISyj7hGigVPpquzzr72geRzngliexSMPZXWw0vt5CUxxUtinZZVDAXDAZxBQPBdneSi7euPpOO/dty4ddAkfXWXQJUyMIJlcKsCzeuMiEZ75J8yE2M1hDVZNTaUG3iHM/t4jHVVFIHEnkBNNEBf0ND5DT4bs0FNp8CjkE3yuJiLCut2jpD/IrQ9d1b5CoiLfa2m6yZvoopXhADlTz+MHXhK1BLwUGOKudEjUEmO9HkA5X3sHZ0DSSm9Jg23RQ5oIv0QmPRf67gvXHN4geNpjYGQAAmPjswfWpMbz23xlkGd+ARK5mrNWEETf3bltD4hmese0F0hxMDCBeAB6vgxvAHjaY2BkYGBW+HcARDIAAdM7BkYGVMANAE1nAwJ42mPMYVBkAAJGXyCRwsDArMBgxPgFiHWgNBAzRUBoOGQAAMdwB+UAAAAAKgAqACoAKgBUAHQAhgCoANIA8gEWAToBVAF8AaIBsAAAeNpjYGRgYBBgkGFgZwABJiBmZACJOTDogQQACCwApwB42n1RXUsCQRQ9s1rUQ9JTiPQw9BAFYetihT71AUElGSn1nLaZuK3mbkJ/pJ8R/Yyy/kA99St67szdSURChrn33HvPnHtnBkAGz0hBpecBvHAnWGGZUYIdcj4sTjH/ZXEaG/ixeAZZtWLxLHKqbPEC9lXd4gyK6sniVyypocVvcNW3xUPMOYsWvyPjZBP8mULOWcUBuujhEX200cItYmisoYl1eg8uCihxJo1jXCEi0yfTxOc815AottUGAuZCsjrU0tjlPiEKyYrpmzgjw6jc0WocCjtmbPT2WAtE92+OSCKf3nQZ0F4jL/OGotkUVRNpHMky7BYepEt/KnNaTU/oXEj/aMRyOYVH/59GolDjrpBRlfcKx+6qmTcv4cs7+Ywn1QtUL8j9Y54uY5Mr4gnzPz15lbywA/ousy3Wq9Sv4JJKDdyMOhklF3Xew/Q5ZX4g2W2xRWp72KHdok3+2mO+Q7bPTj07l8/z0dj8Ndwz02atz1rwC0zLcWwAAHjaY2BiAIP/zQxGDNiAAAMDIxMjMwMzgxCDMIMIgyiDGIM4gwSDJIMUgzSDDCMLW3pOZUGGIYQyYi/NyzQydXMGAAIJCc0AAA==) format(\'woff\');font-weight:normal;font-style:normal}text{filter:drop-shadow(0px 1px 0px rgba(0,0,0,.2))}%253C/style%253E%253Cdefs%253E%253Cpattern id=\'ch1\' x=\'1\' y=\'0\' width=\'2\' height=\'2\' viewBox=\'0 0 2 2\' patternUnits=\'userSpaceOnUse\'%253E%253Cpath d=\'M0,0h1v1h1v1h-1v-1h-1z\' fill=\'var(--dm41)\'/%253E%253C/pattern%253E%253Cpattern id=\'ch2\' x=\'1\' y=\'0\' width=\'2\' height=\'2\' viewBox=\'0 0 2 2\' patternUnits=\'userSpaceOnUse\'%253E%253Cpath d=\'M0,0h1v1h1v1h-1v-1h-1z\' fill=\'var(--dm37)\'/%253E%253C/pattern%253E%253Cpattern id=\'ch3\' x=\'1\' y=\'0\' width=\'2\' height=\'2\' viewBox=\'0 0 2 2\' patternUnits=\'userSpaceOnUse\'%253E%253Cpath d=\'M0,0h1v1h1v1h-1v-1h-1z\' fill=\'var(--dm48)\'/%253E%253C/pattern%253E%253Cg id=\'a\'%253E%253Cpath d=\'M0,0h12v12h-12z\'/%253E%253Cpath d=\'M0,10h12v2h-12z\' fill=\'var(--dmb25)\'/%253E%253Cpath d=\'M2,2h8v8h2v2h-2v-1h-1v-1h-6v1h-1v1h-2v-2h2z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M2,2h8v8h2v2h-1v-1h-1v-1h-8v1h-1v1h-1v-2h2z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M2,2h8v8h-8z\' fill=\'var(--dmb35)\'/%253E%253Cpath d=\'M2,2h8v8h-3v-2h-2v2h-3z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M2,2h8v8h-2v-2h-1v-1h-2v1h-1v2h-2z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M2,2h8v8h-1v-3h-1v-1h-4v1h-1v3h-1z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M2,2h8v3h-1v-1h-6v1h-1z\' fill=\'var(--dmb15)\'/%253E%253C/g%253E%253Cpath id=\'u\' d=\'M0,0h12v12h-12z\' fill=\'var(--dmw15)\'/%253E%253Cg id=\'e0\'%253E%253Cpath d=\'M5,6h2v1h1v1h1v2h-6v-2h1v-1h1z\' fill=\'var(--dm6)\'/%253E%253Cpath d=\'M4,8h1v1h-1zM6,8h1v1h-1z\' fill=\'black\'/%253E%253Cpath d=\'M6,6h1v1h1v1h1v2h-1v-2h-1v-1h-1zM4,9h1v1h-1zM6,9h1v1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg id=\'e1\'%253E%253Cpath d=\'M4,7h4v2h-4z\' fill=\'var(--dm4)\'/%253E%253Cg%253E%253Cpath d=\'M3,8h1v2h-1z\' fill=\'var(--dm4)\'/%253E%253Cpath d=\'M3,8h1v1h-1z\' fill=\'var(--dmb25)\'/%253E%253Cpath d=\'M3,9h1v1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M8,8h1v2h-1z\' fill=\'var(--dm4)\'/%253E%253Cpath d=\'M8,8h1v1h-1z\' fill=\'var(--dmb25)\'/%253E%253Cpath d=\'M8,9h1v1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M4,4h4v1h1v1h-1v1h-1v1h-2v-1h-1v-1h-1v-1h1z\' fill=\'white\'/%253E%253Cpath d=\'M4,5h1v1h-1zM7,5h1v1h-1z\' fill=\'var(--dm6)\'/%253E%253Cpath d=\'M4,4h1v1h-1zM7,4h1v1h1v1h-1v2h-1v1h-2v-1h-1v-1h1v1h1v-1h1v-1h1v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253C/g%253E%253Cg id=\'e2\'%253E%253Cg%253E%253Cpath d=\'M3,3h1v3h-1zM8,3h1v3h-1z\' fill=\'var(--dm4)\'/%253E%253Cpath d=\'M8,3h1v3h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cpath d=\'M4,4h1v4h-1zM7,4h1v4h-1z\' fill=\'var(--dm4)\'/%253E%253Cpath d=\'M5,5h2v3h1v1h-1v-1h-2v1h-1v-1h1z\' fill=\'var(--dm18)\'/%253E%253Cpath d=\'M5,6h2v1h-2z\' fill=\'white\'/%253E%253Cpath d=\'M4,4h1v2h-1zM6,5h1v1h1v3h-1v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg id=\'e3\'%253E%253Cg%253E%253Cpath d=\'M5,3h2v2h-2z\' fill=\'white\'/%253E%253Cpath d=\'M6,4h1v1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M4,5h1v1h-1zM7,5h1v1h-1z\' fill=\'white\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M5,6h2v2h-2z\' fill=\'white\'/%253E%253Cpath d=\'M6,6h1v2h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M4,8h1v2h-1zM7,8h1v2h-1z\' fill=\'white\'/%253E%253Cpath d=\'M7,8h1v2h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M3,6h1v1h-1z\' fill=\'white\'/%253E%253Cpath d=\'M3,4h1v2h-1z\' fill=\'var(--dm38)\'/%253E%253Cpath d=\'M3,3h1v1h-1z\' fill=\'var(--dm6)\'/%253E%253Cpath d=\'M3,3h1v1h-1z\' fill=\'var(--dm6)\'/%253E%253C/g%253E%253Cg%253E%253Cpath d=\'M7,6h1v2h-1z\' fill=\'white\'/%253E%253Cpath d=\'M8,6h1v3h-1z\' fill=\'var(--dm48)\'/%253E%253Cpath d=\'M7,6h1v1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253C/g%253E%253Cg id=\'e4\'%253E%253Cpath d=\'M3,9h1v-1h2v1h2v-1h1v2h-6z\' fill=\'var(--dm38)\'/%253E%253Cpath d=\'M3,7h1v2h-1zM5,7h2v2h-1v-1h-1zM8,7h1v1h-1z\' fill=\'var(--dm6)\'/%253E%253Cpath d=\'M4,8h1v2h-1zM6,7h1v3h-1zM8,7h1v3h-1z\' fill=\'var(--dmb15)\'/%253E%253C/g%253E%253Cg id=\'e5\'%253E%253Cpath d=\'M3,3h1v1h4v-1h1v1h-1v3h-1v1h-2v-1h-1v-3h-1zM3,8h1v1h-1zM8,8h1v1h-1z\' fill=\'var(--dm9)\'/%253E%253Cpath d=\'M4,4h1v1h1v1h-1v-1h-1zM5,7h1v1h-1z\' fill=\'var(--dmb15)\'/%253E%253Cpath d=\'M3,3h1v1h-1zM8,3h1v1h-1v3h-1v1h-1v-1h1v-1h-1v-1h1v-1h1zM3,8h1v1h-1zM8,8h1v1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg id=\'e6\'%253E%253Cpath d=\'M4,8h4v1h-1v1h-2v-1h-1z\' fill=\'var(--dm36)\'/%253E%253Cpath d=\'M5,5h2v2h-2z\' fill=\'var(--dm18)\'/%253E%253Cpath d=\'M5,5h2v2h-2z\' fill=\'var(--dm18)\'/%253E%253Cpath d=\'M7,8h1v1h-1v1h-1v-1h1z\' fill=\'var(--dmb15)\'/%253E%253C/g%253E%253Cg id=\'e7\'%253E%253Cpath d=\'M4,8h4v1h-1v1h-2v-1h-1z\' fill=\'var(--dm36)\'/%253E%253Cpath d=\'M5,5h2v2h-2z\' fill=\'var(--dm6)\'/%253E%253Cpath d=\'M5,5h2v2h-2z\' fill=\'var(--dm6)\'/%253E%253Cpath d=\'M7,8h1v1h-1v1h-1v-1h1z\' fill=\'var(--dmb15)\'/%253E%253C/g%253E%253Cg id=\'e8\'%253E%253Cpath d=\'M3,9h1v-2h2v1h2v1h1v1h-6z\' fill=\'var(--dm13)\'/%253E%253Cpath d=\'M3,9h1v1h-1zM5,7h1v3h-1zM7,8h1v2h-1z\' fill=\'var(--dmb25)\'/%253E%253Cg%253E%253Cpath d=\'M4,7h1v1h-1z\' fill=\'white\'/%253E%253Cpath d=\'M8,9h1v1h-1z\' fill=\'white\'/%253E%253Cpath d=\'M6,8h1v1h-1z\' fill=\'white\'/%253E%253Cpath d=\'M4,9h1v1h-1z\' fill=\'white\'/%253E%253C/g%253E%253C/g%253E%253Cg id=\'e9\'%253E%253Cpath d=\'M5,4h2v2h-2z\' fill=\'var(--dm33)\'/%253E%253Cpath d=\'M5,5h1v1h-1z\' fill=\'var(--dm58)\'/%253E%253Cpath d=\'M5,7h1v1h-1zM7,7h1v1h-1z\' fill=\'var(--dm58)\'/%253E%253Cpath d=\'M6,6h2v1h-1v1h-1z\' fill=\'var(--dm48)\'/%253E%253Cpath d=\'M5,8h2v1h1v1h-1v-1h-1v1h-1z\' fill=\'var(--dm26)\'/%253E%253Cpath d=\'M3,5h1v1h1v1h-1v-1h-1z\' fill=\'var(--dm38)\'/%253E%253Cpath d=\'M6,4h1v2h1v1h-1v-1h-1zM5,9h1v1h-1zM7,9h1v1h-1z\' fill=\'var(--dmb15)\'/%253E%253C/g%253E%253Cg id=\'e10\'%253E%253C/g%253E%253Cg id=\'e11\'%253E%253Cpath d=\'M8,7h1v3h-6v-2h5z\' fill=\'var(--dm48)\'/%253E%253Cpath d=\'M4,8h3v1h-3z\' fill=\'var(--dm38)\'/%253E%253Cpath d=\'M7,8h1v1h-1z\' fill=\'white\'/%253E%253Cpath d=\'M4,9h4v1h-4z\' fill=\'var(--dmb15)\'/%253E%253C/g%253E%253Cg id=\'e12\'%253E%253Cpath d=\'M4,6h4v3h-1v1h-2v-1h2v-1h-2v1h-1z\' fill=\'var(--dm38)\'/%253E%253Cpath d=\'M7,6h1v3h-1v1h-1v-1h1v-1h-2v-1h2z\' fill=\'var(--dmb15)\'/%253E%253C/g%253E%253Cg id=\'e13\'%253E%253Cpath d=\'M6,7h1v1h-1z\' fill=\'var(--dm27)\'/%253E%253Cpath d=\'M6,6h1v1h-1z\' fill=\'var(--dm58)\'/%253E%253Cpath d=\'M3,5h1v3h4v-3h1v5h-6z\' fill=\'var(--dm48)\'/%253E%253Cpath d=\'M3,4h6v1h-6zM4,8h4v1h-4z\' fill=\'var(--dm38)\'/%253E%253Cpath d=\'M4,4h1v1h-1zM6,4h1v1h-1zM8,4h1v1h-1z\' fill=\'var(--dm6)\'/%253E%253Cpath d=\'M3,5h1v1h-1zM8,5h1v5h-1v-1h-1v-1h1z\' fill=\'var(--dmb15)\'/%253E%253C/g%253E%253Cg id=\'e14\'%253E%253Cpath d=\'M4,6h4v1h1v3h-6v-3h1z\' fill=\'var(--dm48)\'/%253E%253Cpath d=\'M5,7h2v1h-2z\' fill=\'var(--dm12)\'/%253E%253Cpath d=\'M4,6h1v2h1v-2h2v1h-1v1h1v-1h1v3h-1v-1h-1v1h-1v-1h-1v1h-1v-1h-1v-1h1z\' fill=\'var(--dmb15)\'/%253E%253C/g%253E%253Cg id=\'e15\'%253E%253Cpath d=\'M5,5h1v1h1v1h-1v1h-1v-1h-1v-1h1z\' fill=\'var(--dm5)\'/%253E%253Cpath d=\'M5,5h1v1h1v1h-1v1h-1v-1h-1v-1h1z\' fill=\'var(--dm6)\'/%253E%253C/g%253E%253Cg id=\'e16\'%253E%253Crect x=\'5\' y=\'8\' height=\'1\' width=\'1\' fill=\'var(--dm28)\'/%253E%253Crect x=\'5\' y=\'8\' height=\'1\' width=\'1\' fill=\'var(--dm28)\'/%253E%253Crect x=\'6\' y=\'8\' height=\'1\' width=\'1\' fill=\'var(--dm28)\'/%253E%253Crect x=\'6\' y=\'8\' height=\'1\' width=\'1\' fill=\'var(--dm28)\'/%253E%253Cpath d=\'M4,8h4v1h-1v1h-2v-1h-1z\' fill=\'var(--dm28)\'/%253E%253Cpath d=\'M5,6h2v2h1v1h-1v1h-2v-1h-1v-1h1v1h2v-1h-2z\' fill=\'var(--dmw25)\'/%253E%253Cpath d=\'M5,6h2v1h-1v1h-1v1h1v1h-1v-1h-1v-1h1z\' fill=\'var(--dmw25)\'/%253E%253Cpath d=\'M6,6h1v2h1v1h-1v1h-2v-1h2v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253Cg id=\'e17\'%253E%253Cpath d=\'M3,3h1v1h1v1h-1v-1h-1zM8,3h1v1h-1v1h-1v-1h1z\' fill=\'var(--dm28)\'/%253E%253Cpath d=\'M3,5h1v1h4v-1h1v2h-1v1h-1v1h-2v-1h-1v-1h-1z\' fill=\'white\'/%253E%253Cpath d=\'M3,5h1v1h-1zM8,5h1v1h-1zM5,6h2v1h-2zM4,7h1v1h2v-1h1v1h-1v1h-2v-1h-1z\' fill=\'var(--dmb25)\'/%253E%253C/g%253E%253C/defs%253E%253Cimage href=\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHIAAAByCAMAAAC4A3VPAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAFpQTFRFNS0qW1NQDw4ZCwoTFxYlFBMhLiglGxost7e3FBMg7RwkIJ41vaARgEIbPiMJ/NYXiYmJshUbYDEUGHYoERAbv7+/////LhoHg5PKYm6XPjUxHBsqGxopGhknav76VwAAAaxJREFUeNrsl21vgjAUhWFzXWdhyngRu/H//+baWwZM762BzPph58Q0JjU8uSePN5oNyZMNX58uKU+H9El5Zg8oNnGr7swStzo8plgYC2NhLIyFsTAWxsJYGAtjYSyMhbEwFsbCWBgLY2EsjIWxMBbGwlgYC2NhLIyFsTAWxsJYGAtjYexmY/OkoWJzmzAZGZvbZzb3QZKxiZGh2AhyX/mXHK3Fq0MhFDvQlE9XCcg9pYoQjyuRwdjtSEdUIo9HTsVuQfYRouMdiiJqrIRUROSfq3qZSEhuzNlYx3hZZEJ6ZiU9tz+LxEJGLorlkVbJRKXO65FLYwWkFSdRsbuQG8Y60ivlAnmvVZAOuTQ21ZS/jWWQWosLpuva1hrD3pUhW4rVWmZ6P4ypeeS7T3nb2HXIzs9YR5CmlI1tmjfKjhLeNw0hyXVpSk9UItKcIsU2M2+mBiR9jke2xiGFb2ZpHFEq1ht7ARyhhDz+HNwqcEwjIE+OyCJHY6+ABKXHepqwvLtW1RLzI0QudsdmWndKWmqWX2rRhTcaG0H++SoYjU35o5KKzZLmv/zz+hZgABfeLcXmx3tAAAAAAElFTkSuQmCC\'/%253E', body, minerStats, '%253C/svg%253E' )); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": { "contracts/Libraries/Calcs.sol": { "Calcs": "0x59e24f4a617617443e7dc14fcbaa2fe6234ddc75" }, "contracts/Libraries/Metadata.sol": { "Metadata": "0x63166bcfe21484217eff188d44a65bc5ba317a53" } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"treasuryAddress","type":"address"}],"stateMutability":"payable","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":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"startTokenId","type":"uint256"}],"name":"AttemptStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":true,"internalType":"bytes32","name":"hash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"startTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"difficultyTarget","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"difficultyRadius","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"itemId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"classId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"genderId","type":"uint256"}],"name":"Mined","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"primaryWinner","type":"address"},{"indexed":false,"internalType":"uint256","name":"payout","type":"uint256"},{"indexed":true,"internalType":"address","name":"secondaryWinner","type":"address"},{"indexed":false,"internalType":"uint256","name":"secondaryPayout","type":"uint256"}],"name":"Redeemed","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":"uint256","name":"","type":"uint256"}],"name":"CLASSES","outputs":[{"internalType":"int16","name":"baseHealth","type":"int16"},{"internalType":"int16","name":"baseArmor","type":"int16"},{"internalType":"int16","name":"baseAttack","type":"int16"},{"internalType":"int16","name":"baseSpeed","type":"int16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"SHOP_ITEMS","outputs":[{"internalType":"uint256","name":"cost","type":"uint256"},{"internalType":"int16","name":"healthMod","type":"int16"},{"internalType":"int16","name":"armorMod","type":"int16"},{"internalType":"int16","name":"attackMod","type":"int16"},{"internalType":"int16","name":"speedMod","type":"int16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"approved","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"canRedeem","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDifficulty","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getMiner","outputs":[{"components":[{"internalType":"int16","name":"baseHealth","type":"int16"},{"internalType":"int16","name":"baseArmor","type":"int16"},{"internalType":"int16","name":"health","type":"int16"},{"internalType":"int16","name":"armor","type":"int16"},{"internalType":"int16","name":"attack","type":"int16"},{"internalType":"int16","name":"speed","type":"int16"},{"internalType":"uint16","name":"gold","type":"uint16"},{"internalType":"uint8","name":"genderId","type":"uint8"},{"internalType":"uint8","name":"classId","type":"uint8"},{"internalType":"uint8","name":"skintoneId","type":"uint8"},{"internalType":"uint8","name":"hairColorId","type":"uint8"},{"internalType":"uint8","name":"hairTypeId","type":"uint8"},{"internalType":"uint8","name":"eyeColorId","type":"uint8"},{"internalType":"uint8","name":"eyeTypeId","type":"uint8"},{"internalType":"uint8","name":"mouthId","type":"uint8"},{"internalType":"uint8","name":"headgearId","type":"uint8"},{"internalType":"uint8","name":"armorId","type":"uint8"},{"internalType":"uint8","name":"pantsId","type":"uint8"},{"internalType":"uint8","name":"footwearId","type":"uint8"},{"internalType":"uint8","name":"weaponId","type":"uint8"},{"internalType":"uint8","name":"curseTurns","type":"uint8"},{"internalType":"uint8","name":"buffTurns","type":"uint8"},{"internalType":"uint8","name":"debuffTurns","type":"uint8"},{"internalType":"uint8","name":"revives","type":"uint8"},{"internalType":"uint8","name":"currentChamber","type":"uint8"}],"internalType":"struct Miner","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint8","name":"chamberCount","type":"uint8"}],"name":"getMiner","outputs":[{"components":[{"internalType":"int16","name":"baseHealth","type":"int16"},{"internalType":"int16","name":"baseArmor","type":"int16"},{"internalType":"int16","name":"health","type":"int16"},{"internalType":"int16","name":"armor","type":"int16"},{"internalType":"int16","name":"attack","type":"int16"},{"internalType":"int16","name":"speed","type":"int16"},{"internalType":"uint16","name":"gold","type":"uint16"},{"internalType":"uint8","name":"genderId","type":"uint8"},{"internalType":"uint8","name":"classId","type":"uint8"},{"internalType":"uint8","name":"skintoneId","type":"uint8"},{"internalType":"uint8","name":"hairColorId","type":"uint8"},{"internalType":"uint8","name":"hairTypeId","type":"uint8"},{"internalType":"uint8","name":"eyeColorId","type":"uint8"},{"internalType":"uint8","name":"eyeTypeId","type":"uint8"},{"internalType":"uint8","name":"mouthId","type":"uint8"},{"internalType":"uint8","name":"headgearId","type":"uint8"},{"internalType":"uint8","name":"armorId","type":"uint8"},{"internalType":"uint8","name":"pantsId","type":"uint8"},{"internalType":"uint8","name":"footwearId","type":"uint8"},{"internalType":"uint8","name":"weaponId","type":"uint8"},{"internalType":"uint8","name":"curseTurns","type":"uint8"},{"internalType":"uint8","name":"buffTurns","type":"uint8"},{"internalType":"uint8","name":"debuffTurns","type":"uint8"},{"internalType":"uint8","name":"revives","type":"uint8"},{"internalType":"uint8","name":"currentChamber","type":"uint8"}],"internalType":"struct Miner","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"hashOf","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"uint256","name":"classId","type":"uint256"},{"internalType":"uint256","name":"genderId","type":"uint256"}],"name":"mine","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"uint256","name":"classId","type":"uint256"},{"internalType":"uint256","name":"genderId","type":"uint256"},{"internalType":"bool","name":"startNow","type":"bool"}],"name":"mine","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"redeem","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"redeemableValue","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":"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":"uint256","name":"tokenId","type":"uint256"}],"name":"startAttempt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"pure","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"}]
Contract Creation Code
608060405260006003556001600160ff1b036004557c1990b64a39cb81d974ffeca055dbc033c79935560eae7eef7858c2bde56005557c33216c94739703b2e9ffd940abb780678f326aac1d5cfddef0b1857bcb1960065560405162005471380380620054718339810160408190526200007991620006da565b346729a2241af62c0000146200008e57600080fd5b60208080527f90dd71dc990f2ce7f35ced37a039b35c934c9a354ddea897f86797ca3b1228ff8054600160ff1991821681179092557f7c440c08741bb00fea81a36cc06860e19678a93eb79170af6a46fe5d77d918e280548216831790556301ffc9a760e01b60009081527f139f2d4bfe2727da389bc055ae3f9fd85c7a6f7a206b7f77989ec8ea7e78fdc68054909216831790915580547379ac53f63728684f5b21b6302fc5cef5a8e8b7e96001600160a01b03199182161782558254166001600160a01b03851617909155604080516080808201835260c88252604b8286015260288284018190526060928301819052600780546001600160401b031990811666280028004b00c8179091558451808401865260c3815260558189015260238187018190529085019290925260088054821666280023005500c31790558451808401865260af815260508189015280860192909252603291840182905260098054821666320023005000af1790558451808401865260e18152605a81890152601e81870152840191909152600a805482166632001e005a00e1178155845160a08082018752878252818901889052818701889052818601889052908401879052600b879055600c805484169055855180820187526611c37937e08000808252600f828b018190528289018a90528288018a9052918601899052600d819055600e805486168317905587518084018952818152808b018a90528089018390528088018a9052860189905280825560108054620f000090871617905587518084018952818152808b018a90528089018a90528088018590528601899052601181905560128054640a0000000090871617905587518084018952818152808b018a90528089018a90528088018a9052860184905260135560148054660a00000000000090861617905586518083018852661aa535d3d0c000808252818b018390528189018a90528188018a90529086018490526015819055601680548616660a00000000000f17905587518084018952818152808b018a90528089018390528088018590528601899052601755601880548516640a000f000017905586519182018752662386f26fc1000080835298820181905295810195909552928401839052920152601992909255601a8054909216660a000a000f000f179091555b60328160ff161015620005a5576200040f6002620005ad60201b62001a8d1760201c565b600080546001600160a01b03168260ff811615620004405760ff84166000908152601b602052604090205462000443565b60005b42604051602001620004a2949392919060609490941b6001600160601b031916845260f89290921b7fff000000000000000000000000000000000000000000000000000000000000001660148401526015830152603582015260550190565b6040516020818303038152906040528051906020012090506000600283620004cb91906200077d565b60ff1690506000620004df60048462000766565b905062000509620004fc6002620005b660201b62001a961760201c565b84806000808688620005ba565b82336001600160a01b03166200052b6002620005b660201b62001a961760201c565b60045460055460408051600080825260208201949094529081019190915260608101919091526080810185905260a081018690527f607eb9f7f6c4b2d9b7c1d3c046521d90e79c6fbaebf614c533174cc9a44159919060c00160405180910390a450505080806200059c9062000743565b915050620003eb565b5050620007ce565b80546001019055565b5490565b6040805160a081018252878152602080820187905260ff8085168385015285811660608401528616608083015260008a8152601c825283812080546001600160a01b031916339081179091558152601d909152918220805491926200061f8362000725565b909155505060055460065462000636908862000766565b6200064291906200070a565b6004556000888152601b602090815260408083208451815591840151600183015580840151600290920180546060860151608087015160ff908116620100000262ff0000199282166101000261ffff19909416919096161791909117169290921790915551899133917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050505050505050565b600060208284031215620006ec578081fd5b81516001600160a01b038116811462000703578182fd5b9392505050565b60008219821115620007205762000720620007a2565b500190565b60006000198214156200073c576200073c620007a2565b5060010190565b600060ff821660ff8114156200075d576200075d620007a2565b60010192915050565b600082620007785762000778620007b8565b500690565b600060ff831680620007935762000793620007b8565b8060ff84160691505092915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b614c9380620007de6000396000f3fe6080604052600436106101b75760003560e01c806395d89b41116100ec578063c87b56dd1161008a578063db006a7511610064578063db006a7514610594578063e8a3d485146105b4578063e8bf8432146105c9578063e985e9c5146105e957600080fd5b8063c87b56dd14610534578063cc1f8ffa14610554578063da0dba8f1461057457600080fd5b8063b411dc32116100c6578063b411dc32146104c6578063b6baffe3146104d9578063b861507114610501578063b88d4fde1461051457600080fd5b806395d89b411461042e578063a22cb46514610459578063a8a8c7411461047957600080fd5b806342842e0e1161015957806370a082311161013357806370a08231146103745780637b7a2c68146103aa5780637b7c01be146103fb5780637e551b751461040e57600080fd5b806342842e0e146103145780635f1d8438146103345780636352211e1461035457600080fd5b8063095ea7b311610195578063095ea7b31461028257806318160ddd146102a457806323b872dd146102c75780633cc8f306146102e757600080fd5b806301ffc9a7146101bc57806306fdde031461020a578063081812fc1461024a575b600080fd5b3480156101c857600080fd5b506101f56101d73660046133bc565b6001600160e01b031916600090815260208052604090205460ff1690565b60405190151581526020015b60405180910390f35b34801561021657600080fd5b5060408051808201909152600e81526d44756e67656f6e204d696e65727360901b60208201525b6040516102019190613a0c565b34801561025657600080fd5b5061026a61026536600461362a565b610632565b6040516001600160a01b039091168152602001610201565b34801561028e57600080fd5b506102a261029d366004613309565b610694565b005b3480156102b057600080fd5b506102b9610784565b604051908152602001610201565b3480156102d357600080fd5b506102a26102e2366004613207565b610794565b3480156102f357600080fd5b5061030761030236600461362a565b61099a565b6040516102019190613abb565b34801561032057600080fd5b506102a261032f366004613207565b6109b3565b34801561034057600080fd5b5061030761034f3660046136bb565b6109d3565b34801561036057600080fd5b5061026a61036f36600461362a565b610c21565b34801561038057600080fd5b506102b961038f3660046131bb565b6001600160a01b03166000908152601d602052604090205490565b3480156103b657600080fd5b506103ca6103c536600461362a565b610c7e565b60408051958652600194850b602087015292840b92850192909252820b6060840152900b608082015260a001610201565b6102a2610409366004613642565b610cc2565b34801561041a57600080fd5b506102b961042936600461362a565b610cd0565b34801561043a57600080fd5b50604080518082019091526002815261444d60f01b602082015261023d565b34801561046557600080fd5b506102a26104743660046132e0565b610d2b565b34801561048557600080fd5b5061049961049436600461362a565b610da5565b60408051600195860b815293850b602085015291840b9183019190915290910b6060820152608001610201565b6102a26104d4366004613673565b610ddf565b3480156104e557600080fd5b5060045460055460408051928352602083019190915201610201565b34801561050d57600080fd5b50476102b9565b34801561052057600080fd5b506102a261052f366004613242565b6111e9565b34801561054057600080fd5b5061023d61054f36600461362a565b6112d4565b34801561056057600080fd5b506101f561056f366004613309565b611324565b34801561058057600080fd5b506102b961058f36600461362a565b61164b565b3480156105a057600080fd5b506101f56105af36600461362a565b6117ab565b3480156105c057600080fd5b5061023d6119c5565b3480156105d557600080fd5b506102b96105e436600461362a565b6119e8565b3480156105f557600080fd5b506101f56106043660046131d5565b6001600160a01b039182166000908152601f6020908152604080832093909416825291909152205460ff1690565b600061063d82611a9a565b6106785760405162461bcd60e51b81526020600482015260076024820152661a5b9d985b1a5960ca1b60448201526064015b60405180910390fd5b506000908152601e60205260409020546001600160a01b031690565b600061069f82610c21565b90506001600160a01b0381163314806106db57506001600160a01b0381166000908152601f6020908152604080832033845290915290205460ff165b6107145760405162461bcd60e51b815260206004820152600a6024820152693832b936b4b9b9b4b7b760b11b604482015260640161066f565b81836001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4506000908152601e6020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b600061078f60025490565b905090565b600061079f82610c21565b90506001600160a01b0381163314806107ce57506000828152601e60205260409020546001600160a01b031633145b806107fc57506001600160a01b0381166000908152601f6020908152604080832033845290915290205460ff165b6108355760405162461bcd60e51b815260206004820152600a6024820152693832b936b4b9b9b4b7b760b11b604482015260640161066f565b836001600160a01b0316816001600160a01b0316146108665760405162461bcd60e51b815260040161066f90613a1f565b6001600160a01b0383166108a55760405162461bcd60e51b815260040161066f906020808252600490820152637a65726f60e01b604082015260600190565b81836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46000828152601c6020908152604080832080546001600160a01b0319166001600160a01b038881169190911790915587168352601d909152812080549161092c83613c90565b90915550506001600160a01b0383166000908152601d6020526040812080549161095583613ca7565b90915550506000828152601e60205260409020546001600160a01b031615610994576000828152601e6020526040902080546001600160a01b03191690555b50505050565b6109a261300f565b6109ad82602e6109d3565b92915050565b6109ce838383604051806020016040528060008152506111e9565b505050565b6109db61300f565b6109e483611a9a565b610a205760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b604482015260640161066f565b6000838152601b60209081526040808320815160a08101835281548152600182015493810184905260029091015460ff8082169383019390935261010081048316606083015262010000900490911660808201529190610a81908690611ab7565b90506000610a8e83611b7b565b600161030082015290505b602e81610300015160ff16108015610abc57508460ff1681610300015160ff1611155b8015610acf57506000816040015160010b135b8015610b0a57506000801b8282610300015160ff16602f8110610b0257634e487b7160e01b600052603260045260246000fd5b602002015114155b15610c185781516103008201517359e24f4a617617443e7dc14fcbaa2fe6234ddc7591633963fac891859060ff16602f8110610b5657634e487b7160e01b600052603260045260246000fd5b6020020151604051602001610b75929190918252602082015260400190565b60405160208183030381529060405280519060200120836040518363ffffffff1660e01b8152600401610ba99291906139f7565b6103206040518083038186803b158015610bc257600080fd5b505af4158015610bd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfa9190613455565b61030081018051919250610c0d82613cc2565b60ff16905250610a99565b95945050505050565b6000610c2c82611a9a565b610c625760405162461bcd60e51b81526020600482015260076024820152661a5b9d985b1a5960ca1b604482015260640161066f565b506000908152601c60205260409020546001600160a01b031690565b600b8160088110610c8e57600080fd5b60020201805460019182015490925080820b91620100008204810b916401000000008104820b91600160301b909104900b85565b610994848484846001610ddf565b6000610cdb82611a9a565b610d185760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b2103a37b5b2b71760911b604482015260640161066f565b506000908152601b602052604090205490565b60405181151581526001600160a01b0383169033907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319060200160405180910390a3336000908152601f602090815260408083206001600160a01b0395909516835293905291909120805460ff1916911515919091179055565b60078160048110610db557600080fd5b0154600181810b9250620100008204810b916401000000008104820b91600160301b909104900b84565b60048310610e175760405162461bcd60e51b8152602060048201526005602482015264636c61737360d81b604482015260640161066f565b60088410610e505760405162461bcd60e51b815260040161066f906020808252600490820152636974656d60e01b604082015260600190565b60028210610e895760405162461bcd60e51b815260206004820152600660248201526533b2b73232b960d11b604482015260640161066f565b600b8460088110610eaa57634e487b7160e01b600052603260045260246000fd5b6002020154610ec19067011c37937e080000613b91565b341015610ef95760405162461bcd60e51b815260040161066f9060208082526004908201526318dbdcdd60e21b604082015260600190565b6000610f0460025490565b90506000610f13826001613b91565b905060008215610f7157506000828152601b60209081526040918290205482513360601b6001600160601b03191681840152603481019190915260548082018b90528351808303909101815260749091019092528151910120610fb1565b6040516001600160601b03193360601b16602082015260006034820152605481018990526074016040516020818303038152906040528051906020012090505b600554600454610fc19190613c2a565b8110801590610fde5750600554600454610fdb9190613b91565b81105b6110125760405162461bcd60e51b815260206004820152600560248201526472616e676560d81b604482015260640161066f565b60408051602081018390529081018890526060808201889052608082018790524260a083015241901b6001600160601b03191660c08201524460d48201524360f48201526101140160408051601f19818403018152919052805160209091012060015490915060009081906001600160a01b031661109766d529ae9e86000034613c2a565b604051600081818185875af1925050503d80600081146110d3576040519150601f19603f3d011682016040523d82523d6000602084013e6110d8565b606091505b5091509150816111145760405162461bcd60e51b81526020600482015260076024820152661c185e5b595b9d60ca1b604482015260640161066f565b611122600280546001019055565b61113e84848089611134576000611136565b875b8d8d8d612c74565b8233857f607eb9f7f6c4b2d9b7c1d3c046521d90e79c6fbaebf614c533174cc9a44159918961116e576000611170565b875b60045460055460408051938452602084019290925290820152606081018e9052608081018d905260a081018c905260c00160405180910390a485156111dd57604051849081907f199146747059b20b983dbc277e791596fca74e655180c59d04485ca6d5a736f590600090a35b50505050505050505050565b6111f4848484610794565b823b63ffffffff8116156112cd57604051630a85bd0160e11b80825285916001600160a01b0383169063150b7a02906112379033908b908a908a906004016139ba565b602060405180830381600087803b15801561125157600080fd5b505af1158015611265573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061128991906133d8565b6001600160e01b031916146112cb5760405162461bcd60e51b81526020600482015260086024820152673932b1b2b4bb32b960c11b604482015260640161066f565b505b5050505050565b60606112df82611a9a565b61131b5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b604482015260640161066f565b6109ad82612d8e565b600061132f82611a9a565b61136b5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b604482015260640161066f565b826001600160a01b031661137e83610c21565b6001600160a01b0316146113a45760405162461bcd60e51b815260040161066f90613a1f565b6000828152601b6020908152604091829020825160a08101845281548152600182015492810183905260029091015460ff8082169483019490945261010081048416606083015262010000900490921660808301526003541061143f5760405162461bcd60e51b81526020600482015260136024820152721c1c995d9a5bdd5cdb1e481c995919595b5959606a1b604482015260640161066f565b600081602001511161147f5760405162461bcd60e51b8152602060048201526009602482015268707265706172696e6760b81b604482015260640161066f565b600061148f848360200151611ab7565b9050600061149c83611b7b565b600161030082015290505b602e81610300015160ff161080156114c657506000816040015160010b135b801561150157506000801b8282610300015160ff16602f81106114f957634e487b7160e01b600052603260045260246000fd5b602002015114155b1561160f5781516103008201517359e24f4a617617443e7dc14fcbaa2fe6234ddc7591633963fac891859060ff16602f811061154d57634e487b7160e01b600052603260045260246000fd5b602002015160405160200161156c929190918252602082015260400190565b60405160208183030381529060405280519060200120836040518363ffffffff1660e01b81526004016115a09291906139f7565b6103206040518083038186803b1580156115b957600080fd5b505af41580156115cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115f19190613455565b6103008101805191925061160482613cc2565b60ff169052506114a7565b6000816040015160010b13801561162e575080610300015160ff16602e145b1561163f57600193505050506109ad565b50600095945050505050565b60003361165783610c21565b6001600160a01b03161461167d5760405162461bcd60e51b815260040161066f90613a1f565b6000828152601b6020908152604091829020825160a08101845281548152600182015492810183905260029091015460ff808216948301949094526101008104841660608301526201000090049092166080830152156117095760405162461bcd60e51b81526020600482015260076024820152661cdd185c9d195960ca1b604482015260640161066f565b600061171460025490565b60208084018281526000878152601b9092526040808320865181559151600183015580860151600290920180546060880151608089015160ff908116620100000262ff0000199282166101000261ffff19909416919096161791909117169290921790915551919250829186917f199146747059b20b983dbc277e791596fca74e655180c59d04485ca6d5a736f591a39392505050565b60006117b73383611324565b6117f35760405162461bcd60e51b815260206004820152600d60248201526c63616e6e6f742072656465656d60981b604482015260640161066f565b6000828152601b60209081526040808320815160a081018352815481526001820154938101939093526002015460ff808216928401929092526101008104821660608401526201000090041660808201529061184e846119e8565b90508015611992576000611863600a83613bce565b905061186f8183613c2a565b9150600061187c60025490565b905060008082888660405160200161189e929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c6118c19190613ce2565b90506118cc81610c21565b6020870151600355604051909250339086156108fc029087906000818181858888f19350505050158015611904573d6000803e3d6000fd5b506040516001600160a01b0383169085156108fc029086906000818181858888f1935050505015801561193b573d6000803e3d6000fd5b5060408051868152602081018690526001600160a01b0384169133918b917f58906a2505a9db6390deef9cdde84025599193dcfc2363ab4acc6f7b009e46f1910160405180910390a4506001979650505050505050565b60405162461bcd60e51b81526020600482015260086024820152676e6f2066756e647360c01b604482015260640161066f565b606060405180610f000160405280610edb8152602001613d83610edb9139905090565b6000818152601b60209081526040808320815160a081018352815481526001820154938101939093526002015460ff80821692840192909252610100810482166060840152620100009004166080820152600354611a68576020810151611a5090602e613b91565b611a619066d529ae9e860000613be2565b9392505050565b826003541015611a84576003548160200151611a509190613c2a565b50600092915050565b80546001019055565b5490565b6000908152601c60205260409020546001600160a01b0316151590565b611abf6130db565b611ac76130db565b6000848152601b602052604090205481528215611a615760015b602f811015611b7357601b6000611af88387613b91565b8152602001908152602001600020600001548282602f8110611b2a57634e487b7160e01b600052603260045260246000fd5b602002015260008282602f8110611b5157634e487b7160e01b600052603260045260246000fd5b60200201511415611b6157611b73565b80611b6b81613ca7565b915050611ae1565b509392505050565b611b8361300f565b60006007836060015160ff1660048110611bad57634e487b7160e01b600052603260045260246000fd5b60408051608080820183529290930154600181810b810b810b8552620100008204810b810b810b60208601526401000000008204810b810b810b92850192909252600160301b9004810b810b900b6060830152840151909150600090600b9060ff1660088110611c2d57634e487b7160e01b600052603260045260246000fd5b6040805160a081018252600292909202929092018054825260019081015480820b820b820b60208401908152620100008204830b830b830b848601526401000000008204830b830b830b6060850152600160301b909104820b820b90910b60808301528251610320810190935251845187519294506000939283929190611cb890603090871a613cf6565b60ff16611cc59190613b4d565b611ccf9190613b4d565b60010b81526020018360400151856020015160188960000151600160208110611d0857634e487b7160e01b600052603260045260246000fd5b611d149291901a613cf6565b60ff16611d219190613b4d565b611d2b9190613b4d565b60010b8152602001600060010b8152602001600060010b81526020018360600151856040015160188960000151600260208110611d7857634e487b7160e01b600052603260045260246000fd5b611d849291901a613cf6565b60ff16611d919190613b4d565b611d9b9190613b4d565b60010b8152608084015160608601518851602090930192611dc19060189060031a613cf6565b60ff16611dce9190613b4d565b611dd89190613b4d565b60010b8152602001600061ffff168152602001866040015160ff168152602001866060015160ff16815260200160fa8760000151601560208110611e2c57634e487b7160e01b600052603260045260246000fd5b1a10611e53578651611e439060069060151a613cf6565b611e4e90600a613ba9565b611e64565b8651611e6490600a9060151a613cf6565b60ff1681528651602090910190611e8090600890601b1a613cf6565b60ff1681528651602090910190611e9c90600890601a1a613cf6565b60ff168152865160209091019060fc9060171a10611ed5578651611ec59060049060171a613cf6565b611ed0906009613ba9565b611ee6565b8651611ee69060099060171a613cf6565b60ff1681528651602090910190611f029060049060181a613cf6565b60ff1681528651602090910190611f1e9060089060191a613cf6565b60ff16815260200160087359e24f4a617617443e7dc14fcbaa2fe6234ddc7563977c9b508960000151601060208110611f6757634e487b7160e01b600052603260045260246000fd5b60405160e084901b6001600160e01b031916815291901a600482015260240160206040518083038186803b158015611f9e57600080fd5b505af4158015611fb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd691906136ea565b60ff161161206c578651604051630977c9b560e41b815260109190911a60048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b15801561202f57600080fd5b505af4158015612043573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061206791906136ea565b612127565b60608701518751604051630977c9b560e41b815260109190911a60048201526009907359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b1580156120c557600080fd5b505af41580156120d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120fd91906136ea565b6121079190613c41565b612112906004613c01565b61211d906009613ba9565b6121279190613ba9565b60ff16815260200160087359e24f4a617617443e7dc14fcbaa2fe6234ddc7563977c9b50896000015160116020811061217057634e487b7160e01b600052603260045260246000fd5b60405160e084901b6001600160e01b031916815291901a600482015260240160206040518083038186803b1580156121a757600080fd5b505af41580156121bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121df91906136ea565b60ff1611612275578651604051630977c9b560e41b815260119190911a60048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b15801561223857600080fd5b505af415801561224c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061227091906136ea565b612330565b60608701518751604051630977c9b560e41b815260119190911a60048201526009907359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b1580156122ce57600080fd5b505af41580156122e2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061230691906136ea565b6123109190613c41565b61231b906004613c01565b612326906009613ba9565b6123309190613ba9565b61233b906011613ba9565b60ff16815260200160087359e24f4a617617443e7dc14fcbaa2fe6234ddc7563977c9b50896000015160126020811061238457634e487b7160e01b600052603260045260246000fd5b60405160e084901b6001600160e01b031916815291901a600482015260240160206040518083038186803b1580156123bb57600080fd5b505af41580156123cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123f391906136ea565b60ff1611612489578651604051630977c9b560e41b815260129190911a60048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b15801561244c57600080fd5b505af4158015612460573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061248491906136ea565b612544565b60608701518751604051630977c9b560e41b815260129190911a60048201526009907359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b1580156124e257600080fd5b505af41580156124f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061251a91906136ea565b6125249190613c41565b61252f906004613c01565b61253a906009613ba9565b6125449190613ba9565b61254f906022613ba9565b60ff16815260200160087359e24f4a617617443e7dc14fcbaa2fe6234ddc7563977c9b50896000015160136020811061259857634e487b7160e01b600052603260045260246000fd5b60405160e084901b6001600160e01b031916815291901a600482015260240160206040518083038186803b1580156125cf57600080fd5b505af41580156125e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260791906136ea565b60ff161161269d578651604051630977c9b560e41b815260139190911a60048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b15801561266057600080fd5b505af4158015612674573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061269891906136ea565b612758565b60608701518751604051630977c9b560e41b815260139190911a60048201526009907359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b1580156126f657600080fd5b505af415801561270a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061272e91906136ea565b6127389190613c41565b612743906004613c01565b61274e906009613ba9565b6127589190613ba9565b612763906033613ba9565b60ff16815260200160047359e24f4a617617443e7dc14fcbaa2fe6234ddc7563977c9b5089600001516014602081106127ac57634e487b7160e01b600052603260045260246000fd5b60405160e084901b6001600160e01b031916815291901a600482015260240160206040518083038186803b1580156127e357600080fd5b505af41580156127f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061281b91906136ea565b60ff16116128b1578651604051630977c9b560e41b815260149190911a60048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b15801561287457600080fd5b505af4158015612888573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128ac91906136ea565b61296c565b60608701518751604051630977c9b560e41b815260149190911a60048201526005907359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b15801561290a57600080fd5b505af415801561291e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061294291906136ea565b61294c9190613c41565b612957906004613c01565b612962906005613ba9565b61296c9190613ba9565b612977906044613ba9565b60ff16815260006020820181905260408201819052606082018190526080820181905260a09091015290506129aa6130fa565b60005b6005811015612c4e5780612a4f576101e0830151604051631d9fd14560e11b815260ff90911660048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc7590633b3fa28a906024015b60c06040518083038186803b158015612a1057600080fd5b505af4158015612a24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a489190613332565b9150612bc5565b8060011415612a995761020083015160405163105aefa760e01b815260ff90911660048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc759063105aefa7906024016129f8565b8060021415612ae35761022083015160405163328e76af60e21b815260ff90911660048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc759063ca39dabc906024016129f8565b8060031415612b2d57610240830151604051633c43e4fb60e11b815260ff90911660048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc7590637887c9f6906024016129f8565b8060041415612bc5576102608301516040516359a18db360e11b815260ff90911660048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc759063b3431b669060240160c06040518083038186803b158015612b8a57600080fd5b505af4158015612b9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc29190613332565b91505b81518351612bd39190613b4d565b600190810b900b835260208083015190840151612bf09190613b4d565b600190810b900b602084015260408201516080840151612c109190613b4d565b600190810b900b6080840152606082015160a0840151612c309190613b4d565b600190810b900b60a084015280612c4681613ca7565b9150506129ad565b50508051600190810b810b60408301526020820151810b900b6060820152949350505050565b6040805160a081018252878152602080820187905260ff8085168385015285811660608401528616608083015260008a8152601c825283812080546001600160a01b031916339081179091558152601d90915291822080549192612cd783613ca7565b9091555050600554600654612cec9088613ce2565b612cf69190613b91565b6004556000888152601b602090815260408083208451815591840151600183015580840151600290920180546060860151608087015160ff908116620100000262ff0000199282166101000261ffff19909416919096161791909117169290921790915551899133917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050505050505050565b6060600080612d9c84612dd8565b915091506000612dab85612eed565b8383604051602001612dbf939291906138b7565b60408051601f1981840301815291905295945050505050565b6000818152601b60209081526040808320815160a081018352815481526001820154938101939093526002015460ff808216928401929092526101008104821660608481019190915262010000909104909116608083015291829190612e3d82611b7b565b90506000612e4f868460200151611ab7565b60405163bc535fe360e01b81529091507363166bcfe21484217eff188d44a65bc5ba317a539063bc535fe390612e8d90869086908690600401613a3e565b60006040518083038186803b158015612ea557600080fd5b505af4158015612eb9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612ee191908101906133f4565b94509450505050915091565b606081612f115750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612f3b5780612f2581613ca7565b9150612f349050600a83613bce565b9150612f15565b60008167ffffffffffffffff811115612f6457634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612f8e576020820181803683370190505b5090505b841561300757612fa3600183613c2a565b9150612fb0600a86613ce2565b612fbb906030613b91565b60f81b818381518110612fde57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350613000600a86613bce565b9450612f92565b949350505050565b6040805161032081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101829052610200810182905261022081018290526102408101829052610260810182905261028081018290526102a081018290526102c081018290526102e0810182905261030081019190915290565b604051806105e00160405280602f906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b80356001600160a01b038116811461312f57600080fd5b919050565b8035801515811461312f57600080fd5b8051600181900b811461312f57600080fd5b600082601f830112613166578081fd5b815161317961317482613b25565b613af4565b81815284602083860101111561318d578283fd5b613007826020830160208701613c64565b805161ffff8116811461312f57600080fd5b805161312f81613d73565b6000602082840312156131cc578081fd5b611a6182613118565b600080604083850312156131e7578081fd5b6131f083613118565b91506131fe60208401613118565b90509250929050565b60008060006060848603121561321b578081fd5b61322484613118565b925061323260208501613118565b9150604084013590509250925092565b60008060008060808587031215613257578081fd5b61326085613118565b935061326e60208601613118565b925060408501359150606085013567ffffffffffffffff811115613290578182fd5b8501601f810187136132a0578182fd5b80356132ae61317482613b25565b8181528860208385010111156132c2578384fd5b81602084016020830137908101602001929092525092959194509250565b600080604083850312156132f2578182fd5b6132fb83613118565b91506131fe60208401613134565b6000806040838503121561331b578182fd5b61332483613118565b946020939093013593505050565b600060c08284031215613343578081fd5b82601f830112613351578081fd5b60405160c0810181811067ffffffffffffffff8211171561337457613374613d44565b604052808360c08101861015613388578384fd5b835b60068110156133b15761339c82613144565b8352602092830192919091019060010161338a565b509195945050505050565b6000602082840312156133cd578081fd5b8135611a6181613d5a565b6000602082840312156133e9578081fd5b8151611a6181613d5a565b60008060408385031215613406578182fd5b825167ffffffffffffffff8082111561341d578384fd5b61342986838701613156565b9350602085015191508082111561343e578283fd5b5061344b85828601613156565b9150509250929050565b60006103208284031215613467578081fd5b61346f613aca565b61347883613144565b815261348660208401613144565b602082015261349760408401613144565b60408201526134a860608401613144565b60608201526134b960808401613144565b60808201526134ca60a08401613144565b60a08201526134db60c0840161319e565b60c08201526134ec60e084016131b0565b60e08201526101006134ff8185016131b0565b908201526101206135118482016131b0565b908201526101406135238482016131b0565b908201526101606135358482016131b0565b908201526101806135478482016131b0565b908201526101a06135598482016131b0565b908201526101c061356b8482016131b0565b908201526101e061357d8482016131b0565b9082015261020061358f8482016131b0565b908201526102206135a18482016131b0565b908201526102406135b38482016131b0565b908201526102606135c58482016131b0565b908201526102806135d78482016131b0565b908201526102a06135e98482016131b0565b908201526102c06135fb8482016131b0565b908201526102e061360d8482016131b0565b9082015261030061361f8482016131b0565b908201529392505050565b60006020828403121561363b578081fd5b5035919050565b60008060008060808587031215613657578182fd5b5050823594602084013594506040840135936060013592509050565b600080600080600060a0868803121561368a578283fd5b853594506020860135935060408601359250606086013591506136af60808701613134565b90509295509295909350565b600080604083850312156136cd578182fd5b8235915060208301356136df81613d73565b809150509250929050565b6000602082840312156136fb578081fd5b8151611a6181613d73565b6000815180845261371e816020860160208601613c64565b601f01601f19169290920160200192915050565b805160010b8252602081015161374d602084018260010b9052565b506040810151613762604084018260010b9052565b506060810151613777606084018260010b9052565b50608081015161378c608084018260010b9052565b5060a08101516137a160a084018260010b9052565b5060c08101516137b760c084018261ffff169052565b5060e08101516137cc60e084018260ff169052565b506101008181015160ff90811691840191909152610120808301518216908401526101408083015182169084015261016080830151821690840152610180808301518216908401526101a0808301518216908401526101c0808301518216908401526101e08083015182169084015261020080830151821690840152610220808301518216908401526102408083015182169084015261026080830151821690840152610280808301518216908401526102a0808301518216908401526102c0808301518216908401526102e080830151821690840152610300808301519182168185015290610994565b7f646174613a746578742f706c61696e2c7b226e616d65223a224d696e65722025815261323360f01b6020820152600084516138fa816022850160208901613c64565b7f222c226465736372697074696f6e223a22416e2065736361706520617474656d6022918401918201527f7074207468726f75676820746865206461726b2064756e67656f6e2e222c226160428201526b747472696275746573223a5b60a01b6062820152845161397281606e840160208901613c64565b6a2e961134b6b0b3b2911d1160a91b606e9290910191820152835161399e816079840160208801613c64565b61227d60f01b60799290910191820152607b0195945050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906139ed90830184613706565b9695505050505050565b8281526103408101611a616020830184613732565b602081526000611a616020830184613706565b60208082526005908201526437bbb732b960d91b604082015260600190565b60006109a082019050845182526020808601518184015260ff604087015116604084015260ff606087015116606084015260ff6080870151166080840152613a8960a0840186613732565b6103c083018460005b602f811015613aaf57815183529183019190830190600101613a92565b50505050949350505050565b61032081016109ad8284613732565b604051610320810167ffffffffffffffff81118282101715613aee57613aee613d44565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715613b1d57613b1d613d44565b604052919050565b600067ffffffffffffffff821115613b3f57613b3f613d44565b50601f01601f191660200190565b60008160010b8360010b82821282617fff03821381151615613b7157613b71613d18565b82617fff19038212811615613b8857613b88613d18565b50019392505050565b60008219821115613ba457613ba4613d18565b500190565b600060ff821660ff84168060ff03821115613bc657613bc6613d18565b019392505050565b600082613bdd57613bdd613d2e565b500490565b6000816000190483118215151615613bfc57613bfc613d18565b500290565b600060ff821660ff84168160ff0481118215151615613c2257613c22613d18565b029392505050565b600082821015613c3c57613c3c613d18565b500390565b600060ff821660ff841680821015613c5b57613c5b613d18565b90039392505050565b60005b83811015613c7f578181015183820152602001613c67565b838111156109945750506000910152565b600081613c9f57613c9f613d18565b506000190190565b6000600019821415613cbb57613cbb613d18565b5060010190565b600060ff821660ff811415613cd957613cd9613d18565b60010192915050565b600082613cf157613cf1613d2e565b500690565b600060ff831680613d0957613d09613d2e565b8060ff84160691505092915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114613d7057600080fd5b50565b60ff81168114613d7057600080fdfe646174613a746578742f706c61696e2c7b226e616d65223a2244756e67656f6e204d696e657273222c226465736372697074696f6e223a2244756e67656f6e204d696e65727320697320612066756c6c79206f6e2d636861696e2c2070726f6365647572616c6c792d67656e6572617465642064756e67656f6e20637261776c657220776865726520706c61796572732063616e206d696e6520666f7220616e64206d696e74204e46547320746861742065766f6c7665206173206d6f726520616e64206d6f7265204e46547320617265206d696e74656420696e20616e20617474656d707420746f2065736361706520612034382d6368616d6265722064756e67656f6e20616e642077696e20455448207072697a65732e222c22696d616765223a22646174613a696d6167652f7376672b786d6c3b6261736536342c50484e325a79423462577875637a30696148523063446f764c336433647935334d793576636d63764d6a41774d43397a646d6369494864705a48526f505349784d44416c4969426f5a576c6e61485139496a45774d43556949485a705a58644362336739496a41674d4341324e4341324e43496763484a6c63325679646d56426333426c5933525359585270627a3069654531705a466c4e615751676257566c6443492b5047526c5a6e4d2b504731686332736761575139496d39744969427459584e725657357064484d39496e567a5a584a546347466a5a55397556584e6c496a3438636d566a6443423361575230614430694e694967614756705a326830505349334969426d615778735053496a5a6d5a6d4969382b50484a6c59335167654430694d694967655430694d53496764326c6b64476739496a49694947686c6157646f644430694e5349675a6d6c7362443069497a41774d434976506a77766257467a617a34386257467a617942705a443069636d30694947316863327456626d6c30637a306964584e6c636c4e7759574e6c5432355663325569506a78795a574e30494864705a48526f505349324969426f5a576c6e61485139496a636949475a706247773949694e6d5a6d59694c7a3438636d566a644342345053497949694235505349784969423361575230614430694d694967614756705a3268305053497a4969426d615778735053496a4d4441774969382b5043397459584e72506a78775958526f49476c6b50534a6b4969426b50534a4e4d437777614456324d576778646a566f4c5446324d5767744e586f6949484e306557786c50534a7459584e724f6e56796243676a623230704969382b504842686447676761575139496e556949475139496b30774c44426f4d6e593261444a324c545a6f4d6e59336143303265694976506a78775958526f49476c6b50534a754969426b50534a4e4d437777614446324d576778646a466f4d585978614446324c544e6f4d6e593361433078646930786143307864693078614330786469307861433078646a4e6f4c544a364969382b504842686447676761575139496d636949475139496b30774c44426f4e6e5979614330796469307861433079646a566f4d6e59744d6d67744d5859744d57677a646a526f4c545a364969382b504842686447676761575139496d556949475139496b30774c44426f4e6e597861433030646a4a6f4d3359786143307a646a4a6f4e4859786143303265694976506a78775958526f49476c6b50534a764969426b50534a4e4d43777761445a324e3267744e6e6f6949484e306557786c50534a7459584e724f6e56796243676a623230704969382b504842686447676761575139496d306949475139496b30774c44426f4d585978614446324d576778646a466f4d5859744d57677864693078614446324c54466f4d585933614330796469307a61433078646a4a6f4c5446324c544a6f4c5446324d3267744d6e6f694c7a343863474630614342705a443069615349675a443069545441734d476732646a466f4c544a324e576779646a466f4c545a324c54466f4d6e59744e5767744d6e6f694c7a343863474630614342705a443069636949675a443069545441734d476732646a526f4c5446324d576778646a4a6f4c544a324c544a6f4c544a324d6d67744d6e6f6949484e306557786c50534a7459584e724f6e56796243676a636d30704969382b504842686447676761575139496e4d6949475139496b30774c44426f4e6e5979614330796469307861433079646a4a6f4e485930614330326469307961444a324d576779646930796143303065694976506a786e49476c6b50534a6b6457356e5a573975496a343864584e6c494768795a57593949694e6b49694230636d467563325a76636d3039496e52795957357a624746305a5367774c4451704969382b5048567a5a53426f636d566d5053496a6453496764484a68626e4e6d62334a7450534a30636d4675633278686447556f4e7977794b534976506a78316332556761484a6c5a6a306949323469494852795957357a5a6d39796254306964484a68626e4e735958526c4b4445304c4445704969382b5048567a5a53426f636d566d5053496a5a79496764484a68626e4e6d62334a7450534a30636d4675633278686447556f4d6a45734d436b694c7a343864584e6c494768795a57593949694e6c49694230636d467563325a76636d3039496e52795957357a624746305a5367794f4377784b534976506a78316332556761484a6c5a6a306949323869494852795957357a5a6d39796254306964484a68626e4e735958526c4b444d314c4449704969382b5048567a5a53426f636d566d5053496a6269496764484a68626e4e6d62334a7450534a30636d4675633278686447556f4e4449734e436b694c7a34384c32632b5047636761575139496d3170626d56796379492b5048567a5a53426f636d566d5053496a6253496764484a68626e4e6d62334a7450534a30636d4675633278686447556f4d7977794b534976506a78316332556761484a6c5a6a306949326b69494852795957357a5a6d39796254306964484a68626e4e735958526c4b4445784c4445704969382b5048567a5a53426f636d566d5053496a6269496764484a68626e4e6d62334a7450534a30636d4675633278686447556f4d5467734d436b694c7a343864584e6c494768795a57593949694e6c49694230636d467563325a76636d3039496e52795957357a624746305a5367794e5377774b534976506a78316332556761484a6c5a6a306949334969494852795957357a5a6d39796254306964484a68626e4e735958526c4b444d794c4445704969382b5048567a5a53426f636d566d5053496a6379496764484a68626e4e6d62334a7450534a30636d4675633278686447556f4d7a6b734d696b694c7a34384c32632b5043396b5a575a7a506a78795a574e304947686c6157646f644430694e6a5169494864705a48526f505349324e4349675a6d6c7362443069497a41354d44677759694976506a786e494852795957357a5a6d39796254306964484a68626e4e735958526c4b4467734d546770496a34385a7a3438636d566a64434234505349794d79496764326c6b64476739496a49694947686c6157646f644430694d6a676949475a706247773949694d334e54526a4d6a51694c7a3438636d566a64434234505349794d79496764326c6b64476739496a45694947686c6157646f644430694d6a676949475a706247773949694d34597a59794d7a6b694c7a3438636d566a64434234505349794d794967655430694e53496764326c6b64476739496a49694947686c6157646f644430694d5349675a6d6c7362443069636d6469595367774c4441734d4377774c6a49704969382b50484268644767675a443069545449734f4767786469307961444a324c54466f4d3359744d57673064693078614456324c54466f4e5859744d576730646a466f4e585978614456324d576730646a466f4d33597861444a324d6d6778646a466f4c5446324c54466f4c544a324c54466f4c544e324c54466f4c5452324c54466f4c5456324c54466f4c5456324d5767744e4859744d5767744e58597861433031646a466f4c5452324d5767744d33597861433079646a466f4c5446364969426d615778735053496a4f5455354e546b314969382b50484268644767675a443069545449734f4767786469307961444a324c54466f4d3359744d57673064693078614456324c54466f4e5859744d576730646a466f4c5452324d5767744e58597861433031646a466f4c5452324d5767744d33597861433079646a4a6f4c5446364969426d6157787350534a795a324a684b4449314e5377794e5455734d6a55314c4441754d696b694c7a3438634746306143426b50534a4e4d6a49734e47673064693078614456324d576731646a466f4e48597861444e324d576779646a466f4d585978614330786469307861433079646930786143307a646930786143303064693078614330316469307861433031646a466f4c5452364969426d6157787350534a795a324a684b4441734d4377774c4441754d696b694c7a34384c32632b5048567a5a53426f636d566d5053496a5a4856755a3256766269496764484a68626e4e6d62334a7450534a30636d4675633278686447556f4d4377344b5349675a6d6c7362443069497a55794d32597959794976506a78316332556761484a6c5a6a306949323170626d56796379496764484a68626e4e6d62334a7450534a30636d4675633278686447556f4d4377784f436b6949475a706247773949694d314d6a4e6d4d6d4d694c7a343864584e6c494768795a57593949694e6b6457356e5a57397549694230636d467563325a76636d3039496e52795957357a624746305a5367774c4463704969426d615778735053496a5a6d5a6d4969382b5048567a5a53426f636d566d5053496a62576c755a584a7a49694230636d467563325a76636d3039496e52795957357a624746305a5367774c4445334b5349675a6d6c736244306949325a6d5a694976506a77765a7a34384c334e325a7a343d222c2265787465726e616c5f6c696e6b223a2268747470733a2f2f64756e67656f6e6d696e6572732e636f6d222c2273656c6c65725f6665655f62617369735f706f696e7473223a3235302c226665655f726563697069656e74223a22307837396163353346363337323836383446354232314236333032464335436566354138453862376539227da2646970667358221220e7b2ecc9721e5771c48ca2698d0f7d61bcefdca21f9c82c82ab9dbfbed20420d64736f6c6343000804003300000000000000000000000096c74cdba40fab71b765655cad7ab0411696af54
Deployed Bytecode
0x6080604052600436106101b75760003560e01c806395d89b41116100ec578063c87b56dd1161008a578063db006a7511610064578063db006a7514610594578063e8a3d485146105b4578063e8bf8432146105c9578063e985e9c5146105e957600080fd5b8063c87b56dd14610534578063cc1f8ffa14610554578063da0dba8f1461057457600080fd5b8063b411dc32116100c6578063b411dc32146104c6578063b6baffe3146104d9578063b861507114610501578063b88d4fde1461051457600080fd5b806395d89b411461042e578063a22cb46514610459578063a8a8c7411461047957600080fd5b806342842e0e1161015957806370a082311161013357806370a08231146103745780637b7a2c68146103aa5780637b7c01be146103fb5780637e551b751461040e57600080fd5b806342842e0e146103145780635f1d8438146103345780636352211e1461035457600080fd5b8063095ea7b311610195578063095ea7b31461028257806318160ddd146102a457806323b872dd146102c75780633cc8f306146102e757600080fd5b806301ffc9a7146101bc57806306fdde031461020a578063081812fc1461024a575b600080fd5b3480156101c857600080fd5b506101f56101d73660046133bc565b6001600160e01b031916600090815260208052604090205460ff1690565b60405190151581526020015b60405180910390f35b34801561021657600080fd5b5060408051808201909152600e81526d44756e67656f6e204d696e65727360901b60208201525b6040516102019190613a0c565b34801561025657600080fd5b5061026a61026536600461362a565b610632565b6040516001600160a01b039091168152602001610201565b34801561028e57600080fd5b506102a261029d366004613309565b610694565b005b3480156102b057600080fd5b506102b9610784565b604051908152602001610201565b3480156102d357600080fd5b506102a26102e2366004613207565b610794565b3480156102f357600080fd5b5061030761030236600461362a565b61099a565b6040516102019190613abb565b34801561032057600080fd5b506102a261032f366004613207565b6109b3565b34801561034057600080fd5b5061030761034f3660046136bb565b6109d3565b34801561036057600080fd5b5061026a61036f36600461362a565b610c21565b34801561038057600080fd5b506102b961038f3660046131bb565b6001600160a01b03166000908152601d602052604090205490565b3480156103b657600080fd5b506103ca6103c536600461362a565b610c7e565b60408051958652600194850b602087015292840b92850192909252820b6060840152900b608082015260a001610201565b6102a2610409366004613642565b610cc2565b34801561041a57600080fd5b506102b961042936600461362a565b610cd0565b34801561043a57600080fd5b50604080518082019091526002815261444d60f01b602082015261023d565b34801561046557600080fd5b506102a26104743660046132e0565b610d2b565b34801561048557600080fd5b5061049961049436600461362a565b610da5565b60408051600195860b815293850b602085015291840b9183019190915290910b6060820152608001610201565b6102a26104d4366004613673565b610ddf565b3480156104e557600080fd5b5060045460055460408051928352602083019190915201610201565b34801561050d57600080fd5b50476102b9565b34801561052057600080fd5b506102a261052f366004613242565b6111e9565b34801561054057600080fd5b5061023d61054f36600461362a565b6112d4565b34801561056057600080fd5b506101f561056f366004613309565b611324565b34801561058057600080fd5b506102b961058f36600461362a565b61164b565b3480156105a057600080fd5b506101f56105af36600461362a565b6117ab565b3480156105c057600080fd5b5061023d6119c5565b3480156105d557600080fd5b506102b96105e436600461362a565b6119e8565b3480156105f557600080fd5b506101f56106043660046131d5565b6001600160a01b039182166000908152601f6020908152604080832093909416825291909152205460ff1690565b600061063d82611a9a565b6106785760405162461bcd60e51b81526020600482015260076024820152661a5b9d985b1a5960ca1b60448201526064015b60405180910390fd5b506000908152601e60205260409020546001600160a01b031690565b600061069f82610c21565b90506001600160a01b0381163314806106db57506001600160a01b0381166000908152601f6020908152604080832033845290915290205460ff165b6107145760405162461bcd60e51b815260206004820152600a6024820152693832b936b4b9b9b4b7b760b11b604482015260640161066f565b81836001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4506000908152601e6020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b600061078f60025490565b905090565b600061079f82610c21565b90506001600160a01b0381163314806107ce57506000828152601e60205260409020546001600160a01b031633145b806107fc57506001600160a01b0381166000908152601f6020908152604080832033845290915290205460ff165b6108355760405162461bcd60e51b815260206004820152600a6024820152693832b936b4b9b9b4b7b760b11b604482015260640161066f565b836001600160a01b0316816001600160a01b0316146108665760405162461bcd60e51b815260040161066f90613a1f565b6001600160a01b0383166108a55760405162461bcd60e51b815260040161066f906020808252600490820152637a65726f60e01b604082015260600190565b81836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46000828152601c6020908152604080832080546001600160a01b0319166001600160a01b038881169190911790915587168352601d909152812080549161092c83613c90565b90915550506001600160a01b0383166000908152601d6020526040812080549161095583613ca7565b90915550506000828152601e60205260409020546001600160a01b031615610994576000828152601e6020526040902080546001600160a01b03191690555b50505050565b6109a261300f565b6109ad82602e6109d3565b92915050565b6109ce838383604051806020016040528060008152506111e9565b505050565b6109db61300f565b6109e483611a9a565b610a205760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b604482015260640161066f565b6000838152601b60209081526040808320815160a08101835281548152600182015493810184905260029091015460ff8082169383019390935261010081048316606083015262010000900490911660808201529190610a81908690611ab7565b90506000610a8e83611b7b565b600161030082015290505b602e81610300015160ff16108015610abc57508460ff1681610300015160ff1611155b8015610acf57506000816040015160010b135b8015610b0a57506000801b8282610300015160ff16602f8110610b0257634e487b7160e01b600052603260045260246000fd5b602002015114155b15610c185781516103008201517359e24f4a617617443e7dc14fcbaa2fe6234ddc7591633963fac891859060ff16602f8110610b5657634e487b7160e01b600052603260045260246000fd5b6020020151604051602001610b75929190918252602082015260400190565b60405160208183030381529060405280519060200120836040518363ffffffff1660e01b8152600401610ba99291906139f7565b6103206040518083038186803b158015610bc257600080fd5b505af4158015610bd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfa9190613455565b61030081018051919250610c0d82613cc2565b60ff16905250610a99565b95945050505050565b6000610c2c82611a9a565b610c625760405162461bcd60e51b81526020600482015260076024820152661a5b9d985b1a5960ca1b604482015260640161066f565b506000908152601c60205260409020546001600160a01b031690565b600b8160088110610c8e57600080fd5b60020201805460019182015490925080820b91620100008204810b916401000000008104820b91600160301b909104900b85565b610994848484846001610ddf565b6000610cdb82611a9a565b610d185760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b2103a37b5b2b71760911b604482015260640161066f565b506000908152601b602052604090205490565b60405181151581526001600160a01b0383169033907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319060200160405180910390a3336000908152601f602090815260408083206001600160a01b0395909516835293905291909120805460ff1916911515919091179055565b60078160048110610db557600080fd5b0154600181810b9250620100008204810b916401000000008104820b91600160301b909104900b84565b60048310610e175760405162461bcd60e51b8152602060048201526005602482015264636c61737360d81b604482015260640161066f565b60088410610e505760405162461bcd60e51b815260040161066f906020808252600490820152636974656d60e01b604082015260600190565b60028210610e895760405162461bcd60e51b815260206004820152600660248201526533b2b73232b960d11b604482015260640161066f565b600b8460088110610eaa57634e487b7160e01b600052603260045260246000fd5b6002020154610ec19067011c37937e080000613b91565b341015610ef95760405162461bcd60e51b815260040161066f9060208082526004908201526318dbdcdd60e21b604082015260600190565b6000610f0460025490565b90506000610f13826001613b91565b905060008215610f7157506000828152601b60209081526040918290205482513360601b6001600160601b03191681840152603481019190915260548082018b90528351808303909101815260749091019092528151910120610fb1565b6040516001600160601b03193360601b16602082015260006034820152605481018990526074016040516020818303038152906040528051906020012090505b600554600454610fc19190613c2a565b8110801590610fde5750600554600454610fdb9190613b91565b81105b6110125760405162461bcd60e51b815260206004820152600560248201526472616e676560d81b604482015260640161066f565b60408051602081018390529081018890526060808201889052608082018790524260a083015241901b6001600160601b03191660c08201524460d48201524360f48201526101140160408051601f19818403018152919052805160209091012060015490915060009081906001600160a01b031661109766d529ae9e86000034613c2a565b604051600081818185875af1925050503d80600081146110d3576040519150601f19603f3d011682016040523d82523d6000602084013e6110d8565b606091505b5091509150816111145760405162461bcd60e51b81526020600482015260076024820152661c185e5b595b9d60ca1b604482015260640161066f565b611122600280546001019055565b61113e84848089611134576000611136565b875b8d8d8d612c74565b8233857f607eb9f7f6c4b2d9b7c1d3c046521d90e79c6fbaebf614c533174cc9a44159918961116e576000611170565b875b60045460055460408051938452602084019290925290820152606081018e9052608081018d905260a081018c905260c00160405180910390a485156111dd57604051849081907f199146747059b20b983dbc277e791596fca74e655180c59d04485ca6d5a736f590600090a35b50505050505050505050565b6111f4848484610794565b823b63ffffffff8116156112cd57604051630a85bd0160e11b80825285916001600160a01b0383169063150b7a02906112379033908b908a908a906004016139ba565b602060405180830381600087803b15801561125157600080fd5b505af1158015611265573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061128991906133d8565b6001600160e01b031916146112cb5760405162461bcd60e51b81526020600482015260086024820152673932b1b2b4bb32b960c11b604482015260640161066f565b505b5050505050565b60606112df82611a9a565b61131b5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b604482015260640161066f565b6109ad82612d8e565b600061132f82611a9a565b61136b5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b604482015260640161066f565b826001600160a01b031661137e83610c21565b6001600160a01b0316146113a45760405162461bcd60e51b815260040161066f90613a1f565b6000828152601b6020908152604091829020825160a08101845281548152600182015492810183905260029091015460ff8082169483019490945261010081048416606083015262010000900490921660808301526003541061143f5760405162461bcd60e51b81526020600482015260136024820152721c1c995d9a5bdd5cdb1e481c995919595b5959606a1b604482015260640161066f565b600081602001511161147f5760405162461bcd60e51b8152602060048201526009602482015268707265706172696e6760b81b604482015260640161066f565b600061148f848360200151611ab7565b9050600061149c83611b7b565b600161030082015290505b602e81610300015160ff161080156114c657506000816040015160010b135b801561150157506000801b8282610300015160ff16602f81106114f957634e487b7160e01b600052603260045260246000fd5b602002015114155b1561160f5781516103008201517359e24f4a617617443e7dc14fcbaa2fe6234ddc7591633963fac891859060ff16602f811061154d57634e487b7160e01b600052603260045260246000fd5b602002015160405160200161156c929190918252602082015260400190565b60405160208183030381529060405280519060200120836040518363ffffffff1660e01b81526004016115a09291906139f7565b6103206040518083038186803b1580156115b957600080fd5b505af41580156115cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115f19190613455565b6103008101805191925061160482613cc2565b60ff169052506114a7565b6000816040015160010b13801561162e575080610300015160ff16602e145b1561163f57600193505050506109ad565b50600095945050505050565b60003361165783610c21565b6001600160a01b03161461167d5760405162461bcd60e51b815260040161066f90613a1f565b6000828152601b6020908152604091829020825160a08101845281548152600182015492810183905260029091015460ff808216948301949094526101008104841660608301526201000090049092166080830152156117095760405162461bcd60e51b81526020600482015260076024820152661cdd185c9d195960ca1b604482015260640161066f565b600061171460025490565b60208084018281526000878152601b9092526040808320865181559151600183015580860151600290920180546060880151608089015160ff908116620100000262ff0000199282166101000261ffff19909416919096161791909117169290921790915551919250829186917f199146747059b20b983dbc277e791596fca74e655180c59d04485ca6d5a736f591a39392505050565b60006117b73383611324565b6117f35760405162461bcd60e51b815260206004820152600d60248201526c63616e6e6f742072656465656d60981b604482015260640161066f565b6000828152601b60209081526040808320815160a081018352815481526001820154938101939093526002015460ff808216928401929092526101008104821660608401526201000090041660808201529061184e846119e8565b90508015611992576000611863600a83613bce565b905061186f8183613c2a565b9150600061187c60025490565b905060008082888660405160200161189e929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c6118c19190613ce2565b90506118cc81610c21565b6020870151600355604051909250339086156108fc029087906000818181858888f19350505050158015611904573d6000803e3d6000fd5b506040516001600160a01b0383169085156108fc029086906000818181858888f1935050505015801561193b573d6000803e3d6000fd5b5060408051868152602081018690526001600160a01b0384169133918b917f58906a2505a9db6390deef9cdde84025599193dcfc2363ab4acc6f7b009e46f1910160405180910390a4506001979650505050505050565b60405162461bcd60e51b81526020600482015260086024820152676e6f2066756e647360c01b604482015260640161066f565b606060405180610f000160405280610edb8152602001613d83610edb9139905090565b6000818152601b60209081526040808320815160a081018352815481526001820154938101939093526002015460ff80821692840192909252610100810482166060840152620100009004166080820152600354611a68576020810151611a5090602e613b91565b611a619066d529ae9e860000613be2565b9392505050565b826003541015611a84576003548160200151611a509190613c2a565b50600092915050565b80546001019055565b5490565b6000908152601c60205260409020546001600160a01b0316151590565b611abf6130db565b611ac76130db565b6000848152601b602052604090205481528215611a615760015b602f811015611b7357601b6000611af88387613b91565b8152602001908152602001600020600001548282602f8110611b2a57634e487b7160e01b600052603260045260246000fd5b602002015260008282602f8110611b5157634e487b7160e01b600052603260045260246000fd5b60200201511415611b6157611b73565b80611b6b81613ca7565b915050611ae1565b509392505050565b611b8361300f565b60006007836060015160ff1660048110611bad57634e487b7160e01b600052603260045260246000fd5b60408051608080820183529290930154600181810b810b810b8552620100008204810b810b810b60208601526401000000008204810b810b810b92850192909252600160301b9004810b810b900b6060830152840151909150600090600b9060ff1660088110611c2d57634e487b7160e01b600052603260045260246000fd5b6040805160a081018252600292909202929092018054825260019081015480820b820b820b60208401908152620100008204830b830b830b848601526401000000008204830b830b830b6060850152600160301b909104820b820b90910b60808301528251610320810190935251845187519294506000939283929190611cb890603090871a613cf6565b60ff16611cc59190613b4d565b611ccf9190613b4d565b60010b81526020018360400151856020015160188960000151600160208110611d0857634e487b7160e01b600052603260045260246000fd5b611d149291901a613cf6565b60ff16611d219190613b4d565b611d2b9190613b4d565b60010b8152602001600060010b8152602001600060010b81526020018360600151856040015160188960000151600260208110611d7857634e487b7160e01b600052603260045260246000fd5b611d849291901a613cf6565b60ff16611d919190613b4d565b611d9b9190613b4d565b60010b8152608084015160608601518851602090930192611dc19060189060031a613cf6565b60ff16611dce9190613b4d565b611dd89190613b4d565b60010b8152602001600061ffff168152602001866040015160ff168152602001866060015160ff16815260200160fa8760000151601560208110611e2c57634e487b7160e01b600052603260045260246000fd5b1a10611e53578651611e439060069060151a613cf6565b611e4e90600a613ba9565b611e64565b8651611e6490600a9060151a613cf6565b60ff1681528651602090910190611e8090600890601b1a613cf6565b60ff1681528651602090910190611e9c90600890601a1a613cf6565b60ff168152865160209091019060fc9060171a10611ed5578651611ec59060049060171a613cf6565b611ed0906009613ba9565b611ee6565b8651611ee69060099060171a613cf6565b60ff1681528651602090910190611f029060049060181a613cf6565b60ff1681528651602090910190611f1e9060089060191a613cf6565b60ff16815260200160087359e24f4a617617443e7dc14fcbaa2fe6234ddc7563977c9b508960000151601060208110611f6757634e487b7160e01b600052603260045260246000fd5b60405160e084901b6001600160e01b031916815291901a600482015260240160206040518083038186803b158015611f9e57600080fd5b505af4158015611fb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd691906136ea565b60ff161161206c578651604051630977c9b560e41b815260109190911a60048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b15801561202f57600080fd5b505af4158015612043573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061206791906136ea565b612127565b60608701518751604051630977c9b560e41b815260109190911a60048201526009907359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b1580156120c557600080fd5b505af41580156120d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120fd91906136ea565b6121079190613c41565b612112906004613c01565b61211d906009613ba9565b6121279190613ba9565b60ff16815260200160087359e24f4a617617443e7dc14fcbaa2fe6234ddc7563977c9b50896000015160116020811061217057634e487b7160e01b600052603260045260246000fd5b60405160e084901b6001600160e01b031916815291901a600482015260240160206040518083038186803b1580156121a757600080fd5b505af41580156121bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121df91906136ea565b60ff1611612275578651604051630977c9b560e41b815260119190911a60048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b15801561223857600080fd5b505af415801561224c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061227091906136ea565b612330565b60608701518751604051630977c9b560e41b815260119190911a60048201526009907359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b1580156122ce57600080fd5b505af41580156122e2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061230691906136ea565b6123109190613c41565b61231b906004613c01565b612326906009613ba9565b6123309190613ba9565b61233b906011613ba9565b60ff16815260200160087359e24f4a617617443e7dc14fcbaa2fe6234ddc7563977c9b50896000015160126020811061238457634e487b7160e01b600052603260045260246000fd5b60405160e084901b6001600160e01b031916815291901a600482015260240160206040518083038186803b1580156123bb57600080fd5b505af41580156123cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123f391906136ea565b60ff1611612489578651604051630977c9b560e41b815260129190911a60048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b15801561244c57600080fd5b505af4158015612460573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061248491906136ea565b612544565b60608701518751604051630977c9b560e41b815260129190911a60048201526009907359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b1580156124e257600080fd5b505af41580156124f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061251a91906136ea565b6125249190613c41565b61252f906004613c01565b61253a906009613ba9565b6125449190613ba9565b61254f906022613ba9565b60ff16815260200160087359e24f4a617617443e7dc14fcbaa2fe6234ddc7563977c9b50896000015160136020811061259857634e487b7160e01b600052603260045260246000fd5b60405160e084901b6001600160e01b031916815291901a600482015260240160206040518083038186803b1580156125cf57600080fd5b505af41580156125e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260791906136ea565b60ff161161269d578651604051630977c9b560e41b815260139190911a60048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b15801561266057600080fd5b505af4158015612674573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061269891906136ea565b612758565b60608701518751604051630977c9b560e41b815260139190911a60048201526009907359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b1580156126f657600080fd5b505af415801561270a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061272e91906136ea565b6127389190613c41565b612743906004613c01565b61274e906009613ba9565b6127589190613ba9565b612763906033613ba9565b60ff16815260200160047359e24f4a617617443e7dc14fcbaa2fe6234ddc7563977c9b5089600001516014602081106127ac57634e487b7160e01b600052603260045260246000fd5b60405160e084901b6001600160e01b031916815291901a600482015260240160206040518083038186803b1580156127e357600080fd5b505af41580156127f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061281b91906136ea565b60ff16116128b1578651604051630977c9b560e41b815260149190911a60048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b15801561287457600080fd5b505af4158015612888573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128ac91906136ea565b61296c565b60608701518751604051630977c9b560e41b815260149190911a60048201526005907359e24f4a617617443e7dc14fcbaa2fe6234ddc759063977c9b509060240160206040518083038186803b15801561290a57600080fd5b505af415801561291e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061294291906136ea565b61294c9190613c41565b612957906004613c01565b612962906005613ba9565b61296c9190613ba9565b612977906044613ba9565b60ff16815260006020820181905260408201819052606082018190526080820181905260a09091015290506129aa6130fa565b60005b6005811015612c4e5780612a4f576101e0830151604051631d9fd14560e11b815260ff90911660048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc7590633b3fa28a906024015b60c06040518083038186803b158015612a1057600080fd5b505af4158015612a24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a489190613332565b9150612bc5565b8060011415612a995761020083015160405163105aefa760e01b815260ff90911660048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc759063105aefa7906024016129f8565b8060021415612ae35761022083015160405163328e76af60e21b815260ff90911660048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc759063ca39dabc906024016129f8565b8060031415612b2d57610240830151604051633c43e4fb60e11b815260ff90911660048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc7590637887c9f6906024016129f8565b8060041415612bc5576102608301516040516359a18db360e11b815260ff90911660048201527359e24f4a617617443e7dc14fcbaa2fe6234ddc759063b3431b669060240160c06040518083038186803b158015612b8a57600080fd5b505af4158015612b9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc29190613332565b91505b81518351612bd39190613b4d565b600190810b900b835260208083015190840151612bf09190613b4d565b600190810b900b602084015260408201516080840151612c109190613b4d565b600190810b900b6080840152606082015160a0840151612c309190613b4d565b600190810b900b60a084015280612c4681613ca7565b9150506129ad565b50508051600190810b810b60408301526020820151810b900b6060820152949350505050565b6040805160a081018252878152602080820187905260ff8085168385015285811660608401528616608083015260008a8152601c825283812080546001600160a01b031916339081179091558152601d90915291822080549192612cd783613ca7565b9091555050600554600654612cec9088613ce2565b612cf69190613b91565b6004556000888152601b602090815260408083208451815591840151600183015580840151600290920180546060860151608087015160ff908116620100000262ff0000199282166101000261ffff19909416919096161791909117169290921790915551899133917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050505050505050565b6060600080612d9c84612dd8565b915091506000612dab85612eed565b8383604051602001612dbf939291906138b7565b60408051601f1981840301815291905295945050505050565b6000818152601b60209081526040808320815160a081018352815481526001820154938101939093526002015460ff808216928401929092526101008104821660608481019190915262010000909104909116608083015291829190612e3d82611b7b565b90506000612e4f868460200151611ab7565b60405163bc535fe360e01b81529091507363166bcfe21484217eff188d44a65bc5ba317a539063bc535fe390612e8d90869086908690600401613a3e565b60006040518083038186803b158015612ea557600080fd5b505af4158015612eb9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612ee191908101906133f4565b94509450505050915091565b606081612f115750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612f3b5780612f2581613ca7565b9150612f349050600a83613bce565b9150612f15565b60008167ffffffffffffffff811115612f6457634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612f8e576020820181803683370190505b5090505b841561300757612fa3600183613c2a565b9150612fb0600a86613ce2565b612fbb906030613b91565b60f81b818381518110612fde57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350613000600a86613bce565b9450612f92565b949350505050565b6040805161032081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101829052610200810182905261022081018290526102408101829052610260810182905261028081018290526102a081018290526102c081018290526102e0810182905261030081019190915290565b604051806105e00160405280602f906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b80356001600160a01b038116811461312f57600080fd5b919050565b8035801515811461312f57600080fd5b8051600181900b811461312f57600080fd5b600082601f830112613166578081fd5b815161317961317482613b25565b613af4565b81815284602083860101111561318d578283fd5b613007826020830160208701613c64565b805161ffff8116811461312f57600080fd5b805161312f81613d73565b6000602082840312156131cc578081fd5b611a6182613118565b600080604083850312156131e7578081fd5b6131f083613118565b91506131fe60208401613118565b90509250929050565b60008060006060848603121561321b578081fd5b61322484613118565b925061323260208501613118565b9150604084013590509250925092565b60008060008060808587031215613257578081fd5b61326085613118565b935061326e60208601613118565b925060408501359150606085013567ffffffffffffffff811115613290578182fd5b8501601f810187136132a0578182fd5b80356132ae61317482613b25565b8181528860208385010111156132c2578384fd5b81602084016020830137908101602001929092525092959194509250565b600080604083850312156132f2578182fd5b6132fb83613118565b91506131fe60208401613134565b6000806040838503121561331b578182fd5b61332483613118565b946020939093013593505050565b600060c08284031215613343578081fd5b82601f830112613351578081fd5b60405160c0810181811067ffffffffffffffff8211171561337457613374613d44565b604052808360c08101861015613388578384fd5b835b60068110156133b15761339c82613144565b8352602092830192919091019060010161338a565b509195945050505050565b6000602082840312156133cd578081fd5b8135611a6181613d5a565b6000602082840312156133e9578081fd5b8151611a6181613d5a565b60008060408385031215613406578182fd5b825167ffffffffffffffff8082111561341d578384fd5b61342986838701613156565b9350602085015191508082111561343e578283fd5b5061344b85828601613156565b9150509250929050565b60006103208284031215613467578081fd5b61346f613aca565b61347883613144565b815261348660208401613144565b602082015261349760408401613144565b60408201526134a860608401613144565b60608201526134b960808401613144565b60808201526134ca60a08401613144565b60a08201526134db60c0840161319e565b60c08201526134ec60e084016131b0565b60e08201526101006134ff8185016131b0565b908201526101206135118482016131b0565b908201526101406135238482016131b0565b908201526101606135358482016131b0565b908201526101806135478482016131b0565b908201526101a06135598482016131b0565b908201526101c061356b8482016131b0565b908201526101e061357d8482016131b0565b9082015261020061358f8482016131b0565b908201526102206135a18482016131b0565b908201526102406135b38482016131b0565b908201526102606135c58482016131b0565b908201526102806135d78482016131b0565b908201526102a06135e98482016131b0565b908201526102c06135fb8482016131b0565b908201526102e061360d8482016131b0565b9082015261030061361f8482016131b0565b908201529392505050565b60006020828403121561363b578081fd5b5035919050565b60008060008060808587031215613657578182fd5b5050823594602084013594506040840135936060013592509050565b600080600080600060a0868803121561368a578283fd5b853594506020860135935060408601359250606086013591506136af60808701613134565b90509295509295909350565b600080604083850312156136cd578182fd5b8235915060208301356136df81613d73565b809150509250929050565b6000602082840312156136fb578081fd5b8151611a6181613d73565b6000815180845261371e816020860160208601613c64565b601f01601f19169290920160200192915050565b805160010b8252602081015161374d602084018260010b9052565b506040810151613762604084018260010b9052565b506060810151613777606084018260010b9052565b50608081015161378c608084018260010b9052565b5060a08101516137a160a084018260010b9052565b5060c08101516137b760c084018261ffff169052565b5060e08101516137cc60e084018260ff169052565b506101008181015160ff90811691840191909152610120808301518216908401526101408083015182169084015261016080830151821690840152610180808301518216908401526101a0808301518216908401526101c0808301518216908401526101e08083015182169084015261020080830151821690840152610220808301518216908401526102408083015182169084015261026080830151821690840152610280808301518216908401526102a0808301518216908401526102c0808301518216908401526102e080830151821690840152610300808301519182168185015290610994565b7f646174613a746578742f706c61696e2c7b226e616d65223a224d696e65722025815261323360f01b6020820152600084516138fa816022850160208901613c64565b7f222c226465736372697074696f6e223a22416e2065736361706520617474656d6022918401918201527f7074207468726f75676820746865206461726b2064756e67656f6e2e222c226160428201526b747472696275746573223a5b60a01b6062820152845161397281606e840160208901613c64565b6a2e961134b6b0b3b2911d1160a91b606e9290910191820152835161399e816079840160208801613c64565b61227d60f01b60799290910191820152607b0195945050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906139ed90830184613706565b9695505050505050565b8281526103408101611a616020830184613732565b602081526000611a616020830184613706565b60208082526005908201526437bbb732b960d91b604082015260600190565b60006109a082019050845182526020808601518184015260ff604087015116604084015260ff606087015116606084015260ff6080870151166080840152613a8960a0840186613732565b6103c083018460005b602f811015613aaf57815183529183019190830190600101613a92565b50505050949350505050565b61032081016109ad8284613732565b604051610320810167ffffffffffffffff81118282101715613aee57613aee613d44565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715613b1d57613b1d613d44565b604052919050565b600067ffffffffffffffff821115613b3f57613b3f613d44565b50601f01601f191660200190565b60008160010b8360010b82821282617fff03821381151615613b7157613b71613d18565b82617fff19038212811615613b8857613b88613d18565b50019392505050565b60008219821115613ba457613ba4613d18565b500190565b600060ff821660ff84168060ff03821115613bc657613bc6613d18565b019392505050565b600082613bdd57613bdd613d2e565b500490565b6000816000190483118215151615613bfc57613bfc613d18565b500290565b600060ff821660ff84168160ff0481118215151615613c2257613c22613d18565b029392505050565b600082821015613c3c57613c3c613d18565b500390565b600060ff821660ff841680821015613c5b57613c5b613d18565b90039392505050565b60005b83811015613c7f578181015183820152602001613c67565b838111156109945750506000910152565b600081613c9f57613c9f613d18565b506000190190565b6000600019821415613cbb57613cbb613d18565b5060010190565b600060ff821660ff811415613cd957613cd9613d18565b60010192915050565b600082613cf157613cf1613d2e565b500690565b600060ff831680613d0957613d09613d2e565b8060ff84160691505092915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114613d7057600080fd5b50565b60ff81168114613d7057600080fdfe646174613a746578742f706c61696e2c7b226e616d65223a2244756e67656f6e204d696e657273222c226465736372697074696f6e223a2244756e67656f6e204d696e65727320697320612066756c6c79206f6e2d636861696e2c2070726f6365647572616c6c792d67656e6572617465642064756e67656f6e20637261776c657220776865726520706c61796572732063616e206d696e6520666f7220616e64206d696e74204e46547320746861742065766f6c7665206173206d6f726520616e64206d6f7265204e46547320617265206d696e74656420696e20616e20617474656d707420746f2065736361706520612034382d6368616d6265722064756e67656f6e20616e642077696e20455448207072697a65732e222c22696d616765223a22646174613a696d6167652f7376672b786d6c3b6261736536342c50484e325a79423462577875637a30696148523063446f764c336433647935334d793576636d63764d6a41774d43397a646d6369494864705a48526f505349784d44416c4969426f5a576c6e61485139496a45774d43556949485a705a58644362336739496a41674d4341324e4341324e43496763484a6c63325679646d56426333426c5933525359585270627a3069654531705a466c4e615751676257566c6443492b5047526c5a6e4d2b504731686332736761575139496d39744969427459584e725657357064484d39496e567a5a584a546347466a5a55397556584e6c496a3438636d566a6443423361575230614430694e694967614756705a326830505349334969426d615778735053496a5a6d5a6d4969382b50484a6c59335167654430694d694967655430694d53496764326c6b64476739496a49694947686c6157646f644430694e5349675a6d6c7362443069497a41774d434976506a77766257467a617a34386257467a617942705a443069636d30694947316863327456626d6c30637a306964584e6c636c4e7759574e6c5432355663325569506a78795a574e30494864705a48526f505349324969426f5a576c6e61485139496a636949475a706247773949694e6d5a6d59694c7a3438636d566a644342345053497949694235505349784969423361575230614430694d694967614756705a3268305053497a4969426d615778735053496a4d4441774969382b5043397459584e72506a78775958526f49476c6b50534a6b4969426b50534a4e4d437777614456324d576778646a566f4c5446324d5767744e586f6949484e306557786c50534a7459584e724f6e56796243676a623230704969382b504842686447676761575139496e556949475139496b30774c44426f4d6e593261444a324c545a6f4d6e59336143303265694976506a78775958526f49476c6b50534a754969426b50534a4e4d437777614446324d576778646a466f4d585978614446324c544e6f4d6e593361433078646930786143307864693078614330786469307861433078646a4e6f4c544a364969382b504842686447676761575139496d636949475139496b30774c44426f4e6e5979614330796469307861433079646a566f4d6e59744d6d67744d5859744d57677a646a526f4c545a364969382b504842686447676761575139496d556949475139496b30774c44426f4e6e597861433030646a4a6f4d3359786143307a646a4a6f4e4859786143303265694976506a78775958526f49476c6b50534a764969426b50534a4e4d43777761445a324e3267744e6e6f6949484e306557786c50534a7459584e724f6e56796243676a623230704969382b504842686447676761575139496d306949475139496b30774c44426f4d585978614446324d576778646a466f4d5859744d57677864693078614446324c54466f4d585933614330796469307a61433078646a4a6f4c5446324c544a6f4c5446324d3267744d6e6f694c7a343863474630614342705a443069615349675a443069545441734d476732646a466f4c544a324e576779646a466f4c545a324c54466f4d6e59744e5767744d6e6f694c7a343863474630614342705a443069636949675a443069545441734d476732646a526f4c5446324d576778646a4a6f4c544a324c544a6f4c544a324d6d67744d6e6f6949484e306557786c50534a7459584e724f6e56796243676a636d30704969382b504842686447676761575139496e4d6949475139496b30774c44426f4e6e5979614330796469307861433079646a4a6f4e485930614330326469307961444a324d576779646930796143303065694976506a786e49476c6b50534a6b6457356e5a573975496a343864584e6c494768795a57593949694e6b49694230636d467563325a76636d3039496e52795957357a624746305a5367774c4451704969382b5048567a5a53426f636d566d5053496a6453496764484a68626e4e6d62334a7450534a30636d4675633278686447556f4e7977794b534976506a78316332556761484a6c5a6a306949323469494852795957357a5a6d39796254306964484a68626e4e735958526c4b4445304c4445704969382b5048567a5a53426f636d566d5053496a5a79496764484a68626e4e6d62334a7450534a30636d4675633278686447556f4d6a45734d436b694c7a343864584e6c494768795a57593949694e6c49694230636d467563325a76636d3039496e52795957357a624746305a5367794f4377784b534976506a78316332556761484a6c5a6a306949323869494852795957357a5a6d39796254306964484a68626e4e735958526c4b444d314c4449704969382b5048567a5a53426f636d566d5053496a6269496764484a68626e4e6d62334a7450534a30636d4675633278686447556f4e4449734e436b694c7a34384c32632b5047636761575139496d3170626d56796379492b5048567a5a53426f636d566d5053496a6253496764484a68626e4e6d62334a7450534a30636d4675633278686447556f4d7977794b534976506a78316332556761484a6c5a6a306949326b69494852795957357a5a6d39796254306964484a68626e4e735958526c4b4445784c4445704969382b5048567a5a53426f636d566d5053496a6269496764484a68626e4e6d62334a7450534a30636d4675633278686447556f4d5467734d436b694c7a343864584e6c494768795a57593949694e6c49694230636d467563325a76636d3039496e52795957357a624746305a5367794e5377774b534976506a78316332556761484a6c5a6a306949334969494852795957357a5a6d39796254306964484a68626e4e735958526c4b444d794c4445704969382b5048567a5a53426f636d566d5053496a6379496764484a68626e4e6d62334a7450534a30636d4675633278686447556f4d7a6b734d696b694c7a34384c32632b5043396b5a575a7a506a78795a574e304947686c6157646f644430694e6a5169494864705a48526f505349324e4349675a6d6c7362443069497a41354d44677759694976506a786e494852795957357a5a6d39796254306964484a68626e4e735958526c4b4467734d546770496a34385a7a3438636d566a64434234505349794d79496764326c6b64476739496a49694947686c6157646f644430694d6a676949475a706247773949694d334e54526a4d6a51694c7a3438636d566a64434234505349794d79496764326c6b64476739496a45694947686c6157646f644430694d6a676949475a706247773949694d34597a59794d7a6b694c7a3438636d566a64434234505349794d794967655430694e53496764326c6b64476739496a49694947686c6157646f644430694d5349675a6d6c7362443069636d6469595367774c4441734d4377774c6a49704969382b50484268644767675a443069545449734f4767786469307961444a324c54466f4d3359744d57673064693078614456324c54466f4e5859744d576730646a466f4e585978614456324d576730646a466f4d33597861444a324d6d6778646a466f4c5446324c54466f4c544a324c54466f4c544e324c54466f4c5452324c54466f4c5456324c54466f4c5456324d5767744e4859744d5767744e58597861433031646a466f4c5452324d5767744d33597861433079646a466f4c5446364969426d615778735053496a4f5455354e546b314969382b50484268644767675a443069545449734f4767786469307961444a324c54466f4d3359744d57673064693078614456324c54466f4e5859744d576730646a466f4c5452324d5767744e58597861433031646a466f4c5452324d5767744d33597861433079646a4a6f4c5446364969426d6157787350534a795a324a684b4449314e5377794e5455734d6a55314c4441754d696b694c7a3438634746306143426b50534a4e4d6a49734e47673064693078614456324d576731646a466f4e48597861444e324d576779646a466f4d585978614330786469307861433079646930786143307a646930786143303064693078614330316469307861433031646a466f4c5452364969426d6157787350534a795a324a684b4441734d4377774c4441754d696b694c7a34384c32632b5048567a5a53426f636d566d5053496a5a4856755a3256766269496764484a68626e4e6d62334a7450534a30636d4675633278686447556f4d4377344b5349675a6d6c7362443069497a55794d32597959794976506a78316332556761484a6c5a6a306949323170626d56796379496764484a68626e4e6d62334a7450534a30636d4675633278686447556f4d4377784f436b6949475a706247773949694d314d6a4e6d4d6d4d694c7a343864584e6c494768795a57593949694e6b6457356e5a57397549694230636d467563325a76636d3039496e52795957357a624746305a5367774c4463704969426d615778735053496a5a6d5a6d4969382b5048567a5a53426f636d566d5053496a62576c755a584a7a49694230636d467563325a76636d3039496e52795957357a624746305a5367774c4445334b5349675a6d6c736244306949325a6d5a694976506a77765a7a34384c334e325a7a343d222c2265787465726e616c5f6c696e6b223a2268747470733a2f2f64756e67656f6e6d696e6572732e636f6d222c2273656c6c65725f6665655f62617369735f706f696e7473223a3235302c226665655f726563697069656e74223a22307837396163353346363337323836383446354232314236333032464335436566354138453862376539227da2646970667358221220e7b2ecc9721e5771c48ca2698d0f7d61bcefdca21f9c82c82ab9dbfbed20420d64736f6c63430008040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000096c74cdba40fab71b765655cad7ab0411696af54
-----Decoded View---------------
Arg [0] : treasuryAddress (address): 0x96C74cdba40faB71B765655CaD7AB0411696Af54
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000096c74cdba40fab71b765655cad7ab0411696af54
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.